如何通过入口向外部Kubernetes集群公开服务? [英] How to expose a service to outside Kubernetes cluster via ingress?

查看:15
本文介绍了如何通过入口向外部Kubernetes集群公开服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难将AWS集群中的服务公开给外部并通过浏览器访问它。由于我的previous question没有得出任何答案,我决定从几个方面简化这个问题。

首先,我已经创建了一个部署,无需任何配置即可工作。基于this article,我做了

  1. kubectl create namespace tests

  2. 基于paulbouwer/hello-kubernetes:1.8创建文件probe-service.yaml并部署kubectl create -f probe-service.yaml -n tests

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-kubernetes-first
    spec:
      type: ClusterIP
      ports:
      - port: 80
        targetPort: 8080
      selector:
        app: hello-kubernetes-first
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-kubernetes-first
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: hello-kubernetes-first
      template:
        metadata:
          labels:
            app: hello-kubernetes-first
        spec:
          containers:
          - name: hello-kubernetes
            image: paulbouwer/hello-kubernetes:1.8
            ports:
            - containerPort: 8080
            env:
            - name: MESSAGE
              value: Hello from the first deployment!
    
  3. 创建ingress.yaml并应用它(kubectl apply -f .probesingress.yaml -n tests)

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-kubernetes-ingress
    spec:
      rules:
      - host: test.projectname.org
        http:
          paths:
          - pathType: Prefix
            path: "/test"
            backend:
              service:
                name: hello-kubernetes-first
                port:
                  number: 80
      - host: test2.projectname.org
        http:
          paths:
          - pathType: Prefix
            path: "/test2"
            backend:
              service:
                name: hello-kubernetes-first
                port:
                  number: 80
      ingressClassName: nginx
    

其次,我可以看到DNS实际上指向集群,并且应用了入口规则:

  • 如果我打开http://test.projectname.org/test或任何不相关的路径(http://test.projectname.org/test3),我会显示NET::ERR_CERT_AUTHORITY_INVALID,但
  • 如果我在浏览器中使用&OPEN";,则不相关的路径提供ERR_TOO_MANY_REDIRECTS,而http://test.projectname.org/test提供Cannot GET /test
现在,撇开TLS问题不谈(这些问题应该单独提问),为什么我可以得到Cannot GET /test?看起来入口控制器(inress-nginx)得到了规则(否则它不会区分路径;这就是为什么我不显示DNS设置,尽管它们在上一个问题中进行了描述),但它没有在/test显示简单的Hello-Kubernetes页面,而是返回这个简单的404消息。为什么?可能会出什么问题?如何调试?

一些调试信息:

  • kubectl version --short通知Kubernetes客户端版本为v1.21.5,服务器版本为v1.20.7-ek-d88609

  • kubectl get ingress -n tests显示hello-kubernetes-ingress确实存在,nginx类,2个预期主机,地址与AWS控制台中显示的负载均衡器地址相同

  • kubectl get all -n tests显示

    NAME                                          READY   STATUS    RESTARTS   AGE
    pod/hello-kubernetes-first-6f77d8ff99-gjw5d   1/1     Running   0          5h4m
    pod/hello-kubernetes-first-6f77d8ff99-ptwsn   1/1     Running   0          5h4m
    pod/hello-kubernetes-first-6f77d8ff99-x8w87   1/1     Running   0          5h4m
    
    NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
    service/hello-kubernetes-first   ClusterIP   10.100.18.189   <none>        80/TCP    5h4m
    
    NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/hello-kubernetes-first   3/3     3            3           5h4m
    
    NAME                                                DESIRED   CURRENT   READY   AGE
    replicaset.apps/hello-kubernetes-first-6f77d8ff99   3         3         3       5h4m
    
  • ingress-nginx通过以下图表安装在我之前:

    apiVersion: v2
    name: nginx
    description: A Helm chart for Kubernetes
    type: application
    version: 4.0.6
    appVersion: "1.0.4"
    dependencies:
    - name: ingress-nginx
      version: 4.0.6
      repository: https://kubernetes.github.io/ingress-nginx
    

    与图表一起应用的值覆盖与extraArgs中的original ones不同(好吧,这些值是在安装后更新的):default-ssl-certificate: "nginx-ingress/dragon-family-com"不是逗号

