Я попал в очень странную ситуацию, когда kube-proxy
не принимает соединения на некоторых узлах, и, честно говоря, я в тупике.
Задний план:
eu-central-1
, распределенных по трем зонам доступности (a, b, c)v1.14.6
но это наблюдалось также с v.1.13.x
kube-proxy
журналы, на самом деле вывод кажется совершенно идентичнымkube-proxy
делает прослушивает данный порт, но время ожидания запросов истеклоingress
сервис, внутренний балансировщик нагрузки и порт HTTPS (443)Пример ниже. Оба узла находятся в одной зоне доступности.
Здоровый узел:
curl --connect-timeout 5 -sD - -k https://localhost:32028/healthz
HTTP/2 200
date: Sun, 13 Oct 2019 13:51:32 GMT
content-type: text/html
content-length: 0
sudo netstat -taupen | grep kube-proxy | grep LISTEN
tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 0 21284 3162/kube-proxy
tcp6 0 0 :::32618 :::* LISTEN 0 23820 3162/kube-proxy
tcp6 0 0 :::32012 :::* LISTEN 0 21359 3162/kube-proxy
tcp6 0 0 :::10256 :::* LISTEN 0 21280 3162/kube-proxy
tcp6 0 0 :::30259 :::* LISTEN 0 21358 3162/kube-proxy
tcp6 0 0 :::30844 :::* LISTEN 0 21361 3162/kube-proxy
tcp6 0 0 :::32028 :::* LISTEN 0 21360 3162/kube-proxy
tcp6 0 0 :::30048 :::* LISTEN 0 21357 3162/kube-proxy
Нездоровый узел:
curl -v --connect-timeout 5 -sD - -k https://localhost:32028/healthz'
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connection timed out after 5001 milliseconds
* Curl_http_done: called premature == 1
* stopped the pause stream!
* Closing connection 0
sudo netstat -taupen | grep kube-proxy | grep LISTEN
tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 0 23611 2726/kube-proxy
tcp6 0 0 :::32618 :::* LISTEN 0 22662 2726/kube-proxy
tcp6 0 0 :::32012 :::* LISTEN 0 22654 2726/kube-proxy
tcp6 0 0 :::10256 :::* LISTEN 0 21872 2726/kube-proxy
tcp6 0 0 :::30259 :::* LISTEN 0 22653 2726/kube-proxy
tcp6 0 0 :::32028 :::* LISTEN 0 22656 2726/kube-proxy
tcp6 0 0 :::30844 :::* LISTEN 0 22655 2726/kube-proxy
tcp6 0 0 :::30048 :::* LISTEN 0 22652 2726/kube-proxy
Окружающая среда:
kubectl get services nginx-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress LoadBalancer 100.67.138.99 xxxx-yyyy.elb.eu-central-1.amazonaws.com 80:30259/TCP,443:32028/TCP,22:32012/TCP 47h
kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.1", GitCommit:"d647ddbd755faf07169599a625faf302ffc34458", GitTreeState:"clean", BuildDate:"2019-10-02T23:49:07Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.6", GitCommit:"96fac5cd13a5dc064f7d9f4f23030a6aeface6cc", GitTreeState:"clean", BuildDate:"2019-08-19T11:05:16Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}
kubectl get deployment nginx-ingress -oyaml
:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
checksum/config: 0f815cbf49129a18dacd05c1f35c0e2c0a36d0ad4f8f0272828a558c49c40aed
configmap.reloader.stakater.com/reload: ingress-nginx,tcp-services,udp-services
deployment.kubernetes.io/revision: "5"
creationTimestamp: "2019-10-11T14:16:23Z"
generation: 18
labels:
app: nginx-ingress
chart: nginx-ingress-0.26.1
heritage: Tiller
k8s-addon: ingress-nginx.addons.k8s.io
k8s-app: nginx-ingress-controller
release: nginx-ingress-private
name: nginx-ingress
namespace: backend
resourceVersion: "85333311"
selfLink: /apis/extensions/v1beta1/namespaces/backend/deployments/nginx-ingress
uid: b4a6f226-ec31-11e9-bd40-066623cdec10
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx-ingress
release: nginx-ingress-private
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
app: nginx-ingress
k8s-addon: ingress-nginx.addons.k8s.io
k8s-app: nginx-ingress-controller
release: nginx-ingress-private
spec:
containers:
- args:
- /nginx-ingress-controller
- --logtostderr=true
- --stderrthreshold=0
- --http-port=80
- --https-port=443
- --healthz-port=10254
- --default-backend-service=$(POD_NAMESPACE)/nginx-ingress-default
- --configmap=$(POD_NAMESPACE)/ingress-nginx
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/nginx-ingress
- --default-ssl-certificate=$(POD_NAMESPACE)/certs-tls
- --ingress-class=private
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: STAKATER_TCP_SERVICES_CONFIGMAP
value: 060d83d51ec7d01fe8af12484189acf792044690
- name: STAKATER_UDP_SERVICES_CONFIGMAP
value: da39a3ee5e6b4b0d3255bfef95601890afd80709
- name: STAKATER_INGRESS_NGINX_CONFIGMAP
value: 6a393dab54c63f4117785f635b7c00c64e140853
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
name: nginx-ingress
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 10m
memory: 50Mi
securityContext:
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
runAsUser: 33
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: nginx-ingress
serviceAccountName: nginx-ingress
terminationGracePeriodSeconds: 60
status:
availableReplicas: 3
conditions:
- lastTransitionTime: "2019-10-11T14:16:24Z"
lastUpdateTime: "2019-10-11T21:55:50Z"
message: ReplicaSet "nginx-ingress-6d994d7b96" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2019-10-13T11:05:46Z"
lastUpdateTime: "2019-10-13T11:05:46Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 18
readyReplicas: 3
replicas: 3
updatedReplicas: 3
/etc/kubernetes/manifests/kube-proxy.manifest
:
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
creationTimestamp: null
labels:
k8s-app: kube-proxy
tier: node
name: kube-proxy
namespace: kube-system
spec:
containers:
- command:
- /bin/sh
- -c
- mkfifo /tmp/pipe; (tee -a /var/log/kube-proxy.log < /tmp/pipe & ) ; exec /usr/local/bin/kube-proxy
--cluster-cidr=100.96.0.0/11 --conntrack-max-per-core=131072 --hostname-override=ip-aaa-bbb-ccc-ddd.eu-central-1.compute.internal
--kubeconfig=/var/lib/kube-proxy/kubeconfig --master=https://api.xxx.yyy.zzz
--oom-score-adj=-998 --resource-container="" --v=2 > /tmp/pipe 2>&1
image: k8s.gcr.io/kube-proxy:v1.14.6
name: kube-proxy
resources:
requests:
cpu: 100m
securityContext:
privileged: true
volumeMounts:
- mountPath: /var/lib/kube-proxy/kubeconfig
name: kubeconfig
readOnly: true
- mountPath: /var/log/kube-proxy.log
name: logfile
- mountPath: /lib/modules
name: modules
readOnly: true
- mountPath: /etc/ssl/certs
name: ssl-certs-hosts
readOnly: true
- mountPath: /run/xtables.lock
name: iptableslock
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- key: CriticalAddonsOnly
operator: Exists
volumes:
- hostPath:
path: /var/lib/kube-proxy/kubeconfig
name: kubeconfig
- hostPath:
path: /var/log/kube-proxy.log
name: logfile
- hostPath:
path: /lib/modules
name: modules
- hostPath:
path: /usr/share/ca-certificates
name: ssl-certs-hosts
- hostPath:
path: /run/xtables.lock
type: FileOrCreate
name: iptableslock
status: {}
kubectl get service nginx-ingress -oyaml
:
apiVersion: v1
kind: Service
metadata:
annotations:
dns.alpha.kubernetes.io/internal: private.xxx.yyy.zzz
external-dns.alpha.kubernetes.io/hostname: private.xxx.yyy.zzz
kubernetes.io/ingress.class: private
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "false"
creationTimestamp: "2019-10-11T14:16:23Z"
labels:
app: nginx-ingress
chart: nginx-ingress-0.26.1
heritage: Tiller
k8s-addon: ingress-nginx.addons.k8s.io
release: nginx-ingress-private
name: nginx-ingress
namespace: backend
resourceVersion: "84591201"
selfLink: /api/v1/namespaces/backend/services/nginx-ingress
uid: b4a1b347-ec31-11e9-bd40-066623cdec10
spec:
clusterIP: 100.xxx.yyy.zzz
externalTrafficPolicy: Local
healthCheckNodePort: 32618
ports:
- name: http
nodePort: 30259
port: 80
protocol: TCP
targetPort: http
- name: https
nodePort: 32028
port: 443
protocol: TCP
targetPort: https
- name: ssh
nodePort: 32012
port: 22
protocol: TCP
targetPort: 22
selector:
app: nginx-ingress
release: nginx-ingress-private
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- hostname: xxx-yyy.elb.eu-central-1.amazonaws.com
kubectl get pods -n backend -o wide
:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
drone-drone-server-59586dd487-rmv9b 1/1 Running 0 2d10h aaa.bbb.13.19 ip-172-xxx-yyy-180.eu-central-1.compute.internal <none> <none>
kube-slack-848c9646fd-8w5mw 1/1 Running 0 2d10h aaa.bbb.13.10 ip-172-xxx-yyy-180.eu-central-1.compute.internal <none> <none>
nginx-ingress-5nlzg 1/1 Running 0 9h aaa.bbb.14.164 ip-172-xxx-yyy-201.eu-central-1.compute.internal <none> <none>
nginx-ingress-7xb54 1/1 Running 0 9h aaa.bbb.15.120 ip-172-xxx-yyy-156.eu-central-1.compute.internal <none> <none>
nginx-ingress-default-589975445-qdjvz 1/1 Running 0 9h aaa.bbb.14.150 ip-172-xxx-yyy-201.eu-central-1.compute.internal <none> <none>
nginx-ingress-jqtd6 1/1 Running 0 9h aaa.bbb.12.84 ip-172-xxx-yyy-29.eu-central-1.compute.internal <none> <none>
nginx-ingress-z9nt8 1/1 Running 0 9h aaa.bbb.13.57 ip-172-xxx-yyy-180.eu-central-1.compute.internal <none> <none>
sonarqube-sonarqube-746cbc858b-ks87c 1/1 Running 0 2d10h aaa.bbb.12.13 ip-172-xxx-yyy-29.eu-central-1.compute.internal <none> <none>
youtrack-0 1/1 Running 0 2d10h aaa.bbb.12.52 ip-172-xxx-yyy-29.eu-central-1.compute.internal <none> <none>
Мы будем очень благодарны за любые идеи о том, что может быть не так или как отладить проблему в дальнейшем.
ОБНОВИТЬ: Видит, что «нездоровые» / неработающие узлы - это только узлы, на которых находится nginx. не развернут. Развертывание модулей nginx как DeamonSet
вместо того Deployment
решает вопрос. Это все еще не дает ответа на вопрос, почему эта проблема возникает только при строго определенных условиях (не простой порт HTTP + внутренний балансировщик нагрузки) и как ее решить.
Я бы сказал, что все работает так, как задумано.
Обратите внимание, что, указав в службе nginx-ingress (LB) Ingress Controller следующую аннотацию:
externalTrafficPolicy: Local
вы обеспечиваете входящий трафик, который будет обслуживаться только этими модулями (репликами Ingress Controller), которые являются локальными для узла. В AWS NLB не знает, какие узлы (зарегистрированные цели Load Balancer) не владеют собственной репликой Nginx-Ingress Controller, поэтому иногда распределенный трафик LB дает сбой.
Чтобы избежать такого поведения, вам необходимо вручную удалить эти узлы из зондов LB healthcheck.
Почему переход с «Развертывания» на «DeamonSet» решает проблему в вашем случае? Потому что это гарантирует, что каждый узел запускает копию Ingress Controller Pod.
Обратите внимание, что это поведение Load Balancer, зависящее от облачного провайдера, задокументировано. Вот.
если вы не заботитесь о сохранении исходных IP-адресов клиентов, просто измените 'externalTrafficPolicy
' из 'Local
'к'Cluster
'чтобы решить вашу проблему.