[Kubernetes] controller核心管理
目录
控制器controller
controller作用及分类
controller用于控制pod
控制器主要分为:
-
Deployments 部署无状态应用,控制pod升级,回退
-
ReplicaSet 副本集,控制pod扩容,裁减
-
ReplicationController (相当于ReplicaSet的老版本,现在建议使用Deployments加ReplicaSet替代 RC)
-
StatefulSets 部署有状态应用,结合Service、存储等实现对有状态应用部署
-
DaemonSet 守护进程集,运行在所有集群节点(包括master),比如使用filebeat,node_exporter
-
Jobs 一次性
-
Cronjob 周期性
Deployment
Replicaset控制器的功能
-
支持新的基于集合的selector(以前的rc里没有这种功能)
-
通过改变Pod副本数量实现Pod的扩容和缩容
Deployment控制器的功能
-
Deployment集成了上线部署、滚动升级、创建副本、回滚等功能
-
Deployment里包含并使用了ReplicaSet
Deployment用于部署无状态应用
无状态应用的特点:
-
所有pod无差别
-
所有pod中容器运行同一个image
-
所有pod可以运行在集群中任意node上
-
所有pod无启动顺序先后之分
-
随意pod数量扩容或缩容
-
例如简单运行一个静态web程序
-

创建deployment类型应用
准备yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
# 资源限制
resources:
requests:
memory: "150Mi"
limits:
memory: "200Mi"
# 存活探针
livenessProbe:
tcpSocket:
port: http
initialDelaySeconds: 5
periodSeconds: 5
# 就绪探针
readinessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 3
periodSeconds: 3
验证
kubectl get pod

查看deployment名称
kubectl get deployment

查看replicaset名称
kubectl get replicaset
#或
kubectl get rs

访问deployment
查看pod的IP地址
kubectl get pod -o wide

可以看到pod在node2节点,pod的IP为10.244.104.10
查看所有集群节点的网卡
ifconfig tunl0 | head -2



总结:可以看到所有集群节点的IP为10.244.0.0/16这个大网段内的子网
在任意集群节点上都可以访问此deploy里的pod
ping -c 4 10.244.166.145
curl http://10.244.166.145

删除deployment中的pod
强制删除pod(注意:是删除deployment中的pod)
kubectl delete pod podname --grace-period=0 --force
再次查看,会发现又重新启动了一个pod(节点发生变化,IP发生变化)
总结:pod的IP不是固定的,就算把整个集群关闭再启动,pod也会自动启动,但是IP地址会发生变化 。既然IP地址不是固定的,所以需要一个固定的访问endpoint给用户,那么这种方式就是service
pod版本升级
查看帮助
kubectl set image -h
升级前验证nginx版本
kubectl describe pods deployment-nginx-57c677596f-fqb6v | grep Image:
kubectl exec deployment-nginx-57c677596f-fqb6v -- nginx -v

升级为1.29版本
kubectl set image deployment deploy-nginx nginx=nginx:1.29-alpine --record
kubectl exec deploy-nginx-b5d6b46fb-f56rg -- nginx -v

说明:
-
deployment deploy-nginx代表名为deploy-nginx的deployment
-
nginx=nginx:1.29-alpine前面的nginx为容器名
-
--record 表示会记录
容器名怎么查看?
-
kubectl describe pod pod名 查看
-
kubectl edit deployment deployment名 来查看容器名
-
kubectl get deployment deployment名 -o yaml 来查看容器名
验证
如果升级的pod数量较多,则需要一定时间,可通过下面命令查看是否已经成功
kubectl rollout status deployment deploy-nginx

pod版本回退
查看历史版本信息
kubectl rollout history deployment deploy-nginx

定义要回退的版本(还需要执行才是真的回退版本)
kubectl rollout history deployment deploy-nginx --revision=1

执行回退
kubectl rollout undo deployment deploy-nginx --to-revision=1

验证
回到了1.26版本,但version的ID 变了
kubectl rollout history deployment deploy-nginx
kubectl describe pod deploy-nginx-66d785bdb5-8jjdw | grep Image
kubectl exec deploy-nginx-66d785bdb5-8jjdw -- nginx -v

总结:
-
升级:kubectl set image deployment deployment-nginx c1=nginx:1.27-alpine --record
-
查看历史记录:kubectl rollout history deployment deployment-nginx
-
查看指定版本信息:kubectl rollout history deployment deployment-nginx --revision=序号
-
回退:kubectl rollout undo deployment deployment-nginx --to-revision=序号
-
无论是升级还是回退,pod都是先创建再删除
副本扩容
获取帮助
kubectl scale -h
扩容为2个副本
kubectl scale deployment deploy-nginx --replicas=2
查看
kubectl get pods -o wide

