简体   繁体   English

在 GKE 上创建 SSL web 服务的困难

[英]Difficulties creating a SSL web service on GKE

I am trying to create an API that serves HTTPS traffic publicly and is reachable by an IP address (not the domain), using a GKE cluster.我正在尝试创建一个 API 来公开服务 HTTPS 流量,并且可以使用 GKE 集群通过 IP 地址(不是域)访问。 Docker images have been tested locally. Docker镜像已经在本地测试过了。 They were capable of serving HTTPS on their own, but as far as I've come to realize, this is not necessary for the setup that I am imagining.他们能够自己服务 HTTPS,但据我所知,这对于我想象的设置不是必需的。

So what I've come up with so far is to have a Kubernetes Service exposing it's 8443 port and having an Ingress load balancer mapping to that port and using self-signed certificates created using this tutorial - basic-ingress-secret referred in the template.所以到目前为止我想出的是有一个 Kubernetes 服务公开它的 8443 端口并有一个入口负载均衡器映射到该端口并使用使用本教程创建的自签名证书 - 模板中提到的basic-ingress-secret . The only thing I have skipped is the domain binding given I am not in the possession of a domain.我唯一跳过的是域绑定,因为我没有拥有域。 I hoped it would bind the certificate to the external IP, but this is unfortunately not the case (have tried to attach an IP to a CN of the certificate, as some users have noted here ).我希望它将证书绑定到外部 IP,但不幸的是,情况并非如此(已尝试将 IP 附加到证书的 CN,正如一些用户在此处指出的那样)。

This is my yaml for service:这是我的 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"

This is my yaml for 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

It is way simpler than these documentations explain.它比这些文档解释的要简单得多。

1.- Create the self-signed certs 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.- Create the secret 2.- 创建秘密

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

3.- Create the Ingress object 3.- 创建入口 object

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

Note: To make is work on GKE, your service must be of type NodePort注意:要在 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>

I have found a final solution that suits my current needs.我找到了适合我当前需求的最终解决方案。

The issue with the setup above was that I didn't had a nodePort: value setup and that the SSL certificate was not properly working so I have purchased a domain, secured a static IP for the Ingress load balancer using gcloud compute addresses create some-static-ip --global and pointed that domain to the IP.上述设置的问题是我没有nodePort: value 设置,并且 SSL 证书无法正常工作,所以我购买了一个域,确保了 static ZA12A3079E14CED46E69BA52B8Ar9 用于gcloud compute addresses create some-static-ip --global的计算地址gcloud compute addresses create some-static-ip --global并将该域指向 IP。 I have then created a self-signed SSL certificate again following this tutorial and using my new domain.然后,我按照本教程并使用我的新域再次创建了一个自签名 SSL 证书。

The final yaml for the service:服务的最终 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"

The final yaml for the LB: 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

The service now serves HTTPS traffic (only 443 port) on my.domain.com/some/* (placeholder domain and path).该服务现在为 my.domain.com/some/*(占位符域和路径)上的 HTTPS 流量(仅 443 端口)提供服务。 It is a simple HTTPS service setup that would require only a purchase of CA issued SSL certificate and a proper scaling configuration to be fully productionalized, from the DevOps standpoint.从 DevOps 的角度来看,这是一个简单的 HTTPS 服务设置,只需购买 CA 颁发的 SSL 证书和适当的扩展配置即可完全生产。 Unless someone has found some serious drawbacks to this setup.除非有人发现此设置有一些严重的缺点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM