1、Replication Controller
Replication Controller,简称 RC,复制控制器,可确保 Pod 副本数达到期望值,也就是 RC 可确保一个 Pod 总 是可用,或一组 Pod 的数量永远处于一个定值。
如果存在的 Pod 大于设定的期望值,RC 会终止额外的 Pod。反之,当 Pod 数量小于期望值时,RC 将启动更多 的 Pod 来保证达到该期望值。
与手动创建 Pod 不同,使用 RC 控制的 Pod,在失败、 删除或终止时会自动替换为正常运行的 Pod,因此,为 达到高可用的效果,即使应用程序只需要一个 Pod,也 应该使用 RC 或其他控制器的方式管理。
RC 类似于进程管理监控程序,监视多个节点上的多个 Pod。
1)定义 Replication Controller
[root@k8s-master test]# vim t006.yaml apiVersion: v1 kind: ReplicationController # 元数据 metadata: # rc名称 name: test0019 # 定义资源信息 spec: # 定义副本数量 replicas: 3 # 定义资源标签 selector: app: test0019 # 定义pod信息 template: metadata: # pod名称 name: test0019 # 定义pod标签 labels: app: test0019 spec: containers: - name: busybox image: docker.io/library/busybox:latest imagePullPolicy: Never command: - "/bin/sh" - "-c" - "sleep 3600 [root@k8s-master test]# kubectl create -f t006.yaml replicationcontroller/test0019 created [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0018 1/1 Running 10 (6m31s ago) 29m test0019-5m27n 1/1 Running 0 11m test0019-pwxrf 1/1 Running 0 11m test0019-qcgm7 1/1 Running 0 11m
2)测试pod数量控制
# 删除其中一个pod [root@k8s-master test]# kubectl delete pod test0019- test0019-29g8v test0019-29lsq test0019-t7ctx [root@k8s-master test]# kubectl delete pod test0019-29g8v pod "test0019-29g8v" deleted # 会重新创建一个新的pod [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0018 0/1 CrashLoopBackOff 13 (23s ago) 39m test0019-29lsq 1/1 Running 0 79s test0019-t7ctx 1/1 Running 0 79s test0019-xgfqv 1/1 Running 0 34s # 直接删除rc [root@k8s-master test]# kubectl delete rc test0019 replicationcontroller "test0019" deleted [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0018 1/1 Running 12 (6m21s ago) 37m test0019-5m27n 1/1 Terminating 0 18m test0019-pwxrf 1/1 Terminating 0 18m test0019-qcgm7 1/1 Terminating 0 18m # 会将全部创建的pod都删除 [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0018 1/1 Running 13 (14s ago) 37m # 直接对rc控制的pod集做修改,修改复制集数量 [root@k8s-master test]# kubectl edit replicationcontrollers test0019 replicationcontroller/test0019 edited
# 默认滚动更新,创建一个新的pod [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0018 0/1 CrashLoopBackOff 13 (96s ago) 40m test0019-29lsq 1/1 Running 0 2m32s test0019-l9l8p 1/1 Running 0 4s test0019-t7ctx 1/1 Running 0 2m32s test0019-xgfqv 1/1 Running 0 107s
2、ReplicaSet
ReplicaSet,简称 RS,在 Kubernetes v1.2 版本,由旧 的 Replication Controller 升级而来。与 RC 的主要区别 在于,RS 支持基于集合的 Label Selector (标签选择器) 功能。
RS 主要作用于 Deployment 协调创建、删除和更新 Pod,在实际应用中,虽然 ReplicaSet 可以单独使用, 但一般建议使用 Deployment 来自动管理 ReplicaSet, 除非自定义的 Pod 不需要更新或有其他编排等。
RS 比 RC 具有更强大的功能及灵活性,所以如果只有这 两种选择,建议选择 RS。
1)环境准备
# 使用-f删除rc,准备rs环境 [root@k8s-master test]# kubectl delete -f t006.yaml replicationcontroller "test0019" deleted [root@k8s-master test]# kubectl delete pod test0018 pod "test0018" deleted [root@k8s-master test]# kubectl get pod No resources found in default namespace.
2)定义ReplicaSet
[root@k8s-master test]# vim t007.yaml apiVersion: apps/v1 kind: ReplicaSet # 元数据 metadata: # rs名称 name: test0020 # 定义资源信息 spec: # 定义副本数量 replicas: 3 # 定义资源标签 # 更高级的标签匹配形式,使用In操作符来匹配“tier”标签的值是否在给定的值列表中。具体来说,它正在查找“tier”标签的值为“test0020”的资源 # matchLabels和matchExpressions可以通用,也可以选一中方式用 selector: matchLabels: tier: test0020 matchExpressions: - key: tier operator: In values: - busybox - test0020 # 定义pod信息 template: metadata: # pod名称 name: test0020 # 定义pod标签 labels: # 标签1 app: test0020 # 标签2 tier: test0020 spec: restartPolicy: Always nodeSelector: abc: "1" containers: - name: busybox image: docker.io/library/busybox.latest imagePullPolicy: Never command: - "/bin/sh" - "-c" - "sleep 60" [root@k8s-master test]# kubectl create -f t007.yaml replicaset.apps/test0020 created # 60秒之后pod关闭,查看pod的标签 [root@k8s-master test]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS test0020-ml99b 0/1 ErrImageNeverPull 0 35s app=test0020,tier=test0020 test0020-sbgql 0/1 ErrImageNeverPull 0 35s app=test0020,tier=test0020 test0020-xlmkx 0/1 ErrImageNeverPull 0 35s app=test0020,tier=test0020 [root@k8s-master test]# kubectl label pod test0020-ml99b zm=0001 pod/test0020-ml99b labeled # 可以单独修改rc中的一个pod的标签 [root@k8s-master test]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS test0020-ml99b 0/1 ErrImageNeverPull 0 4m2s app=test0020,tier=test0020,zm=0001 test0020-sbgql 0/1 ErrImageNeverPull 0 4m2s app=test0020,tier=test0020 test0020-xlmkx 0/1 ErrImageNeverPull 0 4m2s app=test0020,tier=test0020 # rs与rc都不会单独使用
3、无状态和有状态应用特性
1)无状态应用
无状态应用:不将数据或应用状态存储到集群或永久性 存储空间的应用。
常见的无状态应用包括 Web 服务器、负载均衡器、静态 文件服务器等。
以 web 服务器为例:客户端的每次请求必须具备自描述 信息,通过这些信息识别客户端身份,服务端不会保存 任何客户端请求者信息。
2)无状态应用特点
易于扩展:由于无状态应用不保存请求状态,因此可 以轻松地将它们部署在多个服务器上,从而实现水平 扩展。
高可用性:由于无状态应用的每个请求都是独立的, 因此即使某个请求失败,也不会影响其他请求的处 理。这有助于提高应用的可用性。
安全性:无状态应用通常不保存敏感数据,因此不太 可能泄露敏感信息。
可替代性:由于无状态应用不保存请求状态,因此不 同的服务器可以处理相同的请求,这意味着任何一个 服务器都可以替代其他服务器来处理请求。
3)有状态应用
有状态应用:应用程序的处理需要依赖特定的状态或数 据存储。
“有状态应用”的例子有很多,比如 Redis、MySQL 这样 的数据库,它们的“状态”就是在内存或者磁盘上产生的数 据,是应用的核心价值所在,如果不能够把这些数据及 时保存再恢复,那绝对会是灾难性的后果。
4)有状态应用特点
依赖状态:应用程序的处理依赖于特定的状态信息。
数据持久化:有状态应用通常需要将状态数据持久化 存储,以便后续请求可以访问和使用。
有序性:由于有状态应用处理请求时依赖先前的状 态,因此请求之间的顺序可能很重要。
4、Deployment 无状态应用
在 Kubernetes 中,Deployment 是最常用的 Pod 控制 器,一般用于部署企业内部的无状态服务(微服务居多), 可利用 Deployment 的高级功能做到无缝迁移、自动扩 缩容、自动容灾、一键回滚等功能。
1)创建deployment
[root@k8s-master test]# kubectl create deployment test0021 --image=docker.io/library/busybox:latest --replicas=3 -o=yaml --dry-run=client > t008.yaml # 命令拆分 # kubectl:k8s命令工具 # create:新建一个k8s资源 # deploy:该资源类型为deployment # test0021:该deploymet资源名为test0021 # --image=docker.io/library/busybox:latest:拉取本地的busybox:latest版本的镜像 # --replicas=3:创建的pod数量 # -o yaml:输出为yaml格式 # --dry-run=client:不真正创建资源,仅预览该deployment资源的配置信息 # > t008.yaml:预览的配置信息输出到t008.yaml文件内 # 使用kubectl命令工具生成的deployment资源配置文件 [root@k8s-master test]# vim t008.yaml # API版本,只能使用这个 apiVersion: apps/v1 # 资源类型 kind: Deployment # 元数据信息 metadata: # 时间注解(没有) creationTimestamp: null # 标签 labels: app: test0021 # 名称 name: test0021 # deployment的配置信息 spec: # 创建pod的数量 replicas: 3 # 标签选择器,与template的label对应,apiVersion为apps/v1时必须指定该字段 selector: # 匹配标签 matchLabels: # 匹配这个标签 app: test0021 # pod的更新策略 strategy: {} # 定义pod资源配置 template: # 元数据 metadata: creationTimestamp: null # pod标签 labels: app: test0021 # 配置容器信息 spec: containers: - image: docker.io/library/busybox:latest imagePullPolicy: Never command: - "/bin/sh" - "-c" - "sleep 600" name: busybox resources: {} status: {}
2)修改生成的yaml文件
# 原本生成的文件中是没有 imagePullPolicy: Never 的 # 手动加上此句 # 其余不需要动
3)使用yaml文件创建pod
[root@k8s-master test]# kubectl get pod No resources found in default namespace. [root@k8s-master test]# kubectl create -f t008.yaml deployment.apps/test0021 created [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0021-6d8b55bc5f-2hhpj 1/1 Running 0 3s test0021-6d8b55bc5f-79m46 1/1 Running 0 3s test0021-6d8b55bc5f-ftv8c 1/1 Running 0 3s [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0021-6d8b55bc5f-2hhpj 1/1 Running 0 3s test0021-6d8b55bc5f-79m46 1/1 Running 0 3s test0021-6d8b55bc5f-ftv8c 1/1 Running 0 3s [root@k8s-master test]# kubectl get rs NAME DESIRED CURRENT READY AGE test0021-6d8b55bc5f 3 3 3 50s [root@k8s-master test]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE test0021 3/3 3 3 55s
4)测试副本数量控制机制
# 删除rc [root@k8s-master test]# kubectl delete replicasets.apps test0021-6d8b55bc5f replicaset.apps "test0021-6d8b55bc5f" deleted # 将原先的3个pod下架,重新创建3个pod运行 [root@k8s-master test]# kubectl get po NAME READY STATUS RESTARTS AGE test0021-6d8b55bc5f-2hhpj 1/1 Terminating 0 2m54s test0021-6d8b55bc5f-79m46 1/1 Terminating 0 2m54s test0021-6d8b55bc5f-ftv8c 1/1 Terminating 0 2m54s test0021-6d8b55bc5f-wmnhl 1/1 Running 0 11s test0021-6d8b55bc5f-xfghc 1/1 Running 0 11s test0021-6d8b55bc5f-xjgrc 1/1 Running 0 11s [root@k8s-master test]# kubectl get po NAME READY STATUS RESTARTS AGE test0021-6d8b55bc5f-wmnhl 1/1 Running 0 32s test0021-6d8b55bc5f-xfghc 1/1 Running 0 32s test0021-6d8b55bc5f-xjgrc 1/1 Running 0 32s # 直接删除deployment [root@k8s-master test]# kubectl delete deployments.apps test0021 deployment.apps "test0021" deleted [root@k8s-master test]# kubectl get po NAME READY STATUS RESTARTS AGE test0021-6d8b55bc5f-wmnhl 1/1 Terminating 0 60s test0021-6d8b55bc5f-xfghc 1/1 Terminating 0 60s test0021-6d8b55bc5f-xjgrc 1/1 Terminating 0 60s [root@k8s-master test]# kubectl get po No resources found in default namespace.
5、更新 Deployment
更新当前 Deployment 的 Nginx Pod 的底层镜像模板, 并使用 --record 记录当前更改的参数,方便后期回滚更新。
也可使用 “kubectl edit deployments.apps nginx”命令 对 deployment 资源编辑再更新,后面的 nginx 为 deployment 资源名。
1)重新创建一个deployment文件,并创建3个pod
[root@k8s-master test]# kubectl create deployment test0022 --image=docker.io/library/nginx:1.20.0 --replicas=4 -o yaml --dry-run=client > t009.yaml [root@k8s-node01 ~]# crictl images | grep 1.20.0 docker.io/library/nginx 1.20.0 7ab27dbbfbdf4 137MB [root@k8s-master test]# vim t009.yaml
[root@k8s-master test]# kubectl create -f t009.yaml deployment.apps/test0022 created [root@k8s-master test]# kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test0022-785469b684-9d8qv 1/1 Running 0 73s 172.16.58.212 k8s-node02 <none> <none> test0022-785469b684-c5hl5 1/1 Running 0 73s 172.16.85.219 k8s-node01 <none> <none> test0022-785469b684-dqrrs 1/1 Running 0 73s 172.16.85.220 k8s-node01 <none> <none> test0022-785469b684-vsxxl 1/1 Running 0 73s 172.16.58.213 k8s-node02 <none> <none> [root@k8s-master test]# curl 172.16.58.212 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
2)镜像升级的2种方式(edit与set)
# 镜像平滑升级,修改文件中镜像的版本 [root@k8s-master test]# kubectl edit deployments.apps test0022 deployment.apps/test0022 edited spec: containers: - image: docker.io/library/nginx:1.22.0 [root@k8s-master test]# kubectl describe pod test0022-5f5677c58-2d66c Containers: nginx: Container ID: Image: docker.io/library/nginx:1.22.0 # 使用set升级 [root@k8s-master test]# kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.25.0 deployment.apps/test0022 image updated [root@k8s-master test]# kubectl describe deployments.apps test0022 Pod Template: Labels: app=test0022 Containers: nginx: Image: docker.io/library/nginx:1.25.0
3)查看回滚历史记录(rollout history)
# 查看deployment的回滚历史记录 [root@k8s-master test]# kubectl rollout history deployment test0022 deployment.apps/test0022 REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> # 删除deployment [root@k8s-master test]# kubectl delete -f t009.yaml deployment.apps "test0022" deleted [root@k8s-master test]# kubectl get pod No resources found in default namespace. # 重新创建deployment [root@k8s-master test]# kubectl create -f t009.yaml deployment.apps/test0022 created [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test0022-785469b684-5nfmm 1/1 Running 0 2s test0022-785469b684-c8bdx 1/1 Running 0 2s test0022-785469b684-krlfp 1/1 Running 0 2s test0022-785469b684-zptjq 1/1 Running 0 2s # 查看回滚历史记录 [root@k8s-master test]# kubectl rollout history deployment test0022 deployment.apps/test0022 REVISION CHANGE-CAUSE 1 <none> [root@k8s-master test]# kubectl describe deployments.apps test0022 Image: docker.io/library/nginx:1.20.0
4)使升级时携带标签(--record)
# 在set升级的时候添加--record [root@k8s-master test]# kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.22.0 --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/test0022 image updated # 查看历史纪录,发现携带标记信息 [root@k8s-master test]# kubectl rollout history deployment test0022 deployment.apps/test0022 REVISION CHANGE-CAUSE 1 <none> 2 kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.22.0 --record=true # 查看详细信息 [root@k8s-master test]# kubectl describe deployments.apps test0022 Image: docker.io/library/nginx:1.22.0 [root@k8s-master test]# kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.25.0 --record Flag --record has been deprecated, --record will be removed in the future deployment.apps/test0022 image updated [root@k8s-master test]# kubectl rollout history deployment test0022 deployment.apps/test0022 REVISION CHANGE-CAUSE 1 <none> 2 kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.22.0 --record=true 3 kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.25.0 --record=true
注意: 当且仅当 Deployment 的 Pod 模板 (即.spec.template) 更改时,才会触发,Deployment更 新,例如更改内存、CPU 配置或者容器的 image。
6、回滚 Deployment
查看更新deployment更新历史
REVISION:版本
CHANGE-CAUSE:改变操作
1 版本为之前的 1.20.0 版本的 nginx,2 版本是升级 后的 nginx1.22.0,3版本为升级的现在的nginx1.25.0
1)查看回滚历史记录的详细信息(--revision)
# 查看历史版本为x的历史纪录信息 [root@k8s-master test]# kubectl rollout history deployment test0022 --revision=2 deployment.apps/test0022 with revision #2 Pod Template: Labels: app=test0022 pod-template-hash=5f5677c58 Annotations: kubernetes.io/change-cause: kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.22.0 --record=true Containers: nginx: Image: docker.io/library/nginx:1.22.0 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> [root@k8s-master test]# kubectl rollout history deployment test0022 --revision=1 deployment.apps/test0022 with revision #1 Pod Template: Labels: app=test0022 pod-template-hash=785469b684 Containers: nginx: Image: docker.io/library/nginx:1.20.0 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> [root@k8s-master test]# kubectl rollout history deployment test0022 --revision=3 deployment.apps/test0022 with revision #3 Pod Template: Labels: app=test0022 pod-template-hash=875f94b45 Annotations: kubernetes.io/change-cause: kubectl set image deploy test0022 nginx=docker.io/library/nginx:1.25.0 --record=true Containers: nginx: Image: docker.io/library/nginx:1.25.0 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none>
2)回滚到上一版本(rollout undo)
# 回滚到上一版本 [root@k8s-master test]# kubectl rollout undo deployment test0022 deployment.apps/test0022 rolled back [root@k8s-master test]# kubectl describe deployments.apps test0022 Image: docker.io/library/nginx:1.22.0 [root@k8s-master test]# kubectl rollout undo deployment test0022 deployment.apps/test0022 rolled back [root@k8s-master test]# kubectl describe deployments.apps test0022 Image: docker.io/library/nginx:1.25.0
3)回滚到指定版本(--to-revision)
# 指定回滚版本 [root@k8s-master test]# kubectl rollout undo deployment test0022 --to-revision 1 deployment.apps/test0022 rolled back [root@k8s-master test]# kubectl describe deployments.apps test0022 Image: docker.io/library/nginx:1.20.0
7、扩容 Deployment
Deploymentg管理无差别容器
1)生成yaml文件,创建deployment
# 生成yaml文件,并修改yaml文件 [root@k8s-master test]# kubectl create deployment test001 --image=docker.io/library/busybox:latest --replicas=3 -o=yaml --dry-run=client > test001.yaml # 未设置开机后执行的命令,开机后会自动执行重启命令 [root@k8s-master test]# vim test001.yaml apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: test001 name: test001 spec: replicas: 3 selector: matchLabels: app: test001 strategy: {} template: metadata: creationTimestamp: null labels: app: test001 spec: containers: - image: docker.io/library/busybox:latest imagePullPolicy: Never name: busybox resources: {} status: {} # 创建deployment [root@k8s-master test]# kubectl create -f test001.yaml # 查看pod节点 # CrashLoopBackOff重启 # Completed完成 [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test001-698b98bb8f-68xjm 0/1 CrashLoopBackOff 1 (8s ago) 11s test001-698b98bb8f-m6mwc 0/1 CrashLoopBackOff 1 (9s ago) 11s test001-698b98bb8f-rdckx 0/1 CrashLoopBackOff 1 (8s ago) 11s [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test001-698b98bb8f-68xjm 0/1 Completed 2 (19s ago) 22s test001-698b98bb8f-m6mwc 0/1 Completed 2 (20s ago) 22s test001-698b98bb8f-rdckx 0/1 Completed 2 (19s ago) 22s # 在yaml文件中添加下面内容,开机后会进入睡眠模式10分钟然后重启 [root@k8s-master test]# vim test001.yaml command: - "/bin/sh" - "-c" - "sleep 600" # 替换pod节点,热启动(reload pod节点) [root@k8s-master test]# kubectl replace -f test001.yaml # 查看pod节点 [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test001-64c7957b5c-gr5vp 1/1 Running 0 41s test001-64c7957b5c-wlhfn 1/1 Running 0 39s test001-64c7957b5c-xcbwz 1/1 Running 0 43s
2)命令行扩容(速度会更快一些相比于缩容)
# 扩容5个pod [root@k8s-master test]# kubectl scale deployment test001 --replicas=5 deployment.apps/test001 scaled [root@k8s-master test]# kubectl get pod NAME READY STATUS RESTARTS AGE test001-64c7957b5c-2w5jt 1/1 Running 0 10s test001-64c7957b5c-gr5vp 1/1 Running 0 4m18s test001-64c7957b5c-sb5fz 1/1 Running 0 10s test001-64c7957b5c-wlhfn 1/1 Running 0 4m16s test001-64c7957b5c-xcbwz 1/1 Running 0 4m20s
3)命令行缩容
# 缩容到2个
[root@k8s-master test]# kubectl scale deployment test001 --replicas=2
[root@k8s-master test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test001-64c7957b5c-2w5jt 1/1 Running 0 89s
test001-64c7957b5c-gr5vp 1/1 Running 0 5m37s
test001-64c7957b5c-sb5fz 1/1 Terminating 0 89s
test001-64c7957b5c-wlhfn 1/1 Terminating 0 5m35s
test001-64c7957b5c-xcbwz 1/1 Terminating 0 5m39s
[root@k8s-master test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test001-64c7957b5c-2w5jt 1/1 Running 0 2m4s
test001-64c7957b5c-gr5vp 1/1 Running 0 6m12s