继续扩容(我们这里只有2个node,但是可以大于node节点数据)
kubectl scale deployment deployment-nginx --replicas=4

副本裁减
指定副本数为1进行裁减
kubectl scale deployment deployment-nginx --replicas=1

副本数量可以降为0,有需要就启动,无需要就停止
kubectl scale deployment deployment-nginx --replicas=0
查看(pod?deployment?replicas?)

pod没有了,但是deployment和replicaset还在
多副本滚动更新
先扩容多副本
kubectl scale deployment deployment-nginx --replicas=16

滚动更新
kubectl set image deployment deployment-nginx nginx=nginx:1.29-alpine --record

验证
kubectl describe pods deployment-nginx-78568c956b-2lwq6 | grep Image

kubectl rollout status deployment deployment-nginx

删除deployment
删除deployment,里面的pod也会被自动删除
kubectl delete deployment deployment-nginx

Replicaset
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-nginx
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
应用YAML文件,验证
kubectl get rs

kubectl get pods

kubectl get deployment

说明:找不到对应的deployment,说明创建rs并没有创建deployment
进行扩容
kubectl scale replicaset rs-nginx --replicas=4
查看副本数量
kubectl get rs
kubectl get pods

版本升级
kubectl describe pods rs-nginx-2ftcr | grep Image:

kubectl set image replicaset replicaset-nginx c1=nginx:latest --record

检查,版本并没发生变化,replicaset无法实现版本更新
kubectl describe pods rs-nginx-2ftcr | grep Image:

控制器controller进阶
DaemonSet
DaemonSet介绍
-
Daemonset能够让所有(或者特定)的节点运行同一个pod。
-
当节点加入到K8s集群中,pod会被(DaemonSet)调度到该节点上运行,当节点从K8S集群中被移 除,被Daemonset调度的pod会被移除。
-
如果删除DaemonSet,所有跟这个DaemonSet相关的pods都会被删除。
-
如果一个DaemonSet的Pod被杀死、停止、或者崩溃,那么DaemonSet将会重新创建一个新的副 本在这台计算节点上。
-
DaemonSet一般应用于日志收集、监控采集、分布式存储守护进程等。
DaemonSet应用案例
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-nginx
namespace: default
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
tolerations: #代表容忍,保证在所有节点运行(仅容忍node节点的污点,master不容忍)
- key: node-role.kubernetes.io/master #能容忍的污点key
effect: NoSchedule #能容忍的污点effect
containers:
- name: c1
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
resources: #资源限制是为了防止节点资源被占太多
requests:
memory: "150Mi"
limits:
memory: "200Mi"
应用YAML文件
kubectl apply -f daemonset-nginx.yml
验证
kubectl get daemonset

无法进行扩缩容,可以进行版本升级
kubectl describe pod daemonset-nginx-hf8kp | grep Image:
kubectl set image daemonset daemonset-nginx c1=nginx:1.29-alpine --record


总结:daemonset无法扩缩容,但可以升级回退版本
Job
job介绍
-
对于ReplicaSet而言,它希望pod保持预期数目、持久运行下去,除非用户明确删除,否则这些对象一直存在,它们针对的是耐久性任务如web服务等
-
对于非耐久性任务,比如压缩文件,任务完成后,pod需要结束运行,不需要pod继续保持在系统中,这个时候就要用到job
-
job负责批量处理短暂的一次性任务,即执行一次的任务,他保证批处理任务的一个或多个Pod成功结束。
job应用案例
- 计算圆周率2000位
apiVersion: batch/v1
kind: Job
metadata:
name: job
namespace: default
spec:
template:
metadata:
name: pod-pi
spec:
nodeName: node1
containers:
- name: job-pi
image: perl
imagePullPolicy: IfNotPresent
command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]
restartPolicy: Never

任务执行结束,变为completed
kubectl logs job-9w5tb

- 创建固定次数job
apiVersion: batch/v1
kind: Job
metadata:
name: job2
namespace: default
spec:
completions: 10 #执行的总次数
parallelism: 1 #每一步并发执行pod数量
template:
metadata:
name: job-count-pod
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ["echo","hello"]
restartPolicy: Never
查看
kubectl get pod

kubectl get job

验证输出
kubectl logs job2-4q88x

