一、 RC&RS
Replication Controller(复制控制器,RC)和ReplicaSet(复制集,RS)是两种简单部署Pod的方式。因为在生产环境中,主要使用更高级的Deployment等方式进行Pod的管理和部署,这俩个控制器一般很少使用。
1.1 Replication Controller
官方文档:https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicationcontroller/
Replication Controller(简称RC)可确保Pod副本数达到期望值,也就是RC定义的数量。换句话说,Replication Controller可确保一个Pod或一组同类Pod总是可用。
如果存在的Pod大于设定的值,则Replication Controller将终止额外的Pod。如果太小,Replication Controller将启动更多的Pod用于保证达到期望值。与手动创建Pod不同的是,用Replication Controller维护的Pod在失败、删除或终止时会自动替换。因此即使应用程序只需要一个Pod,也应该使用Replication Controller或其他方式管理。Replication Controller类似于进程管理程序,但是Replication Controller不是监视单个节点上的各个进程,而是监视多个节点上的多个Pod。
定义一个Replication Controller示例文件
apiVersion: v1 #必填,api版本号
kind: ReplicationController #必填,资源类型
metadata:
name: nginx #必填,名称
spec:
replicas: 3 #必填,副本数
selector: #必填,选择器
app: nginx
template: #必填,以下为pod模板信息定义
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: 10.122.6.81:5000/image/nginx:v1
ports:
- containerPort: 80
1.2 ReplicaSet
官方文档:https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicaset/
ReplicaSet是支持基于集合的标签选择器的下一代Replication Controller,它主要用作Deployment协调创建、删除和更新Pod,和Replication Controller唯一的区别是,ReplicaSet支持标签选择器。在实际应用中,虽然ReplicaSet可以单独使用,但是一般建议使用Deployment来自动管理ReplicaSet,除非自定义的Pod不需要更新或有其他编排等。
定义一个ReplicaSet的示例如下
apiVersion: apps/v1 #必填,api版本号
kind: ReplicaSet #必填,资源类型
metadata:
name: nginx-rs #必填,名称
spec:
replicas: 6 #必填,副本数
selector: #必填,选择器
matchLabels:
tier: nginx-rs
template: #必填,以下为pod模板信息定义
metadata:
labels:
tier: nginx-rs
spec:
containers:
- name: nginx
image: 10.122.6.81:5000/image/nginx:v1
ports:
- containerPort: 80
Replication Controller和ReplicaSet的创建删除和Pod并无太大区别,Replication Controller目前几乎已经不在生产环境中使用,ReplicaSet也很少单独被使用,都是使用更高级的资源Deployment、DaemonSet、StatefulSet进行管理Pod。
二、Deployment
官方文档:https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/
用于部署无状态的服务,这个最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configserver、zuul、springboot。他可以管理多个副本的Pod实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。
deployment工作方式
在创建一个新的deployment时他会自动创建一个rs控制,这个rs控制器无需手动维护是由deployment进行管理的,rs控制器只实现pod副本数量的管理以及pod的配置,在修改template
pod模板信息的内容时会触发Deployment的更新策略,Deployment会生成新的rs控制器应用你所修改的配置,旧的rs控制器并不会被删除而是把他的副本数设置为0,旧的rs保存数量由revisionHistoryLimit
进行控制。
2.1 Deployment文件示例
apiVersion: apps/v1 #必选,api版本号
kind: Deployment #必选,资源类型
metadata: #必选,元数据
name: nginx-1 #必选,名称
namespace: default #可选,命名空间
spec: #必选,定义控制器信息
progressDeadlineSeconds: 600 #在部署更新时的最大时间
replicas: 1 #必选,期望副本数
revisionHistoryLimit: 10 #保留历史rs控制器数据,默认为10
selector: #必选,选择器
matchLabels: #标签选择器,主要用于选择下面template所定义的标签信息
app: nginx-1
strategy: #更新,升级策略,默认值如下
rollingUpdate: #滚动更新的配置参数
maxSurge: 25% #允许更新时pod副本超出期望值的百分比,默认25
maxUnavailable: 25% #更新过程中不可用的pod副本的百分比,默认25
type: RollingUpdate #更新升级策略,RollingUpdate滚动更新,Recreate重建,默认滚动更新
template: #以下为定义pod模板信息,请查看pod详解
metadata:
creationTimestamp: null
labels:
app: nginx-1
spec:
containers:
- image: 10.122.6.81:5000/image/nginx:v1
...
状态解析
# kubectl get deployments.apps -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-1 1/1 1 1 7m39s nginx 10.122.6.81:5000/image/nginx:v1 app=nginx-1
- NAME: Deployment名称
- READY:Pod的状态,已经Ready的个数
- UP-TO-DATE:已经达到期望状态的被更新的副本数
- AVAILABLE:已经可以用的副本数
- AGE:显示应用程序运行的时间
- CONTAINERS:容器名称
- IMAGES:容器的镜像
- SELECTOR:管理的Pod的标签
2.2 Deployment的更新
Deployment的更新使用yaml文件进行修改之后使用kubectl apply -f
进行更新,也可以直接使用kubectl edit
直接进行修改,但是推荐使用kubectl set
进行更新。请注意如果使用这个命令进行更新服务,如果更新镜像即使镜像不做改变重复使用命令进行更新,会重复的创建新的deploy的版本,所以如果创建更新时如果修改的内容有多个最好是先暂停更新之后统一修改后在启用更新,这样就只会生产一个新的deploy的版本,这样的好处是方便回滚。
更新容器镜像
kubectl set image deploy deploy名称 容器名称=镜像 --record
--record #会记录更新的内容,之后使用kubectl rollout history可以看到更新的参数
#示例
kubectl set image deploy nginx-1 nginx-1=10.122.6.81:5000/image/nginx:v2 --record
更新容器资源限制
kubectl set resources deploy/deploy名称 --containers=容器名称 --limits=cpu=40m,memory=100Mi --requests=cpu=40m,memory=100Mi --record
--limits #容器最大可使用资源
--requests #容器启动时申请的资源
--containers #pod中如果存在多个容器,可以选择容器进行更新
--all #pod中所以容器全部设置,不写--containers参数默认all
#示例
kubectl set resources deploy/nginx-1 --limits=cpu=20m,memory=30Mi --requests=cpu=20m,memory=30Mi
更新容器变量
#查看deploy中容器所有变量
kubectl set env deploy/deploy名称 --list
#修改变量
kubectl set env deploy/nginx-1 --containers=centos type=centos7 name=zhangzhuo
--list #查看pod中所有容器变量
--containers #选项pod中容器,不写默认所有
2.3 Deployment回滚
deployment每次更新时会创建一个新的rs控制器用来运行更新后的pod,旧的rs控制器副本数会变为0,所以我们可是使用kubectl rollout
命令进行回滚操作,并且还可以设置停止更新,之后在回复更新。
查看历史版本信息相关命令
#查看deploy历史版本信息,默认会保存最近的10个,由deploy的.deploy.spce.revisionHistoryLimit设置
kubectl rollout history deploy/deploy名称
#查看指定版本详细信息
kubectl rollout history deployment nginx-1 --revision=1
--revisin #指定版本号
#验证deploy升级状态
kubectl rollout status deployment nginx-1 --timeout=1s
--timeout #检测超时时间,默认为一直监听状态直到完成或失败
回滚deploy
注意:回滚并不会一直回滚之前的版本,如果当前版本为7,回滚后会把6变成8,如果再次回滚还会回滚到7,把7变为9。以此类推。
#回滚到指定版本
kubectl rollout undo deployment nginx-1 --to-revision=6
--ro-revision #指定回滚的版本,不指定默认为上一个版本
暂停更新与恢复更新
如果使用命令进行更新deploy,需要更新的内容较多的话,需要使用到暂停更新来避免每次修改会生成一个更新,而是先暂停等所以更新操作完成后,在启用更新生成一次更新信息,以方便后续有问题的回滚操作。
#暂停更新
kubectl rollout pause deployment deploy名称
#启用更新
kubectl rollout resume deployment deploy名称
#示例
kubectl rollout history deployment nginx-1 #查看记录现在的版本号
kubectl rollout pause deployment nginx-1 #暂停更新
kubectl set resources deploy/nginx-1 --containers=nginx --limits=cpu=101m,memory=100Mi --requests=cpu=101m,memory=100Mi
kubectl set env deploy/nginx-1 --containers=centos type=centos10 name=zhangzhuo zhangzhuo=xxxx
kubectl rollout resume deployment nginx-1 #启用更新
kubectl rollout history deployment nginx-1 #再次验证版本号是否只增加1
三、StatefulSet
官方文档: https://kubernetes.io/zh/docs/concepts/workloads/controllers/statefulset/
StatefulSet 是用来管理有状态应用的工作负载 API 对象。StatefulSet 用来管理某 Pod集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod。不同的是,StatefulSet为每个Pod维护了一个粘性标识。这些Pod是根据相同的规范创建的,但是不可互换,每个Pod都有一个持久的标识符,在重新调度时也会保留,一般格式为StatefulSetName-Number。比如定义一个名字是Redis-Sentinel的StatefulSet,指定创建三个Pod,那么创建出来的Pod名字就为Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。而StatefulSet创建的Pod一般使用Headless Service(无头服务)进行通信,和普通的Service的区别在于Headless Service没有ClusterIP,它使用的是Endpoint进行互相通信,Headless一般的格式为:statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
StatefulSet限制
- 给定 Pod 的存储必须由 PersistentVolume 驱动基于所请求的
storage class
来提供,或者由管理员预先提供。 - 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
- StatefulSet 当前需要无头服务(没有clusterIP的service资源)来负责 Pod 的网络标识。你需要负责创建此服务。
- 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet 缩放为 0。
- 在默认 Pod 管理策略(
OrderedReady
) 时使用滚动更新,可能进入需要人工干预 才能修复的损坏状态。
StatefulSet部署与扩缩
- 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为
0..N-1
。 - 当删除 Pod 时,它们是逆序终止的,顺序为
N-1..0
。 - 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
- 在 Pod 终止之前,所有的继任者必须完全关闭。
3.1 StatefulSet示例文件
#无头服务创建
apiVersion: v1
kind: Service
metadata:
name: nginx-1
spec:
ports:
- port: 80
name: web
clusterIP: None #主要是这里为None
selector:
app: nginx-1
---
#StatefulSet资源
apiVersion: apps/v1 #必须,api版本
kind: StatefulSet #必须,资源类型
metadata: #元数据信息
name: web #名称
spec: #必须,定义控制器信息
podManagementPolicy: OrderedReady #必须,pod扩缩策略,默认策略为OrderedReady,其他策略Parallel
replicas: 3 #必须,副本数
revisionHistoryLimit: 10 #必须,历史版本保存的最大数量,默认10
selector: #必须选择器配置,选择pod
matchLabels: #标签选择器
app: nginx-1
serviceName: nginx-1 #管理这个StatefulSet的service名称(无头服务)
updateStrategy: #更新策略配置
rollingUpdate: #RollingUpdate更新策略才需要
partition: 0 #表示在滚动更新时保留的pod编号,为0即表示保留小于0的即不保留
type: RollingUpdate #类型默认为RollingUpdate滚动更新,其他参数Ondelete在更新pod后只有删除pod才会触发更新
template: #以下为pod配置
metadata:
creationTimestamp: null
labels:
app: nginx-1
spec:
containers:
...
3.2 StatefulSet扩缩容
演示一个StatefulSet的创建启动过程,这里使用3个副本
kubectl get pod -l app=nginx-1 -w
NAME READY STATUS RESTARTS AGE
web-0 0/1 Pending 0 0s #先调度web-0
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 2s #web-0状态为running
web-1 0/1 Pending 0 0s #之后调度web-1
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 2s #web-1状态为running
web-2 0/1 Pending 0 0s #之后调度web-2
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 1s
- 对于多个副本的StatefulSet,在启动pod时会依次0..N的逐个启动pod。
- 如果在启动过程中前面启动的pod出现问题会暂停新的pod启动等待之前的pod启动成功后,重新在启动新的pod
3.3 StatefulSet更新策略
StatefulSet默认的更新策略为滚动更新,具体配置如下
updateStrategy: #更新策略配置
rollingUpdate:
partition: 0
type: RollingUpdate #类型默认为RollingUpdate滚动更新,其他参数Nodelete
#滚动更新演示
kubectl set env sts/web test=1 #执行更新
kubectl get pod -l app=nginx-1 -w
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 30m
web-1 1/1 Running 0 30m
web-2 1/1 Running 0 30m
web-2 1/1 Terminating 0 30m #先更新web-2
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 2s
web-1 1/1 Terminating 0 30m #之后更新web-1
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 3s
web-0 1/1 Terminating 0 31m #最后更新web-0
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 2s
- 对于多个副本的StatefulSet,在更新pod时会依次N..0的逐个更新pod。
- 如果在更新过程中前面运行的pod出现问题会暂停pod更新等待之前的pod启动成功后,重新在接着进行更新。
NoDelete更新策略
#配置如下
updateStrategy:
type: OnDelete #更新策略,OnDelete在更新pod后只有删除pod才会触发更新
#演示如下
kubectl set env sts/web test=1 zhang=1 #执行更新
kubectl get pod -l app=nginx-1 -w #验证更新过程,这里可以看到sts并没有进行更新,
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 5m57s
web-1 1/1 Running 0 6m12s
web-2 1/1 Running 0 6m24s
kubectl delete pod web-0 #删除web-0,验证是否触发更新
kubectl exec -it web-0 -- env | grep zhang #验证web-0是否有更新的变量
zhang=1
kubectl exec -it web-1 -- env | grep zhang #可以看到web-1没有进行删除所以没有进行更新,没有我们更新的变量
3.4 StatefulSet实现灰度发布
StatefulSet在使用rollingUpdate滚动更新策略时,可以设置partition参数实现简单的灰度发布
示例如下
#配置如下
updateStrategy:
rollingUpdate:
partition: 1 #表示在滚动更新时保留的pod编号,为1即表示保留小于1的pod不进行更新
type: RollingUpdate
#演示
kubectl set env sts/web test=1 zhang=1 test1=sss #更新
get pod -l app=nginx-1 -w
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 14s
web-1 1/1 Running 0 53s
web-2 1/1 Running 0 57s
web-2 1/1 Terminating 0 80s #更新web-2
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 2s
web-1 1/1 Terminating 0 84s #更新web-1
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 2s
#由于0小于1所以没有进行更新
3.5 StatefulSet级联删除与非级联删除
级联删除(默认)删除StatefulSet时同时删除pod,非级联删除删除StatefulSet时不会删除pod,此时的pod会变成孤儿pod,再次删除pod时pod不会被重建。
#非级联删除
kubectl delete sts web --cascade=false
statefulset.apps "web" deleted
--cascade=false #关闭级联删除
#验证pod是否存在
kubectl get pod -l app=nginx-1
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 11m
web-1 1/1 Running 0 10m
web-2 1/1 Running 0 10m
四、DaemonSet
官方文档:https://kubernetes.io/zh/docs/concepts/workloads/controllers/daemonset/
DaemonSet称为守护进程集,缩写为ds,在所有节点或者是匹配的节点上都部署一个Pod。
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的一些典型用法
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
4.1 DaemonSet示例文件
apiVersion: apps/v1 #必须,api版本
kind: DaemonSet #必须,api类型
metadata: #必须,元数据信息
labels: #可选,标签
app: nginx-1
name: nginx-1 #必须,名称
spec: #控制器配置信息
revisionHistoryLimit: 10
updateStrategy: #更新策略
rollingUpdate:
maxUnavailable: 1 #最大不可用1
type: RollingUpdate #默认滚动更新,还有其他策略为Ondelete
selector: #选择器配置
matchLabels:
app: nginx-1
template: #以下为pod配置
metadata:
creationTimestamp: null
labels:
app: nginx-1
spec:
containers:
...
4.2 DaemonSet更新回滚
updateStrategy: #更新策略
rollingUpdate: #滚动更新配置
maxUnavailable: 1 #最大不可用1
type: RollingUpdate #默认滚动更新,还有其他策略为Ondelete删除pod时才进行更新,建议使用Ondelete