如何在DigitalOceanKubernetes上使用Cert-Manager设置Nginx入口
介绍
Kubernetes Ingresses 允许您灵活地将流量从 Kubernetes 集群外部路由到集群内部的服务。 这是使用 Ingress Resources 来完成的,它定义了将 HTTP 和 HTTPS 流量路由到 Kubernetes 服务的规则,以及 Ingress Controllers,它通过负载平衡流量并将其路由到适当的来实现规则后端服务。
流行的入口控制器包括 Nginx、Contour、HAProxy 和 Traefik。 Ingress 为设置多个 LoadBalancer 服务提供了一种更高效、更灵活的替代方案,每个服务都使用自己的专用负载均衡器。
在本指南中,我们将设置 Kubernetes 维护的 Nginx 入口控制器 ,并创建一些入口资源以将流量路由到几个虚拟后端服务。 设置好 Ingress 后,我们将 cert-manager 安装到我们的集群中,以管理和配置 TLS 证书,用于加密到 Ingress 的 HTTP 流量。 本指南 not 使用 Helm 包管理器。 有关使用 Helm 推出 Nginx 入口控制器的指南,请参阅 如何使用 Helm 在 DigitalOcean Kubernetes 上设置 Nginx 入口。
先决条件
在开始阅读本指南之前,您应该准备好以下内容:
- 启用了 基于角色的访问控制 (RBAC) 的 Kubernetes 1.15+ 集群。 此设置将使用 DigitalOcean Kubernetes 集群,但您可以使用 另一种方法 自由创建集群。
kubectl
命令行工具安装在您的本地机器上并配置为连接到您的集群。 您可以在官方文档中阅读更多关于安装kubectl
的信息。 如果您使用的是 DigitalOcean Kubernetes 集群,请参考 如何连接到 DigitalOcean Kubernetes 集群 了解如何使用kubectl
连接到您的集群。- 您可以指向 Ingress 使用的 DigitalOcean 负载均衡器的域名和 DNS A 记录。 如果您使用 DigitalOcean 管理您域的 DNS 记录,请参阅 如何管理 DNS 记录 以了解如何创建
A
记录。 - 安装在本地计算机上的
wget
命令行实用程序。 您可以使用操作系统内置的包管理器安装wget
。
设置好这些组件后,您就可以开始阅读本指南了。
第 1 步 — 设置虚拟后端服务
在部署 Ingress Controller 之前,我们将首先创建并推出两个虚拟 echo 服务,我们将使用 Ingress 将外部流量路由到这些服务。 echo 服务将运行 hashicorp/http-echo Web 服务器容器,该容器返回一个页面,其中包含在 Web 服务器启动时传入的文本字符串。 要了解有关 http-echo
的更多信息,请参阅其 GitHub Repo,要了解有关 Kubernetes 服务的更多信息,请参阅 Kubernetes 官方文档中的 Services。
在您的本地计算机上,使用 nano
或您喜欢的编辑器创建并编辑一个名为 echo1.yaml
的文件:
nano echo1.yaml
粘贴以下服务和部署清单:
echo1.yaml
apiVersion: v1 kind: Service metadata: name: echo1 spec: ports: - port: 80 targetPort: 5678 selector: app: echo1 --- apiVersion: apps/v1 kind: Deployment metadata: name: echo1 spec: selector: matchLabels: app: echo1 replicas: 2 template: metadata: labels: app: echo1 spec: containers: - name: echo1 image: hashicorp/http-echo args: - "-text=echo1" ports: - containerPort: 5678
在这个文件中,我们定义了一个名为 echo1
的服务,它使用 app: echo1
标签选择器将流量路由到 Pod。 它接受端口 80
上的 TCP 流量并将其路由到端口 5678
、http-echo
的默认端口。
然后我们定义一个 Deployment,也称为 echo1
,它使用 app: echo1
Label Selector 管理 Pod。 我们指定 Deployment 应该有 2 个 Pod 副本,并且 Pod 应该启动一个名为 echo1
的容器来运行 hashicorp/http-echo
映像。 我们传入 text
参数并将其设置为 echo1
,以便 http-echo
Web 服务器返回 echo1
。 最后,我们在 Pod 容器上打开端口 5678
。
对虚拟服务和部署清单感到满意后,保存并关闭文件。
然后,使用带有 -f
标志的 kubectl apply
创建 Kubernetes 资源,指定刚刚保存的文件作为参数:
kubectl apply -f echo1.yaml
您应该看到以下输出:
Outputservice/echo1 created deployment.apps/echo1 created
通过确认它有一个 ClusterIP(服务暴露在其上的内部 IP)来验证服务是否正确启动:
kubectl get svc echo1
您应该看到以下输出:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 60s
这表明 echo1
服务现在在端口 80
上的 10.245.222.129
内部可用。 它将流量转发到它选择的 Pod 上的 containerPort 5678
。
现在 echo1
服务已启动并运行,请对 echo2
服务重复此过程。
创建并打开一个名为 echo2.yaml
的文件:
echo2.yaml
apiVersion: v1 kind: Service metadata: name: echo2 spec: ports: - port: 80 targetPort: 5678 selector: app: echo2 --- apiVersion: apps/v1 kind: Deployment metadata: name: echo2 spec: selector: matchLabels: app: echo2 replicas: 1 template: metadata: labels: app: echo2 spec: containers: - name: echo2 image: hashicorp/http-echo args: - "-text=echo2" ports: - containerPort: 5678
在这里,我们基本上使用与上面相同的服务和部署清单,但命名并重新标记服务和部署 echo2
。 另外,为了提供一些多样性,我们只创建了 1 个 Pod 副本。 我们确保将 text
参数设置为 echo2
,以便 Web 服务器返回文本 echo2
。
保存并关闭文件,使用 kubectl
创建 Kubernetes 资源:
kubectl apply -f echo2.yaml
您应该看到以下输出:
Outputservice/echo2 created deployment.apps/echo2 created
再次验证服务是否已启动并正在运行:
kubectl get svc
您应该会看到分配有 ClusterIP 的 echo1
和 echo2
服务:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 6m6s echo2 ClusterIP 10.245.128.224 <none> 80/TCP 6m3s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 4d21h
现在我们的虚拟回显 Web 服务已经启动并运行,我们可以继续推出 Nginx 入口控制器。
第 2 步 — 设置 Kubernetes Nginx 入口控制器
在这一步中,我们将推出 Kubernetes 维护的 Nginx 入口控制器 的 v1.1.1
。 注意有几个 Nginx Ingress Controller; Kubernetes 社区维护本指南中使用的社区和 Nginx Inc.。 维护 kubernetes-ingress。 本教程中的说明基于官方 Kubernetes Nginx Ingress Controller 安装指南中的说明。
Nginx Ingress Controller 由一个 Pod 组成,该 Pod 运行 Nginx Web 服务器并监视 Kubernetes 控制平面以获取新的和更新的 Ingress Resource 对象。 入口资源本质上是后端服务的流量路由规则列表。 例如,Ingress 规则可以指定到达路径 /web1
的 HTTP 流量应定向到 web1
后端 Web 服务器。 使用 Ingress Resources,您还可以执行基于主机的路由:例如,将命中 web1.your_domain.com
的请求路由到后端 Kubernetes Service web1
。
在这种情况下,因为我们将 Ingress Controller 部署到 DigitalOcean Kubernetes 集群,所以 Controller 将创建一个 LoadBalancer 服务,该服务提供一个 DigitalOcean 负载均衡器,所有外部流量都将定向到该负载均衡器。 此负载均衡器会将外部流量路由到运行 Nginx 的 Ingress Controller Pod,然后将流量转发到适当的后端服务。
我们将从创建 Nginx Ingress Controller Kubernetes 资源开始。 这些包括包含控制器配置的 ConfigMap、基于角色的访问控制 (RBAC) 角色以授予控制器对 Kubernetes API 的访问权限,以及使用 Nginx 入口控制器映像的 v1.1.1
的实际入口控制器部署。 要查看这些所需资源的完整列表,请参阅 Kubernetes Nginx Ingress Controller 的 GitHub 存储库中的 manifest。
注意:在本教程中,我们按照DigitalOcean Provider的官方安装说明进行操作。 您应该根据您的 Kubernetes 提供商选择适当的清单文件。
要创建资源,请使用 kubectl apply
和 -f
标志来指定托管在 GitHub 上的清单文件:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/do/deploy.yaml
我们在这里使用 apply
以便将来我们可以对 Ingress Controller 对象进行增量 apply
更改,而不是完全覆盖它们。 要了解有关 apply
的更多信息,请参阅 Kubernetes 官方文档中的 管理资源。
您应该看到以下输出:
Outputnamespace/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 validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created role.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created
此输出还可作为从 deploy.yaml
清单创建的所有 Ingress Controller 对象的方便摘要。
确认 Ingress Controller Pod 已启动:
kubectl get pods -n ingress-nginx \ -l app.kubernetes.io/name=ingress-nginx --watch
OutputNAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-l2jhk 0/1 Completed 0 13m ingress-nginx-admission-patch-hsrzf 0/1 Completed 0 13m ingress-nginx-controller-c96557986-m47rq 1/1 Running 0 13m
点击 CTRL+C
返回提示。
现在,通过使用 kubectl
获取服务详细信息来确认 DigitalOcean 负载均衡器已成功创建:
kubectl get svc --namespace=ingress-nginx
几分钟后,您应该会看到一个外部 IP 地址,对应于 DigitalOcean 负载均衡器的 IP 地址:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 10.245.201.120 203.0.113.0 80:31818/TCP,443:31146/TCP 14m ingress-nginx-controller-admission ClusterIP 10.245.239.119 <none> 443/TCP 14m
记下负载均衡器的外部 IP 地址,因为您将在后面的步骤中需要它。
注意: 默认情况下,Nginx Ingress LoadBalancer Service 将 service.spec.externalTrafficPolicy
设置为值 Local
,它将所有负载均衡器流量路由到运行 Nginx Ingress Pod 的节点。 其他节点将故意使负载均衡器健康检查失败,以使 Ingress 流量不会被路由到它们。 外部流量策略超出了本教程的范围,但要了解更多信息,您可以参考官方的 A Deep Dive into Kubernetes External Traffic Policies 和 Source IP for Services with Type=LoadBalancer Kubernetes 文档。
此负载均衡器在 HTTP 和 HTTPS 端口 80 和 443 上接收流量,并将其转发到 Ingress Controller Pod。 然后入口控制器将流量路由到适当的后端服务。
我们现在可以将我们的 DNS 记录指向这个外部负载均衡器,并创建一些入口资源来实现流量路由规则。
第三步——创建入口资源
让我们首先创建一个最小的 Ingress Resource 来将指向给定子域的流量路由到相应的后端服务。
在本指南中,我们将使用测试域 example.com。 您应该将其替换为您拥有的域名。
我们将首先创建一个简单的规则,将指向 echo1.example.com 的流量路由到 echo1
后端服务,并将指向 echo2.example.com 的流量路由到echo2
后端服务。
首先在您喜欢的编辑器中打开一个名为 echo_ingress.yaml
的文件:
nano echo_ingress.yaml
粘贴以下入口定义:
echo_ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-ingress spec: rules: - host: echo1.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: echo1 port: number: 80 - host: echo2.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: echo2 port: number: 80
编辑完 Ingress 规则后,保存并关闭文件。
在这里,我们指定要创建一个名为 echo-ingress
的 Ingress Resource,并根据 Host 标头路由流量。 HTTP 请求主机头指定目标服务器的域名。 要了解有关主机请求标头的更多信息,请参阅 Mozilla 开发人员网络 定义页面 。 主机 echo1.example.com 的请求将被定向到步骤 1 中设置的 echo1
后端,主机 echo2.example.com 的请求将被定向到 echo2
后端。
您现在可以使用 kubectl
创建 Ingress:
kubectl apply -f echo_ingress.yaml
您将看到以下确认 Ingress 创建的输出:
Outputingress.networking.k8s.io/echo-ingress created
要测试 Ingress,请导航到您的 DNS 管理服务并为 echo1.example.com
和 echo2.example.com
创建指向 DigitalOcean 负载均衡器的外部 IP 的 A 记录。 负载均衡器的外部 IP 是我们在上一步中获取的 ingress-nginx
服务的外部 IP 地址。 如果您使用 DigitalOcean 管理您域的 DNS 记录,请参阅 如何管理 DNS 记录 以了解如何创建 A
记录。
创建必要的 echo1.example.com
和 echo2.example.com
DNS 记录后,您可以使用 curl
命令行实用程序测试您创建的入口控制器和资源。
从您的本地计算机,curl
echo1
服务:
curl echo1.example.com
您应该从 echo1
服务获得以下响应:
Outputecho1
这确认您对 echo1.example.com
的请求正通过 Nginx 入口正确路由到 echo1
后端服务。
现在,对 echo2
服务执行相同的测试:
curl echo2.example.com
您应该从 echo2
服务获得以下响应:
Outputecho2
这确认您对 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 资源、将 tls
部分附加到 Ingress 规范并配置一个或多个 Issuers 或 ClusterIssuers 来指定您的首选来自动请求和配置证书颁发机构。 要了解有关 Issuer 和 ClusterIssuer 对象的更多信息,请参阅 Issuers 上的官方 cert-manager 文档。
按照官方 安装说明 安装 cert-manager 及其 自定义资源定义 (CRD),例如 Issuers 和 ClusterIssuers。 请注意,将创建一个名为 cert-manager
的命名空间,其中将创建 cert-manager 对象:
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml
您应该看到以下输出:
Outputcustomresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created . . . deployment.apps/cert-manager-webhook created mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
要验证我们的安装,请检查 cert-manager
命名空间以运行 pod:
kubectl get pods --namespace cert-manager
OutputNAME READY STATUS RESTARTS AGE cert-manager-578cd6d964-hr5v2 1/1 Running 0 99s cert-manager-cainjector-5ffff9dd7c-f46gf 1/1 Running 0 100s cert-manager-webhook-556b9d7dfd-wd5l6 1/1 Running 0 99s
这表明 cert-manager 安装成功。
在我们开始为我们的 echo1.example.com
和 echo2.example.com
域颁发证书之前,我们需要创建一个颁发者,它指定可以从中获取签名 x509 证书的证书颁发机构。 在本指南中,我们将使用 Let's Encrypt 证书颁发机构,它提供免费的 TLS 证书,并提供用于测试证书配置的暂存服务器和用于推出可验证 TLS 证书的生产服务器。
让我们创建一个测试 ClusterIssuer 以确保证书供应机制正常运行。 ClusterIssuer 不是命名空间范围的,可以由任何命名空间中的 Certificate 资源使用。
在您喜欢的文本编辑器中打开一个名为 staging_issuer.yaml
的文件:
nano staging_issuer.yaml
粘贴以下 ClusterIssuer 清单:
staging_issuer.yaml
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging namespace: cert-manager spec: acme: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: your_email_address_here # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: nginx
在这里,我们指定要创建一个名为 letsencrypt-staging
的 ClusterIssuer,并使用 Let's Encrypt 登台服务器。 我们稍后将使用生产服务器来推出我们的证书,但生产服务器会限制针对它的请求,因此出于测试目的,您应该使用暂存 URL。
然后我们指定一个电子邮件地址来注册证书,并创建一个名为 letsencrypt-staging
的 Kubernetes Secret 来存储 ACME 帐户的私钥。 我们还使用 HTTP-01
挑战机制。 要了解有关这些参数的更多信息,请参阅 Issuers 上的官方 cert-manager 文档。
使用 kubectl
推出 ClusterIssuer:
kubectl create -f staging_issuer.yaml
您应该看到以下输出:
Outputclusterissuer.cert-manager.io/letsencrypt-staging created
我们现在将重复此过程以创建生产 ClusterIssuer。 请注意,只有在对上一步中配置的 Ingress 资源进行注释和更新后,才会创建证书。
在您喜欢的编辑器中打开一个名为 prod_issuer.yaml
的文件:
nano prod_issuer.yaml
粘贴以下清单:
prod_issuer.yaml
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod namespace: cert-manager spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: your_email_address_here # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: nginx
请注意不同的 ACME 服务器 URL 和 letsencrypt-prod
密钥名称。
完成编辑后,保存并关闭文件。
使用 kubectl
推出此发行者:
kubectl create -f prod_issuer.yaml
您应该看到以下输出:
Outputclusterissuer.cert-manager.io/letsencrypt-prod created
现在我们已经创建了 Let's Encrypt staging 和 prod ClusterIssuers,我们准备修改上面创建的 Ingress Resource 并为 echo1.example.com
和 echo2.example.com
路径启用 TLS 加密。
如果您使用的是 DigitalOcean Kubernetes,您首先需要实现 一种解决方法,以便 Pod 可以使用 Ingress 与其他 Pod 通信。 如果你没有使用 DigitalOcean Kubernetes,你可以跳到 Step 6。
第 5 步 — 通过负载均衡器启用 Pod 通信(可选)
在从 Let's Encrypt 提供证书之前,cert-manager 首先执行自检以确保 Let's Encrypt 可以访问验证您的域的 cert-manager Pod。 要在 DigitalOcean Kubernetes 上通过此检查,您需要通过 Nginx Ingress 负载均衡器启用 Pod-Pod 通信。
为此,我们将创建一个指向云负载均衡器外部 IP 的 DNS A 记录,并使用此子域注释 Nginx Ingress Service 清单。
首先导航到您的 DNS 管理服务并为 workaround.example.com
创建一个指向 DigitalOcean 负载均衡器的外部 IP 的 A 记录。 负载均衡器的外部 IP 是我们在步骤 2 中获取的 ingress-nginx
服务的外部 IP 地址。 如果您使用 DigitalOcean 管理您域的 DNS 记录,请参阅 如何管理 DNS 记录 了解如何创建 A 记录。 在这里,我们使用子域 workaround
,但您可以自由使用您喜欢的任何子域。
现在您已经创建了指向 Ingress 负载均衡器的 DNS 记录,请使用 do-loadbalancer-hostname 注释来注释 Ingress LoadBalancer 服务。 在您喜欢的编辑器中打开一个名为 ingress_nginx_svc.yaml
的文件,然后粘贴到以下 LoadBalancer 清单中:
ingress_nginx_svc.yaml
apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: 'true' service.beta.kubernetes.io/do-loadbalancer-hostname: "workaround.example.com" labels: helm.sh/chart: ingress-nginx-4.0.6 app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/version: 1.1.1 app.kubernetes.io/managed-by: Helm app.kubernetes.io/component: controller name: ingress-nginx-controller namespace: ingress-nginx spec: type: LoadBalancer externalTrafficPolicy: Local ports: - name: http port: 80 protocol: TCP targetPort: http - name: https port: 443 protocol: TCP targetPort: https selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller
此服务清单是从您在步骤 2 中安装的完整 Nginx Ingress 清单文件 中提取的。 一定要复制你安装的Nginx Ingress版本对应的Service manifest; 在本教程中,这是 1.1.1
。 还要确保将 do-loadbalancer-hostname
注释设置为 workaround.example.com
域。
完成后,保存并关闭文件。
使用 kubectl apply
修改正在运行的 ingress-nginx-controller
服务:
kubectl apply -f ingress_nginx_svc.yaml
您应该看到以下输出:
Outputservice/ingress-nginx-controller configured
这确认您已注释 ingress-nginx-controller
服务,并且集群中的 Pod 现在可以使用此 ingress-nginx-controller
负载均衡器相互通信。
第 6 步 — 颁发登台和生产 Let's Encrypt 证书
要为我们的域颁发暂存 TLS 证书,我们将使用在步骤 4 中创建的 ClusterIssuer 注释 echo_ingress.yaml
。 这将使用 ingress-shim 为 Ingress 清单中指定的域自动创建和颁发证书。
在您喜欢的编辑器中打开 echo_ingress.yaml
:
nano echo_ingress.yaml
将以下内容添加到 Ingress 资源清单:
echo_ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-ingress annotations: cert-manager.io/cluster-issuer: "letsencrypt-staging" kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - echo1.example.com - echo2.example.com secretName: echo-tls rules: - host: echo1.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: echo1 port: number: 80 - host: echo2.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: echo2 port: number: 80
这里我们添加一个注解,将 cert-manager ClusterIssuer 设置为 letsencrypt-staging
,即第 4 步创建的测试证书 ClusterIssuer。 我们还添加了一个描述入口类型的注释,在本例中为 nginx
。
我们还添加了一个 tls
块来指定我们要为其获取证书的主机,并指定一个 secretName
。 此密钥将包含 TLS 私钥和颁发的证书。 请务必将 example.com
替换为您为其创建 DNS 记录的域。
完成更改后,保存并关闭文件。
我们现在将使用 kubectl apply
将此更新推送到现有的 Ingress 对象:
kubectl apply -f echo_ingress.yaml
您应该看到以下输出:
Outputingress.networking.k8s.io/echo-ingress configured
您可以使用 kubectl describe
来跟踪您刚刚应用的 Ingress 更改的状态:
kubectl describe ingress
OutputEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal UPDATE 6s (x3 over 80m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 6s cert-manager Successfully created Certificate "echo-tls"
成功创建证书后,您可以在其上运行 describe
以进一步确认其成功创建:
kubectl describe certificate
您应该在 Events
部分看到以下输出:
OutputEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Requested 64s cert-manager Created new CertificateRequest resource "echo-tls-vscfw" Normal Issuing 40s cert-manager The certificate has been successfully issued
这确认 TLS 证书已成功颁发,并且 HTTPS 加密现在对配置的两个域处于活动状态。
我们现在准备向后端 echo
服务器发送请求,以测试 HTTPS 是否正常运行。
运行以下 wget
命令向 echo1.example.com
发送请求并将响应头打印到 STDOUT
:
wget --save-headers -O- echo1.example.com
您应该看到以下输出:
Output. . . HTTP request sent, awaiting response... 308 Permanent Redirect . . . ERROR: 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’: Unable to locally verify the issuer's authority. To connect to echo1.example.com insecurely, use `--no-check-certificate'.
这表明 HTTPS 已成功启用,但证书无法验证,因为它是 Let's Encrypt 登台服务器颁发的假临时证书。
现在我们已经使用这个临时假证书测试了一切正常,我们可以为两个主机 echo1.example.com
和 echo2.example.com
推出生产证书。 为此,我们将使用 letsencrypt-prod
ClusterIssuer。
更新 echo_ingress.yaml
以使用 letsencrypt-prod
:
nano echo_ingress.yaml
对文件进行以下更改:
echo_ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-ingress annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - echo1.example.com - echo2.example.com secretName: echo-tls rules: - host: echo1.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: echo1 port: number: 80 - host: echo2.example.com http: paths: - pathType: Prefix path: "/" backend: service: name: echo2 port: number: 80
在这里,我们将 ClusterIssuer 名称更新为 letsencrypt-prod
。
对更改感到满意后,保存并关闭文件。
使用 kubectl apply
展开更改:
kubectl apply -f echo_ingress.yaml
Outputingress.networking.k8s.io/echo-ingress configured
等待几分钟,让 Let's Encrypt 生产服务器颁发证书。 您可以使用 certificate
对象上的 kubectl describe
跟踪其进度:
kubectl describe certificate echo-tls
看到以下输出后,证书已成功颁发:
Output Normal Issuing 28s cert-manager Issuing certificate as Secret was previously issued by ClusterIssuer.cert-manager.io/letsencrypt-staging Normal Reused 28s cert-manager Reusing private key stored in existing Secret resource "echo-tls" Normal Requested 28s cert-manager Created new CertificateRequest resource "echo-tls-49gmn" Normal Issuing 2s (x2 over 4m52s) cert-manager The certificate has been successfully issued
我们现在将使用 curl
执行测试,以验证 HTTPS 是否正常工作:
curl echo1.example.com
您应该看到以下内容:
Output<html> <head><title>308 Permanent Redirect</title></head> <body> <center><h1>308 Permanent Redirect</h1></center> <hr><center>nginx/1.15.9</center> </body> </html>
这表明 HTTP 请求被重定向以使用 HTTPS。
在 https://echo1.example.com
上运行 curl
:
curl https://echo1.example.com
您现在应该看到以下输出:
Outputecho1
您可以使用详细的 -v
标志运行前面的命令,以深入了解证书握手并验证证书信息。
至此,您已经使用 Let's Encrypt 证书为您的 Nginx Ingress 成功配置了 HTTPS。
结论
在本指南中,您将设置一个 Nginx 入口来负载平衡并将外部请求路由到 Kubernetes 集群内的后端服务。 您还通过安装 cert-manager 证书配置程序并为两个主机路径设置 Let's Encrypt 证书来保护 Ingress。
Nginx Ingress Controller 有很多替代品。 要了解更多信息,请参阅 Kubernetes 官方文档中的 Ingress 控制器。
有关使用 Helm Kubernetes 包管理器推出 Nginx 入口控制器的指南,请参阅 如何使用 Helm 在 DigitalOcean Kubernetes 上设置 Nginx 入口。