24-Kubernetes-1
1、kubenetes安装
(1)环境准备
关闭防火墙,关闭selinux
| 角色 | 主机名 | IP | 最小配置 | 建议配置 | 操作系统 |
|---|---|---|---|---|---|
| Master 节点 | master01 | 192.168.88.10 | 2C4G | 2C4G | Rockylinux 9.4 |
| Worker 节点 | worker01 | 192.168.88.20 | 2C2G | 2C4G | Rockylinux 9.4 |
Master 节点需要运行 apiserver、etcd、scheduler、controller-manager 等组件,管理整个集群,所以对配置要求比较高,至少是 2 核 CPU、4GB 的内存。
而 Worker 节点没有管理工作,只运行业务应用,所以配置可以低一些,为了节省资源可以给它分配 2 核 CPU 和 2GB 的内存。
基于模拟生产环境的考虑,在 Kubernetes 集群之外还需要有一台起辅助作用的服务器。它的名字叫 Console,意思是控制台,我们要在上面安装命令行工具 kubectl,所有对Kubernetes 集群的管理命令都是从这台主机发出去的。这也比较符合实际情况,因为安全的原因,集群里的主机部署好之后应该尽量少直接登录上去操作。要提醒你的是,Console 这台主机只是逻辑上的概念,不一定要是独立,完全可以复用 Master/Worker 节点作为控制。
(2)配置主机名(全)
[root@localhost ~]# hostnamectl set-hostname worker01
[root@localhost ~]# hostnamectl set-hostname master01
[root@localhost ~]# vi /etc/hosts
192.168.88.10 master01
192.168.88.10 worker01
(3)关闭交换分区(全)
swapoff -a; sed -i '/swap/d' /etc/fstab
(4)配置时间同步(全)
yum -y install chrony
# 修改配置文件 /etc/chrony.conf ,添加如下行
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
# 启动服务
systemctl restart chronyd
systemctl enable chronyd
# 检查状态
chronyc tracking
(5)修改内核参数(全)
cat >>/etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# net.ipv4.ip_forward = 1 启用了IPv4的IP转发功能,允许服务器作为网络路由器转发数据包。
# net.bridge.bridge-nf-call-iptables = 1 当使用网络桥接技术时,将数据包传递到iptables进行处理。
(6)安装容器进行时(全)
dnf install -y yum-utils
# 使用 阿里云仓库
dnf config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 containerd
dnf -y install containerd.io-1.7.29
修改 containerd 配置文件
# 创建默认配置文件
cd /etc/containerd
mv config.toml config.toml.orig
containerd config default > /etc/containerd/config.toml
# 修改 Containerd cgroup 配置
sed -i "s#SystemdCgroup\ \=\ false#SystemdCgroup\ \=\ true#g" /etc/containerd/config.toml
# grep -i SystemdCgroup /etc/containerd/config.toml
# SystemdCgroup = true # false 改为 true
# 修改 sandbox 沙箱镜像地址(就是 pause 镜像地址)
sed -i "s#registry.k8s.io#registry.aliyuncs.com/google_containers#g" /etc/containerd/config.toml
# grep -i sandbox_image /etc/containerd/config.toml
# sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8"
# 修改镜像仓库 从 registry.k8s.io 修改为 阿里云
启动 containerd 服务
Bash
systemctl enable --now containerd
systemctl status containerd
ctr version
(7)安装 kubeadm 和 k8s 组件
k8s 官方的仓库访问受限,我们使用阿里云的仓库
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/rpm/repodata/repomd.xml.key
EOF
#安装
dnf install -y kubeadm-1.32.2 kubelet-1.32.2 kubectl-1.32.2
#启动服务
systemctl enable --now kubelet
(8)master节点配置(M)
2.1 生成 kubeadm 初始化的配置文件
kubeadm config print init-defaults > kubeadm-config.yaml
2.2 修改配置文件
默认生成的kubeadm初始化配置文件 kubeadm-config.yaml 需要修改以下内容:
localAPIEndpoint:
advertiseAddress: 10.206.0.12 # 修改为 master节点IP地址,如果使用公有云,配置虚机的内网地址
bindPort: 6443
... ...
imageRepository: registry.aliyuncs.com/google_containers # 修改为阿里云镜像仓库
kind: ClusterConfiguration
kubernetesVersion: 1.32.2 # # 需要安装的 k8s 版本号
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 # 添加 pod 网络 CIDR 地址
2.3 下载集群初始化所需镜像
# 查看 Kubernetes 初始化需要用到的镜像
[root@master-01 ~]# kubeadm config --config=kubeadm-config.yaml images list
# 下载初始化需要用的镜像
[root@master-01 ~]# kubeadm config --config=kubeadm-config.yaml images pull
# 查看下载后的镜像 使用 ctr 命令
[root@master-01 ~]# ctr -n k8s.io image list
2.4 集群初始化
执行 kubeadm init 命令来初始化集群
kubeadm init --config=kubeadm-config.yaml
2.5 配置 kubectl 的认证文件
在 master 节点 执行以下 3 条命令,会生成文件 $HOME/.kube/config ,kubectl 需要使用此文件连接集群。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
2.6 验证集群
执行 kubectl get nodes 命令,可以看到 master-01 节点已经成功加入集群。
[root@master-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-01 NotReady control-plane 68s v1.32.2
(9)worker节点配置(W)
Worker 节点加入集群 (在 worker 节点执行)
在 worker 节点 只需要执行在集群初始化成功输出的 kubeadm join 命令即可。
kubeadm join 192.168.88.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:eafa1cd5876b2633d85b2c93db24345dde1c254989761c832c9a8a39074e8461
返回 master 节点 执行 kubectl get nodes 命令,可以发现 worker 节点也成功加入了集群。
[root@master01 ~]# kubeadm token create --print-join-command
kubeadm join 192.168.88.10:6443 --token ytx5ko.v10hywmdykk3obd0 --discovery-token-ca-cert-hash sha256:eafa1cd5876b2633d85b2c93db24345dde1c254989761c832c9a8a39074e8461
[root@master-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-01 NotReady control-plane 4m39s v1.32.2
worker-01 NotReady <none> 2m2s v1.32.2
(10)安装网络插件(全)
我们使用 Calico 网络插件,calico 用到的镜像在 hub.docker.com 上,国内需要配置加速器,或者导入离线镜像。
# 导入镜像, ctr 是 containerd 的客户端命令
ctr -n k8s.io image import calico-3.29.2.image '所有节点都要执行'
# 下载 calico YAML 文件
curl https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/calico.yaml -O
# 安装 calico 插件
kubectl create -f calico.yaml '只需要在master节点执行'
执行以下命令检查 calico 是否安装成功
[root@master-01 ~]# kubectl -n kube-system get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-77969b7d87-ftjnt 1/1 Running 0 4m40s 10.244.184.66 master-01 <none> <none>
calico-node-jlknl 1/1 Running 0 4m40s 10.206.0.10 worker-01 <none> <none>
calico-node-knkhg 1/1 Running 0 4m40s 10.206.0.12 master-01 <none> <none>
Calico 安装成功后,再次检查节点状态显示为 Ready。
[root@master-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-01 Ready control-plane 57m v1.32.2
worker-01 Ready <none> 54m v1.32.2
(11)验证安装结果
#控制面组件状态显示 Healthy
[root@master-01 ~]# kubectl get cs
#所有 Pod 状态为 Running
[root@master-01 ~]# kubectl get pods -A
(12)设置命令行补全
dnf -y install bash-completion
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
2、容器运行时工具
(1)containerd
1)Containerd 简介
containerd 最初是 Docker Engine 的核心组件,后来因各种原因被捐赠给 CNCF(云原生计算基金会)。作为一个符合 OCI(Open Container Initiative)规范的容器运行时,containerd 专注于镜像和容器的管理,现已发展成为 Kubernetes 默认的容器运行时之一。
从 Kubernetes 1.24 版本开始,Kubernetes 不再直接支持 Docker,而是推荐使用 containerd 或其他符合 CRI(Container Runtime Interface)的运行时。因此,掌握 containerd 的配置和使用已成为 Kubernetes 运维和开发的必备技能。
2)Containerd 安装
Yum 方式安装
yum install -y yum-utils
# 使用 阿里云仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 containerd
yum -y install containerd.io-1.7.25
#修改 containerd 配置文件
# 创建默认配置文件
cd /etc/containerd
mv config.toml config.toml.orig
containerd config default > /etc/containerd/config.toml
#启动 containerd 服务
systemctl enable --now containerd
systemctl status containerdctr version
二进制方式安装
#下载安装包
官网有两种类型的安装包
containerd-1.7.25-linux-amd64.tar.gz[1]** **: 只包含 containerd,如果只需要运行容器,用 docker 就好了, containerd 用起来还是不顺手。***
cri-containerd-cni-1.7.25-linux-amd64.tar.gz[2]\****: 包含 containerd 和 runc,还在systemd 文件,如果是在 Kubernetes 中使用,建议选择这个安装包。
# 下载
cd /tmp/
wget https://github.com/containerd/containerd/releases/download/v1.7.25/cri-containerd-cni-1.7.25-linux-amd64.tar.gz
# 解压
mkdir -p /tmp/containerd
tar xvf cri-containerd-cni-1.7.25-linux-amd64.tar.gz -C /tmp/containerdcd /tmp/containerd
#安装
# 复制 containerd 二进制文件到 PATH 目录
mv -v usr/local/bin/* /usr/local/bin/
mv -v usr/local/sbin/runc /usr/local/sbin/
# 复制 containerd 启动文件
mv etc/systemd/system/containerd.service /usr/lib/systemd/system/
# 生成 containerd 配置文件
mkdir /etc/containerd
cd /etc/containerd
containerd config default > /etc/containerd/config.toml
# 以下步骤仅在 kubernetes 使用 Containerd 做 CR 的时候执行。
# 复制 CNI 插件 mv opt/* /opt/
# 复制 CNI 配置文件 mv etc/cni /etc/
# 复制 crictl 配置文件 mv etc/crictl.yaml /etc/
#启动服务
systemctl enable --now containerd
systemctl status containerd
# ctr version
Client: Version: v1.7.25
Revision: bcc810d6b9066471b0b6fa75f557a15a1cbf31bb
Go version: go1.22.10
Server: Version: v1.7.25
Revision: bcc810d6b9066471b0b6fa75f557a15a1cbf31bb
UUID: 55afd148-6867-4674-9b3e-961246af9c05
# crictl version
Version: 0.1.0
RuntimeName: containerd
RuntimeVersion: v1.7.25
RuntimeApiVersion: v1
3)Containerd 镜像加速器配置
'修改 containerd 配置文件 /etc/containerd/config.toml
# 在配置文件 161 行,修改以下配置:
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
# 在 config_path 后面添加一个目录
config_path = "/etc/containerd/certs.d"
'创建加速器配置文件
mkdir -p /etc/containerd/certs.d/
cd /etc/containerd/certs.d/
mkdir docker.io
cd docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://registry-1.docker.io"
[host."https://docker.mirrors.ustc.edu.cn"]
capabilities = ["pull", "resolve"]
EOF
'加速器可以配置多个,阿里云、华为云、腾讯云都提供镜像加速器,需要注册镜像服务后才能看到。
[host."https://hub-mirror.c.163.com"]
capabilities = ["pull", "resolve"]
[host."https://docker.mirrors.ustc.edu.cn"]
capabilities = ["pull", "resolve"]
[host."https://reg-mirror.qiniu.com"]
capabilities = ["pull", "resolve"]
[host."https://docker.m.daocloud.io"]
capabilities = ["pull", "resolve"]
4)Containerd 镜像管理
# 拉取 nginx 镜像
ctr images pull --all-platforms --hosts-dir "/etc/containerd/certs.d" docker.io/library/nginx:latest
# 如果镜像拉取失败,添加 debug 参数 查看详细信息
ctr --debug images pull --all-platforms --hosts-dir "/etc/containerd/certs.d" docker.io/library/nginx:latest
# 查看镜像
ctr images ls
# containerd 中也有 namespace, 默认是 default
ctr -n default images ls
# Kubernetes 使用 k8s.io 的命名空间
ctr ns ls
NAME LABELS default k8s.io
# 导入镜像
ctr images import nginx.img
# 导出镜像
ctr images export nginx.img docker.io/library/nginx:latest
# 镜像重命名
ctr images tag docker.io/library/nginx:latest reg.chijinjing.cn/library/nginx:latest、
5)Containerd 连接 Harbor 仓库
Harbor 是我们工作中使用比较多的私有镜像仓库,看一下如何使用 ctr 连接 harbor 仓库 。
# 拉取镜像
ctr images pull --all-platforms --hosts-dir "/etc/containerd/certs.d" docker.io/library/busybox:latest
# 镜像重命名
ctr images tag docker.io/library/busybox:latest reg.chijinjing.cn/library/busybox:latest
# 推送镜像
ctr images push --user=admin reg.chijinjing.cn/library/busybox:latest
#注意在拉取镜像的时候要加 --all-platforms,否则推送镜像时会有报错。
ctr images pull --user admin:Harbor12345 www.sxtb.online/os/rockylinux:9
#创建 Harbor 认证的 Secret
替换 <Harbor用户名>、<Harbor密码>(注意:如果是 Harbor 2.x,密码建议用「机器人账号」或「普通用户密码」,不要用 admin 的初始密码):
kubectl create secret docker-registry harbor-secret \
--docker-server=www.sxtb.online \
--docker-username=<你的Harbor用户名> \
--docker-password=<你的Harbor密码> \
--docker-email=your@email.com # 邮箱可选
#修改 Pod YAML,添加 imagePullSecrets
这样即使不依赖本地镜像,kubelet 也能主动从 Harbor 拉取:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
# 添加这行,引用 Harbor 认证 Secret
imagePullSecrets:
- name: harbor-secret
6)Containerd 容器管理
Containerd 创建容器时跟 docker 不太一样, Containerd 创建容器时分静态容器 和 动态容器。
静态容器:只是容器的一个声明,没有真正运行。•动态容器:就像 docker run 一样 启动容器。
# 创建静态容器
ctr containers create docker.io/library/nginx:latest nginx-01
# 查看静态容器
ctr containers ls
CONTAINER IMAGE RUNTIME nginx-01 docker.io/library/nginx:latest io.containerd.runc.v2
# 启动动态容器
ctr task start -d nginx-01
# 查看动态容器
ctr task ls
TASK PID STATUS nginx-01 10367 RUNNING
Containerd 也提供一个命令 可以直接运行容器
ctr run -d docker.io/library/nginx:latest nginx_web
# ctr task ls
TASK PID STATUS nginx-01 10367 RUNNINGnginx-02 16524 RUNNING
# 暂停容器
ctr task pause nginx-02
# ctr task ls
TASK PID STATUS nginx-01 10367 RUNNINGnginx-02 16524 PAUSED
# 恢复容器
ctr task resume nginx-02
# ctr task ls
TASK PID STATUS nginx-01 10367 RUNNINGnginx-02 16524 RUNNING
# 进入容器 --exec-id 后面跟一个唯一标识ID,随便写就行
ctr task exec -t --exec-id 123 nginx-02 bash
(2)CRI客户端
1)介绍
crictl 是容器运行时接口 CRI 的客户端工具,主要在 Kubernetes 的场景下用来管理容器。 ctr 命令是 Containerd 的客户端,但使用体验不太好,在 Kubernetes 集群中可以使用 crictl 来代替,接下来我们看一下如何使用 crictl 来管理容器和镜像。
2)安装和配置
#Yum 安装
yum -y install cri-tools
#二进制安装
VERSION="v1.30.0" # check latest version in /releases page
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
#crictl 默认从以下位置搜索容器运行时
•`unix:///run/containerd/containerd.sock`•`unix:///run/crio/crio.sock`•`unix:///var/run/cri-dockerd.sock`
#建议通过 配置文件 来指定 容器运行时的位置
cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: false
EOF
3)镜像管理
# 查看镜像
crictl image ls
IMAGE TAG IMAGE ID SIZE
registry.aliyuncs.com/google_containers/coredns v1.11.3 c69fa2e9cbf5f 18.6MB
registry.aliyuncs.com/google_containers/etcd 3.5.16-0 a9e7e6b294baf 57.7MB
# 如果使用 ctr 命令在 Kubernetes 中查看镜像,注意要加 -n 参数
ctr -n=k8s.io images ls
# 拉取镜像
crictl pull busybox
# 查看镜像详细信息
crictl inspecti busybox
# crictl 没有针对镜像的 push 和 tag 命令
4)容器管理
# 查看所有容器,包含已经退出的
crictl ps -a
# 查看容器日志,--since 定义显示最近多长时间的日志
crictl logs --since 10m ec9fe7d065ed7
5)Pod 管理
# 查看 Pod
[root@master-01 ~]# crictl pods --namespace kube-system
(3)容器命令nerdctl
1)介绍
Kubernetes 容器运行时 从 Docker 切换到 Containerd 之后,使用 ctr 或 crictl 命令管理容器和镜像都不方便,今天我们介绍一个新的命令行工具 nerdctl 。 nerdctl 是一个与 docker cli 风格兼容的 containerd 客户端工具,而且直接兼容 docker compose 的语法,容器运行时切到 containerd 后,对于已经习惯 docker 命令的用户来 说非常友好,也可以提高 containerd 的使用率。
2)安装
#从 GitHub 下载 压缩包解压即可
# 下载
wget https://github.com/containerd/nerdctl/releases/download/v2.0.3/nerdctl-2.0.3-linux-amd64.tar.gz
# 解压
tar Cxzvvf /usr/local/bin nerdctl-2.0.3-linux-amd64.tar.gz
# nerdctl version
Client:
Version: v2.0.3
3)配置
nerdctl 是用来替代 ctl 命令的,因此默认会自动搜索 containerd.sock 文件,我们也可以根据需要给 nerdctl 提供配置文件。
mkdir -p /etc/nerdctl/
cat >/etc/nerdctl/nerdctl.toml <<EOF
debug = false
debug_full = false
address = "unix:///var/run/containerd/containerd.sock"
namespace = "k8s.io"
cgroup_manager = "systemd"
hosts_dir = ["/etc/containerd/certs.d", "/etc/docker/certs.d"]
EOF
Containerd 中也有 namespace 的概念,默认使用 default ,Kubernetes 的镜像是存放在 `k8s.io` 的命名空间下,上面的配置中我们指定的默认的命名空间是 k8s.io,在 Kubernetes 的场景下比较方便,大家根据需要来配置即可。
4)镜像管理
# 下载镜像
# nerdctl pull busybox
# 查看本地镜像列表
nerdctl images
# 镜像 重命名
nerdctl tag busybox:latest reg.chijinjing.cn/library/busybox:latest
# 登录镜像仓库
nerdctl login -u=admin -p=password reg.chijinjing.cn
# 推送镜像
nerdctl push reg.chijinjing.cn/library/busybox:latest
# 导出镜像
nerdctl save nginx:1.22.1 -o nignx-1.22.1.img
导入镜像
nerdctl load -i nignx-1.22.1.img
通过上面的命令我们可以发现,nerdctl 和 docker cli 是完全兼容的,比 ctr 命令用起来顺手多了。
5)容器管理
我们看一下如何使用 nerdctl 启动容器
# 启动一个容器
nerdctl run --name=nginx-01 -d nginx:1.22.1
# 查看正在运行的容器
nerdctl ps
如果看到如下报错说明没有正确配置CNI 插件,最好是在 kubernetes 集群中使用 nerdctl,网络插件都配好了。
nerdctl run -d nginx:1.22.1
#进入到容器 shell 中
nerdctl exec -it nginx-01 sh
#查看容器日志
nerdctl logs -f nginx-01
停止容器
nerdctl stop nginx-01
nerdctl ps -a
#启动容器
nerdctl start nginx-01
nerdctl ps
#删除容器
# 强制删除容器
nerdctl rm nginx-01 --force
# 删除所有容器
nerdctl rm $(nerdctl ps -aq) --force
(4)总结
nerdctl 也支持构建镜像 和 docker compose 语法,如果有这种需求还是建议用 docker,nerdctl 主要还是用在 kubernetes 中用来替代 ctr 命令的。
下表是docker、nerdctl、ctr、crictl 四个客户端命令的对照表。

3、kubernetes命令
- Pod:Kubernetes 中最小的可部署单元,包含一个或多个共存于同一节点的容器
- Node:Kubernetes 集群中的物理机或虚拟机,作为 Pod 的运行载体
- Services:定义 Pod 集合的抽象层,提供访问这些 Pod 的稳定网络端点
- Deployment:通过创建、更新和删除操作来管理 Pod 期望状态与生命周期的控制器
- Namespace:集群内的逻辑分区,用于隔离和组织不同用户或团队的资源
查看帮助信息
# 查看 Deployment 资源的帮助(含字段说明、示例)
kubectl explain deployment
# 查看 Deployment 下的 spec 字段(深入配置)
kubectl explain deployment.spec
# 查看 Deployment.spec.template 字段(Pod 模板配置)
kubectl explain deployment.spec.template.spec.containers
# 列出集群所有可操作的资源类型(含简写、API 组)
kubectl api-resources
# 带详细信息(如命名空间、是否可缩放)
kubectl api-resources -o wide
#生成yaml文件模版
kubectl run nginx-pod --image=nginx:1.22.1 --dry-run=client -o yaml
(1)资源创建与删除
#apply 与 create 是两种不同的资源创建方式:apply 采用声明式方法,而 create 采用命令式方法。
#应用配置文件至 Pod:
kubectl apply -f <JSON/YAML配置文件>
#使用通配符批量处理 JSON/YAML 配置文件:
kubectl apply -f '*.json'
#通过配置文件创建新资源:
kubectl create -f <配置文件>
-f 选项支持目录路径或配置文件 URL:
kubectl create -f <目录路径>
或
kubectl create -f <文件URL>
#通过配置文件中指定的类型和名称删除资源:
kubectl delete -f <配置文件>
#生成pod模版
kubectl run mysql-wp -n wordpress-ns --image=harbor.sxtb.online/app/mysql:8.0 --dry-run=client -o yaml
#生成configmap模版
kubectl create cm wp-info --from-literal WORDPRESS_DB_HOST="127.0.0.1" --from-literal WORDPRESS_DB_USER="user1" --from-literal WORDPRESS_DB_PASSWORD="123456" --from-literal WORDPRESS_DB_NAME="wp" --dry-run=client -o yaml
#生成secrets模版
kubectl create -n wordpress-ns secret docker-registry my-harbor-secret --docker-server=harbor.sxtb.online --docker-username=admin --docker-password=Harbor12345 --docker-email=chijj@xxhf.cn --dry-run=client -o yaml
(2)Pod相关命令
#获取集群中所有 Pod 的 JSON 格式列表:
kubectl get pods -o json
#列出当前命名空间中的所有 Pod 并输出 YAML 格式详情:
kubectl get pods -o yaml
#以纯文本格式输出详细信息(包含各 Pod 所在节点):
kubectl get pods -o wide
#使用 -n 选项列出特定命名空间中的所有 Pod:
kubectl get pods -n <命名空间名称>
#列出集群所有 Pod:
kubectl get pods -A
#按容器重启次数排序列出所有 Pod:
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'
#列出所有处于运行状态的 Pod:
kubectl get pods --field-selector=status.phase=Running
#删除特定 Pod:
kubectl delete pod <Pod名称>
#删除所有
kubectl delete
#显示 Pod 详细信息:
kubectl describe pod <Pod名称>
#通过 YAML 文件创建 Pod:
kubectl create -f pod.yaml
或
kubectl apply -f pod.yaml
#在 Pod 的特定容器中执行命令:
kubectl exec <Pod名称> -c <容器名称> <命令>
#在 Pod 容器中启动交互式 shell 会话:
# 单容器 Pod
kubectl exec -it <Pod名称> -- /bin/sh
# 多容器 Pod
kubectl exec -it <Pod名称> -c <容器名称> -- /bin/sh
#显示所有 Pod 的资源使用统计:
kubectl top pods
#添加或更新 Pod 注解:
kubectl annotate pod <Pod名称> <键>=<值>
#添加或更新 Pod 标签:
kubectl label pod <Pod名称> 新标签=<标签名称>
#列出所有 Pod 并显示标签:
kubectl get pods --show-labels
#将本地端口转发至 Pod:
kubectl port-forward <Pod名称> <监听端口号>:<转发端口号>
#快速创建pod
kubectl run nginx-01 --image=www.sxtb.online/app/nginx:1.22.1
(3)集群管理与上下文命令
#显示集群中主节点和服务的端点信息:
kubectl cluster-info
#输出当前上下文的客户端和服务端版本信息:
kubectl version
#显示合并后的 kubeconfig 设置:
kubectl config view
#使用 jsonpath 表达式从 kubeconfig 文件中提取所有用户名称:
kubectl config view -o jsonpath='{.users[*].name}'
#显示 kubectl 当前使用的上下文:
kubectl config current-context
#显示上下文列表:
kubectl config get-contexts
#设置默认上下文:
kubectl config use-context <上下文名称>
#打印服务端支持的 API 资源(包括核心资源和自定义资源):
kubectl api-resources
#以 "组/版本" 格式打印服务端支持的 API 版本:
kubectl api-versions
#使用 --all-namespaces 选项跨所有命名空间列出目标对象:
kubectl get pods --all-namespaces
(4)DaemonSet 管理
#创建新 DaemonSet:
kubectl create daemonset <daemonset名称>
#列出一个或多个 DaemonSet:
kubectl get daemonset
#在默认编辑器中打开指定 DaemonSet 进行编辑:
kubectl edit daemonset <daemonset名称>
#删除 DaemonSet:
kubectl delete daemonset <daemonset名称>
#检查 DaemonSet 滚动更新状态:
kubectl rollout status daemonset
#显示指定命名空间中 DaemonSet 的详细信息:
kubectl describe ds <daemonset名称> -n <命名空间名称>
(5)部署管理
#列出一个或多个部署:
kubectl get deployment
#显示指定部署的详细信息(含配置、事件和状态):
kubectl describe deployment <部署名称>
#在默认编辑器中打开部署配置:
kubectl edit deployment <部署名称>
#通过指定镜像创建部署:
kubectl create deployment <部署名称> --image=<镜像名称>
#删除指定部署及其关联资源(Pod 和 ReplicaSet):
kubectl delete deployment <部署名称>
#检查部署滚动更新状态:
kubectl rollout status deployment <部署名称>
#通过更新容器镜像执行滚动更新:
kubectl set image deployment/<部署名称> <容器名称>=镜像:<新镜像版本>
#回滚到上一修订版本:
kubectl rollout undo deployment/<部署名称>
#强制替换配置文件中的资源:
kubectl replace --force -f <配置文件>
(6)事件检索与筛选
#检索系统所有资源的近期事件:
kubectl get events
#筛选仅显示警告类型事件:
kubectl get events --field-selector type=Warning
#按创建时间排序事件:
kubectl get events --sort-by=.metadata.creationTimestamp
#列出排除 Pod 相关事件的其他资源事件:
kubectl get events --field-selector involvedObject.kind!=Pod
#列出特定节点的事件:
kubectl get events --field-selector involvedObject.kind=Node,involvedObject.name=<节点名称>
#筛选排除正常类型事件:
kubectl get events --field-selector type!=Normal
(7)日志管理
#打印指定 Pod 的日志:
kubectl logs <Pod名称>
#打印最近一小时的 Pod 日志:
kubectl logs --since=1h <Pod名称>
#读取 Pod 最近 50 行日志:
kubectl logs --tail=50 <Pod名称>
#持续流式输出指定 Pod 的日志(可按容器筛选):
kubectl logs -f <Pod名称> [-c <容器名称>]
#实时持续显示 Pod 日志:
kubectl logs -f <Pod名称>
#获取指定 Pod 内容器截至当前的日志:
kubectl logs -c <容器名称> <Pod名称>
#将 Pod 日志保存至文件:
kubectl logs <Pod名称> > pod.log
#打印 Pod 前一个实例的日志:
kubectl logs --previous <Pod名称>
(8)命名空间管理
#创建新命名空间:
kubectl create namespace <命名空间名称>
#列出所有命名空间:
kubectl get namespaces
#显示指定命名空间的详细描述(含状态和资源配额):
kubectl describe namespace <命名空间名称>
#删除指定命名空间及其包含的所有资源:
kubectl delete namespace <命名空间名称>
#在默认编辑器中打开命名空间配置:
kubectl edit namespace <命名空间名称>
#显示特定命名空间内所有 Pod 的资源使用情况(CPU 和内存):
kubectl top pods --namespace=<命名空间名称>
(9)节点管理
#更新一个或多个节点的污点设置:
kubectl taint node <节点名称>
#列出集群所有节点:
kubectl get node
#从集群移除特定节点:
kubectl delete node <节点名称>
#显示所有节点的资源使用情况(CPU 和内存):
kubectl top nodes
#列出运行在特定节点上的所有 Pod:
kubectl get pods -o wide | grep <节点名称>
#添加或更新节点注解:
kubectl annotate node <节点名称> <键>=<值>
#将节点标记为不可调度:
kubectl cordon node <节点名称>
#将节点重新标记为可调度:
kubectl uncordon node <节点名称>
#安全驱逐节点所有 Pod(适用于维护或下线场景):
kubectl drain node <节点名称>
#添加或更新节点标签:
kubectl label node <节点名称> <键>=<值>
(10)副本管理
#列出集群所有副本控制器:
kubectl get rc
#列出特定命名空间中的副本控制器:
kubectl get rc --namespace=”<命名空间名称>”
#列出集群所有副本集:
kubectl get replicasets
#显示副本集详细信息:
kubectl describe replicasets <副本集名称>
#扩缩容指定资源(部署、副本集或副本控制器)的副本数量:
kubectl scale --replicas=<副本数量> <资源类型>/<资源名称>
(11)秘钥、证书管理
#创建密钥:
kubectl create secret (docker-registry | generic | tls)
#列出所有密钥:
kubectl get secrets
#显示密钥详细信息:
kubectl describe secret <密钥名称>
#删除指定密钥:
kubectl delete secret <密钥名称>
# 查看集群证书的过期时间、存储路径等信息
kubeadm certs check-expiration
# 仅查看证书过期时间
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -enddate
# 续期所有证书(有效期重置为 1 年)
kubeadm certs renew all
systemctl restart kubelet # 续期完成后,重启控制面组件(使新证书生效)
# 仅续期 apiserver 证书
kubeadm certs renew apiserver
# 仅续期 admin.conf 配置文件中的证书
kubeadm certs renew admin.conf
# 生成 CA 根证书(核心)
kubeadm certs generate-ca
# 生成 apiserver 证书(需指定集群 API 地址、节点 IP 等)
kubeadm certs generate-apiserver \
--apiserver-advertise-address=192.168.1.100 \ # 控制面 IP
--apiserver-cert-extra-sans=master1,192.168.1.101 # 额外的 SAN 域名/IP
(12)服务管理
#列出所有服务:
kubectl get services
#显示服务详细信息:
kubectl describe service <服务名称>
#通过部署创建服务:
kubectl expose deployment <部署名称> --port=<端口> --target-port=<目标端口> --type=<类型>
#编辑服务配置:
kubectl edit service <服务名称>
#列出所有服务账户:
kubectl get serviceaccounts
#显示服务账户详细信息:
kubectl describe serviceaccount <服务账户名称>
#替换服务账户(需先导出现有配置):
kubectl get serviceaccount <服务账户名称> -o yaml > serviceaccount.yaml
kubectl replace -f serviceaccount.yaml
#删除服务账户:
kubectl delete serviceaccount <服务账户名称>
(13)有状态集
列出所有有状态集:
kubectl get statefulsets
删除有状态集(保留关联 Pod):
kubectl delete statefulset <有状态集名称> --cascade=false
(24)token
#生成新的加入集群 Token
kubeadm token create
# 生成永不过期的 Token(--ttl 0 表示无过期)
kubeadm token create --ttl 0
# 生成 Token 并输出完整的 join 命令
kubeadm token create --print-join-command
# 列出所有已生成的 Token
kubeadm token list
# 删除指定 Token(替换为你的 Token 字符串)
kubeadm token delete abcdef.0123456789abcdef
# 删除所有过期 Token
kubeadm token prune
4、Pod
(1)介绍
Kubernetes 让 Pod 去编排处理容器,然后把 Pod 作为应用调度部署的最小单位,Pod 也因此成为了 Kubernetes 世界里的“原子”,基于Pod 就可以构建出更多更复杂的业务形态了。
(2)YAML描述Pod
因为 Pod 也是 API 对象,所以它也必然具有 apiVersion、kind、metadata、spec 这四个基本组成部分。
# API版本:Pod属于核心组,固定为v1
apiVersion: v1
# 资源类型:明确声明是Pod
kind: Pod
# 元数据:Pod的基础标识信息
metadata:
name: nginx-pod # Pod名称(同一命名空间内唯一)
namespace: default # 命名空间(默认default,可选)
labels: # 标签(用于Service/Deployment关联)
app: nginx # 核心标签:标识应用
env: dev # 扩展标签:标识环境
annotations: # 注解(非标识性元数据,放这里!)
key1: "value1" # 自定义注解
key2: "value2" # 支持字符串值
kubernetes.io/description: "This is a test pod" # 系统/工具类注解
# 规格:Pod的核心配置(容器、资源等)
spec:
# 容器列表:Pod的核心,一个Pod可包含多个容器(此处单容器)
containers:
- name: nginx-container # 容器名称(Pod内唯一)
image: nginx:alpine # 容器镜像(轻量版nginx,推荐指定版本)
ports: # 容器端口声明(仅标识,不映射宿主机)
- containerPort: 80 # 容器监听的端口
protocol: TCP # 协议(默认TCP,可选)
# 资源限制(可选,但推荐配置,避免资源抢占)
resources:
requests: # 容器最小资源需求(调度依据)
cpu: 100m # 100毫核(1核=1000m)
memory: 128Mi # 128兆内存
limits: # 容器最大资源上限(超出会被OOM杀死)
cpu: 500m
memory: 256Mi
# 重启策略:Pod的重启规则(默认Always)
restartPolicy: Always
#运行方法
kubectl apply -f Pod.yaml
(3)pod标签
#查看标签
kubectl get pod --show-labels
#给pod打标签
'修改yaml文件
metadata:
labels:
key: value
'命令行
kubectl label pod nginx-pod tier=front
#更新标签
'yaml文件
kubectl apply -f XXX.yaml
'命令行
kubectl label pod nginx-pod ower=abc --overwrite
#删除标签
'yaml文件
删除yaml文件内的标签,重新构建
'命令行
kubectl label pod nginx-pod tire-
#更具标签查找
基于等值查找
kubectl get pods --show-labels -l env=fat #key=value
基于集合查找
kubectl get pods --show-labels -l "dev in (fat,prov)" #key值 in (value1,value2..)
kubectl get pods --show-labels -l dev #按key值查找
(4)Pod生命周期
Pod 遵循预定义的生命周期,起始于 Pending 阶段, 如果至少其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以失败状态结束而进入 Succeeded 或者 Failed 阶段。
Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到Pod 停止或者被终止。
#挂起(Pending):
Pod 信息已经提交给了集群,但是还没有被调度器调度到合适的节点或者 Pod 里的镜像正在下载
#运行中(Running):
该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态
#成功(Succeeded):
Pod 中的所有容器都被成功终止,并且不会再重启
#失败(Failed):
Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止
#未知(Unknown):
因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败导致的
(5)容器状态
一旦调度器将 Pod 分派给某个节点,kubelet 就通过容器运行时开始为 Pod 创建容器。容器的状态有三种:Waiting(等待)、Running(运行中)和 Terminated(已终止)。
#Waiting (等待)
如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态。 处于 Waiting 状态的容器仍在运行它完成启动所需要的操作:例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等。 当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
#Running(运行中)
Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。 如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时, 你也会看到关于容器进入 Running 状态的信息。
#Terminated(已终止)
处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时, 你会看到容器进入此状态的原因、退出代码以及容器执行期间的起止时间。
如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行
(6)容器重启策略
Pod 的 spec 中包含一个 restartPolicy 字段,
可能取值包括:
Always 一直重启
OnFailure 看返回值
Never 从不重启
默认值是 Always。
restartPolicy 适用于 Pod 中的所有容器。restartPolicy 仅针对同一节点上 kubelet 的容器重启动作。当 Pod 中的容器退出时,kubelet 会按指数回退方式计算重启的延迟(10s、20s、40s、...),其最长延迟为 5 分钟。
(7)容器生命周期回调
有两个回调暴露给容器:
•PostStart
这个回调在容器被创建之后立即被执行。 但是,不能保证回调会在容器入口点(ENTRYPOINT)之前执行。
•PreStop # 优雅退出
在容器被终止之前,此回调会被调用。在容器终止之前调用,常用于在容器结束前优雅的释放资源。
YAML
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx:1.22.1
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
postStart 指的是,在容器启动后,立刻执行一个指定的操作。需要明确的是,postStart 定义的操作,虽然是在 Docker 容器 ENTRYPOINT 执行之后,但它并不严格保证顺序。也就是说,在 postStart 启动时,ENTRYPOINT 有可能还没有结束。当然,如果 postStart 执行超时或者错误,Kubernetes 会在该 Pod 的 Events 中报出该容器启动失败的错误信息,导致 Pod 也处于失败的状态。
preStop 发生的时机,则是容器被杀死之前(比如,收到了 SIGKILL 信号)。而需要明确的是,preStop 操作的执行,是同步的。所以,它会阻塞当前的容器杀死流程,直到这个 Hook 定义操作完成之后,才允许容器被杀死,这跟 postStart 不一样。
所以,在这个例子中,我们在容器成功启动之后,在 /usr/share/message 里写入了一句“欢迎信息”(即 postStart 定义的操作)。而在这个容器被删除之前,我们则先调用了 nginx 的退出指令(即 preStop 定义的操作),从而实现了容器的“优雅退出”。
5、namespace
#查看命名空间
kubectl get namespaces
#查看命名空间中的pod
kubectl get pods -n kube-system #-n指定查看哪个命名空间,不加-n 就是默认查看default的pod
#创建命名空间
'命令'
kubectl create namespace dev-games
'生成yaml文件
kubectl get ns dev-games -o yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev-games
#使用命名空间
'yaml文件内编写'
metadata:
name: nginx-pod # Pod名称(同一命名空间内唯一)
namespace: default # 命名空间(默认default,可选)
#删除命名空间
kubectl -n dev-games get all #先查看名称空间内的所有资源,确认没有用,可以删除
kubectl delete namespace dev-games
6、特殊的容器
(1)pause容器
每启动一个容器,就会产生一个pause容器
第一个启动的容器,申请一个network namespace,剩下启动的容器都加入此网络的名称空间,所以Pod内的容器共享网络。
nerdctl -n k8s.io ps | grep pause
# 1. 启动 pause 容器
nerdctl run -d --name pause \
-p 8880:80 \
--ipc=shareable \
registry.aliyuncs.com/google_containers/pause:3.8
# 2. 启动 nginx 共享 pause 的网络和 IPC
nerdctl run -d --name nginx-pause \
--net=container:pause \
--ipc=container:pause \
--pid=container:pause \
registry.cn-beijing.aliyuncs.com/xxhf/nginx:1.22.1
# 3. 启动 centos 共享 pause 的网络和 IPC
nerdctl run -it --name rocky-pause \
--net=container:pause \
--ipc=container:pause \
--pid=container:pause \
registry.cn-beijing.aliyuncs.com/xxhf/rockylinux:9 sh
#可以在容器中看到其他容器的进程
sh-5.1# ps -ef
UID PID PPID C STIME TTY TIME CMD
65535 1 0 0 08:32 ? 00:00:00 /pause
root 8 0 0 08:33 ? 00:00:00 nginx: master process nginx -g daemon off;
101 36 8 0 08:33 ? 00:00:00 nginx: worker process
101 37 8 0 08:33 ? 00:00:00 nginx: worker process
root 38 0 0 08:33 pts/0 00:00:00 sh
--net=container:<container_name>:容器与另一个指定容器共享网络命名空间。这意味着两个容器共享相同的网络栈,可以直接通信。使用此模式时,两个容器可以看到彼此的网络接口和端口。
--ipc=container:<container_name>:容器与另一个指定容器共享IPC命名空间。这使得两个容器可以直接进行IPC通信,共享相同的IPC资源。例如,可以使用这个选项在容器之间共享内存段。
--pid=container:<container_name>:容器与另一个指定容器共享PID命名空间。这使得两个容器可以共享相同的进程命名空间,进程在两个容器之间是可见的。例如,可以使用此选项在一个容器中监视和管理另一个容器的进程。
(2)InitContainer
等待其他模块 Ready:这个可以用来解决服务之间的依赖问题
初始化配置
[root@master01 ~]# vim InitContainer.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
# 添加这行,引用 Harbor 认证 Secret
imagePullSecrets:
- name: harbor-secret
containers:
- name: myapp-container
image: www.sxtb.online/os/busybox:latest
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: www.sxtb.online/os/busybox:latest
command: ['sh', '-c', "echo 123456"]
- name: init-mydb
image: www.sxtb.online/os/busybox:latest
command: ['sh', '-c',"echo 567"]
#如果 initContainers:未启动,未设置重启策略,将会一直重启,要设置RestartPolicy为Never不影响后续的容器启动
7、Job离线业务
“离线业务”可以分为两种。一种是“临时任务”,跑完就完事了,下次有需求了说一声再重新安排;另一种是“定时任务”,可以按时按点周期运行,不需要过多干预。
对应到 Kubernetes 里,“临时任务”就是 API 对象 Job,“定时任务”就是 API 对象 CronJob,使用这两个对象你就能够在 Kubernetes 里调度管理任意的离线业务了。
使用 YAML 描述 Job
Job 的 YAML“文件头”部分还是那几个必备字段:
•apiVersion 不是 v1,而是 batch/v1。
•kind 是 Job,这个和对象的名字是一致的。
•metadata 里仍然要有 name 标记名字,也可以用 labels 添加任意的标签。
使用以下命令可以生成一下 job 对象模板
比如用 busybox 创建一个“echo-job”,命令就是这样的:
Bash
# 生成 job YAML模板
[root@master01 ~]# kubectl create job echo-job --image=www.sxtb.online/os/busybox:latest --dry-run=client -o yaml
apiVersion: batch/v1
kind: Job
metadata:
creationTimestamp: null
name: echo-job
spec:
template:
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- image: www.sxtb.online/os/busybox:latest
name: echo-job
command: ["/bin/echo"]
args: ["hello","world"]
restartPolicy: Never
会生成一个基本的 YAML 文件,保存之后做点修改,就有了一个 Job 对象:
(1)job
[root@master01 ~]# kubectl apply -f job.yml
[root@master01 ~]# kubectl get job
NAME STATUS COMPLETIONS DURATION AGE
echo-job Complete 1/1 3s 2m51s
[root@master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
echo-job-qnr8c 0/1 Completed 0 19s
[root@master01 ~]# kubectl logs echo-job-qnr8c
hello world
这里列出几个控制离线作业的重要字段,其他更详细的信息可以参考 Job 文档:
•activeDeadlineSeconds,设置 job 运行的超时时间。
•backoffLimit,设置 Pod 的失败重试次数。
•completions,Job 完成需要运行多少个 Pod,默认是 1 个。
•parallelism,它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源。
要注意这 4 个字段是属于 Job 级别的,用来控制模板里的 Pod 对象。
下面我再创建一个 Job 对象,名字叫“sleep-job”,它随机睡眠一段时间再退出,模拟运行时间较长的作业。Job 的参数设置成 15 秒超时,最多重试 2 次,总共需要运行完 4 个 Pod,但同一时刻最多并发 2 个 Pod:
apiVersion: batch/v1
kind: Job
metadata:
name: sleep-job
spec:
activeDeadlineSeconds: 15
backoffLimit: 2
completions: 4
parallelism: 2
template:
spec:
imagePullSecrets:
- name: harbor-secret
restartPolicy: OnFailure
containers:
- name: echo-job
image: www.sxtb.online/os/busybox:latest
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- sleep $(($RANDOM % 10 + 1)) && echo done
[root@master01 ~]# kubectl get jobs
NAME STATUS COMPLETIONS DURATION AGE
echo-job Complete 1/1 4s 15m
sleep-job Complete 4/4 23s 41s
[root@master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
echo-job-qnr8c 0/1 Completed 0 20m
sleep-job-2blgq 0/1 Completed 0 5m23s
sleep-job-jd4fn 0/1 Completed 0 5m23s
sleep-job-kjzpx 0/1 Completed 0 5m12s
sleep-job-qqr4b 0/1 Completed 0 5m13s
(2) CronJob
使用 YAML 描述 CronJob
使用命令 kubectl create 来创建 CronJob 的样板。
要注意两点。第一,因为 CronJob 的名字有点长,所以 Kubernetes 提供了简写 cj,这个简写也可以使用命令 kubectl api-resources 看到;第二,CronJob 需要定时运行,所以我们在命令行里还需要指定参数 --schedule。
[root@master01 ~]# kubectl create cronjob echo-cj --image=busybox:latest --schedule="*/2 * * * *" --dry-run=client -o yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: echo-cj
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
imagePullSecrets:
- name: harbor-secret
restartPolicy: OnFailure
containers:
- name: echo-cj
image: www.sxtb.online/os/busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/echo"]
args: ["hello", "world"]
[root@master01 ~] # kubectl apply -f cronjob.yaml
[root@master01 ~] # kubectl get jobs
NAME STATUS COMPLETIONS DURATION AGE
echo-cj-29546606 Complete 1/1 3s 44s
[root@master01 ~] # kubectl logs echo-cj-29546606-zj5ch
hello world
[root@master01 ~] # kubectl get cj
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
echo-cj */1 * * * * <none> False 0 45s 4m
#我们还是重点关注它的 spec 字段,你会发现它居然连续有三个 spec 嵌套层次:
第一个 spec 是 CronJob 自己的对象规格声明
第二个 spec 从属于“jobTemplate”,它定义了一个 Job 对象。
第三个 spec 从属于“template”,它定义了 Job 里运行的 Pod。
所以,CronJob 其实是又组合了 Job 而生成的新对象,我还是画了一张图,方便你理解它的“套娃”结构:
8、应用配置文件
Kubernetes 里专门用来管理配置信息的两种对象:ConfigMap 和 Secret,使用它们来灵活地配置、定制我们的应用。
(1)ConfigMap
#ConfigMap 用来保存明文配置
[root@master01 ~]# kubectl create cm info --dry-run=client -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: info
#ConfigMap 存储的是配置数据,是静态的字符串,并不是容器,所以它们就不需要用“spec”字段来说明运行时的“规格”。
既然 ConfigMap 要存储数据,我们就需要用另一个含义更明确的字段“data”。
要生成带有“data”字段的 YAML 样板,你需要在 kubectl create 后面多加一个参数 --from-literal ,表示从字面值生成一些数据:
[root@master01 ~]# kubectl create cm info --from-literal=k=v --dry-run=client -o yaml
apiVersion: v1
data:
k: v
kind: ConfigMap
metadata:
name: info
#把 YAML 样板文件修改一下,再多增添一些 Key-Value,就得到了一个比较完整的 ConfigMap 对象:
apiVersion: v1
kind: ConfigMap
metadata:
name: info
data:
count: '10'
debug: 'on'
path: '/etc/systemd'
greeting: |
say hello to kubernetes.
say hi to the world.
#现在就可以使用 kubectl apply 把这个 YAML 交给 Kubernetes,让它创建 ConfigMap 对象了:
[root@master01 ~]# kubectl apply -f cm.yaml
[root@master01 ~]# kubectl get cm
NAME DATA AGE
info 4 31s
kube-root-ca.crt 1 2d
[root@master01 ~]# kubectl describe cm info
Name: info
Namespace: default
#创建 ConfigMap
•使用字面值创建
kubectl create configmap cm-conf --from-literal=debug=on --from-literal=count=10
•从目录创建
kubectl create configmap nginx-config --from-file=nginx-conf
kubectl get cm nginx-config
kubectl describe cm nginx-config
•从文件创建
kubectl create configmap nginx-config-2 --from-file=nginx-conf/default.conf
(2)Secret
#Secret 用来保存秘密配置
#Secret 有四种类型:
'Service Account Token:
用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中;
'Opaque:
base64 编码格式的 Secret,用来存储密码、密钥等 key: value
'kubernetes.io/dockerconfigjson :
用来存储私有 docker registry 的认证信息。
'kubernetes.io/tls:
•TLS(传输层安全):用于存储 TLS 证书和私钥,以支持加密通信。它可以用于需要TLS证书的场景。Https
对应具体有用途如下:
•身份识别的凭证信息
•一般的机密信息(格式由用户自行解释)
•访问私有镜像仓库的认证信息
•HTTPS 通信的证书和私钥
#我们先创建 Opaque 类型的,创建 YAML 样板的命令是 kubectl create secret generic ,同样,也要使用参数 --from-literal 给出 Key-Value 值:
'kubectl create secret generic user --from-literal=username=root --dry-run=client -o yaml
得到的 Secret 对象大概是这个样子:
apiVersion: v1
kind: Secret
metadata:
name: user
data:
username: cm9vdA==
Secret 对象第一眼的感觉和 ConfigMap 非常相似,只是“kind”字段由“ConfigMap”变成了“Secret”,后面同样也是“data”字段,里面也是 Key-Value 的数据。
这串“乱码”就是 Secret 与 ConfigMap 的不同之处,不让用户直接看到原始数据,起到一定的保密作用。不过它的手法非常简单,只是做了 Base64 编码,根本算不上真正的加密,我们可以直接使用 Linux 命令"base64" 来解密 :
# base64 解码
[root@k8s cm-sc]# echo "cm9vdA==" | base64 -d
root
# base64 编码 注意要加 -n 参数
[root@k8s cm-sc]# echo -n "mysql" | base64
bXlzcWw=
[root@k8s cm-sc]# echo -n "123456" | base64
MTIzNDU2
#我们再来重新编辑 Secret 的 YAML,为它添加两个新的数据,方式可以是参数 --from-literal 自动编码,也可以是自己手动编码:
[root@master01 ~]# kubectl create secret generic user --from-literal username=root --from-literal password=123456 --from-literal db=mysql --dry-run=client -o yaml
apiVersion: v1
data:
db: bXlzcWw=
password: MTIzNDU2
username: cm9vdA==
kind: Secret
metadata:
creationTimestamp: null
name: user
#使用 kubectl apply、kubectl get、kubectl describe 创建和查看对象:
kubectl apply -f secret.yaml
kubectl get secrets
kubectl describe secrets user
#创建Secret
#docker registry 认证的 secret
[root@master01 ~] # kubectl create -n wordpress-ns secret docker-registry my-harbor-secret --docker-server=www.sxtb.online --docker-username=admin --docker-password=Harbor12345 --docker-email=chijj@xxhf.cn --dry-run=client -o yaml
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJ3d3cuc3h0Yi5vbmxpbmUiOnsidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiSGFyYm9yMTIzNDUiLCJlbWFpbCI6ImNoaWpqQHh4aGYuY24iLCJhdXRoIjoiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9In19fQ==
kind: Secret
metadata:
creationTimestamp: null
name: my-harbor-secret
namespace: wordpress-ns
type: kubernetes.io/dockerconfigjson
#以环境变量的方式
“valueFrom”字段指定了环境变量值的来源,可以是“configMapKeyRef”或者“secretKeyRef”,然后你要再进一步指定应用的 ConfigMap/Secret 的“name”和它里面的“key”。
'kubectl explain pod.spec.containers.env.valueFrom
下面是 引用了 ConfigMap 和 Secret 对象的 Pod 定义
apiVersion: v1
kind: Pod
metadata:
name: env-pod
labels:
owner: xxhf
env: dev
spec:
containers:
- name: busy
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3000"]
env:
- name: COUNT # 环境变量名字
valueFrom:
configMapKeyRef:
name: info # configmap 名字
key: count # info configmap 中定义 count key
- name: DEBUG
valueFrom:
configMapKeyRef:
name: info
key: debug
- name: USERNAME
valueFrom:
secretKeyRef:
name: user # secret 名字
key: username # user secset 中的 username key
- name: PASSWORD
valueFrom:
secretKeyRef:
name: user
key: password
#用 kubectl apply 创建 Pod,再用 kubectl exec 进入 Pod,验证环境变量是否生效:
kubectl apply -f env-pod.yaml
kubectl exec -it env-pod -- sh
echo $COUNT
echo $DEBUG
echo $USERNAME
echo $PASSWORD
#以 Volume 的方式
Kubernetes 为 Pod 定义了一个“Volume”的概念,可以翻译成是“存储卷”。如果把 Pod 理解成是一个虚拟机,那么 Volume 就相当于是虚拟机里的磁盘。
注意: Volume 属于 Pod,不属于容器,所以它和字段“containers”是同级的,都属于“spec”。
#下面让我们来定义两个 Volume,分别引用 ConfigMap 和 Secret,名字是 cm-vol 和 sec-vol:
spec:
volumes:
- name: cm-vol # 卷名字
configMap:
name: info
- name: sec-vol
secret:
secretName: user
#使用 “volumeMounts”字段来挂载卷,可以把定义好的 Volume 挂载到容器里的某个路径下,所以需要在里面用“mountPath” “name”明确地指定挂载路径和 Volume 的名字。
containers:
- name: busy
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3000"]
volumeMounts:
- mountPath: /tmp/configmap # 挂载点
name: cm-vol # volume 的名字
- mountPath: /tmp/secret
name: sec-vol
#把“volumes”和“volumeMounts”字段都写好之后,配置信息就可以加载成文件了。
#下面是 Pod 的完整 YAML 描述,然后使用 kubectl apply 创建它.
apiVersion: v1
kind: Pod
metadata:
name: env-pod
labels:
owner: xxhf
env: dev
spec:
volumes:
- name: cm-vol
configMap:
name: info
- name: sec-vol
secret:
secretName: user
containers:
- name: busy
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sleep", "3000"]
volumeMounts:
- mountPath: /tmp/configmap
name: cm-vol
- mountPath: /tmp/secret
name: sec-vol
#创建之后,我们还是用 kubectl exec 进入 Pod,看看配置信息被加载成了什么形式:
kubectl apply -f vol-pod.yaml
kubectl get pod
kubectl exec -it env-pod -- sh
ConfigMap 和 Secret 都变成了目录的形式,而它们里面的 Key-Value 变成了一个个的文件,而文件名就是 Key。
因为这种形式上的差异,以 Volume 的方式来使用 ConfigMap/Secret,就和环境变量不太一样。
环境变量用法简单,更适合存放简短的字符串,而 Volume 更适合存放大数据量的配置文件,在 Pod 里加载成文件后让应用直接读取使用。
9、部署wordpress
(1)一个pod中部署
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
namespace: default
labels:
app: wordpress
env: web
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: wordpress
image: www.sxtb.online/app/wordpress:php7.4
ports:
- containerPort: 80
hostPort: 8080
hostIP: 0.0.0.0
protocol: TCP
env:
- name: WORDPRESS_DB_HOST
value: '127.0.0.1'
- name: WORDPRESS_DB_USER
value: 'user1'
- name: WORDPRESS_DB_PASSWORD
value: '123456'
- name: WORDPRESS_DB_NAME
value: 'wp'
- name: mysql
image: www.sxtb.online/app/mysql:8.0
securityContext:
runAsUser: 0 # 以root运行,解决权限问题
privileged: true # 提升权限
ports:
- containerPort: 3306
hostPort: 3306
hostIP: 0.0.0.0
protocol: TCP
env:
- name: MYSQL_DATABASE
value: 'wp'
- name: MYSQL_USER
value: 'user1'
- name: MYSQL_PASSWORD
value: '123456'
- name: MYSQL_ROOT_PASSWORD
value: '123456'
# 核心修复:挂载emptyDir卷到MySQL数据目录,确保目录存在且权限正确
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql # MySQL数据目录
subPath: mysql # 子路径,避免目录冲突
# 定义卷
volumes:
- name: mysql-data
emptyDir: {} # 临时存储卷,Pod删除后数据丢失(测试用)
restartPolicy: Always
[root@master01 ~]# kubectl apply -f Pod.yaml
[root@master01 ~]# kubectl port-forward --address 0.0.0.0 pod/wordpress 8080:80
(2)两个pod中部署
[root@master01 wordpress] # vim 1-prepare.yaml
# 1. 创建名称空间
apiVersion: v1
kind: Namespace
metadata:
name: wordpress-ns
---
# 2. 设置harbor仓库拉取密钥(指定命名空间)
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3h0Yi5vbmxpbmUiOnsidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiSGFyYm9yMTIzNDUiLCJlbWFpbCI6ImNoaWpqQHh4aGYuY24iLCJhdXRoIjoiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9In19fQ==
kind: Secret
metadata:
name: harbor-secret
namespace: wordpress-ns
type: kubernetes.io/dockerconfigjson
---
# 3. MySQL 配置 ConfigMap(指定命名空间)
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-info
namespace: wordpress-ns # 关键:指定命名空间
data:
MYSQL_DATABASE: wp
MYSQL_PASSWORD: "123456"
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_USER: user1
[root@master01 wordpress] # vim 2-mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-wp
namespace: wordpress-ns
labels:
run: mysql-wp
spec:
imagePullSecrets: # 新增:拉取私有 Harbor MySQL 镜像需要密钥
- name: harbor-secret
containers:
- name: mysql-wp
image: harbor.sxtb.online/app/mysql:8.0
ports: # 暴露 3306 端口
- containerPort: 3306
protocol: TCP
env: # 引用 ConfigMap 环境变量
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: mysql-info
key: MYSQL_DATABASE
- name: MYSQL_PASSWORD
valueFrom:
configMapKeyRef:
name: mysql-info
key: MYSQL_PASSWORD
- name: MYSQL_ROOT_PASSWORD
valueFrom:
configMapKeyRef:
name: mysql-info
key: MYSQL_ROOT_PASSWORD
- name: MYSQL_USER
valueFrom:
configMapKeyRef:
name: mysql-info
key: MYSQL_USER
restartPolicy: Always
[root@master01 wordpress] # vim 3-wp-info.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wp-info
namespace: wordpress-ns
data:
WORDPRESS_DB_HOST: 10.244.5.41
WORDPRESS_DB_NAME: wp
WORDPRESS_DB_PASSWORD: "123456"
WORDPRESS_DB_USER: user1
[root@master01 wordpress] # vim 4-wordpress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress-ns
labels:
app: wordpress
spec:
replicas: 5 # 5个WordPress副本
selector:
matchLabels:
app: wordpress
strategy: {} # 使用默认更新策略
template:
metadata:
labels:
app: wordpress
spec: # 核心修正:所有容器相关配置都在 template.spec 下
imagePullSecrets: # 修正缩进:放在 spec 层级
- name: harbor-secret
# 初始化容器:检测 MySQL Service 就绪(最简稳定版)
initContainers:
- name: test-mysql
image: harbor.sxtb.online/os/busybox:latest # 固定版本,保证nc可用
command:
- sh
- -c
- sleep 10 # 给MySQL初始化缓冲时间
# 主容器:WordPress
containers:
- name: wordpress
image: harbor.sxtb.online/library/wordpress:php7.4
ports:
- containerPort: 80
protocol: TCP
env:
- name: WORDPRESS_DB_HOST
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_HOST
- name: WORDPRESS_DB_NAME
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_NAME
- name: WORDPRESS_DB_PASSWORD
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_PASSWORD
- name: WORDPRESS_DB_USER
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_USER
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
#先运行1、2然后查看mysql的ip地址写到3内运行,再运行4
wp
WORDPRESS_DB_PASSWORD: “123456”
WORDPRESS_DB_USER: user1
[root@master01 wordpress] # vim 4-wordpress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress-ns
labels:
app: wordpress
spec:
replicas: 5 # 5个WordPress副本
selector:
matchLabels:
app: wordpress
strategy: {} # 使用默认更新策略
template:
metadata:
labels:
app: wordpress
spec: # 核心修正:所有容器相关配置都在 template.spec 下
imagePullSecrets: # 修正缩进:放在 spec 层级
- name: harbor-secret
# 初始化容器:检测 MySQL Service 就绪(最简稳定版)
initContainers:
- name: test-mysql
image: harbor.sxtb.online/os/busybox:latest # 固定版本,保证nc可用
command:
- sh
- -c
- sleep 10 # 给MySQL初始化缓冲时间
# 主容器:WordPress
containers:
- name: wordpress
image: harbor.sxtb.online/library/wordpress:php7.4
ports:
- containerPort: 80
protocol: TCP
env:
- name: WORDPRESS_DB_HOST
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_HOST
- name: WORDPRESS_DB_NAME
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_NAME
- name: WORDPRESS_DB_PASSWORD
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_PASSWORD
- name: WORDPRESS_DB_USER
valueFrom:
configMapKeyRef:
name: wp-info
key: WORDPRESS_DB_USER
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
#先运行1、2然后查看mysql的ip地址写到3内运行,再运行4
#
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)