Get Hands-on with Amazon EKS - Workshop Event Series
Whether you're taking your first steps with Kubernetes or you're an experienced practitioner looking to sharpen your skills, our Amazon EKS workshop series delivers practical, real-world experience that moves you forward. Learn directly from AWS solutions architects and EKS specialists through hands-on sessions designed to build your confidence with Kubernetes. Register now and start building with Amazon EKS!
如何提供对 Amazon EKS 集群中的多个 Kubernetes 服务的外部访问权限?
我想提供对我的 Amazon Elastic Kubernetes Service (Amazon EKS) 集群中多个 Kubernetes 服务的外部访问权限。
简短描述
使用用于 Kubernetes 的 NGINX 入口控制器或 AWS 负载均衡器控制器提供对 Amazon EKS 集群中的多个 Kubernetes 服务的外部访问权限。NGINX 入口控制器主要由 NGINX 维护。要检查 NGINX 入口控制器的问题,请参阅 GitHub 网站上的问题列表。AWS 负载均衡器控制器主要由 Amazon Web Services (AWS) 维护。要检查 AWS 负载均衡器控制器上的问题,请参阅 GitHub 网站上的问题列表。
**重要提示:**入口控制器和 IngressClass(来自 Kubernetes 网站)与入口(来自 Kubernetes 网站)不同。入口是一种 Kubernetes 资源,可将集群外部的 HTTP 和 HTTPS 路由公开到集群内的服务。入口控制器通常可使用负载均衡器完成入口用途(通常使用负载均衡器)。您不能在没有入口控制器的情况下使用入口。IngressClass 用于标识哪个入口控制用于完成入口对象请求。
前提条件:安装 AWS 负载均衡器控制器。最佳实践是使用 AWS 负载均衡器控制器为 Amazon EKS 中的 LoadBalancer 类型服务对象创建和管理网络负载均衡器。
解决方法
以下解决方案使用 Kubernetes GitHub 网站上的 kubernetes/ingress-nginx 入口控制器。可供公众使用的另一个入口控制器是来自 NGINX GitHub 网站的 nginxinc/kubernetes-ingress。
部署用于 Kubernetes 的 NGINX 入口控制器
您可以通过传输控制协议(TCP)或传输层安全性协议(TLS)部署用于 Kubernetes 的 NGINX 入口控制器。
**注意:**以下解决方案已在 Amazon EKS 版本 1.22、NGINX 入口控制器版本 1.3.0 和 AWS 负载均衡器控制器版本 2.4.3 上进行了测试。
(选项 1)网络负载均衡器上的 NGINX 入口控制器及 TCP
1. 获取 YAML 文件以部署以下 Kubernetes 对象:namespace、serviceaccounts、configmap、clusterroles、clusterrolebindings、roles、rolebindings、services、deployments、ingressclasses 和 validatingwebhookconfigurations。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml
2. 编辑文件。然后,在 ingress-nginx-controller 服务对象部分,将所有 service.beta.kubernetes.io 注释替换为以下内容:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
3. 应用清单:
kubectl apply -f deploy.yaml
示例输出:
namespace/ingress-nginx created serviceaccount/ingress-nginx created configmap/ingress-nginx-controller created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx created service/ingress-nginx-controller-admission created service/ingress-nginx-controller created deployment.apps/ingress-nginx-controller created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
(选项 2) 网络负载均衡器上的 NGINX 入口控制器 TLS 终止
默认情况下,先前的解决方案将会终止 NGINX 入口控制器中的 TLS。此外,您还可以配置 NGINX 入口服务,以终止网络负载均衡器处的 TLS。
1. 下载 deploy.yaml 模板:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
2. 编辑文件。然后,在 ingress-nginx-controller 服务对象部分,将所有 service.beta.kubernetes.io 注释替换为以下内容:
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:XXXXXXXX:certificate/XXXXXX-XXXXXXX-XXXXXXX-XXXXXXXX service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
**注意:**请确保包含 service.beta.kubernetes.io/aws-load-balancer-ssl-cert 的 ARN。
3. 编辑文件,然后更改 Kubernetes 集群的 Amazon Virtual Private Cloud (Amazon VPC) CIDR:
proxy-real-ip-cidr: XXX.XXX.XXX/XX
4. 应用清单:
kubectl apply -f deploy.yaml
**注意:**先前的清单使用 ExternalTrafficPolicy 作为 local 以保留源(客户端)IP 地址。在 Amazon VPC 中将此配置与自定义 DHCP 名称结合使用会导致出现问题。为防止问题发生,请将以下补丁应用于 kube-proxy:
kubectl edit daemonset kube-proxy -n kube-system
5. 编辑清单以包含以下片段:
spec: template: spec: containers: - name: kube-proxy command: - kube-proxy - --hostname-override=$(NODE_NAME) - --v=2 - --config=/var/lib/kube-proxy-config/config env: - name: NODE_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName
验证已部署的资源
AWS 负载均衡器控制器
命令:
kubectl get all -n kube-system --selector app.kubernetes.io/instance=aws-load-balancer-controller
示例输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/aws-load-balancer-controller-85cd8965dc-ctkjt 1/1 Running 0 48m 192.168.37.36 ip-192-168-59-225.us-east-2.compute.internal none none pod/aws-load-balancer-controller-85cd8965dc-wpwx9 1/1 Running 0 48m 192.168.53.110 ip-192-168-59-225.us-east-2.compute.internal none> none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/aws-load-balancer-webhook-service ClusterIP 10.100.154.44 none 443/TCP 19h app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/aws-load-balancer-controller 2/2 2 2 19h aws-load-balancer-controller 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.0 app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/aws-load-balancer-controller-85cd8965dc 2 2 2 19h aws-load-balancer-controller 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.0 app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller,pod-template-hash=85cd8965dc
NGINX 入口控制器
命令:
kubectl get all -n ingress-nginx --selector app.kubernetes.io/instance=ingress-nginx
示例输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/ingress-nginx-controller-54d8b558d4-k4pdf 1/1 Running 0 56m 192.168.46.241 ip-192-168-59-225.us-east-2.compute.internal none none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/ingress-nginx-controller LoadBalancer 10.100.99.129 ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80:32578/TCP,443:30724/TCP 15h app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx service/ingress-nginx-controller-admission ClusterIP 10.100.190.61 none 443/TCP 15h app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/ingress-nginx-controller 1/1 1 1 15h controller k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/ingress-nginx-controller-54d8b558d4 1 1 1 15h controller k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx,pod-template-hash=54d8b558d4 NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR job.batch/ingress-nginx-admission-create 1/1 2s 15h create k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 controller-uid=242bdf56-de16-471d-a691-1ca1dbc10a41 job.batch/ingress-nginx-admission-patch 1/1 2s 15h patch k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 controller-uid=a9e710d2-5001-4d40-a435-ddc8993bfe42
IngressClass
命令:
kubectl get ingressclass
示例输出:
NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 19h nginx k8s.io/ingress-nginx none 15h
测试部署设置
**注意:**以下步骤将运行两个微服务。如果 Kubernetes 为默认类型,则会在内部公开微服务。
1. 设置部署或微服务。例如,hostname-app 和 apache-app。
hostname-app 的 hostname-app-svc.yaml 文件的示例:
apiVersion: apps/v1 kind: Deployment metadata: name: hostname-app namespace: default spec: replicas: 2 selector: matchLabels: app: hostname-app template: metadata: labels: app: hostname-app spec: containers: - name: hostname-app image: k8s.gcr.io/serve_hostname:1.1 --- apiVersion: v1 kind: Service metadata: name: hostname-svc namespace: default spec: ports: - port: 80 targetPort: 9376 protocol: TCP selector: app: hostname-app
apache-app 的 apache-app-svc.yaml 文件的示例:
apiVersion: apps/v1 kind: Deployment metadata: name: apache-app namespace: default spec: replicas: 2 selector: matchLabels: app: apache-app template: metadata: labels: app: apache-app spec: containers: - name: apache-app image: httpd:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: apache-svc namespace: default labels: spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: apache-app
2. 应用您的配置。
hostname-app:
kubectl apply -f hostname-app-svc.yaml
apache-app:
kubectl apply -f apache-app-svc.yaml
3. 验证是否已创建资源。
部署
命令:
kubectl get deployment hostname-app apache-app -n default
示例输出:
NAME READY UP-TO-DATE AVAILABLE AGE hostname-app 2/2 2 2 29m apache-app 2/2 2 2 29m
服务
命令:
kubectl get svc apache-svc hostname-svc -n default
示例输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE apache-svc ClusterIP 10.100.73.51 none 80/TCP 29m hostname-svc ClusterIP 10.100.100.44 none 80/TCP 29m
测试 NGINX 入口控制器
1. 访问您从命令行中检索到的负载均衡器的 DNS URL:
curl -I ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com
示例输出:
HTTP/1.1 404 Not Found Date: Thu, 03 Mar 2022 14:03:11 GMT Content-Type: text/html Content-Length: 146 Connection: keep-alive
注意:对于所有未定义入口规则的域请求,默认服务器将会返回 404 Not Found(404 未找到)页面。根据定义的规则,除非请求与配置匹配,否则入口控制器不会将流量转移到特定后端服务。由于已针对入口对象配置主机字段,您必须为请求的主机标头提供相同的主机名。在测试环境中,使用 curl 标志提供主机标头。在生产环境中,将负载均衡器 DNS 名称映射到任何 DNS 提供商上的主机名 (例如 Amazon Route 53)。
2. 实施入口,使其使用 NGINX 入口控制器提供的单个负载均衡器与您的服务连接。
示例 micro-ingress.yaml:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: micro-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: hostname.mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: / pathType: Prefix - host: apache.mydomain.com http: paths: - backend: service: name: apache-svc port: number: 80 path: / pathType: Prefix
**注意:**有关更多信息,请参阅基于名称的虚拟主机(来自 Kubernetes 网站)
3. 验证是否已创建资源。
入口
命令:
kubectl get ingress -n default
示例输出:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 29m
4. 将主机标头添加到请求。
第一个配置的域:
curl -i -H "Host: hostname.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
示例输出:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 18:50:38 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Connection: keep-alive
第二个配置的域:
curl -i -H "Host: apache.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
示例输出:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 18:51:00 GMT Content-Type: text/html Content-Length: 45 Connection: keep-alive Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes
在添加主机标头后,如果流量与入口中定义的规则匹配,则入口控制器会将它重定向到后端配置的服务。
要保持相同的域名,但根据访问的路径转移流量,您必须通过入口添加基于路径的路由。
例如:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: path-ingress namespace: default annotations: kubernetes.io/ingress.class: nginxd nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: /hostname pathType: Prefix - host: mydomain.com http: paths: - backend: service: name: apache-svc port: number: 80 path: /apache pathType: Prefix
注意:如果请求的主机标头为 mydomain.com,则上述示例只会返回 200 响应。可以在 /hostname 或 /apache 路径上访问这些请求。对于所有其他请求,则会返回 404 响应。
5. 验证是否已添加基于路径的路由:
命令:
kubectl get ingress -n default
输出:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 164m path-ingress none mydomain.com,mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 120m
命令:
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/hostname
-或者-
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/apache
使用 AWS 负载均衡器控制器测试入口
1. 使用以下示例入口清单启动应用程序负载均衡器:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: micro-ingress-alb namespace: default annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: rules: - host: alb.hostname.mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: / pathType: Prefix - host: alb.apache.mydomain.com http: - backend: service: name: apache-svc port: number: 80 path: / pathType: Prefix
2. 验证是否已启动应用程序负载均衡器。
命令:
kubectl get ingress -n default
输出:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 164m micro-ingress-alb none alb.hostname.mydomain.com,alb.apache.mydomain.com k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com 80 18m path-ingress none mydomain.com,mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 120m
基于第一个配置的域的请求:
curl -i -H "Host: alb.hostname.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
示例输出:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 20:46:02 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Connection: keep-alive
基于第二个配置的域的请求:
curl -i -H "Host: alb.apache.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
示例输出:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 20:46:14 GMT Content-Type: text/html Content-Length: 45 Connection: keep-alive Server: Apache/2.4.53 (Unix) Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes
