我正在裸机上设置 Kubernetes 集群。我使用 Kubeadm 进行安装。为了使我的服务可以从集群外部访问,我安装了 NGINX Ingress,使用以下文档:NGINX 文档
因为我不想在没有 TLS 安全性的情况下与我的服务进行通信,所以我通过 cert-manager 配置了证书:证书管理器文档。
$kubectl get certificate
NAME READY SECRET AGE
certificate-tls-prod True tls-secret-prod 3h1m
tls-secret-prod True tls-secret-prod 41m
证书生成成功并被客户端认可。
现在,我尝试在集群中安装我自己的 Docker 注册表(registry:2.7.1)。部署 Pod 和服务后,我尝试docker login
从我的客户端执行操作,但不起作用。
入口配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
# nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
cert-manager.io/issuer: "letsencrypt-prod"
namespace: default
name: nginx-ingress
spec:
tls:
- hosts:
- example.com
secretName: tls-secret-prod
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: docker-registry
port:
number: 5000
当我尝试通过简单的 curl 访问服务时:
curl -v https://example.com/
* Trying <cluster-ip>:443...
* Connected to example.com (<cluster-ip>) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=example.com
* start date: Jul 13 10:03:45 2021 GMT
* expire date: Oct 11 10:03:44 2021 GMT
* subjectAltName: host "example.com" matched cert's "example.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.77.0
> Accept: */*
>
* Received HTTP/0.9 when not allowed
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (1) Received HTTP/0.9 when not allowed
握手似乎正确。但是,最后出了点问题。
Docker 注册表 pod 的日志:
http: TLS handshake error from <ingress-pod-ip>:38686: tls: first record does not look like a TLS handshake
Ingress Pod 的日志:
[error] 84#84: *40 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: <cluster-ip>, server: example.com, request: "GET / HTTP/1.1", upstream: "http://<registry-pod-ip>:5000/", host: "example.com"
客户端Docker登录的日志:
docker login https://example.com
Error response from daemon: Get "https://example.com/v2/": net/http: HTTP/1.x transport connection broken: malformed HTTP response "\x15\x03\x01\x00\x02\x02"
据我了解,问题出在组件之一尝试使用 http 而不是 https 进行通信。顺便说一句,上游是使用 http 的,这看起来很奇怪。
不幸的是,我似乎无法解决这个问题。我尝试在入口声明中使用几个注释(已注释)来强制使用 https,但没有成功。
我看到了这个Github 上的问题,但我的 apiserver 没有该参数--kubelet-https=false
如果您有任何线索可以帮助我,我将不胜感激。
答案1
作为托马斯评论中提到:
我设法让它工作了。看来这是来自docker注册表配置。我修改了证书并重新启动了pod。