- 一次性备份MySQL数据库
通过job控制器创建应用备份MySQL数据库
1:MySQL数据库准备
vim mysqld.yml
#写入
apiVersion: v1
kind: Service
metadata:
name: mysql-test
namespace: default
spec:
ports:
- port: 3306
name: mysql
clusterIP: None #无头服务
selector:
app: mysql-dump #匹配pod名称
---
apiVersion: apps/v1
kind: StatefulSet #有状态控制器
metadata:
name: db
namespace: default
spec:
selector:
matchLabels:
app: mysql-dump
serviceName: "mysql-test"
template:
metadata:
labels:
app: mysql-dump #pod名称
spec:
nodeName: node1 #将资源创建到node1
containers:
- name: mysql #容器名称
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD #mysql管理员密码设置
value: "abc123"
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql" #数据库中数据挂载
name: mysql-data
volumes:
- name: mysql-data
hostPath:
path: /opt/mysqldata
创建用于实现任务的资源清单文件
kubectl apply -f mysqld.yml
查看资源
kubectl get pod -o wide
kubectl get statefulsets


运行在node1节点,可以查看node1节点数据库目录
ls /opt/mysqldata/

创建用于实现任务的资源清单文件
vim job_mysqld.yml
#写入
apiVersion: batch/v1
kind: Job
metadata:
name: mysql-dump
spec:
template:
metadata:
name: mysql-dump
spec:
nodeName: node2
containers:
- name: mysql-dump
image: mysql:5.7
command: ["/bin/sh","-c","mysqldump --host=mysql-test -uroot -pabc123 --databases mysql > /root/mysql_back.sql"]
volumeMounts:
- mountPath: "/root"
name: mysql-data
restartPolicy: Never
volumes:
- name: mysql-data
hostPath:
path: /opt/mysqldump
cronjob
类似于Linux系统的crontab,在指定的时间周期运行相关的任务
- 周期性输出字符
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob1
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo hello kubernetes
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
应用并验证
kubectl apply -f cronjob.yml
kubectl get cronjob

kubectl get pod

pod会每分钟生成一个
kubectl logs cronjob1-29294286-sb8g6

- 周期性备份MySQL数据库
MySQL数据库准备
vim mysqld.yml
#写入
apiVersion: v1
kind: Service
metadata:
name: mysql-test
namespace: default
spec:
ports:
- port: 3306
name: mysql
clusterIP: None #无头服务
selector:
app: mysql-dump #匹配pod名称
---
apiVersion: apps/v1
kind: StatefulSet #有状态控制器
metadata:
name: db
namespace: default
spec:
selector:
matchLabels:
app: mysql-dump
serviceName: "mysql-test"
template:
metadata:
labels:
app: mysql-dump #pod名称
spec:
nodeName: node2 #将资源创建到node2
containers:
- name: mysql #容器名称
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD #mysql管理员密码设置
value: "abc123"
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql" #数据库中数据挂载
name: mysql-data
volumes:
- name: mysql-data
hostPath:
path: /opt/mysqldata
运行YAML文件
kubectl apply -f mysqld.yml
验证
kubectl get pod
cronjob控制器类型应用资源清单文件
vim cronjob_mysqld.yml
#写入
apiVersion: batch/v1
kind: CronJob
metadata:
name: mysql-dump
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
nodeName: node1
containers:
- name: c1
image: mysql:5.7
command: ["/bin/sh","-c","mysqldump --host=mysql-test -uroot -pabc123 --databases mysql > /root/mysql`date +%Y%m%d%H%M`.sql"]
volumeMounts:
- name: mysql-data
mountPath: "/root"
restartPolicy: Never
volumes:
- name: mysql-data
hostPath:
path: /opt/mysqldump

在node1节点查看mysql备份文件

控制器controller之StatefulSet
statefulset控制器作用
-
statefulset是用来管理有状态应用的控制器
-
statefulset用来管理应用的部署、扩缩容及滚动更新
-
statefulset为pod提供持久存储和持久标识符
无状态应用与有状态应用
无状态应用
-
请求本身包含了响应端为响应这一请求所需的全部信息。每一个请求都像首次执行一样,不会依赖之前的数据进行响应
-
不需要持久化的数据
-
无状态应用的多个实例之间互不依赖,可以无序的部署、删除或伸缩
有状态应用
-
前后请求有关联与依赖
-
需要持久化的数据
-
有状态应用的多个实例之间有依赖,不能相互替换:无论怎么调度,每个pod都有一个永久不变的ID
statefulset的特点
-
稳定的、唯一的网络标识符。(无ClusterIP通过headless服务实现)
-
稳定的、持久的存储(通过静态存储PV,PVC,动态存储storageclass实现)
-
有序的、优雅的部署和缩放
-
有序的、自动的滚动更新(从最大数更新,例如:编号2,编号1,编号0)
statefulset的YAML组成
需要三个部分组成:
-
headless service:实现稳定,唯一的网络标识
-
statefulset类型资源:写法和deployment几乎一致,就是类型不一样
-
volumeClaimTemplate:指定存储卷
创建statefulset应用
网络存储NFS部署
1:nfs服务器,地址192.168.18.138
[root@nfsserver ~]# mkdir -p /data/nfs
[root@nfsserver ~]# vim /etc/exports
#写入
/opt/k8s_disk *(rw,no_root_squash,sync)
#解析:*允许所有用户访问;rw可读写;no_root_squash禁用安全降权规则。
[root@nfsserver ~]# systemctl restart nfs-server.service
[root@nfsserver ~]# systemctl enable nfs-server.service
[root@nfsserver ~]# systemctl stop firewalld.service
[root@nfsserver ~]# setenforce 0
[root@nfsserver ~]# showmount -e

