k8s控制器详解
k8s控制器
1、deployment
1、什么是deploy?

-
是一个k8s的资源对象,管理无状态的应用(就是没有顺序的,后面还有一个控制器是有状态,也就是有序的)
-
就是一个pod管理器,确保了一定数量的pod始终运行
-
特性
-
支持pod的多副本
-
支持pod的更新策略
-
能够控制校正pod
-
要求pod无状态,无序的,没有顺序的
-
为pod和replicaset(rs)提供了声明式更新的能力
-
-
deploy核心原理
-
就是通过标签来管理pod,不要随意的修改标签
-
为什么一定要用标签来进行关联了?
-
用ip来进行关联的话,这个pod如果被删除了,pod的ip就会变动
-
只需要用标签来关联一组pod即可
-
-
2、deploy创建
- 通过命令行生成配置文件 kubectl create
[root@master01 test]# kubectl create deployment web1 --image=nginx --replicas 3 --dry-run=client -o yaml > web1.yml
# 查看deploy和rs资源
[root@master01 test]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 3/3 3 3 5s
[root@master01 test]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web1-5756d98cd9 3 3 3 27s
# 查看pod
[root@master01 test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1-5756d98cd9-gxwbt 1/1 Running 0 33s 10.246.73.161 node <none> <none>
web1-5756d98cd9-lhc7m 1/1 Running 0 33s 10.246.73.163 node <none> <none>
web1-5756d98cd9-mrklt 1/1 Running 0 33s 10.246.73.162 node <none> <none>
3、deploy的字段
[root@master01 test]# cat web1.yml
apiVersion: apps/v1
kind: Deployment
metadata: # deploy的元数据
creationTimestamp: null
labels: # deploy的标签,用这个来关联一组pod
app: web1
name: web1 # deploy的名字
spec:
replicas: 3 # 副本数量,3个pod
selector: # 标签选择器
matchLabels: # 匹配的规则
app: web1 # app=web1
strategy: {}
template: # pod模版
metadata: # pod的描述信息 pod不需要name和namesapce,因为多个pod中name是唯一的,所以不能写name,否则都是这个名字,ns也是上面就定义了的,不能跨多个命名空间管理pod
creationTimestamp: null
labels: # pod的标签,一定要与之前的一样,这样deploy才能关联这个pod
app: web1
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
# 查看deploy和rs
4、修改副本数量
-
edit在线修改,但是不会保存到配置文件,适用于测试环境,想要立即生效的
-
可以查看当前运行pod的yml文件
[root@master01 test]# kubectl edit deployments.apps web1
# 修改副本数量为2
replicas: 2
[root@master01 test]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 2/2 2 2 11m
[root@master01 test]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web1-5756d98cd9 2 2 2 11m
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web1-5756d98cd9-lhc7m 1/1 Running 0 11m
web1-5756d98cd9-mrklt 1/1 Running 0 11m
- 命令行修改
[root@master01 test]# kubectl scale deployment --replicas=3 web1
deployment.apps/web1 scaled
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web1-5756d98cd9-9l5x4 1/1 Running 0 3s
web1-5756d98cd9-lhc7m 1/1 Running 0 12m
web1-5756d98cd9-mrklt 1/1 Running 0 12m
[root@master01 test]#
- 修改yaml文件,然后apply应用文件即可
5、deploy更新的策略
-
有2种更新策略
-
一个是重建,就是先删除之前所有pod,再次创建新的pod
-
一个是滚动更新,逐步替换旧pod,创建新的pod,保证了服务的持续可用,这个是默认的deploy更新的策略
-
-
更新的话,这个rs会有多个版本
-
重建策略
[root@master01 test]# cat web1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web1
name: web1
spec:
replicas: 3
selector:
matchLabels:
app: web1
strategy:
type: Recreate # 策略为重建
template:
metadata:
creationTimestamp: null
labels:
app: web1
spec:
containers:
- image: httpd
name: nginx
# 如果后续更新镜像的话,就会先删除所有的容器,然后再次创建新的pod
-
滚动更新
-
maxSurge 先创建多少个,再删除多少个,更新的时候,允许超过副本数的最大pod数, 设置1 副本数量为3 最多可以同时存在4个pod
-
maxUnavailable 先删除多少个,再创建多少个 更新时,允许不可用最大pod数, 设置为0 则必须保证至少3个pod可用
-
默认值是25% 2个都是最优的,默认这个情况最优解
-
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多可超出期望副本数的 Pod 数量(绝对数或百分比)
maxUnavailable: 0 # 更新期间最多不可用的 Pod 数量(绝对数或百分比)
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.21
6、镜像升级和回滚
-
主要应用于镜像升级,就是镜像的版本更换
-
回滚用的很少
-
镜像更新的方式
-
edit,yaml文件修改
-
kubectl set image 修改
-
[root@master01 test]# kubectl set image deploy web1 nginx=nginx:1.9
deployment.apps/web1 image updated
# 查看这个deploy的更新的历史记录
[root@master01 test]# kubectl rollout history deployment web1
deployment.apps/web1
REVISION CHANGE-CAUSE
1 <none>
2 <none>
[root@master01 test]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web1-9b456b48f 0 0 0 112s
web1-9f7649757 2 2 2 74s
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web1-9f7649757-p8wv2 1/1 Running 0 82s
web1-9f7649757-xtv4s 1/1 Running 0 73s
-
回滚的操作
-
在升级的时候,打个标记,这样的话,容易标识
-
kubectl rollout 选项
-
status 显示当前升级的状态
-
history 显示升级的记录
-
pause 暂停版本升级
-
resume 继续已经暂停的版本升级过程
-
restart 重启版本升级过程
-
undo 回滚到上一级版本, --to-revison 回滚到指定的版本
-
-
# 打上标记
[root@master01 test]# kubectl set image deploy web1 nginx=nginx:latest --record=true
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/web1 image updated
# 查看镜像版本历史信息
[root@master01 test]# kubectl rollout history deployment web1
deployment.apps/web1
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 kubectl set image deploy web1 nginx=nginx:latest --record=true
# 回滚到上一个版本
[root@master01 test]# kubectl rollout undo deployment web1
deployment.apps/web1 rolled back
# 发现回滚了
[root@master01 test]# kubectl get deployments.apps -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web1 2/2 2 2 7m nginx nginx:1.9 app=web1
# 更加精确的撤销,指定版本的话
[root@master01 test]# kubectl rollout undo deployment web1 --to-revision=1
deployment.apps/web1 rolled back
[root@master01 test]# kubectl get ^C
[root@master01 test]# kubectl get deployments.apps -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web1 2/2 2 2 9m2s nginx httpd app=web1
7、金丝雀发布(灰度发布)
-
就是在镜像的升级过程中,一部分新创建的pod出来后,暂停更新,测试这个新版本的pod接收流量,如果可以预期的运行,就继续滚动更新,否则就回滚
-
降低了风险,平滑无感回滚,实现真正的真实环境验证
# 将镜像升级并暂停更新
[root@master01 test]# kubectl set image deploy web1 nginx=nginx:latest && kubectl rollout pause deployment web1
# 查看更新状态,有一个更新完成了,还是一个没有更新好
[root@master01 test]# kubectl rollout status deployment web1
Waiting for deployment "web1" rollout to finish: 1 out of 2 new replicas have been updated...
# 多创建了一个
[root@master01 test]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
b1 1/1 Running 0 8m27s
web1-7d54584655-rkpq7 1/1 Running 0 16s
web1-7d54584655-xmjcj 1/1 Running 0 16s
web1-65cc44b58-bffbw 0/1 Pending 0 0s
web1-65cc44b58-bffbw 0/1 Pending 0 0s
web1-65cc44b58-bffbw 0/1 ContainerCreating 0 0s
web1-65cc44b58-bffbw 0/1 ContainerCreating 0 1s
web1-65cc44b58-bffbw 1/1 Running 0 2s
# 三个pod
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
b1 1/1 Running 0 10m
web1-65cc44b58-bffbw 1/1 Running 0 106s
web1-7d54584655-rkpq7 1/1 Running 0 2m37s
web1-7d54584655-xmjcj 1/1 Running 0 2m37s
# 测试在新的pod上面访问
[root@master01 test]# kubectl get pod web1-65cc44b58-bffbw -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1-65cc44b58-bffbw 1/1 Running 0 3m5s 10.246.73.187 node <none> <none>
[root@master01 test]# curl 10.246.73.187 -I
HTTP/1.1 200 OK
# 继续更新
[root@master01 test]# kubectl rollout resume deployment web1
deployment.apps/web1 resumed
# 之前的pod被删除了
# 现在运行的全是新创建的pod
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
b1 1/1 Running 0 14m
web1-65cc44b58-bffbw 1/1 Running 0 4m58s
web1-65cc44b58-tgkgh 1/1 Running 0 18s
2、Statefulset控制器
-
管理的是有序的
-
就是每个pod的都有唯一的标识符
-
0-N-1的序号,顺序创建,sts-0 sts-1 sts-2
-
串行的,就是先启动第一个pod,然后再启动第二个pod,删除也是一样的
-
有序更新
-
滚动更新这个pod名字还是保持不变的,还是0-n-1的序号
-
-
如果规模非常的大,删除和创建的速度特别的慢
-
要求,需要这个headless service
-
就是需要提供这个service
-
提供稳定的网络标识(dns),即使pod重建ip变化,dns名称保持不变
-
就是为每个pod创建dns A记录
-
支持Pod之间的相互发现
-
保证了有序启动和关闭,依靠这个服务,解析每一个pod的dns,确保按照顺序创建
-
[root@master01 test]# cat web1.yml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
clusterIP: None # 设置为none就是 headless svc
selector:
app: web1
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
creationTimestamp: null
labels:
app: web1
name: web1
spec:
replicas: 2
selector:
matchLabels:
app: web1
serviceName: "nginx"
template:
metadata:
creationTimestamp: null
labels:
app: web1
spec:
containers:
- image: nginx
name: nginx
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
b1 1/1 Running 0 2m44s
web1-0 1/1 Running 0 3m37s
web1-1 1/1 Running 0 3m34s
root@web1-0:/# cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.246.73.181 web1-0.nginx.default.svc.cluster.local web1-0
3、daemonset控制器
-
确保每一个节点上运行一个pod副本
-
更新,一个一个节点的更新,先删除,再创建
-
适用场景,日志收集,监控,网络插件,安全
-
kube-proxy每个节点都会运行,网络通信的
[root@master01 test]# cat web1.yml
apiVersion: apps/v1
kind: DaemonSet # ds控制器
metadata:
creationTimestamp: null
labels:
app: web1
name: web1
spec:
selector:
matchLabels:
app: web1
template:
metadata:
creationTimestamp: null
labels:
app: web1
spec:
containers:
- image: nginx
name: nginx
# 为什么只有一个节点创建了呢?因为其他2个master节点有污点,无法进行调度
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
b1 1/1 Running 0 5m7s
web1-w9zcn 1/1 Running 0 26s
4、job控制器
5、cronjob控制器
-
污点,调度器也就是污点的策略
-
灰度策略,

浙公网安备 33010602011771号