ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage
Edit page

2.4 K8s控制器资源对象之 Rs& Deployment

ReplicaSet(一般不直接使用)

简称:rs

yaml示例

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp
  namespace: default
  labels:
    app: myapp
    
spec:
  replicas: 2  #核心配置1:pod副本数量
  selector:    #核心配置2:标签选择器
    matchLabels:
      app: myapp
      release: canary
  template:    #核心配置3:pod资源模板
    metadata:
      name: myapp-pod
      labels:               #标签必须定义,而且必须满足标签选择器的匹配,否则Pod会无限创建
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp-container
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
[root@k8smaster manifests]# kubectl create -f rs-demo.yaml 
replicaset.apps/myapp created
[root@k8smaster manifests]# kubectl get rs
NAME      DESIRED   CURRENT   READY     AGE
myapp     2         2         2         19s
[root@k8smaster manifests]# kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
myapp-gz7jf   1/1       Running   0          28s
myapp-qlqrb   1/1       Running   0          28s

#在线调整副本数(replicas)和升级(image)
[root@k8smaster manifests]# kubectl edit rs myapp
#修改replicas: 5
[root@k8smaster manifests]# kubectl get rs
NAME      DESIRED   CURRENT   READY     AGE
myapp     5         5         5         2m
[root@k8smaster manifests]# kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
myapp-6vggd   1/1       Running   0          50s
myapp-gz7jf   1/1       Running   0          2m
myapp-jsdrx   1/1       Running   0          50s
myapp-qlqrb   1/1       Running   0          2m
myapp-vprqk   1/1       Running   0          50s
[root@k8smaster manifests]# kubectl get rs -o wide
NAME      DESIRED   CURRENT   READY     AGE       CONTAINERS        IMAGES                 SELECTOR
myapp     5         5         5         4m        myapp-container   ikubernetes/myapp:v2   app=myapp,release=canary

ReplicaSet缺点

rs通过kubectl edit 修改image版本的升级方式有个缺陷:就是已经创建的pod版本不会升级,只有pod重建后,才会使用新版本的镜像。需要我们手动将原先的pod删除,然后rs控制器自动重建,重建后的pod就会是新版本的image。如果要实现实时更新,这个操作我们可以使用deployment自动实现。

Deployment(重点)

简称:deploy

Deployment、ReplicaSet、Pod关系

Deployment控制多个ReplicaSet,ReplicaSet控制Pod,它们组成三层逻辑结构。Deployment主要职责是为了保证 pod 的数量和健康,90% 的功能与 Replication Controller 完全一样,可以看做新一代的 Replication Controller。但是,它又具备了 Replication Controller 之外的新特性。

Deployment特性

  • Replication Controller 全部功能:Deployment继承了Replication Controller全部功能。
  • 多种升级策略strategy
    • Recreate(删除所有已存在的 pod, 重新创建新的);
    • RollingUpdate(滚动升级,逐步替换的策略),滚动升级时,支持更多的附加参数,例如设置最大不可用 pod 数量,最小升级间隔时间等等。
  • 事件和状态查看:可以查看 Deployment 的升级详细进度和状态。
    • kubectl rollout status deployment/myapp-deployment 查看状态。
    • 也可以使用kubectl describe命令查看
  • 回滚:当升级 pod 镜像或者相关参数的时候发现问题,可以使用回滚操作回滚到上一个稳定的版本或者指定的版本。
    • kubectl rollout undo deployment/myapp-deployment [--to-revision=2] 回滚到上一个版本或升级历史中的revision=2的版本。
  • 版本记录: 每一次对 Deployment 的操作,都能保存下来,给予后续可能的回滚使用。
    • kubectl rollout history deployment/myapp-deployment 查看升级历史
  • 暂停和启动:对于每一次升级,都能够随时暂停和启动。
    • kubectl rollout pause|resume deployment/myapp-deployment

Deployment详解

1、Deployment.spec

apiVersion: apps/v1
kind: deployment
metadata:
  name: myapp-deployment
  namespace: default
  
spec:  #4个常用字段
  replicas:  #Pod副本数量
  selector:  #Pod的标签选择器
  template:  #Pod资源模板
    metadata:
    spec:
  strategy:  #Pod滚动升级策略
  revisionHistoryLimit:  #定义保留历史版本最大数量,默认为10个(保留的RS的版本数量,用于回滚操作)

