将 TLS 添加到 Kubernetes 服务的最简单方法是什么?

What's the easiest way to add TLS to a Kubernetes service?

我在 GKE 上的 Kubernetes 上公开公开了一个简单的 Web 服务器,并注册了一个域。我希望为此添加 TLS,以便通过 HTTPS 访问它。我听说过很多关于使用 Let's Encrypt 的信息,并最终尝试了这个:https://github.com/jetstack/cert-manager/blob/master/docs/tutorials/acme/quick-start/index.rst 但发现它完全让人不知所措。考虑到我的部署只是一个服务和 pod,是否有更简单的方法来使用 Let's Encrypt?

我使用的配置是:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: gcr.io/my-repo
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
        readinessProbe:
          initialDelaySeconds: 10
          httpGet:
            path: /healthz
            port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: web-balancer-service
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    run: web
  type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-app

spec:
  rules:
  - host: my.domain.com
    http:
      paths:
      - path: /*
        backend:
          serviceName: web-balancer-service
          servicePort: 8080

========================================

编辑:按照@Utku Özdemir 的建议,我尝试将这些更改编入 YAML。我用

创建了 IP 地址
gcloud compute addresses create example-ip-address --global

以及证书和配置:https://gist.github.com/nickponline/ab74d3d179e21474551b7596c6478eea

一切都正确,但是当我用 kubectl describe ManagedCertificates example-certificate 检查 ManagedCertificates 时说

Spec:
  Domains:
    app.domain.xyz
Status:
  Certificate Name:    xxxxxxxxxxxxxxxxxx
  Certificate Status:  Provisioning
  Domain Status:
    Domain:  app.domain
    Status:  FailedNotVisible
Events:      <none>

我已经等了 24 小时,所以假设这不会改变。

由于您使用 GKE 本身的入口控制器,当您创建 Ingress 资源时,它会触发创建 Load Balancer Google 云平台中的资源。通常,SSL 终止是入口控制器的责任,因此 GCP 负载均衡器负责执行 SSL 终止。

这意味着,cert-manager 将不适用于您的情况,因为证书将存在于您的集群之外,并且流量 在进入您的集群之前已经被 SSL 终止群集。

幸运的是,GCP 具有自行配置的 SSL (Let's Encrypt) 支持。要使用它,您需要按照以下步骤操作:

  1. 转到 GCP 上的负载平衡屏幕,切换到高级视图,然后跳转到证书选项卡(或只需单击 here)。

  2. 创建新的 SSL 证书,并选择 "Create Google-managed certificate"。在域字段中,写下您想要 SSL 证书的确切域。它应该是这样的:

  1. 转到 External IP Addresses 屏幕,并保留一个新的静态 IP 地址。选择类型为全局(在撰写本文时,GCP ingress controller 仅支持全局 IP 地址)。应如下所示:

  1. 获取您保留的静态 IP(在此示例中为 34.95.84.106

转到您的域注册商,并为您的域(SSL 证书中的那个)添加 A 类型的记录以指向您分配的静态 IP。在此示例中,它将是 my-app.example.com -> 34.95.84.106.

  1. 最后,您需要编辑您的入口以放置 2 个注释,因此它会提示 Google 云的入口控制器使用您保留的静态 IP 和您创建的证书。请参阅下面的入口示例:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-app
  annotations:
    ingress.gcp.kubernetes.io/pre-shared-cert: my-ssl-certificate # the name of the SSL certificate resource you created
    kubernetes.io/ingress.global-static-ip-name: my-static-ip # the name of the static ip resource you created
    kubernetes.io/ingress.allow-http: "false" # if you want to block plain http
spec:
  rules:
    - host: my-app.example.com
      http:
        paths:
          - path: /*
            backend:
              serviceName: web-balancer-service
              servicePort: 8080

应用它,并通过转到 GCP 上的负载均衡器屏幕验证更改是否得到反映。

重要提示:

  • 如果已经有一个由 Ingress 创建的 GCP 负载均衡器,您在 ingress 上所做的更改(注释)将不会反映到现有的负载均衡器。因此,删除您现有的入口,确保现有的负载均衡器消失,并使用正确的注释创建入口,这样负载均衡器将被正确配置。

  • 要使 Let's Encrypt 供应正常工作,您的 DNS 记录应该就位。它在颁发证书之前使用 DNS 检查域的所有者。此外,初始 配置可能需要相当长的时间 (最多半小时)。