如何在 DigitalOcean Kubernetes 上使用 Cert-Manager 设置 Nginx Ingress

介绍

Kubernetes Ingresses允许您灵活地将流量从您的Kubernetes集群以外路由到集群内部的服务,这是通过使用Ingress _Resources_来实现的,该系统定义了将HTTP和HTTPS流量路由到Kubernetes Services的规则,以及Ingress _Controllers_通过负载平衡流量并将其路由到相应的后端服务来执行规则。

受欢迎的 Ingress 控制器包括 Nginx, Contour, HAProxyTraefik

在本指南中,我们将设置由 Kubernetes 维护的 Nginx Ingress Controller,并创建一些 Ingress 资源,以将流量路由到几个愚蠢的后端服务。一旦我们设置了 Ingress,我们将安装 cert-manager在我们的集群中,以管理和提供用于加密 Ingress 的 HTTP 流量的 TLS 证书。本指南使用了 Helm的包管理器。 有关使用头盔的 Nginx Ingress Controller 部署的指南,请参阅 [How To Set Up a Nginx Ingress on DigitalOcean Kubernetes Using Helm(https://andsky.com/tech/tutorials/how-to-set-up-an-nginx-ingress-on-digitalocean-kubernetes-using-helm)。

如果您正在寻找一个管理的Kubernetes托管服务,请查看我们的简单的,用于增长的管理的Kubernetes服务(https://www.digitalocean.com/products/kubernetes)。

前提条件

在您开始使用本指南之前,您应该拥有以下内容:

此设置将使用一个 DigitalOcean Kubernetes集群,但您可以使用 [另一种方法]创建一个集群(https://andsky.com/tech/tutorials/how-to-create-a-kubernetes-cluster-using-kubeadm-on-ubuntu-18-04)。请参阅 [ 如何连接到DigitalOcean Kubernetes集群系统([INKL4])]以连接到您的集群。 您可以阅读有关安装kubectl 的更多信息(在官方文档中)。 如果您正在使用DigitalOcean Kubernetes集群,请参阅 如何连接到DigitalOcean Kubernetes集群系统以了解如何使用kubectl连接到您的集群。 一个域名和本地DNS记录,您可以指向使用DigitalOcean Load Balancer

一旦您设置了这些组件,您已经准备好开始使用本指南。

步骤 1 – 设置 Dummy Backend 服务

在我们部署 Ingress 控制器之前,我们首先会创建并部署两个 dummy echo 服务,我们将使用 Ingress 路由外部流量。echo 服务将运行 hashicorp/http-echo] Web 服务器容器,该服务器将返回包含在 Web 服务器启动时传输的文本字符串的页面。 有关 http-echo 的更多信息,请参阅其 GitHub Repo,以及有关 Kubernetes 服务的更多信息,请参阅 Kubernetes 官方文件夹中的 Services

在本地计算机上,使用nano或您最喜欢的编辑器创建和编辑名为echo1.yaml的文件:

1nano echo1.yaml

贴入以下服务与部署宣言:

 1[label echo1.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: echo1
 6spec:
 7  ports:
 8  - port: 80
 9    targetPort: 5678
10  selector:
11    app: echo1
12---
13apiVersion: apps/v1
14kind: Deployment
15metadata:
16  name: echo1
17spec:
18  selector:
19    matchLabels:
20      app: echo1
21  replicas: 2
22  template:
23    metadata:
24      labels:
25        app: echo1
26    spec:
27      containers:
28      - name: echo1
29        image: hashicorp/http-echo
30        args:
31        - "-text=echo1"
32        ports:
33        - containerPort: 5678

在此文件中,我们定义了一个名为echo1的服务,该服务通过app:echo1标签选择器将流量路由到Pods,它接受80端口的TCP流量,并将其路由到5678端口,即http-echo的默认端口。

然后我们定义了一个部署,也被称为echo1,它使用app:echo1管理Pod,我们指定了部署应该有2个Pod复制品,并且Pod应该启动一个名为echo1的容器,运行hashicorp/http-echo图像。

一旦你对你的愚蠢的服务和部署表现感到满意,保存并关闭文件。

然后,使用kubectl 应用创建 Kubernetes 资源,并指定您刚刚保存的文件为参数:

1kubectl apply -f echo1.yaml

你应该看到以下结果:

1[secondary_label Output]
2service/echo1 created
3deployment.apps/echo1 created

通过确认它具有集群IP,即服务暴露的内部IP来验证服务的正确启动:

1kubectl get svc echo1

你应该看到以下结果:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)   AGE
3echo1 ClusterIP 10.245.222.129   <none>        80/TCP 60s

这表明echo1服务现在可以在端口80上的10.245.222.129内部提供,它将流量转发到所选择的Pods上的集装箱端口5678

现在echo1服务已启动并运行,对echo2服务重复此过程。

创建并打开名为 'echo2.yaml' 的文件:

 1[label echo2.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  name: echo2
 6spec:
 7  ports:
 8  - port: 80
 9    targetPort: 5678
10  selector:
11    app: echo2
12---
13apiVersion: apps/v1
14kind: Deployment
15metadata:
16  name: echo2
17spec:
18  selector:
19    matchLabels:
20      app: echo2
21  replicas: 1
22  template:
23    metadata:
24      labels:
25        app: echo2
26    spec:
27      containers:
28      - name: echo2
29        image: hashicorp/http-echo
30        args:
31        - "-text=echo2"
32        ports:
33        - containerPort: 5678

在这里,我们基本使用相同的服务和部署表达式,如上所述,但命名并重新标记服务和部署echo2。 此外,为了提供一些变异,我们只创建 1 Pod 副本,确保我们将文本参数设置为echo2,以便网络服务器返回文本echo2

保存和关闭文件,并使用kubectl创建Kubernetes资源:

1kubectl apply -f echo2.yaml

你应该看到以下结果:

1[secondary_label Output]
2service/echo2 created
3deployment.apps/echo2 created

再次,检查服务是否已启动和运行:

1kubectl get svc

您应该看到具有分配的 ClusterIP 的echo1echo2服务:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)   AGE
3echo1 ClusterIP 10.245.222.129   <none>        80/TCP 6m6s
4echo2 ClusterIP 10.245.128.224   <none>        80/TCP 6m3s
5kubernetes ClusterIP 10.245.0.1       <none>        443/TCP 4d21h

现在,我们的愚蠢的响应网络服务正在运行,我们可以继续推出 Nginx Ingress 控制器。

步骤 2 — 设置Kubernetes Nginx Ingress控制器

在此步骤中,我们将推出 Kubernetes 维护的 Nginx Ingress 控制器v1.1.1。 请注意,有 若干 Nginx Ingress 控制器; Kubernetes 社区维护了本指南中使用的控制器, Nginx Inc. 维护了 kubernetes-ingress. 本教程中的说明是基于官方 Kubernetes Nginx Ingress 控制器 安装指南的指示。

Nginx Ingress 控制器由一个 Pod 组成,该 Pod 运行 Nginx 网页服务器,并监视 Kubernetes 控制飞机寻找新的和更新的 Ingress 资源对象。 Ingress 资源基本上是对后端服务的流量路由规则列表。例如,一个 Ingress 规则可以指定到达路径 /web1 的 HTTP 流量应导向 web1 后端 Web 服务器。 使用 Ingress 资源,您还可以执行基于主机的路由:例如,将触及 web1.your_domain.com 到后端 Kubernetes 服务 web1 的路由请求。

在这种情况下,由于我们正在部署 Ingress 控制器到 DigitalOcean Kubernetes 集群中,控制器将创建一个 LoadBalancer 服务,提供一个 DigitalOcean 负载平衡器,向其导向所有外部流量。

我们将首先创建 Nginx Ingress 控制器 Kubernetes 资源,这些资源包括包含控制器配置的 ConfigMaps、基于角色的访问控制(RBAC)角色,允许控制器访问 Kubernetes API,以及使用 Nginx Ingress 控制器图像的实际 Ingress 控制器部署。

<$>[注] 注: 在本教程中,我们正在遵循 [DigitalOcean Provider] 的官方安装说明(https://kubernetes.github.io/ingress-nginx/deploy/#digital-ocean)。

要创建资源,请使用kubectl 应用-f 旗帜来指定在 GitHub 上托管的 manifest 文件:

1kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/do/deploy.yaml

我们在这里使用应用,以便在未来我们可以逐步应用 Ingress Controller 对象的更改,而不是完全重写它们。

你应该看到以下结果:

 1[secondary_label Output]
 2namespace/ingress-nginx created
 3serviceaccount/ingress-nginx created
 4configmap/ingress-nginx-controller created
 5clusterrole.rbac.authorization.k8s.io/ingress-nginx created
 6clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
 7role.rbac.authorization.k8s.io/ingress-nginx created
 8rolebinding.rbac.authorization.k8s.io/ingress-nginx created
 9service/ingress-nginx-controller-admission created
10service/ingress-nginx-controller created
11deployment.apps/ingress-nginx-controller created
12validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
13clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
14clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
15job.batch/ingress-nginx-admission-create created
16job.batch/ingress-nginx-admission-patch created
17role.rbac.authorization.k8s.io/ingress-nginx-admission created
18rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
19serviceaccount/ingress-nginx-admission created

此输出还可作为从deploy.yaml宣言中创建的所有 Ingress Controller 对象的方便总结。

确认 Ingress Controller Pods 已启动:

1kubectl get pods -n ingress-nginx \
2  -l app.kubernetes.io/name=ingress-nginx --watch
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3ingress-nginx-admission-create-l2jhk 0/1 Completed 0 13m
4ingress-nginx-admission-patch-hsrzf 0/1 Completed 0 13m
5ingress-nginx-controller-c96557986-m47rq 1/1 Running 0 13m

点击CTRL+C返回您的提示。

现在,通过使用kubectl获取服务详细信息,确认DigitalOcean负载平衡器已成功创建:

1kubectl get svc --namespace=ingress-nginx

几分钟后,你应该看到一个外部IP地址,与DigitalOcean负载平衡器的IP地址相匹配:

1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)                      AGE
3ingress-nginx-controller LoadBalancer 10.245.201.120 203.0.113.0 80:31818/TCP,443:31146/TCP 14m
4ingress-nginx-controller-admission ClusterIP 10.245.239.119   <none>            443/TCP 14m

记住负载平衡器的外部IP地址,因为您将在以后的步骤中需要它。

<$>[注] 注: 默认情况下,Nginx Ingress LoadBalancer 服务将service.spec.externalTrafficPolicy设置为值Local,该值将所有负载平衡器流量路由到运行 Nginx Ingress Pods 的节点。其他节点将故意失败负载平衡器健康检查,以便 Ingress 流量不会被路由到它们。 外部交通政策超出本教程的范围,但要了解更多,您可以从官方 Kubernetes docs 查阅 A Deep Dive into Kubernetes External Traffic PoliciesSource IP for Services with Type=LoadBalancer

这个负载平衡器接收 HTTP 和 HTTPS 端口 80 和 443 的流量,并将其传送到 Ingress Controller Pod。

现在我们可以将 DNS 记录指向这个外部负载平衡器,并创建一些 Ingress 资源来实施流量路由规则。

步骤 3 – 创建 Ingress 资源

让我们从创建一个最小的 Ingress 资源开始,将特定子域的流量路由到相应的后端服务。

在本指南中,我们将使用测试域名 example.com. 您应该用您所拥有的域名代替。

首先,我们将创建一个简单的规则,将向 **echo1.example.com 指向的流量路由到echo1后端服务,并将向 **echo2.example.com 指向的流量路由到echo2后端服务。

首先,在你最喜欢的编辑器中打开一个名为「echo_ingress.yaml」的文件:

1nano echo_ingress.yaml

用下面的入门定义:

 1[label echo_ingress.yaml]
 2apiVersion: networking.k8s.io/v1
 3kind: Ingress
 4metadata:
 5  name: echo-ingress
 6spec:
 7  rules:
 8  - host: echo1.example.com
 9    http:
10        paths:
11        - pathType: Prefix
12          path: "/"
13          backend:
14            service:
15              name: echo1
16              port:
17                number: 80
18  - host: echo2.example.com
19    http:
20        paths:
21        - pathType: Prefix
22          path: "/"
23          backend:
24            service:
25              name: echo2
26              port:
27                number: 80

当您完成编辑 Ingress 规则后,保存并关闭文件。

在这里,我们已经指定了我们希望创建一个名为echo-ingress的 Ingress 资源,并根据主机标题创建路由流量。 HTTP 请求主机标题指定目标服务器的域名。 有关主机请求标题的更多信息,请参阅 Mozilla Developer Network 定义页面。 与主机 echo1.example.com的请求将被导向在步骤 1中设置的echo1后端,并且与主机 echo2.example.com的请求将被导向到echo2后端。

您现在可以使用kubectl创建 Ingress:

1kubectl apply -f echo_ingress.yaml

您将看到以下输出,确认 Ingress 创建:

1[secondary_label Output]
2ingress.networking.k8s.io/echo-ingress created

要测试 Ingress,请导航到您的 DNS 管理服务并创建echo1.example.comecho2.example.com的 A 记录,指向 DigitalOcean Load Balancer 的外部 IP。

一旦您创建了必要的echo1.example.comecho2.example.com DNS 记录,您可以使用curl命令行实用程序测试您创建的 Ingress 控制器和资源。

从您的本地计算机,弯曲``echo1服务:

1curl echo1.example.com

您应该从echo1服务中获得以下答案:

1[secondary_label Output]
2echo1

这确认您的echo1.example.com请求正在通过 Nginx 入口正确地路由到echo1后端服务。

现在,对echo2服务进行相同的测试:

1curl echo2.example.com

您应该从echo2服务获得以下答案:

1[secondary_label Output]
2echo2

这确认您的echo2.example.com请求正在通过 Nginx 入口正确地路由到echo2后端服务。

在此时,您已成功设置了最少的 Nginx Ingress 来执行基于虚拟主机的路由. 在下一步,我们将安装 cert-manager来为我们的 Ingress 提供 TLS 证书,并启用更安全的 HTTPS 协议。

步骤 4 – 安装和配置 Cert-Manager

在此步骤中,我们将安装 cert-manager 的 v1.7.1 到我们的集群中。 cert-manager 是一个 Kubernetes 插件,它提供来自 Let's Encrypt和其他证书授权机构(CA)的 TLS 证书,并管理其生命周期。 证书可以通过注明 Ingress Resources,将一个 tls 部分附加到 Ingress 规格中,并配置一个或多个 IssuersClusterIssuers 来指定您偏好的证书授权机构来自动请求和配置。 若要了解有关 Issuer 和 ClusterIssuer 对象的更多信息,请参阅 Issuers上的官方 cert-manager 文件。

安装 cert-manager 及其 自定义资源定义 (CRDs) 如 Issuers 和 ClusterIssuers 通过遵循官方 安装说明 进行安装。

1kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml

你应该看到以下结果:

1[secondary_label Output]
2customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
3customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
4customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
5customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
6. . .
7deployment.apps/cert-manager-webhook created
8mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
9validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

要验证我们的安装,请检查cert-manager Namespace 运行 pods:

1kubectl get pods --namespace cert-manager
1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3cert-manager-578cd6d964-hr5v2 1/1 Running 0 99s
4cert-manager-cainjector-5ffff9dd7c-f46gf 1/1 Running 0 100s
5cert-manager-webhook-556b9d7dfd-wd5l6 1/1 Running 0 99s

这表明 cert-manager 安装成功。

在我们开始为我们的echo1.example.comecho2.example.com域发行证书之前,我们需要创建一个发行器,该证书指定了可以获得签名的 x509 证书的证书权限。

让我们创建一个测试 ClusterIssuer 来确保证书提供机制正常工作. 一个 ClusterIssuer 不是名称空间的范围,可以在任何名称空间中使用 Certificate 资源。

在您最喜爱的文本编辑器中打开名为 staging_issuer.yaml 的文件:

1nano staging_issuer.yaml

在下列 ClusterIssuer 宣言中插入:

 1[label staging_issuer.yaml]
 2apiVersion: cert-manager.io/v1
 3kind: ClusterIssuer
 4metadata:
 5 name: letsencrypt-staging
 6 namespace: cert-manager
 7spec:
 8 acme:
 9   # The ACME server URL
10   server: https://acme-staging-v02.api.letsencrypt.org/directory
11   # Email address used for ACME registration
12   email: your_email_address_here
13   # Name of a secret used to store the ACME account private key
14   privateKeySecretRef:
15     name: letsencrypt-staging
16   # Enable the HTTP-01 challenge provider
17   solvers:
18   - http01:
19       ingress:
20         class:  nginx

在这里,我们指定了我们希望创建一个名为letsencrypt-staging的 ClusterIssuer,并使用 Let’s Encrypt 阶段服务器。

然后我们指定一个电子邮件地址来注册证书,并创建一个名为letsencrypt-staging的Kubernetes 秘密,以存储ACME帐户的私钥。

使用kubectl滚动 ClusterIssuer:

1kubectl create -f staging_issuer.yaml

你应该看到以下结果:

1[secondary_label Output]
2clusterissuer.cert-manager.io/letsencrypt-staging created

现在我们将重复这个过程来创建生产集群发行器. 请注意,在注释和更新前一步提供的 Ingress 资源后,才会创建证书。

在您最喜欢的编辑器中打开名为 prod_issuer.yaml 的文件:

1nano prod_issuer.yaml

在下面的宣言中:

 1[label prod_issuer.yaml]
 2apiVersion: cert-manager.io/v1
 3kind: ClusterIssuer
 4metadata:
 5  name: letsencrypt-prod
 6  namespace: cert-manager
 7spec:
 8  acme:
 9    # The ACME server URL
10    server: https://acme-v02.api.letsencrypt.org/directory
11    # Email address used for ACME registration
12    email: your_email_address_here
13    # Name of a secret used to store the ACME account private key
14    privateKeySecretRef:
15      name: letsencrypt-prod
16    # Enable the HTTP-01 challenge provider
17    solvers:
18    - http01:
19        ingress:
20          class: nginx

请注意不同的 ACME 服务器 URL,以及letsencrypt-prod的秘密密密钥名称。

完成编辑后,保存并关闭文件。

使用kubectl滚出此发行器:

1kubectl create -f prod_issuer.yaml

你应该看到以下结果:

1[secondary_label Output]
2clusterissuer.cert-manager.io/letsencrypt-prod created

现在,我们已经创建了我们的 Let’s Encrypt 插座并制作了 ClusterIssuers,我们已经准备好修改我们上面创建的 Ingress 资源,并启用了 TLS 加密用于echo1.example.comecho2.example.com路径。

如果您正在使用DigitalOcean Kubernetes,您需要首先实施((https://github.com/digitalocean/digitalocean-cloud-controller-manager/blob/master/docs/controllers/services/examples/README.md#accessing-pods-over-a-managed-load-balancer-from-inside-the-cluster)),以便Pods可以使用Ingress与其他Pods进行通信. 如果您不使用DigitalOcean Kubernetes,您可以跳过到(#step-6-%E2%80%94-issuing-staging-and-production-let%E2%80%99s-encrypt-证书)。

步骤 5 — 通过负载平衡器启用Pod通信(可选)

在提供 Let's Encrypt 证书之前,cert-manager 首先会进行自我检查,以确保 Let's Encrypt 能够到达验证您的域名的cert-manager Pod。

要做到这一点,我们将创建一个 DNS A 记录,该记录指向云负载平衡器的外部 IP,并在该子域中注明 Nginx Ingress 服务表现。

首先,导航到您的 DNS 管理服务,创建一个workaround.example.com的 A 记录,指向 DigitalOcean 负载平衡器的外部 IP。 负载平衡器的外部 IP 地址是ingress-nginx服务的外部 IP 地址,我们在步骤 2 中收集了它,如果您正在使用 DigitalOcean 来管理您的域的 DNS 记录,请参阅 如何管理 DNS 记录以了解如何创建一个记录。

现在你已经创建了一个指向 Ingress 负载平衡器的 DNS 记录,请用 do-loadbalancer-hostname] 注释来注释 Ingress LoadBalancer 服务,在你最喜欢的编辑器中打开一个名为 ingress_nginx_svc.yaml 的文件,然后粘贴下面的 LoadBalancer 表达式:

 1[label ingress_nginx_svc.yaml]
 2apiVersion: v1
 3kind: Service
 4metadata:
 5  annotations:
 6    service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: 'true'
 7    service.beta.kubernetes.io/do-loadbalancer-hostname: "workaround.example.com"
 8  labels:
 9    helm.sh/chart: ingress-nginx-4.0.6
10    app.kubernetes.io/name: ingress-nginx
11    app.kubernetes.io/instance: ingress-nginx
12    app.kubernetes.io/version: 1.1.1
13    app.kubernetes.io/managed-by: Helm
14    app.kubernetes.io/component: controller
15  name: ingress-nginx-controller
16  namespace: ingress-nginx
17spec:
18  type: LoadBalancer
19  externalTrafficPolicy: Local
20  ports:
21    - name: http
22      port: 80
23      protocol: TCP
24      targetPort: http
25    - name: https
26      port: 443
27      protocol: TCP
28      targetPort: https
29  selector:
30    app.kubernetes.io/name: ingress-nginx
31    app.kubernetes.io/instance: ingress-nginx
32    app.kubernetes.io/component: controller

此服务宣言是从您在步骤 2 中安装的完整的 Nginx Ingress 宣言文件中提取的;在本教程中,这就是1.1.1

完成后,保存并关闭文件。

使用kubectl apply修改运行的ingress-nginx-controller服务:

1kubectl apply -f ingress_nginx_svc.yaml

你应该看到以下结果:

1[secondary_label Output]
2service/ingress-nginx-controller configured

这确认您已经注明了ingress-nginx-controller服务,并且群集中的Pods现在可以使用这个ingress-nginx-controller负载平衡器相互通信。

步骤6 - 发行停产和生产让我们加密证书

为了为我们的域发行一个阶段性 TLS 证书,我们将用步骤 4 所创建的 ClusterIssuer 注释 echo_ingress.yaml,这将使用 ingress-shim 自动创建和发行 Ingress 宣言中指定的域的证书。

在你最喜欢的编辑器中打开echo_ingress.yaml:

1nano echo_ingress.yaml

将以下内容添加到 Ingress 资源宣言中:

 1[label echo_ingress.yaml]
 2apiVersion: networking.k8s.io/v1
 3kind: Ingress
 4metadata:
 5  name: echo-ingress
 6  annotations:
 7    cert-manager.io/cluster-issuer: "letsencrypt-staging"
 8    kubernetes.io/ingress.class: "nginx"
 9spec:
10  tls:
11  - hosts:
12    - echo1.example.com
13    - echo2.example.com
14    secretName: echo-tls
15  rules:
16    - host: echo1.example.com
17      http:
18        paths:
19          - pathType: Prefix
20            path: "/"
21            backend:
22              service:
23                name: echo1
24                port:
25                  number: 80
26    - host: echo2.example.com
27      http:
28        paths:
29          - pathType: Prefix
30            path: "/"
31            backend:
32              service:
33                name: echo2
34                port:
35                  number: 80

在这里,我们添加了一个注释,将Cert-Manager ClusterIssuer设置为letsencrypt-staging,在步骤 4 中创建的测试证书 ClusterIssuer。

我们还添加了一个tls块来指定我们想要获得证书的主机,并指定一个secretName。这个秘密将包含TLS私钥和发行的证书。

完成更改后,保存并关闭文件。

现在我们将将此更新推到现有的 Ingress 对象中,使用 kubectl 应用:

1kubectl apply -f echo_ingress.yaml

你应该看到以下结果:

1[secondary_label Output]
2ingress.networking.k8s.io/echo-ingress configured

您可以使用kubectl 描述来跟踪您刚刚应用的 Ingress 更改的状态:

1kubectl describe ingress
1[secondary_label Output]
2Events:
3  Type Reason Age From Message
4  ----    ------             ----              ----                      -------
5  Normal UPDATE 6s (x3 over 80m)  nginx-ingress-controller Ingress default/echo-ingress
6  Normal CreateCertificate 6s cert-manager Successfully created Certificate "echo-tls"

一旦成功创建证书,您可以运行一个描述,以进一步确认其成功创建:

1kubectl describe certificate

您应该在事件部分中看到以下输出:

1[secondary_label Output]
2Events:
3  Type Reason Age From Message
4  ----    ------     ----   ----          -------
5  Normal Requested 64s cert-manager Created new CertificateRequest resource "echo-tls-vscfw"
6  Normal Issuing 40s cert-manager The certificate has been successfully issued

这证实 TLS 证书已成功发行,并且 HTTPS 加密现在已对配置的两个域进行激活。

我们现在已经准备好向后端Echo服务器发送请求,以测试HTTPS是否正常工作。

运行以下wget命令,将请求发送到echo1.example.com并将响应标题打印到STDOUT:

1wget --save-headers -O- echo1.example.com

你应该看到以下结果:

1[secondary_label Output]
2. . .
3HTTP request sent, awaiting response... 308 Permanent Redirect
4. . .
5ERROR: cannot verify echo1.example.com's certificate, issued by ‘ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=(STAGING) Artificial Apricot R3,O=(STAGING) Let's Encrypt,C=US’:
6  Unable to locally verify the issuer's authority.
7To connect to echo1.example.com insecurely, use `--no-check-certificate'.

这表明 HTTPS 已成功启用,但证书无法验证,因为它是 Let’s Encrypt 站点服务器发行的假临时证书。

现在,我们已经测试了使用此临时假证书的所有功能,我们可以为两个主机echo1.example.comecho2.example.com发布生产证书。

更新「echo_ingress.yaml」以使用「letsencrypt-prod」:

1nano echo_ingress.yaml

对文件进行以下更改:

 1[label echo_ingress.yaml]
 2apiVersion: networking.k8s.io/v1
 3kind: Ingress
 4metadata:
 5  name: echo-ingress
 6  annotations:
 7    cert-manager.io/cluster-issuer: "letsencrypt-prod"
 8    kubernetes.io/ingress.class: "nginx"
 9spec:
10  tls:
11  - hosts:
12    - echo1.example.com
13    - echo2.example.com
14    secretName: echo-tls
15  rules:
16    - host: echo1.example.com
17      http:
18        paths:
19          - pathType: Prefix
20            path: "/"
21            backend:
22              service:
23                name: echo1
24                port:
25                  number: 80
26    - host: echo2.example.com
27      http:
28        paths:
29          - pathType: Prefix
30            path: "/"
31            backend:
32              service:
33                name: echo2
34                port:
35                  number: 80

在这里,我们将 ClusterIssuer 名称更新为letsencrypt-prod

一旦您对更改感到满意,请保存并关闭文件。

使用kubectl 应用滚动更改:

1kubectl apply -f echo_ingress.yaml
1[secondary_label Output]
2ingress.networking.k8s.io/echo-ingress configured

请等待几分钟,让 Let's Encrypt 生产服务器发行该证书,您可以使用在证书对象上的kubectl 描述来跟踪其进展:

1kubectl describe certificate echo-tls

一旦您看到以下输出,证书已成功发行:

1[secondary_label Output]
2 Normal Issuing 28s cert-manager Issuing certificate as Secret was previously issued by ClusterIssuer.cert-manager.io/letsencrypt-staging
3  Normal Reused 28s cert-manager Reusing private key stored in existing Secret resource "echo-tls"
4  Normal Requested 28s cert-manager Created new CertificateRequest resource "echo-tls-49gmn"
5  Normal Issuing 2s (x2 over 4m52s)  cert-manager The certificate has been successfully issued

现在我们将使用弯曲进行测试,以验证 HTTPS 是否正常工作:

1curl echo1.example.com

你应该看到以下:

1[secondary_label Output]
2<html>
3<head><title>308 Permanent Redirect</title></head>
4<body>
5<center><h1>308 Permanent Redirect</h1></center>
6<hr><center>nginx/1.15.9</center>
7</body>
8</html>

这表明HTTP请求正在被重定向使用HTTPS。

运行 curlhttps://echo1.example.com 上:

1curl https://echo1.example.com

现在你应该看到以下结果:

1[secondary_label Output]
2echo1

您可以使用字母-v标志运行以前的命令,以深入证书握手并验证证书信息。

此时,您已成功配置 HTTPS 使用您的 Nginx Ingress 的 Let's Encrypt 证书。

结论

在本指南中,您设置了一个 Nginx Ingress 来加载平衡,并将外部请求路由到您的 Kubernetes 集群中的后端服务中。

对 Nginx Ingress 控制器有许多替代方案. 要了解更多信息,请参阅官方 Kubernetes 文档中的 Ingress 控制器

有关使用 Helm Kubernetes 包管理器部署 Nginx Ingress 控制器的指南,请参阅 How To Set Up a Nginx Ingress on DigitalOcean Kubernetes Using Helm

Published At
Categories with 技术
comments powered by Disqus