【问题标题】:Difficulties creating a SSL web service on GKE在 GKE 上创建 SSL Web 服务的困难
【发布时间】:2020-09-18 06:33:21
【问题描述】:

我正在尝试使用 GKE 集群创建一个公开服务 HTTPS 流量并且可通过 IP 地址(而非域)访问的 API。 Docker 镜像已经在本地进行了测试。他们能够自己提供 HTTPS,但据我所知,这对于我想象的设置来说不是必需的。

所以到目前为止,我想出的是让 Kubernetes 服务公开它的 8443 端口,并让 Ingress 负载均衡器映射到该端口,并使用使用 this tutorial - basic-ingress-secret 创建的自签名证书模板。我唯一跳过的是域绑定,因为我没有拥有域。我希望它将证书绑定到外部 IP,但不幸的是,情况并非如此(已尝试将 IP 附加到证书的 CN,正如一些用户所指出的 here)。

这是我的服务 yaml:

apiVersion: v1
kind: Service
metadata:
  name: some-node
spec:
  selector:
    app: some
  ports:
  - protocol: "TCP"
    port: 8443
    targetPort: 8443
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: some-node-deploy
spec:
  selector:
    matchLabels:
      app: some
  replicas: 3
  template:
    metadata:
      labels:
        app: some
    spec:
      containers:
      - name: some-container
        image: "gcr.io/some-27417/some:latest"

这是我的 Ingress yaml:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: basic-ingress-secret
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: some-node
          servicePort: 8443

【问题讨论】:

  • 这取决于您的负载均衡器的配置方式。它可以终止 TLS(与您的后端说纯 HTTP),在较低级别运行(例如:TCP,在这种情况下您需要包含 LB DNS 的证书),或终止 TLS 并使用单独的 TLS 连接到您的后端。在所有情况下,您都需要有效的公开颁发的证书,或者您的应用程序可以验证的证书(已知的自签名 CA,或自签名证书的证书固定)。最简单的方法可能是在负载均衡器上终止 TLS 并与您的后端进行 HTTP 通信。
  • 从前面评论的长度可以看出,这对于stackoverflow来说太宽泛了,
  • @Marc 感谢您的建议和 cmets,我已经更新了我的帖子。希望现在更清楚一点。

标签: ssl kubernetes https google-kubernetes-engine


【解决方案1】:

这比这些文档解释的要简单。

1.- 创建自签名证书

openssl req -newkey rsa:2048 -nodes -keyout tls.key -out tls.csr
openssl x509 -in tls.csr -out tls.crt -req -signkey tls.key

2.- 创建秘密

kubectl create secret tls basic-ingress-secret --cert tls.crt --key tls.key

3.- 创建 Ingress 对象

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: basic-ingress-secret
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: some-node
          servicePort: 8443

注意:要在 GKE 上运行,您的服务必须是 NodePort 类型

$ kubectl describe svc some-node
Name:                     some-node
Namespace:                default
Labels:                   run=nginx
Annotations:              <none>
Selector:                 run=nginx
Type:                     NodePort
IP:                       10.60.6.214
Port:                     <unset>  8443/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30250/TCP
Endpoints:                10.56.0.17:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

【讨论】:

    【解决方案2】:

    我找到了适合我当前需求的最终解决方案。

    上述设置的问题是我没有设置 nodePort: 值,并且 SSL 证书无法正常工作,因此我购买了一个域,使用 @987654323 为 Ingress 负载均衡器保护了一个静态 IP @并将该域指向IP。然后,我在 this tutorial 之后使用我的新域再次创建了自签名 SSL 证书。

    服务的最终 yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: some-node
    spec:
      selector:
        app: some
      ports:
      - port: 80
        targetPort: 30041
        nodePort: 30041
      type: NodePort
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: some-node-deploy
    spec:
      selector:
        matchLabels:
          app: some
      replicas: 3
      template:
        metadata:
          labels:
            app: some
        spec:
          containers:
          - name: some-container
            image: "gcr.io/some-project/some:v1"
    

    LB 的最终 yaml:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: basic-ingress
      annotations:
        kubernetes.io/ingress.class: "gce"
        kubernetes.io/ingress.global-static-ip-name: "some-static-ip"
        kubernetes.io/ingress.allow-http: "false"
    spec:
      tls:
      - secretName: basic-ingress-secret
      rules:
        - host: my.domain.com
          http:
            paths:
            - path: /some/*
              backend:
                serviceName: some-node
                servicePort: 80
    

    该服务现在在 my.domain.com/some/*(占位符域和路径)上提供 HTTPS 流量(仅 443 端口)。从 DevOps 的角度来看,这是一个简单的 HTTPS 服务设置,只需购买 CA 颁发的 SSL 证书和适当的扩展配置即可完全生产化。除非有人发现此设置存在严重缺陷。

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 2018-06-16
      • 2023-01-09
      • 2016-01-17
      • 2011-11-29
      • 2012-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多