Kubernetes 上的 NGINX Ingress 不使用 HTTPS

Kubernetes 上的 NGINX Ingress 不使用 HTTPS

我正在裸机上设置 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。

相关内容