障害回復期間中のkubernetesDNSの応答が15秒を超えています

1。概要:

1.1環境

バージョン情報は次のとおりです。a
。オペレーティングシステム:centos 7.6
c、kubernetesバージョン:v1.15.0


1.2障害回復期間中のDNSクエリ遅延の現象

kubernetes dnsの実装はcorednsであり、Deploymentのダブルコピーの形式で2つのノードを別々にデプロイし
ます。corednsインスタンスはすぐに停止しました(サーバーは即座にダウンし、k8sサービストラフィックは削除されませんでした)。ビジネスポッドがDNSにクエリを実行すると、DNSサーバーから15秒の失敗応答を受け取る可能性があります(/ etcが原因) /resolv.confファイルのデフォルトはタイムアウト5秒で、2回再試行します)。kuberntesがサービストラフィックを削除すると(iptables natテーブルまたはlvsルールに反映されます。削除効果は通常、サーバーがダウンしてから約40秒です)、10.96.0.10はDNATしか削除できないため、15秒の遅延現象はなくなります。通常動作時のポッドのIPです。

cni0ネットワークカードでパケットをキャプチャします。udpログは次のとおりです。合計3つのログ、ログエントリは5秒のタイムアウトに制限されたクエリです(ランダムな送信元ポートは変更されません。このログでは41805です)。再試行してください。 2回なので、合計3つのレコード、合計15秒があります。障害回復期間中、ビジネスコンテナは同じ送信元ポートを使用して、15秒間ダウンしたDNSコンテナに移動することがわかります。

# 10.96.0.10 被DNAT成 10.244.1.52.53,狂干15秒
21:27:52.521261 IP 10.244.0.80.41805 > 10.244.1.52.53: 51985+ AAAA? kubernetes.default.svc.cluster.local. (54)
21:27:57.521607 IP 10.244.0.80.41805 > 10.244.1.52.53: 51985+ AAAA? kubernetes.default.svc.cluster.local. (54)
21:28:02.522524 IP 10.244.0.80.41805 > 10.244.1.52.53: 51985+ AAAA? kubernetes.default.svc.cluster.local. (54)

ここに画像の説明を挿入

2遅延緩和方法:

/etc/resolv.cnfファイルで複数のネームサーバーフィールドを使用すると、遅延が15秒から2秒に驚くほど短縮されました(centos7コンテナは2秒であり、パケットキャプチャ分析により、2秒のほとんどがダウンタイムに消費されます。マシンはAレコードとAAAAレコードを照会します)。デプロイメントフォームのcorednsをStatefulsetモードに変更しました。各ポッドには固定サービスがあり、これらのサービスのIPは/etc/resolv.cnfファイルのネームサーバーフィールドに書き込まれます。

2.1 corednsStatefulSet的yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    k8s-app: kube-dns
  name: coredns
  namespace: kube-system
spec:
  replicas: 2
  selector:
    matchLabels:
      k8s-app: kube-dns
  serviceName: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: k8s-app
                operator: In
                values:
                - kube-dns
            topologyKey: kubernetes.io/hostname
      containers:
      - args:
        - -conf
        - /etc/coredns/Corefile
        image: 192.168.1.70:5000/coredns:1.3.1
        imagePullPolicy: IfNotPresent
        readinessProbe:
          failureThreshold: 2
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        name: coredns
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          limits:
            memory: 170Mi
          requests:
            cpu: 100m
            memory: 70Mi
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          readOnlyRootFilesystem: true
        volumeMounts:
        - mountPath: /etc/coredns
          name: config-volume
          readOnly: true
      dnsPolicy: Default
      nodeSelector:
        beta.kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      restartPolicy: Always
      serviceAccount: coredns
      serviceAccountName: coredns
      terminationGracePeriodSeconds: 30
      tolerations:
      - key: CriticalAddonsOnly
        operator: Exists
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: Corefile
            path: Corefile
          name: coredns
        name: config-volume


2.2 corednsconfigmap的yaml

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system

2.4 yamlのcorednsサービス(2つのサービス)

apiVersion: v1
kind: Service
metadata:
  labels:
    statefulset.kubernetes.io/pod-name: coredns-0
    k8s-app: kube-dns
  name: coredns-0
  namespace: kube-system
spec:
  clusterIP: 10.96.0.11
  ports:
  - name: dns
    port: 53
    protocol: UDP
    targetPort: 53
  - name: dns-tcp
    port: 53
    protocol: TCP
    targetPort: 53
  - name: metrics
    port: 9153
    protocol: TCP
    targetPort: 9153
  selector:
    k8s-app: kube-dns
    statefulset.kubernetes.io/pod-name: coredns-0
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    statefulset.kubernetes.io/pod-name: coredns-1
    k8s-app: kube-dns
  name: coredns-1
  namespace: kube-system
spec:
  clusterIP: 10.96.0.12
  ports:
  - name: dns
    port: 53
    protocol: UDP
    targetPort: 53
  - name: dns-tcp
    port: 53
    protocol: TCP
    targetPort: 53
  - name: metrics
    port: 9153
    protocol: TCP
    targetPort: 9153
  selector:
    k8s-app: kube-dns
    statefulset.kubernetes.io/pod-name: coredns-1
  sessionAffinity: None
  type: ClusterIP

3救済効果:

coredns-0はマスターサーバーで実行され、coredns-1はnode1サーバーで実行され、すべての前に同じ名前のk8sサービスがあります。
ここに画像の説明を挿入

ネームサーバーの最初の値は10.96.0.12(node1サーバー上のインスタンスcoredns-1のサービス)であるため、マスターサーバー上のビジネスコンテナcentosは最初にnode1上のcorednsにクエリを実行します。
ここに画像の説明を挿入

node1サーバーはすぐにシャットダウンし、ビジネスコンテナのnslookupコマンドには2秒かかります(ipv6が完全にシャットダウンされた場合、AAAAレコードがクエリされないため、消費量は1秒になります)。この記事のシナリオでは、この2秒間の現象は、node1のcorednsが通常の動作を再開するまで続きます。
ここに画像の説明を挿入


4要約:

/etc/resolv.confファイルで複数のネームサーバーを使用すると、dnsクエリ要求がすぐに失敗するという効果が生じる可能性があります。ネームサーバーがクエリに失敗すると、次のネームサーバーにすばやく要求します。kubernetesクラスターコンテナで、/ etc / resolve.confにネームサーバーが1つだけ含まれている場合(たとえば、10.96.0.10)、リカバリ期間中に複数の遅延が発生する可能性があります(異常なdnsサーバーにクエリを再試行するビジネス) )。

おすすめ

転載: blog.csdn.net/nangonghen/article/details/113665216