2:所有node节点安装nfs客户端软件包
yum install nfs-utils -y
3:验证nfs可用性
showmount -e 192.168.18.138


4:master节点上创建yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: volume-nfs
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nfs-disks
volumes:
- name: nfs-disks
nfs:
path: /opt/k8s_disk
server: 192.168.18.138
5:应用yaml文件
kubectl apply -f dep-volume-nfs.yml
6:查看存储pod
kubectl get pod

7:在nfs服务器上创建index文件
[root@nfsserver ~]# cd /opt/k8s_disk/
[root@nfsserver k8s_disk]# echo "hello nfs storage" > index.html
8:在master上可以直接验证查看
kubectl get pod -o wide
curl 10.244.166.134
curl 10.244.104.8


PV(持久化存储卷)与 PVC(持久存储卷声明)
kubernetes存储卷的分类太丰富了,每种类型都要写相应的接口与参数才行,这就让维护与管理难度加大。 kubernetes支持分类查看 参考文档:https://kubernetes.io/zh-cn/docs/concepts/storage/
persistentvolume(PV)是配置好的一段存储(可以是任意类型的存储卷)
也就是说将网络存储共享出来,配置定义成PV。
PersistentVolumeClaim(PVC)是用户pod使用PV的申请请求。
用户不需要关心具体的volume实现细节,只需要关心使用需求。
pv与pvc之间的关系
-
pv提供存储资源(生产者)
-
pvc使用存储资源(消费者)
-
使用pvc绑定pv

实现nfs类型pv与pvc
1:编写pv的yaml文件
apiVersion: v1
kind: PersistentVolume #类型pv
metadata:
name: pv-nfs #名称
spec:
capacity:
storage: 10Gi #大小
accessModes:
- ReadWriteMany #访问方式
nfs:
path: /opt/k8s_disk #nfs共享目录
server: 192.168.18.138 #nfs服务器IP
访问模式3种:
-
ReadWriteOnce 单节点读写挂载
-
ReadOnlyMany 多节点只读挂载
-
ReadWriteMany 多节点读写挂载
我们要实现多个nginx跨节点之间的数据共享,所以选择ReadWriteMany模式。
2:创建pv并验证
kubectl apply -f pv-nfs.yml
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 1Gi RWX Retain Available 73s
说明:
-
RWX为ReadWriteMany的简写
-
Retain是回收策略
-
Retain表示不使用了需要手动回收
3:创建pvc的yaml文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
4:应用yaml
kubectl apply -f pvc-nfs.yml
5:验证
kubectl get pvc

查看pv,绑定成功
kubectl get pv

6:创建nginx应用yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx-nfs
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: www
persistentVolumeClaim:
claimName: pvc-nfs
7:运行yaml文件
kubectl apply -f dep-nginx-nfs.yml
8:验证
kubectl get pod -o wide
curl http://10.244.166.135

可修改index.html以便与之前实验区分

动态供给
1:下载class插件文件
wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/class.yaml
cp class.yaml storageclass-nfs.yml
vim class.yaml
#写入
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
archiveOnDelete: "false"
kubectl apply -f storageclass-nfs.yml
kubectl get storageclass

-
RECLAIMPOLICY pv回收策略,pod或者pvc被删除后,pv是否删除还是保留
-
VOLUMEBINDINGMODE Immediate模式下pvc与pv立即绑定,主要是不等待相关pod调度完成,不关心其运行节点,直接完成
-
ALLOWVOLUMEEXPANSION pvc扩容 false不允许,true允许
2:下载并创建rbac
wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/rbac.yaml
cp rbac.yaml storageclass-nfs-rbac.yaml
kubectl apply -f storageclass-nfs-rbac.yaml

