Deployment控制器

有状态/无状态是什么

Kubernetes(通常简称为"k8s")是一种用于管理容器化应用程序的工具。在 Kubernetes 中,有两种主要的应用程序类型:有状态应用程序和无状态应用程序。

简单来说,有状态应用程序是指需要在应用程序之间保持某种状态或数据的应用程序,例如数据库或缓存。

这些应用程序需要在 Kubernetes 集群中部署和管理,并确保它们的状态和数据在部署和更新期间保持一致。这可以通过将数据存储在持久化卷中并将其附加到应用程序中来实现。

相反,无状态应用程序是指不需要在应用程序之间保持任何状态或数据的应用程序,例如 Web 服务器或应用程序服务器。

这些应用程序可以在 Kubernetes 集群中轻松部署和管理,并且它们可以在任何节点上运行,因为它们不依赖于任何特定的节点。由于它们没有状态或数据,因此它们可以在部署和更新期间轻松地扩展或缩小。

在实际应用中,有状态应用程序和无状态应用程序的区别对于如何在 Kubernetes 中部署和管理应用程序至关重要,因此了解它们的区别非常重要。

目前最好用、用的最多的、无状态pod控制器。

无状态是指,可以随机在任意节点、创建、删除pod,启动N个副本,副本之间默认没什么关系,如nginx的upstream后端多节点。

我们这里去改造eladmin-api,使用Deployment控制器管理。

deployment-mysql.yaml

secret.yaml

cat >env-secret.txt<<'EOF'
DB_PWD=www.yuchaoit.cn
DB_USER=root
EOF

kubectl -n yuchao create secret generic eladmin-secret --from-env-file=env-secret.txt 
kubectl -n yuchao get secret

deployment-mysql.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: yuchao
spec:
  replicas: 1    #指定Pod副本数
  selector:        #指定Pod的选择器
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:    #给Pod打label,必须和上方的matchLabels匹配
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        args:
        - --character-set-server=utf8mb4
        - --collation-server=utf8mb4_unicode_ci
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: eladmin-secret
              key: DB_PWD
        - name: MYSQL_DATABASE
          value: "eladmin"
        resources:
          requests:
            memory: 200Mi
            cpu: 50m
          limits:
            memory: 1Gi
            cpu: 500m
        readinessProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 3306
          initialDelaySeconds: 15
          periodSeconds: 20
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
      volumes: 
      - name: mysql-data
        hostPath: 
          path: /k8s-mysql/
      nodeSelector:   # 使用节点选择器将Pod调度到指定label的节点
        mysql: "true"

deployment-eladmin.yaml

前提

kubectl -n yuchao create secret docker-registry registry-10.0.0.66 --docker-username=admin --docker-password=admin --docker-email=yc_uuu@163.com --docker-server=10.0.0.66:5000


[root@k8s-master ~/k8s-all]#kubectl -n yuchao get svc -owide
NAME    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE   SELECTOR
mysql   ClusterIP   10.106.247.171   <none>        3306/TCP   3s    app=mysql
redis   ClusterIP   10.105.65.167    <none>        6379/TCP   37s   app=redis
[root@k8s-master ~/k8s-all]#

[root@k8s-master ~/k8s-all]#cat env-configs.txt 
DB_HOST=10.106.247.171
REDIS_HOST=10.105.65.167
REDIS_PORT=6379


[root@k8s-master ~/k8s-all]#kubectl -n yuchao create configmap eladmin --from-env-file=env-configs.txt
configmap/eladmin created


[root@k8s-master ~/k8s-all]#kubectl -n yuchao get cm
NAME               DATA   AGE
eladmin            3      7s
kube-root-ca.crt   1      14m

cat >env-secret.txt<<'EOF'
DB_PWD=www.yuchaoit.cn
DB_USER=root
EOF

[root@k8s-master ~/k8s-all]#kubectl -n yuchao create secret generic eladmin-secret --from-env-file=env-secret.txt 
secret/eladmin-secret created
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get secret -owide
NAME                 TYPE                             DATA   AGE
eladmin-secret       Opaque                           2      7s
registry-10.0.0.66   kubernetes.io/dockerconfigjson   1      11m

# 进入数据库,导入数据
[root@k8s-master ~/k8s-all/eladmin]#cd sql/
[root@k8s-master ~/k8s-all/eladmin/sql]#kubectl -n yuchao cp eladmin.sql mysql-7c7cf8495f-5w5bk:/tmp

