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サーバーにクエリを再試行するビジネス) )。