3:创建动态供给的deployment
需要一个deployment来专门实现pv与pvc的自动创建
下载对应的deployment文件
wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/deployment.yaml
编辑yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0 #替换国内镜像源
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.18.138 #nfs服务器地址
- name: NFS_PATH
value: /opt/k8s_disk #路径
volumes:
- name: nfs-client-root
nfs:
server: 192.168.18.138 #nfs服务器地址
path: /opt/k8s_disk #路径
应用
kubectl apply -f deployment.yaml
kubectl get pod

4:nginx应用使用动态供给
创建statefulset应用来调用名为nfs-client的storageclass,以实现动态供给
apiVersion: v1
kind: Service
metadata:
name: nginx-svc #service名称
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None #无头服务
selector:
app: nginx #service关联pod标签
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web #名称+编号=pod名称
spec:
serviceName: "nginx-svc" #关联service名称
replicas: 2
selector:
matchLabels:
app: nginx #控制器关联pod标签
template:
metadata:
labels:
app: nginx #pod标签
spec:
containers:
- name: nginx-c #扩缩容会用到容器名
image: nginx:1.26-alpine
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates: #pvc模板
- metadata:
name: www #构成pvc名称
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-client"
resources:
requests:
storage: 1Gi
应用YAML文件
kubectl apply -f nginx-storageclass-nfs.yml
查看资源
kubectl get pod
kubectl get service
kubectl get statefulset
kubectl get pvc
kubectl get pv

到nfs-server中,查看/data/nfs目录,会发现有两个文件夹,保存两个pod网站数据
[root@nfsserver ~]# cd /opt/k8s_disk/
[root@nfsserver k8s_disk]# ls

往两个目录中分别写入index.html内容进行查看
[root@nfsserver k8s_disk]# echo "this is web0" > default-www-web-0-pvc-a307f611-9d7e-4948-94dd-7daf3a864393/index.html
[root@nfsserver k8s_disk]# echo "this is web1" > default-www-web-1-pvc-9aaf423c-0ffb-4f22-a1d7-14698c2c7e2e/index.html
[root@master]# kubectl get pod -o wide

[root@master ~]# curl http://10.244.166.136
this is web0
[root@master ~]# curl http://10.244.104.7
this is web1

使用kube-dns解析无头服务域名,可以直接看到后端pod的地址
kubectl get svc -n kube-system

dig -t a nginx-svc.default.svc.cluster.local. @10.96.0.10

解析pod域名
dig -t a web-0.nginx-svc.default.svc.cluster.local. @10.96.0.10
尝试删除web0后观察发现新创建的pod名字没变,但IP变了,而web0依然可以被解析,说明statefulset是通过域名解析的
在集群里创建pod访问域名,观察负载均衡
kubectl run -it centos --image=centos:7 --image-pull-policy=IfNotPresent
curl http://nginx-svc.default.svc.cluster.local.

金丝雀发布更新
它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。(灰度发布)

Statefulset可以使用partition参数来实现金丝雀更新,partition参数可以控制StatefulSet控制器更新的 Pod,下面,就进行StatefulSet控制器的金丝雀更新实战。
kubectl get sts web -o yaml
...
updateStrategy:
rollingUpdate:
partition: 0 #默认分区号0,表示更新0及大于0的所有pod
type: RollingUpdate
...
说明:
使用patch参数来指定了statefulset控制器的partition参数为1,表示当更新时,只有Pod的编号大于等 于1的才更新。
修改更新
kubectl patch sts web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":1}}}}'
再次观察,值设置为1
updateStrategy:
rollingUpdate:
partition: 1
查看更新前版本
kubectl describe pod web-0 | grep Image:
kubectl describe pod web-1 | grep Image:

更新版本
[root@master ~]# kubectl set image sts/web nginx-c=nginx:1.29-alpine
statefulset.apps/web image updated
再次查看版本,发现只有web-1进行了更新
kubectl describe pod web-1 | grep Image:
kubectl describe pod web-0 | grep Image:

直观查看pod版本列表
kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image

扩容数量为4,观察版本更新
kubectl scale sts web --replicas=4
kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image

发现:新增的pod都使用的新版本
缩容数量为1,观察版本变化
kubectl scale sts web --replicas=1
kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image

发现,就剩下原来的老版本的pod,说明位置没变,不可变基础设施,再次扩容,观察版本会发现扩容依旧是按照partition的位置部署新版本

实现全部更新
kubectl patch sts web -p '{"spec:"{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'
kubectl set image sts/web nginx-c=nginx:1.29-alpine
kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image

更多推荐



所有评论(0)