[root@k8s-master ~/k8s-all/eladmin/sql]#kubectl -n yuchao exec -it mysql-7c7cf8495f-5w5bk -- bash


root@mysql-7c7cf8495f-5w5bk:/# mysql -uroot -pwww.yuchaoit.cn eladmin < /tmp/eladmin.sql 
mysql: [Warning] Using a password on the command line interface can be insecure.
root@mysql-7c7cf8495f-5w5bk:/#

实践

apiVersion: apps/v1
kind: Deployment
metadata:
  name: eladmin-api
  namespace: yuchao
spec:
  replicas: 1    #指定Pod副本数
  selector:        #指定Pod的选择器
    matchLabels:
      app: eladmin-api
  template:
    metadata:
      labels:    #给Pod打label
        app: eladmin-api
    spec:
      imagePullSecrets:
      - name: registry-10.0.0.66
      containers:
      - name: eladmin-api
        image: 10.0.0.66:5000/eladmin/eladmin-api:v1
        imagePullPolicy: IfNotPresent
        env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: eladmin
              key: DB_HOST
        - name: REDIS_HOST
          valueFrom:
            configMapKeyRef:
              name: eladmin
              key: REDIS_HOST
        - name: REDIS_PORT
          valueFrom:
            configMapKeyRef:
              name: eladmin
              key: REDIS_PORT
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: eladmin-secret
              key: DB_USER
        - name: DB_PWD
          valueFrom:
            secretKeyRef:
              name: eladmin-secret
              key: DB_PWD
        ports:
        - containerPort: 8000
        resources:
          requests:
            memory: 200Mi
            cpu: 50m
          limits:
            memory: 4Gi
            cpu: 2
        livenessProbe:
          tcpSocket:
            port: 8000
          initialDelaySeconds: 20  # 容器启动后第一次执行探测是需要等待多少秒
          periodSeconds: 15     # 执行探测的频率
          timeoutSeconds: 3        # 探测超时时间
        readinessProbe: 
          httpGet: 
            path: /auth/code
            port: 8000
            scheme: HTTP
          initialDelaySeconds: 20 
          timeoutSeconds: 3
          periodSeconds: 15

deployment-redis.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: yuchao
spec:
  replicas: 1    #指定Pod副本数
  selector:        #指定Pod的选择器
    matchLabels:
      app: redis
  template:
    metadata:
      labels:    #给Pod打label,必须和上方的matchLabels匹配
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:3.2
        ports:
        - containerPort: 6379
        resources:
          requests:
            memory: 100Mi
            cpu: 50m
          limits:
            memory: 1Gi
            cpu: 500m
        readinessProbe:
          tcpSocket:
            port: 6379
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 6379
          initialDelaySeconds: 15
          periodSeconds: 20

检查业务pod

