k8s 분산 배포 노드의 포드 반친화성(podAntiAffinity)

백그라운드 및 시나리오 사업에서 핵심 서비스를 이용하여
다수의 레플리카를 구성한 결과 배포 과정에서 동일한 호스트에 여러 개의 동일한 복제본이 동시에 배포되는 것을 발견하였고, 호스트 장애 시 모든 복제본이 드리프트되는 현상이 발생하였다. 동시에 서비스가 간헐적으로 중단될 수 있습니다.

위의 배경을 바탕으로 서비스의 여러 복사본이 서로 다른 호스트에 배포되므로 각 호스트는 서비스의 복사본을 하나만 갖고 실행할 수 있습니다.여기서는 Pod anti-affinity 속성, 즉 Pod anti-affinity가 사용됩니다. 이 기능은 노드에서 이미 실행 중인 Pod의 레이블을 기반으로 동일한 레이블을 가진 Pod가 더 이상 노드에 예약되지 않으므로 각 노드에서 Pod의 복사본 하나만 실행된다는 것입니다.

Pod 선호도와 반선호도의 차이점
Affinity(podAffinity): 지정된 레이블이 있는 Pod와 동일한 노드에 배포
Anti-affinity(podAntiAffinity): 지정된 레이블이 있는 Pod와 동일한 노드에 서비스를 배포하고 싶지 않습니다. 지정된 레이블
podAntiAffinity 실제 배포 반친화성은
소프트 요구 사항과 하드 요구 사항으로 나누어집니다
.RequiredDuringSchedulingIgnoredDuringExecution: 하드 요구 사항은 분산 배포의 효과를 보장하기 위한 조건을 충족해야 합니다. 이 방법은 가장 잘 사용됩니다. PreferredDuringSchedulingIgnoredDuringExecution:
소프트 요구 사항이 완전히 충족되지 않을 수 있습니다. 즉, 동일한 노드에 있을 수 있으며 여러 복사본을 실행할 수 있습니다.

# 配置如下,只需要修改label的配置,即matchExpressions中的key和values的值

# 硬性要求
# 如果节点上的pod标签存在满足app=nginx,则不能部署到节点上
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: "kubernetes.io/hostname"

# 软性要求
# 如果节点上的pod标签存在满足app=nginx,也可以部署到节点上,尽可能先部署到其它节点,如果没有满足也可以部署到此节点(大概是这么理解吧)
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
            - labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - nginx
              topologyKey: "kubernetes.io/hostname"

첨부된 내용은 전체 배포.yaml 구성입니다.


apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  strategy:
    rollingUpdate:
      maxSurge: 30%
      maxUnavailable: 0
    type: RollingUpdate
  minReadySeconds: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: "kubernetes.io/hostname"
      restartPolicy: "Always"
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: "IfNotPresent"
        ports:
        - containerPort: 80
          name: http
          protocol: TCP

실제 프로덕션 환경을 위한 포드 반친화성

        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            # Never schedule multiple replicas on the same node
            - topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app.kubernetes.io/name: ${service}
                  app.kubernetes.io/instance: ${service}

apiVersion:  apps/v1
kind: Deployment
metadata:
  name: ${service}
  labels:
    app.kubernetes.io/name: ${service}
    app.kubernetes.io/version: 0.0.0
    app.kubernetes.io/instance: ${service}
    environment: ${env}
spec:
  replicas: ${replicas}
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app.kubernetes.io/name: ${service}
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ${service}
        app.kubernetes.io/version: 0.0.0
        app.kubernetes.io/instance: ${service}
        logging: "false"
        armsPilotAutoEnable: "off"
        armsPilotCreateAppName: "${service}-${env}"
    spec:
      serviceAccountName: default
      dnsPolicy: ClusterFirst
      imagePullSecrets:
        - name: gemdale-registry.cn-shenzhen.cr.aliyuncs.com-secret
      containers:
        - name: ${service}
          image: ${image}
          imagePullPolicy: IfNotPresent
          env:
            - name: CONSUL_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: ELASTIC_APM_SERVER_URLS
              value: http://apm-server.logging:8200
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: SERVER_PORT
              value: "80"
            - name: JAVA_OPTS
              value: -Duser.timezone=Asia/Shanghai
            - name: WFWAPP
              value: wfw-applog

          volumeMounts:
            - mountPath: /data/appdata/
              name: appdata
            - mountPath: /data/config-repo/
              name: config-repo
            - mountPath: /data/logs/
              name: logs
            - mountPath: /mnt/hgfs/
              name: mnt-hgfs
          ports:
            - containerPort: 80
              name: http
          resources:
            {
    
    }

      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: microservice
                    operator: In
                    values:
                      - "true"
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            # Never schedule multiple replicas on the same node
            - topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  app.kubernetes.io/name: ${service}
                  app.kubernetes.io/instance: ${service}
      volumes:
        - hostPath:
            path: /data/appdata/
            type: DirectoryOrCreate
          name: appdata
        - hostPath:
            path: /data/config-repo/
            type: DirectoryOrCreate
          name: config-repo
        - hostPath:
            path: /data/logs/
            type: DirectoryOrCreate
          name: logs
        - hostPath:
            path: /mnt/hgfs/
            type: DirectoryOrCreate
          name: mnt-hgfs
---
apiVersion: v1
kind: Service
metadata:
  name: ${service}
  labels:
    app.kubernetes.io/name: ${service}
    app.kubernetes.io/version: 0.0.0
    app.kubernetes.io/instance: ${service}
    environment: ${env}
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
  selector:
    app.kubernetes.io/name: ${service}
    app.kubernetes.io/instance: ${service}

Supongo que te gusta

Origin blog.csdn.net/jialiu111111/article/details/132429526
Recomendado
Clasificación