如何在 Amazon EKS 中的自定义路径上访问 Kubernetes 控制面板?

上次更新时间:2020 年 4 月 6 日

我想要在 Amazon Elastic Kubernetes Service (Amazon EKS) 中的自定义路径上访问 Kubernetes 控制面板。

简短描述

要访问 Kubernetes 控制面板,您必须完成以下各项:

  1. 创建或使用现有自签名证书,然后将证书上传到 AWS Certificate Manager (ACM)。
  2. 部署 NGINX 入口控制器并将其公开用作 NodePort 服务。
  3. 为 Application Load Balancer (ALB) 入口控制器创建一个入口对象,将 ALB 中的所有请求转发至您早前使用清单文件部署的 NGINX 入口控制器。
  4. 部署 Kubernetes 控制面板。
  5. 为 NGINX 入口控制器创建一个入口。

此解决方法的原理如下:

  1. ALB 将所有的传入流量转发至 NGINX 入口控制器。
  2. NGINX 入口控制器则评估传入请求的路径模式(例如 /custom-path/additonalcustompath)。
  3. NGINX 入口控制器将 URL 重写到 /additonalcustompath 中,然后再将请求转发至 kubernetes-dashboard 服务。

解决方法

创建或使用现有自签名证书,然后将证书上传到 ACM

如果您想要将现有 ACM 证书用于 ALB,则可以跳过本部分的步骤。

注意:以下步骤适用于 Amazon Linux Amazon 系统映像 (AMI) 版本 2018.03。

1.    使用 OpenSSL 生成私有密钥:

openssl genrsa 2048 > kube-dash-private.key

2.    使用 步骤 1 中生成的密钥创建证书:

openssl req -new -x509 -nodes -sha1 -days 3650 -extensions v3_ca -key kube-dash-private.key > kube-dash-public.crt

重要提示:请务必为常用名称提供完全限定域名,因为 ALB 只允许具有完全限定域名的 ACM 证书连接到侦听器 443。

输出应类似于以下内容:

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:   
Common Name (eg, your name or your server's hostname) []:kube-dashboard.com         ==>This is important
Email Address []:

3.    安装 AWS 命令行界面 (AWS CLI)设置凭证

4.    将私有密钥和证书上传到您的 AWS 区域中的 ACM:

aws acm import-certificate --certificate file://kube-dash-public.crt --private-key file://kube-dash-private.key --region us-east-1

注:us-east-1 替换为您的 AWS 区域。

输出应与以下类似:

{
    "CertificateArn": "arn:aws:acm:us-east-1:your-account:certificate/your-certificate-id"
}

5.    打开 ACM 控制台,然后验证域名出现在您导入的 ACM 证书中。

提示:如果域名没有出现在 ACM 控制台中,则使用有效的完全限定域名重新创建证书。

部署 NGINX 入口控制器并将其公开用作 NodePort 服务

1.    部署 NGINX 入口控制器:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

2.    要将 NGINX 入口控制器公开用作 NodePort 服务,请基于以下内容创建 ingress-controller-service.yaml 文件:

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  # this setting is to make sure the source IP address is preserved.
  type: NodePort
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

3.    应用清单文件:

kubectl apply -f ingress-controller-service.yaml

为 ALB 入口控制器创建一个入口对象,将 ALB 入口控制器中的所有请求转发至您早前使用清单文件部署的 NGINX 入口控制器

1.    部署 ALB 入口控制器

2.    基于以下 alb-ingress.yaml 文件为 ALB 入口控制器创建一个入口对象:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "alb-ingress"
  namespace: "ingress-nginx"
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:your-region:your-account-id:certificate/XXXX-XXXX-XXXX-XXXX-XXXXX
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
  labels:
    app: dashboard
spec:
  rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - path: /*
            backend:
              serviceName: "ingress-nginx"
              servicePort: 80

注意:将 "alb.ingress.kubernetes.io/certificate-arn" 值替换为您的 ACM 证书 ARN。

前述清单文件使用以下注释:

A) "alb.ingress.kubernetes.io/scheme" 注释创建面向互联网的 ALB。
B) "alb.ingress.kubernetes.io/certificate-arn" 注释将 ACM 证书 Amazon 资源名称 (ARN) 与 ALB 的 443 侦听器关联。
C) "alb.ingress.kubernetes.io/listen-ports" 注释为端口 80 和 443 创建侦听器。
D) "alb.ingress.kubernetes.io/actions.ssl-redirect" 注释将传入端口 80 的所有请求重定向至 443。

3.    应用前述步骤 2 中的清单文件:

kubectl apply -f alb-ingress.yaml

部署 Kubernetes 控制面板

要部署 Kubernetes 控制面板,请遵照教程:部署 Kubernetes Web UI(控制面板)中的说明。

为 NGINX 入口控制器创建一个入口

1.    基于以下 ingress-dashboard.yaml 文件为 NGINX 入口控制器创建一个入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  namespace: kubernetes-dashboard
spec:
  rules:
  - http:
      paths:
      - path: /dashboard(/|$)(.*)
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443

注意:"nginx.ingress.kubernetes.io/rewrite-target" 注释会在转发请求至后端 pod 之间重写 URL。在路径/dashboard(/|$)(.*) 中,(.*) 会存储访问 Kubernetes 控制面板时生成的动态 URL。"nginx.ingress.kubernetes.io/rewrite-target" 注释会在转发请求至 kubernetes-dashboard 服务之前替换 URL 中捕获的数据。

2.    应用清单文件 ingress-dashboard.yaml

kubectl apply -f ingress-dashboard.yaml

3.    检查您早前创建的 alb-ingressADDRESS 中的 ALB URL:

kubectl get ingress alb-ingress -n ingress-nginx

您现在可以使用 ALB-URL/dashboard/ 访问 Kubernetes 控制面板。

重要提示:要使控制面板可供用户访问,您必须添加尾部斜杠到 URL 中。

注意:ALB 目标报告运行不正常的状况,因为在默认情况下,ALB 运行状况检查在路径 "/" 上完成,且预期会收到 200 成功代码。然而,NGINX 入口控制器在路径 "/" 返回 404,因为您只配置了 /dashboard(/|$)(.*) 路径。由于所有目标均处于运行不正常状况,请求仍然路由至目标。

清理您早前创建的资源

1.    删除 NGINX 入口控制器的入口:

kubectl delete -f ingress-dashboard.yaml

2.    删除 Kubernetes 控制面板组件和指标服务器:

kubectl delete -f eks-admin-service-account.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

kubectl delete -f metrics-server-$DOWNLOAD_VERSION/deploy/1.8+/

3.    删除 alb-ingressalb-ingress-controller 组件:

kubectl delete -f alb-ingress.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingress-controller.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/rbac-role.yaml

注意:如果您创建了 AWS Identity and Access Management (IAM) 资源,则可以删除 IAM 角色IAM 策略

4.    删除 NodePort 服务和 NGINX 入口控制器:

kubectl delete -f ingress-controller-service.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

5.    如果您创建了 ACM 证书并且想要删除证书,则运行以下命令:

aws acm delete-certificate --certificate-arn arn:aws:acm:us-east-1:your-account-id:certificate/XXXX-XXXX-XXXX-XXXX-XXXXX --region us-east-1

注意:请将 certificate-arn 替换为您的证书 ARN。使用您的 AWS 区域替换 us-east-1。将 your-account-id 替换为您的账户 ID。


这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?