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


# 
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