回答Andrew,我确实尝试过设置HTTPS,但似乎没有帮助,所以我没有在最初的问题中包含我尝试的内容。然而,以下是我所做的:

  1. 已安装证书管理器,当前没有自定义图表:kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml

  2. 基于cert-manager's tutorialSO question创建了具有以下配置的ClusterIssuer:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-backoffice
    
    spec:
      acme:
        server: https://acme-staging-v02.api.letsencrypt.org/directory
        # use https://acme-v02.api.letsencrypt.org/directory after everything is fixed and works
        privateKeySecretRef: # this secret will be created in the namespace of cert-manager
          name: letsencrypt-backoffice-private-key
        # email: <will be used for urgent alerts about expiration etc>
    
        solvers:
        # TODO: add for each domain/second-level domain/*.projectname.org
        - selector:
            dnsZones:
              - test.projectname.org
              - test2.projectname.org
          # haven't made it to work yet, so switched to the simpler to configure http01 challenge
          # dns01:
          #   route53:
          #     region: ... # that of load balancer (but we also have ...)
          #     accessKeyID: <of IAM user with access to Route53>
          #     secretAccessKeySecretRef: # created that
          #       name: route53-credentials-secret
          #       key: secret-access-key
          #     role: arn:aws:iam::645730347045:role/cert-manager
          http01:
            ingress:
              class: nginx
    

    并通过kubectl apply -f issuer.yaml

    应用
  3. 在同一文件中创建了两个证书并再次应用:

    ---
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: letsencrypt-certificate
    spec:
      secretName: tls-secret
      issuerRef:
        kind: ClusterIssuer
        name: letsencrypt-backoffice
      commonName: test.projectname.org
      dnsNames:
      - test.projectname.org
    ---
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: letsencrypt-certificate-2
    spec:
      secretName: tls-secret-2
      issuerRef:
        kind: ClusterIssuer
        name: letsencrypt-backoffice
      commonName: test2.projectname.org
      dnsNames:
      - test2.projectname.org
    
  4. 确保证书颁发正确(跳过痛苦部分,结果为:kubectl get certificates显示两个证书都有READY=true且两个TLS密钥都已创建)

  5. 认为我的入口在另一个命名空间中,入口规范can only中的TLS密码在同一命名空间中被引用(尚未尝试通配符证书和--default-ssl-certificate选项),因此对于每个密码,将它们复制到tests命名空间:

    1. 打开现有密码,如kubectl edit secret tls-secret-2,复制数据和注释
    2. 在测试中创建了空(不透明)密码:kubectl create secret generic tls-secret-2-copy -n tests
    3. 打开它(kubectl edit secret tls-secret-2-copy -n tests)并将数据插入批注
  6. 在入口spec中,添加了TLS位:

    tls:
    - hosts:
      - test.projectname.org
      secretName: tls-secret-copy
    - hosts:
      - test2.projectname.org
      secretName: tls-secret-2-copy
    
  7. 我希望这会有帮助,但实际上并没有什么不同(对于不相关的路径,我得到ERR_TOO_MANY_REDIRECTS,从http重定向到https,NET::ERR_CERT_AUTHORITY_INVALID在https,如果我坚持转到页面,Cannot GET /test)

推荐答案

嗯,我还没有弄清楚for ArgoCD(编辑:已解决,但解决方案是特定于ArgoCD的),但对于此测试服务,路径解析似乎是the source问题的关键。它可能不是唯一的源(将在test2子域上重新测试),但当我在托管区域(test3,以前未在任何地方使用)中创建新的子域并通过A条目将其指向负载均衡器(在AWS控制台中为别名),然后向入口添加具有/路径的新规则时,如下所示:

  - host: test3.projectname.org
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-first
            port:
              number: 80

我终于在http://test3.projectname.org上得到了问候Kubernetes的消息。经过多次尝试/研究和在separate question中的一些帮助,我已经成功地使用了TLS。

实际调试没有成功:查看kubectl logs -n nginx <pod name, see kubectl get pod -n nginx>并不能真正帮助理解传递给服务的路径,而且相当难理解(甚至找不到这些IP来自哪里:它们不是我的、LB的、服务的集群IP;也不知道tests-hello-kubernetes-first-80代表什么-它只是名称空间、服务名称和端口的串联,没有对象有这样的名称,包括入口):

192.168.14.57 - - [14/Nov/2021:12:02:58 +0000] "GET /test2 HTTP/2.0" 404 144
 "-" "<browser's user-agent header value>" 448 0.002
 [tests-hello-kubernetes-first-80] [] 192.168.49.95:8080 144 0.000 404 <some hash>

任何关于调试的更多提示都将是有帮助的;另外,也欢迎关于nginx-inress正确路径~重写的建议。

这篇关于如何通过入口向外部Kubernetes集群公开服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