更新时间:2023-12-07 GMT+08:00

在CCE中实现应用高可用部署

基本原则

在CCE中,容器部署要实现高可用,可参考如下几点:

  1. 集群选择3个控制节点的高可用模式。
  2. 创建节点选择在不同的可用区,在多个可用区(AZ)多个节点的情况下,根据自身业务需求合理的配置自定义调度策略,可达到资源分配的最大化。
  3. 创建多个节点池,不同节点池部署在不同可用区,通过节点池扩展节点。
  4. 工作负载创建时设置实例数需大于2个。
  5. 设置工作负载亲和性规则,尽量让Pod分布在不同可用区、不同节点上。

操作步骤

为了便于描述,假设集群中有4个节点,其可用区分布如下所示。

$ kubectl get node -L topology.kubernetes.io/zone,kubernetes.io/hostname
NAME            STATUS   ROLES    AGE   VERSION                      ZONE     HOSTNAME
192.168.5.112   Ready    <none>   42m   v1.21.7-r0-CCE21.11.1.B007   zone01   192.168.5.112
192.168.5.179   Ready    <none>   42m   v1.21.7-r0-CCE21.11.1.B007   zone01   192.168.5.179
192.168.5.252   Ready    <none>   37m   v1.21.7-r0-CCE21.11.1.B007   zone02   192.168.5.252
192.168.5.8     Ready    <none>   33h   v1.21.7-r0-CCE21.11.1.B007   zone03   192.168.5.8

按如下定义创建负载。这里定义了两条工作负载反亲和规则podAntiAffinity。

  • 第一条在可用区下工作负载反亲和,参数设置如下。
    • 权重weight:权重值越高会被优先调度,本示例设置为50。
    • 拓扑域topologyKey:包含默认和自定义标签,用于指定调度时的作用域。本示例设置为topology.kubernetes.io/zone,此为节点上标识节点在哪个可用区的标签。
    • 标签选择labelSelector:选择Pod的标签,与工作负载本身反亲和。
  • 第二条在节点名称作用域下工作负载反亲和,参数设置如下。
    • 权重weight:设置为50。
    • 拓扑域topologyKey:设置为kubernetes.io/hostname。
    • 标签选择labelSelector:选择Pod的标签,与工作负载本身反亲和。
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: container-0
          image: nginx:alpine
          resources:
            limits:
              cpu: 250m
              memory: 512Mi
            requests:
              cpu: 250m
              memory: 512Mi
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 50
              podAffinityTerm:
                labelSelector:                       # 选择Pod的标签,与工作负载本身反亲和。
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - nginx
                namespaces:
                  - default
                topologyKey: topology.kubernetes.io/zone   # 在同一个可用区下起作用
            - weight: 50
              podAffinityTerm:
                labelSelector:                       # 选择Pod的标签,与工作负载本身反亲和
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - nginx
                namespaces:
                  - default
                topologyKey: kubernetes.io/hostname     # 在节点上起作用
      imagePullSecrets:
        - name: default-secret

创建工作负载,然后查看Pod所在的节点。

$ kubectl get pod -owide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE
nginx-6fffd8d664-dpwbk   1/1     Running   0          17s   10.0.0.132   192.168.5.112
nginx-6fffd8d664-qhclc   1/1     Running   0          17s   10.0.1.133   192.168.5.252

将Pod数量增加到3,可以看到Pod被调度到了另外一个节点,且这个当前这3个节点是在3个不同可用区。

$ kubectl scale --replicas=3 deploy/nginx
deployment.apps/nginx scaled
$ kubectl get pod -owide
NAME                     READY   STATUS    RESTARTS   AGE     IP           NODE
nginx-6fffd8d664-8t7rv   1/1     Running   0          3s      10.0.0.9     192.168.5.8
nginx-6fffd8d664-dpwbk   1/1     Running   0          2m45s   10.0.0.132   192.168.5.112
nginx-6fffd8d664-qhclc   1/1     Running   0          2m45s   10.0.1.133   192.168.5.252

将Pod数量增加到4,可以看到Pod被调度到了最后一个节点。可见根据工作负载反亲和规则,可以将Pod按照可用区和节点较为均匀的分布,更为可靠。

$ kubectl scale --replicas=4 deploy/nginx
deployment.apps/nginx scaled
$ kubectl get pod -owide
NAME                     READY   STATUS    RESTARTS   AGE     IP           NODE
nginx-6fffd8d664-8t7rv   1/1     Running   0          2m30s   10.0.0.9     192.168.5.8
nginx-6fffd8d664-dpwbk   1/1     Running   0          5m12s   10.0.0.132   192.168.5.112
nginx-6fffd8d664-h796b   1/1     Running   0          78s     10.0.1.5     192.168.5.179
nginx-6fffd8d664-qhclc   1/1     Running   0          5m12s   10.0.1.133   192.168.5.252