[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po 
NAME                          READY   STATUS    RESTARTS   AGE
eladmin-api-8c96cfcbb-ljr57   1/1     Running   0          6m20s
mysql-7c7cf8495f-5w5bk        1/1     Running   0          44m
redis-7957d49f44-cxj8z        1/1     Running   0          21s

  * `NAME` 列出了集群中 Deployments 的名称。
  * `READY`显示当前正在运行的副本数/期望的副本数。
  * `UP-TO-DATE`显示已更新以实现期望状态的副本数。
  * `AVAILABLE`显示应用程序可供用户使用的副本数。
  * `AGE` 显示应用程序运行的时间量。

查看pod副本

[root@k8s-master ~/k8s-all]#kubectl -n yuchao get replicasets.apps  -owide
NAME                    DESIRED   CURRENT   READY   AGE     CONTAINERS    IMAGES                                  SELECTOR
eladmin-api-8c96cfcbb   1         1         1       7m56s   eladmin-api   10.0.0.66:5000/eladmin/eladmin-api:v1   app=eladmin-api,pod-template-hash=8c96cfcbb
mysql-7c7cf8495f        1         1         1       46m     mysql         mysql:5.7                               app=mysql,pod-template-hash=7c7cf8495f
redis-7957d49f44        1         1         1       117s    redis         redis:3.2                               app=redis,pod-template-hash=7957d49f44

查看控制器

[root@k8s-master ~/k8s-all]#kubectl -n yuchao get deployments.apps -owide
NAME          READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS    IMAGES                                  SELECTOR
eladmin-api   1/1     1            1           8m22s   eladmin-api   10.0.0.66:5000/eladmin/eladmin-api:v1   app=eladmin-api
mysql         1/1     1            1           46m     mysql         mysql:5.7                               app=mysql
redis         1/1     1            1           2m23s   redis         redis:3.2                               app=redis
[root@k8s-master ~/k8s-all]#

测试副本保障机制

kubectl edit

业务流量加大,添加多个后端

# 方法1,edit
[root@k8s-master ~/k8s-all]#kubectl -n yuchao edit deployments.apps  eladmin-api 
deployment.apps/eladmin-api edited


# 修改副本数为3
spec:
  progressDeadlineSeconds: 600
  replicas: 3

# 检查副本数量,增多了3个节点
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po   
NAME                          READY   STATUS    RESTARTS   AGE
eladmin-api-8c96cfcbb-6rqqj   1/1     Running   0          2m8s
eladmin-api-8c96cfcbb-jpwpw   1/1     Running   0          2m8s
eladmin-api-8c96cfcbb-ljr57   1/1     Running   0          12m
mysql-7c7cf8495f-5w5bk        1/1     Running   0          50m
redis-7957d49f44-cxj8z        1/1     Running   0          6m15s

kubectl apply

最好用以修改yaml文件,apply的形式,这样可以同步确保多环境的yaml文件统一。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: eladmin-api
  namespace: yuchao
spec:
  replicas: 2    #指定Pod副本数

更新deployment

[root@k8s-master ~/k8s-all]#kubectl apply -f deployment-eladmin.yaml 

检查结果
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po
NAME                          READY   STATUS    RESTARTS   AGE
eladmin-api-8c96cfcbb-jpwpw   1/1     Running   0          30m
eladmin-api-8c96cfcbb-ljr57   1/1     Running   0          40m
mysql-7c7cf8495f-5w5bk        1/1     Running   0          79m
redis-7957d49f44-cxj8z        1/1     Running   0          34m
[root@k8s-master ~/k8s-all]#

deployment更新原理

1.再次修改yaml、改为4个副本

apiVersion: apps/v1
kind: Deployment
metadata:
  name: eladmin-api
  namespace: yuchao
spec:
  replicas: 4    #指定Pod副本数
  ...

副本更新原理图

image-20230320174537895

副本数保障机制

#删掉几个pod试试,注意这里是无状态pod的特点,可以随意扩容、缩容,因为多副本之间本身无关联
[root@k8s-master ~]#kubectl -n yuchao delete po eladmin-api-8c96cfcbb-fxhp4 eladmin-api-8c96cfcbb-ggrm6 
pod "eladmin-api-8c96cfcbb-fxhp4" deleted
pod "eladmin-api-8c96cfcbb-ggrm6" deleted


[root@k8s-master ~]#
[root@k8s-master ~]#
[root@k8s-master ~]#kubectl -n yuchao get po
NAME                          READY   STATUS    RESTARTS   AGE
eladmin-api-8c96cfcbb-dfdnb   1/1     Running   0          34s
eladmin-api-8c96cfcbb-jpwpw   1/1     Running   0          93m
eladmin-api-8c96cfcbb-ljr57   1/1     Running   0          103m
eladmin-api-8c96cfcbb-mnffd   1/1     Running   0          34s
mysql-7c7cf8495f-5w5bk        1/1     Running   0          142m
redis-7957d49f44-cxj8z        1/1     Running   0          97m
[root@k8s-master ~]#

etcd管理(重要)

# 1.下载命令
wget https://github.com/etcd-io/etcd/releases/download/v3.5.3/etcd-v3.5.3-linux-amd64.tar.gz

# 2.链接etcd服务端,设置证书
$ export ETCDCTL_API=3
$ etcdctl --endpoints=https://[127.0.0.1]:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key member list -w table

# 直接操作这里即可
$ alias etcdctl='etcdctl --endpoints=https://[127.0.0.1]:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key'

$ etcdctl member list -w table
# 结果
[root@k8s-master ~/k8s-all/etcd-v3.5.3-linux-amd64]#etcdctl member list -w table
+---------------+---------+------------+------------------------+------------------------+------------+
|      ID       | STATUS  |    NAME    |       PEER ADDRS       |      CLIENT ADDRS      | IS LEARNER |
+---------------+---------+------------+------------------------+------------------------+------------+
| bbb7bc08dd69e | started | k8s-master | https://10.0.0.80:2380 | https://10.0.0.80:2379 |      false |
+---------------+---------+------------+------------------------+------------------------+------------+

# 查看etcd数据库,列出所有key

查看etcd下yuchao名称空间

可见以不同的资源类型分前缀,然后再以ns区分,找到对应的资源,如pod

[root@k8s-master ~]#etcdctl get / --prefix=true --keys-only|grep yuchao
/registry/configmaps/yuchao/eladmin
/registry/configmaps/yuchao/kube-root-ca.crt
/registry/deployments/yuchao/eladmin-api
/registry/deployments/yuchao/mysql
/registry/deployments/yuchao/redis
/registry/endpointslices/yuchao/mysql-87kk8
/registry/endpointslices/yuchao/redis-47lgm
/registry/events/yuchao/eladmin-api-8c96cfcbb-6rqqj.174e2fd53a8bdfeb
.....
....
/registry/events/yuchao/eladmin-api.174e319c654aa659
/registry/namespaces/yuchao
/registry/pods/yuchao/eladmin-api-8c96cfcbb-fxhp4
/registry/pods/yuchao/eladmin-api-8c96cfcbb-ggrm6
/registry/pods/yuchao/eladmin-api-8c96cfcbb-jpwpw
/registry/pods/yuchao/eladmin-api-8c96cfcbb-ljr57
/registry/pods/yuchao/mysql-7c7cf8495f-5w5bk
/registry/pods/yuchao/redis-7957d49f44-cxj8z
/registry/replicasets/yuchao/eladmin-api-8c96cfcbb
/registry/replicasets/yuchao/mysql-7c7cf8495f
/registry/replicasets/yuchao/redis-7957d49f44
/registry/secrets/yuchao/eladmin-secret
/registry/secrets/yuchao/registry-10.0.0.66
/registry/serviceaccounts/yuchao/default
/registry/services/endpoints/yuchao/mysql
/registry/services/endpoints/yuchao/redis
/registry/services/specs/yuchao/mysql
/registry/services/specs/yuchao/redis
[root@k8s-master ~]#

查看eladmin-api的数据库

但是是二进制数据,是无法阅读的

[root@k8s-master ~]#etcdctl get / --prefix=true --keys-only|grep deploy  |grep yuchao
/registry/deployments/yuchao/eladmin-api
/registry/deployments/yuchao/mysql
/registry/deployments/yuchao/redis

# 这一步是为了理解,对k8s集群资源的操作,其实是写入etcd的
# 1. 写yaml  2. kubectl create -f xx.yaml   3. 写入etcd数据库

[root@k8s-master ~]#etcdctl get /registry/deployments/yuchao/eladmin-api

版本更新与组件通信原理

初学,不用太去琢磨组件通信原理,基本是蒙的。

k8s部署熟练之后,这些组件你都认识了,再去学原理。

img

# 检查 etcd里的pod

[root@k8s-master ~]#kubectl -n yuchao get po 
NAME                          READY   STATUS    RESTARTS   AGE
eladmin-api-8c96cfcbb-fxhp4   1/1     Running   0          33m
eladmin-api-8c96cfcbb-ggrm6   1/1     Running   0          33m
eladmin-api-8c96cfcbb-jpwpw   1/1     Running   0          65m
eladmin-api-8c96cfcbb-ljr57   1/1     Running   0          75m
mysql-7c7cf8495f-5w5bk        1/1     Running   0          114m
redis-7957d49f44-cxj8z        1/1     Running   0          69m
[root@k8s-master ~]#
[root@k8s-master ~]#
[root@k8s-master ~]#etcdctl get / --prefix=true --keys-only|grep pod|grep eladmin-api
/registry/pods/yuchao/eladmin-api-8c96cfcbb-fxhp4
/registry/pods/yuchao/eladmin-api-8c96cfcbb-ggrm6
/registry/pods/yuchao/eladmin-api-8c96cfcbb-jpwpw
/registry/pods/yuchao/eladmin-api-8c96cfcbb-ljr57

pod和deployment的关系

deployment
↓
etcd(记录deployment的规则,生产3个pod,但是还没被调度)
↓
controller manager(监听deployment数据变化)
↓
replicasets.apps
↓
pod

实践服务更新(重要)

1.提交新镜像(更新eladmin-api的首页),各位只需要找到如下代码,修改一点点内容即可

image-20230320190426793

1. 提交到github,模拟开发
git add .
git commit -m 'yuchao with index /who api'
git push -u origin master


2. 服务端更新代码
直接git pull更新即可


3.更新docker镜像
docker build . -t eladmin:v2 -f Dockerfile.multi
docker tag eladmin:v2 10.0.0.66:5000/eladmin:v2
docker push 10.0.0.66:5000/eladmin:v2
[root@docker01 ~/eladmin]# curl -u admin:admin -X GET http://10.0.0.66:5000/v2/eladmin/tags/list
{"name":"eladmin","tags":["v2"]}



4.修改业务yaml的镜像版本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: eladmin-api
  namespace: yuchao
spec:
  replicas: 4    #指定Pod副本数
  selector:        #指定Pod的选择器
    matchLabels:
      app: eladmin-api
  template:
    metadata:
      labels:    #给Pod打label
        app: eladmin-api
    spec:
      imagePullSecrets:
      - name: registry-10.0.0.66
      containers:
      - name: eladmin-api
        image: 10.0.0.66:5000/eladmin:v2

# 更新
[root@k8s-master ~/k8s-all]#kubectl apply -f deployment-eladmin.yaml 
deployment.apps/eladmin-api configured

# 检测pod变化
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get po -w

# 访问新接口

image-20230320195201925

deployment控制器是怎么定义模板,去控制、去修改最终的pod呢?

滚动更新(重要)

Kubernetes Deployment 的默认更新策略是滚动更新(Rolling Update)。在滚动更新中,Kubernetes 会逐步将新版本的 Pod 替换旧版本的 Pod,以确保应用程序在更新过程中保持可用性。默认情况下,Deployment 会在一段时间内更新一定数量的 Pod,以避免应用程序的服务中断。

在滚动更新期间,Kubernetes Deployment 会监控应用程序的健康状况。如果更新导致应用程序出现异常,Deployment 会自动回滚到旧版本,以确保应用程序的稳定性和可用性。

除了滚动更新之外,Kubernetes Deployment 还提供了多种更新策略,如蓝绿更新、Recreate 策略和自定义策略等。可以根据应用程序的需求选择适当的更新策略。

1.更新yaml,更新镜像版本
kubectl -n yuchao apply -f deploy-eladmin-api.yaml

2.也可以直接在线更新
kubectl -n yuchao edit deploy eladmin-api

3.使用set image命令更新应用版本镜像,
kubectl -n yuchao set image deploy eladmin-api eladmin-api=10.0.0.66:5000/eladmin/eladmin-api:v2 --record

kubectl 命令中,--record 参数的作用是记录当前的操作,将操作的细节存储到 Deployment 对象的注释中。

这个参数会将每次执行的 kubectl 命令及其参数的详细信息记录在 Deployment 对象的注释中,包括部署的时间、执行的命令以及命令的参数等信息。这些记录可以帮助管理员和开发人员在后续的故障排查和系统维护中更好地了解系统的状态和历史操作。

通过使用 --record 参数,可以在 Deployment 对象的注释中保留每次更新的历史记录,从而更好地跟踪和管理应用程序的变化。此外,在运行 kubectl rollout history 命令时,--record 参数可以显示出更新的详细信息。

副本修改

...
spec:
  replicas: 2    #指定Pod副本数
  selector:        #指定Pod的选择器
    matchLabels:
      app: eladmin-api
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate        #指定更新方式为滚动更新,默认策略,通过get deploy yaml查看
    ...

img

策略控制

  • maxSurge:最大激增数, 指更新过程中, 最多可以比replicas预先设定值多出的pod数量, 可以为固定值或百分比,默认为desired Pods数的25%。计算时向上取整(比如0.5,取1),更新过程中最多会有replicas + maxSurge个pod
  • maxUnavailable: 指更新过程中, 最多有几个pod处于无法服务状态 , 可以为固定值或百分比,默认为desired Pods数的25%。计算时向下取整(比如0.5,取0)

在Deployment rollout时,需要保证Available(Ready) Pods数不低于 replicas - maxUnavailable; 保证所有的非异常状态Pods数不多于 replicas + maxSurge

  • 逐步、滚动替换pod
  • 滚动策略也可以人为控制
[root@k8s-master ~/k8s-all]#kubectl -n yuchao get deployments.apps eladmin-api -oyaml
...
spec:
  progressDeadlineSeconds: 600
  replicas: 4
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: eladmin-api
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: eladmin-api
...

更新策略计算

eladmin-api为例,使用默认的策略,更新过程:

  1. maxSurge 25%,2个实例,向上取整,则maxSurge为1,意味着最多可以有2+1=3个Pod,那么此时会新创建1个ReplicaSet,RS-new,把副本数置为1,此时呢,副本控制器就去创建这个新的Pod
  2. 同时,maxUnavailable是25%,副本数2*25%,向下取整,则为0,意味着,滚动更新的过程中,不能有少于2个可用的Pod,因此,旧的Replica(RS-old)会先保持不动,等RS-new管理的Pod状态Ready后,此时已经有3个Ready状态的Pod了,那么由于只要保证有2个可用的Pod即可,因此,RS-old的副本数会有2个变成1个,此时,会删掉一个旧的Pod
  3. 删掉旧的Pod的时候,由于总的Pod数量又变成2个了,因此,距离最大的3个还有1个Pod可以创建,所以,RS-new把管理的副本数由1改成2,此时又会创建1个新的Pod,等RS-new管理了2个Pod都ready后,那么就可以把RS-old的副本数由1置为0了,这样就完成了滚动更新

查看rs副本集

deployment更新策略是

  • 不断的踢掉旧rs的pod
  • 不断的启动新rs的pod
  • 因此deployment还支持回滚功能
  • 每一个rs定义了pod的运行模板属性
# 查看deployment更新事件

[root@k8s-master ~/k8s-all]#kubectl -n yuchao describe deployments.apps eladmin-api 



[root@k8s-master ~/k8s-all]#kubectl -n yuchao get rs
NAME                    DESIRED   CURRENT   READY   AGE
eladmin-api-8c96cfcbb   0         0         0       18h
eladmin-api-9446bcc45   4         4         4       16h
mysql-7c7cf8495f        1         1         1       19h
redis-7957d49f44        1         1         1       18h
[root@k8s-master ~/k8s-all]#

rs与pod关系

image-20230321131359394

更新策略recreate

除了滚动更新以外,还有一种策略是Recreate,直接在当前的pod基础上先删后建,重建策略

...
  strategy:
    type: Recreate
...

当使用 "type: Recreate" 策略进行部署时,现有的应用程序或服务将被停止并从系统中删除,然后新版本的应用程序或服务将被构建并重新启动以替换旧版本。

这种策略可以确保部署的干净性和一致性,但也可能导致应用程序的停机时间。

因此,在选择部署策略时,需要考虑应用程序的可用性和用户体验等因素。

服务回滚

通过滚动升级的策略可以平滑的升级Deployment,若升级出现问题,需要最快且最好的方式回退到上一次能够提供正常工作的版本。为此K8S提供了回滚机制。

revision:更新应用时,K8S都会记录当前的版本号,即为revision,当升级出现问题时,可通过回滚到某个特定的revision

默认配置下,K8S只会保留最近的几个revision,可以通过Deployment配置文件中的spec.revisionHistoryLimit属性增加revision数量,默认是10。

# 查看历史记录
[root@k8s-master ~/k8s-all]#kubectl -n yuchao rollout history deployment eladmin-api 
deployment.apps/eladmin-api 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

需要在更新镜像时,添加--record参数,才有版本记录功能

删除现有eladmin,重建,且携带版本记录

[root@k8s-master ~/k8s-all]#kubectl delete -f deployment-eladmin.yaml 
deployment.apps "eladmin-api" deleted
[root@k8s-master ~/k8s-all]#
[root@k8s-master ~/k8s-all]#kubectl apply -f deployment-eladmin.yaml --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/eladmin-api created


[root@k8s-master ~/k8s-all]#kubectl -n yuchao rollout history deployment eladmin-api 
deployment.apps/eladmin-api 
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=deployment-eladmin.yaml --record=true

[root@k8s-master ~/k8s-all]#

回到具体的一个版本号

kubectl -n yuchao rollout undo deploy eladmin-api --to-revision=1

该功能作用不大,因为生产下的服务变更,大变动会涉及

deployment、image、configmap、secret一起的变更。

而该rollout功能只是回滚了deployment的镜像配置,所以了解即可。

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2024-03-31 19:26:46

results matching ""

    No results matching ""