示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  strategy:
    type: RollingUpdate  #默认为RollingUpdate(滚动更新),此外还有Recreate(重建:同时删除所有后创建)
    rollingUpdate:
      maxSurge: 1  #滚动升级时会先启动1个pod。滚动升级时可以超出期望副本的个数(最大超出数量或百分比)
      maxUnavailable: 1  #滚动升级时,副本数可以少于期望副本数的最大个数(最大不可用数量或百分比)
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp-container
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80

蓝绿部署:2个不同应用版本的deployment同时存在,service关联其中一个deployment,随时可以切换到另一个

金丝雀部署:kubecle rollout pause使新版本的pod只占少数。

2、Deployment创建或更新

kubectl apply

[root@k8smaster manifests]# kubectl apply -f deployment-demo.yaml 
deployment.apps/myapp-deployment created
[root@k8smaster manifests]# kubectl get deploy
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
myapp-deployment   2         2         2            2           9s
[root@k8smaster manifests]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
myapp-deployment-84547bc66f   2         2         2         12m
[root@k8smaster manifests]# kubectl get pods
NAME                                READY     STATUS    RESTARTS   AGE
myapp-deployment-84547bc66f-4bwl9   1/1       Running   0          12m
myapp-deployment-84547bc66f-wwx99   1/1       Running   0          12m

命令行创建:

kubectl run ${DEPLOY_NAME} --image=${IMAGE} --replicas=${NUM}

3、Deployment扩容

kubectl autoscale deployment myapp-deployment --replica=3

4、Deployment升级

deployment升级采用的是滚动升级的方式。

  • 方式1:修改yaml文件,然后使用kubectl apply重新配置deployment
[root@k8smaster manifests]# vim deployment-demo.yaml
#修改image: ikubernetes/myapp:v2
[root@k8smaster manifests]# kubectl apply -f deployment-demo.yaml 
deployment.apps/myapp-deployment configured
[root@k8smaster manifests]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
myapp-deployment-557466758b   3         3         3         7m
myapp-deployment-84547bc66f   0         0         0         37m
  • 方式2:kubectl edit 修改镜像名称后保存,会自动完成升级
[root@k8smaster manifests]# kubectl edit deploy/myapp-deployment
#修改image: ikubernetes/myapp:v2
[root@k8smaster manifests]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
myapp-deployment-557466758b   3         3         3         7m
myapp-deployment-84547bc66f   0         0         0         37m
  • 方式3:kubectl set image命令行
[root@k8smaster manifests]# kubectl set image deployment/myapp-deployment myapp-container=ikubernetes/myapp:v2
[root@k8smaster manifests]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
myapp-deployment-557466758b   3         3         3         10m
myapp-deployment-84547bc66f   0         0         0         40m

此外还可以通过kubectl set resources命令来调整容器的cpu、内存资源分配

  • 方式4:通过kubectl patch打补丁的方式,这种方式补丁需要以json格式给出
[root@k8smaster manifests]# kubectl patch deployment/myapp-deployment -p '{"spec":{"containers":[{"image":"ikubernetes/myapp:v2"}]}}'
[root@k8smaster manifests]# kubectl get rs
NAME                          DESIRED   CURRENT   READY     AGE
myapp-deployment-557466758b   3         3         3         10m
myapp-deployment-84547bc66f   0         0         0         40m
#替换:replace
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'
#新增:add
kubectl patch pod valid-pod --type='json' -p='[{"op": "add", "path": "/metadata/labels/MixedDeploy_Status", "value":"true"}]'
#删除:remove
kubectl patch pod valid-pod --type='json' -p='[{"op": "remove", "path": "/metadata/labels/MixedDeploy_Status"}]'

查看升级进度:

[root@k8smaster manifests]# kubectl rollout status deployment/rolling-update-test

**升级暂停和启动: **

对于每一次升级,都能够随时暂停和启动。

[root@k8smaster manifests]# kubectl rollout pause|resume deployment/rolling-update-test

5、Deployment回滚

查看升级历史:

[root@k8smaster manifests]# kubectl rollout history deployment/myapp-deployment
deployments "myapp-deployment"
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

回滚:

kubectl rollout undo deployment/rolling-update-test [--to-revision=2] #回滚到上一个版本或升级历史中的revision=2的版本。

如何重启deployment下的所有Pod?

​ 有时候我们会修改应用的配置文件,修改后,需要重启Pod使之生效。kubectl没有相应的子命令,那如何手动重启deployment下的所有Pod呢?

​ 我们可以在Pod资源的annotations字段下定义一个任意字段。通过修改这个字段的值来触发deployment的升级,已达到重启Pod的目的。

kubectl patch deployment myapp-deployment  --patch "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"version/restartTime\":\"$(date +%Y%m%d_%H%M%S)\"}}}}}"