如何通过入口向外部Kubernetes集群公开服务? [英] How to expose a service to outside Kubernetes cluster via ingress?
问题描述
我很难将AWS集群中的服务公开给外部并通过浏览器访问它。由于我的previous question没有得出任何答案,我决定从几个方面简化这个问题。
首先,我已经创建了一个部署,无需任何配置即可工作。基于this article,我做了kubectl create namespace tests
基于
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!
创建
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
Cannot GET /test
?看起来入口控制器(inress-nginx)得到了规则(否则它不会区分路径;这就是为什么我不显示DNS设置,尽管它们在上一个问题中进行了描述),但它没有在/test
显示简单的Hello-Kubernetes页面,而是返回这个简单的404消息。为什么?可能会出什么问题?如何调试?
一些调试信息:
kubectl version --short
通知Kubernetes客户端版本为v1.21.5,服务器版本为v1.20.7-ek-d88609kubectl 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,但似乎没有帮助,所以我没有在最初的问题中包含我尝试的内容。然而,以下是我所做的:
已安装证书管理器,当前没有自定义图表:
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml
基于cert-manager's tutorial和SO 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
在同一文件中创建了两个证书并再次应用:
--- 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
确保证书颁发正确(跳过痛苦部分,结果为:
kubectl get certificates
显示两个证书都有READY
=true
且两个TLS密钥都已创建)认为我的入口在另一个命名空间中,入口规范can only中的TLS密码在同一命名空间中被引用(尚未尝试通配符证书和
--default-ssl-certificate
选项),因此对于每个密码,将它们复制到tests
命名空间:- 打开现有密码,如
kubectl edit secret tls-secret-2
,复制数据和注释 - 在测试中创建了空(不透明)密码:
kubectl create secret generic tls-secret-2-copy -n tests
- 打开它(
kubectl edit secret tls-secret-2-copy -n tests
)并将数据插入批注
- 打开现有密码,如
在入口
spec
中,添加了TLS位:tls: - hosts: - test.projectname.org secretName: tls-secret-copy - hosts: - test2.projectname.org secretName: tls-secret-2-copy
我希望这会有帮助,但实际上并没有什么不同(对于不相关的路径,我得到
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屋!