nginx ingress 마지막 고집: admission webhook
k8s 에 서 는 nginx - ingress - controller 를 사용 하여 ingress 를 실현 하지만 취약 한 nginx - controller 는 ingress 를 통 해 nginx 설정 을 분석 합 니 다. 일부 annotation 에 서 는 reload nignx 설정 이 실 패 했 습 니 다. 그 다음 에 controller 가 끊 겨 서 계속 재 부팅 합 니 다. 해당 하 는 ingress 를 삭제 하지 않 는 한.
문제 가 재현 되다
문제 가 있 는 것 만 들 기
ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "false"
nginx.ingress.kubernetes.io/auth-tls-verify-client: optional
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Host $targethost;
proxy_buffering off;
proxy_pass http://$targetbackend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
creationTimestamp: "2020-03-23T04:57:22Z"
generation: 1
name: example-ingress
namespace: kube-system
resourceVersion: "57681168"
selfLink: /apis/extensions/v1beta1/namespaces/kube-system/ingresses/example-ingress
uid: c7f66385-6cc2-11ea-b6a8-246e96d4b538
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: example-svc
servicePort: 8008
path: /
tls:
- hosts:
- example.com
secretName: example-tls
status:
loadBalancer: {}
보기
nginx-ingress-controller
상태 모두 CrashLoopBackOff
# kubectl get po -n kube-system -owide |grep ingress
nginx-ingress-controller-ftfbg 1/2 CrashLoopBackOff 6 8m27s
nginx-ingress-controller-hp4pf 1/2 CrashLoopBackOff 11 24m
nginx-ingress-controller-qlb4l 1/2 CrashLoopBackOff 11 24m
로그 보기
nginx-ingress-controller
, reload 실패 표시 "proxy_pass" directive is duplicate in /tmp/nginx-cfg911768424:822
-------------------------------------------------------------------------------
W0403 10:26:14.716246 1 queue.go:130] requeuing kube-system/nginx-ingress-controller-4txfk, err
-------------------------------------------------------------------------------
Error: exit status 1
2020/04/03 10:26:14 [notice] 137#137: ModSecurity-nginx v1.0.0
2020/04/03 10:26:14 [warn] 137#137: duplicate value "error" in /tmp/nginx-cfg911768424:815
nginx: [warn] duplicate value "error" in /tmp/nginx-cfg911768424:815
2020/04/03 10:26:14 [warn] 137#137: duplicate value "timeout" in /tmp/nginx-cfg911768424:815
nginx: [warn] duplicate value "timeout" in /tmp/nginx-cfg911768424:815
2020/04/03 10:26:14 [emerg] 137#137: "proxy_pass" directive is duplicate in /tmp/nginx-cfg911768424:822
nginx: [emerg] "proxy_pass" directive is duplicate in /tmp/nginx-cfg911768424:822
nginx: configuration file /tmp/nginx-cfg911768424 test failed
-------------------------------------------------------------------------------
W0403 10:26:16.998897 1 nginx_status.go:207] unexpected error obtaining nginx status info: unexpected error scraping nginx status page: unexpected error scraping nginx : Get http://0.0.0.0:18080/nginx_status: dial tcp 0.0.0.0:18080: connect: connection refused
I0403 10:26:17.526801 1 main.go:167] Received SIGTERM, shutting down
I0403 10:26:17.526827 1 nginx.go:364] Shutting down controller queues
I0403 10:26:17.526845 1 status.go:200] updating status of Ingress rules (remove)
I0403 10:26:17.537511 1 status.go:219] removing address from ingress status ([])
I0403 10:26:17.537593 1 nginx.go:372] Stopping NGINX process
2020/04/03 10:26:17 [notice] 141#141: signal process started
I0403 10:26:20.547669 1 nginx.go:385] NGINX process has stopped
I0403 10:26:20.547692 1 main.go:175] Handled quit, awaiting Pod deletion
I0403 10:26:30.547824 1 main.go:178] Exiting with 0
해결 방안
문제 가 있 는 ingress 를 만 들 면 새로 만 든 ingress 규칙 에 영향 을 주 고 또 하나의 클 러 스 터 등급 의 bug 가 탄생 합 니 다. 그러면 방법 이 있 습 니까? ingress 설정 을 미리 검사 하고 문제 가 있 으 면 reload 하지 않 습 니 다. 그 검증 절 차 는 nginx - contrller 에 도착 하 라 고 요청 해 야 합 니 다. k8s - admission - webhook 을 생각 했 습 니까? apiserver 의 지속 적 인 대상 앞에서 요청 을 차단 할 수 있 습 니 다.사용자 정의 인증 규칙 을 실현 합 니 다. 자, 새 버 전의 nginx - ingress - controller (v 0.25.0 +) 에서 관련 기능 을 실 현 했 습 니 다. 해당 설정 만 켜 면 됩 니 다.
ApiServer 설정
Apiserver 에서 webhook 관련 설정 을 열 려 면
MutatingAdmissionWebhook
과 ValidatingAdmissionWebhook
를 포함해 야 합 니 다.--admission-control=MutatingAdmissionWebhook,ValidatingAdmissionWebhook
웹 훅 관련 설정 만 들 기
ValidatingAdmissionWebhook 을 사용 하려 면 https 를 사용 해 야 합 니 다. 해당 인증 서 를 설정 해 야 합 니 다.
openssl req -x509 -newkey rsa:2048 -keyout certificate.pem -out key.pem -days 365 -nodes -subj "/CN=ingress-validation-webhook.ingress-nginx.svc"
CertificateSigningRequest
를 통 해 만 들 수 있 습 니 다 (controller - manager 가 켜 야 합 니 다 --cluster-signing-cert-file
와 --cluster-signing-key-file
다음 스 크 립 트 를 통 해 만 들 수 있 습 니 다. namespace 와 service 는 자신의 SERVICE_NAME=ingress-nginx
NAMESPACE=ingress-nginx
TEMP_DIRECTORY=$(mktemp -d)
echo "creating certs in directory ${TEMP_DIRECTORY}"
cat <<EOF >> ${TEMP_DIRECTORY}/csr.conf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${SERVICE_NAME}
DNS.2 = ${SERVICE_NAME}.${NAMESPACE}
DNS.3 = ${SERVICE_NAME}.${NAMESPACE}.svc
EOF
openssl genrsa -out ${TEMP_DIRECTORY}/server-key.pem 2048
openssl req -new -key ${TEMP_DIRECTORY}/server-key.pem \
-subj "/CN=${SERVICE_NAME}.${NAMESPACE}.svc" \
-out ${TEMP_DIRECTORY}/server.csr \
-config ${TEMP_DIRECTORY}/csr.conf
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: ${SERVICE_NAME}.${NAMESPACE}.svc
spec:
request: $(cat ${TEMP_DIRECTORY}/server.csr | base64 | tr -d '
')
usages:
- digital signature
- key encipherment
- server auth
EOF
kubectl certificate approve ${SERVICE_NAME}.${NAMESPACE}.svc
for x in $(seq 10); do
SERVER_CERT=$(kubectl get csr ${SERVICE_NAME}.${NAMESPACE}.svc -o jsonpath='{.status.certificate}')
if [[ ${SERVER_CERT} != '' ]]; then
break
fi
sleep 1
done
if [[ ${SERVER_CERT} == '' ]]; then
echo "ERROR: After approving csr ${SERVICE_NAME}.${NAMESPACE}.svc, the signed certificate did not appear on the resource. Giving up after 10 attempts." >&2
exit 1
fi
echo ${SERVER_CERT} | openssl base64 -d -A -out ${TEMP_DIRECTORY}/server-cert.pem
kubectl create secret generic ingress-nginx.svc \
--from-file=key.pem=${TEMP_DIRECTORY}/server-key.pem \
--from-file=cert.pem=${TEMP_DIRECTORY}/server-cert.pem \
-n ${NAMESPACE}
ingress 컨트롤 러 설정
ingress contrller 는 다음 매개 변 수 를 사용 해 야 합 니 다. 필요 한 tles 인증 서 를 마 운 트 해 야 합 니 다.
flag
description
example usage
--validating-webhook
admission webhook 주소
:8080
--validating-webhook-certificate
웹 훅 인증서
/usr/local/certificates/validating-webhook.pem
--validating-webhook-key
웹 훅 비밀 키
/usr/local/certificates/validating-webhook-key.pem
검증 하 다.
업데이트 후 문제 가 있 는 ingress 를 만 들 면 차단 되 어 예상 에 부합 합 니 다.
# kubectl apply -f ing.yaml
Error from server: error when creating "ing.yaml": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request:
-------------------------------------------------------------------------------
Error: exit status 1
2020/04/02 10:26:04 [emerg] 331#331: directive "proxy_pass" is not terminated by ";" in /tmp/nginx-cfg461116913:2165
nginx: [emerg] directive "proxy_pass" is not terminated by ";" in /tmp/nginx-cfg461116913:2165
nginx: configuration file /tmp/nginx-cfg461116913 test failed
인용 하 다.
Qinng 's Blog
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
진행 중 실제 IP 획득일반적인 상황 에서 ingress 의 요청 을 통 해 header X-Real-IP 를 휴대 하고 사용 자 는 header 에 따라 실제 방문 IP 를 분석 할 수 있 습 니 다. 특수 한 상황 에서 사용자 요청 은...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.