使用 Venafi 保护 Ingress
本指南将引导您了解如何使用 Venafi Issuer 类型保护 Kubernetes Ingress
资源。
在逐步操作过程中,您将学习如何
- 使用
eksctl
创建 EKS 集群 - 将 cert-manager 安装到 EKS 集群中
- 部署
nginx-ingress
以公开在集群中运行的应用程序 - 配置 Venafi Cloud Issuer
- 配置 cert-manager 以保护您的应用程序流量
虽然本指南侧重于将 EKS 作为 Kubernetes 资源供应器,而 Venafi 作为证书颁发者,但此处步骤通常可用于其他颁发者类型。
先决条件
- 一个 AWS 账户
kubectl
已安装- 访问公开注册的 DNS 区域
- 一个 Venafi Cloud 账户和 API 凭据
创建 EKS 集群
如果您已经拥有正在运行的 EKS 集群,则可以跳过此步骤并继续部署 cert-manager。
eksctl
是一个使部署和管理 EKS 集群变得更容易的工具。
各种平台的安装说明可以在 eksctl
安装说明 中找到。
安装完成后,您可以通过运行以下命令创建基本集群
$ eksctl create cluster
此过程可能需要长达 20 分钟才能完成。使用 eksctl
的完整说明可以在 eksctl
使用部分 中找到。
集群创建完毕后,您应该通过运行以下命令来验证您的集群是否正常运行
$ kubectl get pods --all-namespacesNAME READY STATUS RESTARTS AGEaws-node-8xpkp 1/1 Running 0 115saws-node-tflxs 1/1 Running 0 118scoredns-694d9447b-66vlp 1/1 Running 0 23scoredns-694d9447b-w5bg8 1/1 Running 0 23skube-proxy-4dvpj 1/1 Running 0 115skube-proxy-tpvht 1/1 Running 0 118s
您应该看到类似上面的输出,所有 Pod 都处于运行状态。
安装 cert-manager
在 EKS 上安装 cert-manager 时,没有特殊要求需要注意,因此可以按照常规的 在 Kubernetes 上运行 指南来安装 cert-manager。
请完成安装指南,并在验证 cert-manager 已正确部署后返回此步骤。
安装 ingress-nginx
一个 Kubernetes 入口控制器 被设计为对集群中运行的软件的 HTTP 和 HTTPS 流量的访问点。ingress-nginx
控制器通过提供由您的云提供商的负载均衡器(在本例中为 网络负载均衡器 (NLB))支持的 HTTP 代理服务来实现这一点。
您可以从 ingress-nginx
文档 中获得有关 ingress-nginx
及其工作原理的更多详细信息。
要使用 ELB 部署 ingress-nginx
来公开服务,请运行以下命令
部署 AWS 特定的先决条件清单
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.4.0/deploy/static/provider/aws/deploy.yaml
部署“通用” ingress-nginx
清单
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml
您可能需要等待长达 5 分钟才能使集群和 AWS 账户中的所有必需组件准备好。
您可以运行以下命令来确定 Amazon 分配给您的 NLB 的地址
$ kubectl get service -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx LoadBalancer 10.100.52.175 a8c2870a5a8a311e9a9a10a2e7af57d7-6c2ec8ede48726ab.elb.eu-west-1.amazonaws.com 80:31649/TCP,443:30567/TCP 4m10s
EXTERNAL-IP 字段可能显示 <pending>
一段时间。这表示 NLB 仍在创建中。请重试该命令,直到分配了 EXTERNAL-IP。
EXTERNAL-IP 可用后,您应该运行以下命令来验证流量是否已正确路由到 ingress-nginx
$ curl http://a8c2870a5a8a311e9a9a10a2e7af57d7-6c2ec8ede48726ab.elb.eu-west-1.amazonaws.com/<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>openresty/1.15.8.1</center></body></html>
虽然上述消息通常表示错误(页面未找到),但在这种情况下,它表示流量已正确路由到 ingress-nginx
服务。
注意:尽管 AWS 应用程序负载均衡器 (ALB) 是 AWS 提供的现代负载均衡器,可以从 EKS 中配置,但在撰写本文时,
alb-ingress-controller
只能为存储在 AWS 证书管理器 (ACM) 中的证书提供服务。Kubernetes 1.15 版本应解决此控制器的多个错误修复,并允许 TLS 终止支持。
配置您的 DNS 记录
现在我们的 NLB 已经配置好,我们应该将应用程序的 DNS 记录指向 NLB 的地址。
进入您的 DNS 提供商的控制台,设置一个指向您的 NLB 的 CNAME 记录。
为了演示,我们将在本指南中假设您已创建以下 DNS 条目
example.com CNAME a8c2870a5a8a311e9a9a10a2e7af57d7-6c2ec8ede48726ab.elb.eu-west-1.amazonaws.com
在您完成本教程的其余部分时,请将 example.com
替换为您自己的注册域名。
部署演示应用程序
为了演示,我们提供了一个示例部署,它是一个简单的“hello world”网站。
首先,创建一个将包含您的应用程序的新命名空间
$ kubectl create namespace demonamespace/demo created
将以下 YAML 保存到名为 demo-deployment.yaml
的文件中
apiVersion: v1kind: Servicemetadata:name: hello-kubernetesnamespace: demospec:type: ClusterIPports:- port: 80targetPort: 8080selector:app: hello-kubernetes---apiVersion: apps/v1kind: Deploymentmetadata:name: hello-kubernetesnamespace: demospec:replicas: 2selector:matchLabels:app: hello-kubernetestemplate:metadata:labels:app: hello-kubernetesspec:containers:- name: hello-kubernetesimage: paulbouwer/hello-kubernetes:1.5resources:requests:cpu: 100mmemory: 100Miports:- containerPort: 8080
然后运行
kubectl apply -n demo -f demo-deployment.yaml
请注意,我们部署的服务资源类型为 ClusterIP
,而不是 LoadBalancer
,因为我们将使用之前部署的 ingress-nginx
来公开和保护此服务的流量。
您应该能够在 demo
命名空间中看到两个 Pod 和一个服务
kubectl get po,svc -n demoNAME READY STATUS RESTARTS AGEhello-kubernetes-66d45d6dff-m2lnr 1/1 Running 0 7shello-kubernetes-66d45d6dff-qt2kb 1/1 Running 0 7sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/hello-kubernetes ClusterIP 10.100.164.58 <none> 80/TCP 7s
请注意,我们还没有将此应用程序公开为可通过互联网访问。我们将在后面的步骤中将演示应用程序公开到互联网。
创建 Venafi Issuer 资源
cert-manager 支持 Venafi TPP 和 Venafi Cloud。
请根据您要从何处检索证书,仅执行以下部分之一。
Venafi TPP
假设您已经正确设置了 Venafi TPP 服务器,则可以创建可用于颁发证书的 Venafi Issuer 资源。
为此,您需要确保已获得 TPP 的用户名和密码。
为了使 cert-manager 能够验证您的 Venafi TPP 服务器并设置 Issuer 资源,您需要创建一个包含您的用户名和密码的 Kubernetes 密钥
$ kubectl create secret generic \venafi-tpp-secret \--namespace=demo \--from-literal=username='YOUR_TPP_USERNAME_HERE' \--from-literal=password='YOUR_TPP_PASSWORD_HERE'
然后,我们必须创建一个 Venafi Issuer 资源,它代表 Kubernetes 中的证书颁发机构。
将以下 YAML 保存到名为 venafi-issuer.yaml
的文件中
apiVersion: cert-manager.io/v1kind: Issuermetadata:name: venafi-issuernamespace: demospec:venafi:zone: "Default" # Set this to the Venafi policy zone you want to usetpp:url: https://venafi-tpp.example.com/vedsdk # Change this to the URL of your TPP instancecaBundle: <base64 encoded string of caBundle PEM file, or empty to use system root CAs>credentialsRef:name: venafi-tpp-secret
然后运行
$ kubectl apply -n demo -f venafi-issuer.yaml
运行以下命令时,您应该看到输出中的 Status 部分显示 Issuer 已准备就绪(即已成功验证与 Venafi TPP 服务器的连接)。
$ kubectl describe issuer -n demo venafi-issuerStatus:Conditions:Last Transition Time: 2019-07-17T15:46:00ZMessage: Venafi issuer startedReason: Venafi issuer startedStatus: TrueType: ReadyEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal Ready 14s cert-manager Verified issuer with Venafi server
Venafi Cloud
您可以访问 注册页面 注册 Venafi Cloud 账户。
注册后,您应该通过单击控制面板界面右上角的姓名来获取 API 密钥。
为了使 cert-manager 能够验证您的 Venafi Cloud 账户并设置 Issuer 资源,您需要创建一个包含您的 API 密钥的 Kubernetes 密钥
$ kubectl create secret generic \venafi-cloud-secret \--namespace=demo \--from-literal=apikey=<API_KEY>
然后,我们必须创建一个 Venafi Issuer 资源,它代表 Kubernetes 中的证书颁发机构。
将以下 YAML 保存到名为 venafi-issuer.yaml
的文件中
apiVersion: cert-manager.io/v1kind: Issuermetadata:name: venafi-issuernamespace: demospec:venafi:zone: "Default" # Set this to the Venafi policy zone you want to usecloud:apiTokenSecretRef:name: venafi-cloud-secretkey: apikey
然后运行
$ kubectl apply -n demo -f venafi-issuer.yaml
运行以下命令时,您应该看到输出中的 Status 部分显示 Issuer 已准备就绪(即已成功验证与 Venafi Cloud 服务的连接)。
$ kubectl describe issuer -n demo venafi-issuer...Status:Conditions:Last Transition Time: 2019-07-17T15:46:00ZMessage: Venafi issuer startedReason: Venafi issuer startedStatus: TrueType: ReadyEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal Ready 14s cert-manager Verified issuer with Venafi server
请求证书
现在 Issuer 已配置好,并且我们已确认其设置正确,我们可以开始请求 Kubernetes 应用程序可使用的证书。
有关如何指定和请求证书资源的完整信息,请参阅请求证书指南。
现在,我们将创建一个适用于我们域名 example.com
的基本 X.509 证书。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-com-tlsnamespace: demospec:secretName: example-com-tlsdnsNames:- example.comcommonName: example.comissuerRef:name: venafi-issuer
将此 YAML 保存到名为 example-com-tls.yaml
的文件中,然后运行
$ kubectl apply -n demo -f example-com-tls.yaml
只要您确保 Venafi Cloud 帐户的区域(在我们的示例中,我们使用“默认”区域)已配置了 CA 或包含自定义证书,cert-manager 现在就可以采取步骤来填充 example-com-tls
密钥中的证书。它通过使用 API 密钥向 Venafi Cloud 进行身份验证,然后请求与我们创建的证书资源的规范匹配的证书。
您可以运行 kubectl describe
来检查证书的进度
$ kubectl describe certificate -n demo example-com-tls...Status:Conditions:Last Transition Time: 2019-07-17T17:43:01ZMessage: Certificate is up to date and has not expiredReason: ReadyStatus: TrueType: ReadyNot After: 2019-10-15T12:00:00ZEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal Issuing 33s cert-manager Requesting new certificate...Normal GenerateKey 33s cert-manager Generated new private keyNormal Validate 33s cert-manager Validated certificate request against Venafi zone policyNormal Requesting 33s cert-manager Requesting certificate from Venafi server...Normal Retrieve 15s cert-manager Retrieved certificate from Venafi serverNormal CertIssued 15s cert-manager Certificate issued successfully
证书签发后,您应该会看到类似于上面的事件。
然后,您应该能够看到证书已成功存储在密钥资源中
$ kubectl get secret -n demo example-com-tlsNAME TYPE DATA AGEexample-com-tls kubernetes.io/tls 3 2m47s$ kubectl get secret example-com-tls -o 'go-template={{index .data "tls.crt"}}' | \base64 --decode | \openssl x509 -noout -textCertificate:Data:Version: 3 (0x2)Serial Number:0d:ce:bf:89:04:d4:41:83:f4:4c:32:66:64:fb:60:14Signature Algorithm: sha256WithRSAEncryptionIssuer: C=US, O=DigiCert Inc, CN=DigiCert Test SHA2 Intermediate CA-1ValidityNot Before: Jul 17 00:00:00 2019 GMTNot After : Oct 15 12:00:00 2019 GMTSubject: C=US, ST=California, L=Palo Alto, O=Venafi Cloud, OU=SerialNumber, CN=example.comSubject Public Key Info:Public Key Algorithm: rsaEncryptionPublic-Key: (2048 bit)Modulus:00:ad:2e:66:02:20:c9:b1:6a:00:63:70:4e:22:3c:45:63:6e:e7:fd:4c:94:7d:75:50:22:a2:01:72:99:9c:23:04:90:51:85:4d:47:32:e4:8b:ee:b1:ea:09:1a:de:97:5d:31:05:a2:73:73:4f:06:a3:b2:59:ee:bc:30:f7:26:85:3d:b3:56:e4:c2:97:34:b6:ac:6d:65:7e:a2:4e:b4:ce:f2:0a:0a:4c:d7:32:d7:5a:18:e8:69:c6:34:28:26:36:ef:c5:bc:ae:ba:ca:d2:46:3f:d4:61:39:66:8f:19:cc:d6:d6:10:77:af:51:93:1b:4d:f8:d1:10:19:ab:ac:b3:7b:0b:98:58:29:e6:a9:ac:9f:7a:dc:63:0d:51:f5:bd:9f:f3:03:2e:b3:2d:2f:00:87:f4:e1:cd:5a:32:c6:d8:fb:49:c4:e7:da:3f:0f:8f:bb:66:94:28:5d:99:fe:7c:f0:17:1b:fd:3e:ed:dd:36:bf:8e:62:60:0c:85:7f:76:74:4b:37:d9:c2:e8:74:49:04:bf:f1:83:81:cc:4f:9b:f3:40:97:d4:dc:b6:d3:2d:dc:73:18:93:48:a5:8f:6c:57:7f:ec:62:c0:bc:c2:b0:e9:0a:51:2d:c4:b6:87:68:96:87:f8:9a:86:3c:6a:f1:01:ca:57:c4:07:e7:b0:51Exponent: 65537 (0x10001)X509v3 extensions:X509v3 Authority Key Identifier:keyid:D6:4D:F9:39:60:6C:73:C3:22:F5:AD:30:0C:2F:A0:D5:CA:75:4A:2AX509v3 Subject Key Identifier:A3:B3:47:2C:41:5E:9C:B2:27:97:57:14:A4:2E:BA:8C:93:E7:01:65X509v3 Subject Alternative Name:DNS:example.comX509v3 Key Usage: criticalDigital Signature, Key EnciphermentX509v3 Extended Key Usage:TLS Web Server Authentication, TLS Web Client AuthenticationX509v3 CRL Distribution Points:Full Name:URI:http://crl3.digicert.com/DigiCertTestSHA2IntermediateCA1.crlFull Name:URI:http://crl4.digicert.com/DigiCertTestSHA2IntermediateCA1.crlX509v3 Certificate Policies:Policy: 2.16.840.1.114412.1.1CPS: https://www.digicert.com/CPSAuthority Information Access:OCSP - URI:http://ocsp.digicert.comCA Issuers - URI:http://cacerts.test.digicert.com/DigiCertTestSHA2IntermediateCA1.crtX509v3 Basic Constraints: criticalCA:FALSESignature Algorithm: sha256WithRSAEncryptionae:d4:9c:8a:66:19:9e:7d:12:b7:05:c2:b6:33:b3:9c:a5:40:47:ab:34:8d:1b:0f:51:96:de:e9:46:5a:e4:16:10:43:56:bf:fa:f8:64:f4:cb:53:39:5b:45:ca:7f:15:d9:59:25:21:23:c4:4d:dc:a7:f7:83:21:d2:3f:a8:0a:26:f4:ef:fa:1b:2b:7d:97:7e:28:f3:ca:cd:b2:c4:92:f3:92:27:7f:e0:f1:ac:d6:db:4c:10:8a:f8:6f:09:bb:b3:4f:19:06:aa:bb:74:1c:e0:51:42:f6:8c:7d:77:f7:80:a4:03:ab:a9:ae:ae:2b:89:17:af:2f:eb:f7:3d:61:7c:dd:e1:5d:d2:5a:c5:6a:f6:c8:92:4c:0a:b5:75:d1:dd:39:f2:a7:a2:10:8c:6d:bf:ca:08:ad:b9:a9:df:e3:59:8f:64:16:3c:7e:8a:6e:27:fc:49:d7:06:f0:bd:94:15:f2:fd:0f:94:8a:b8:73:67:73:53:22:df:9d:36:e9:34:f9:2a:68:00:59:78:6d:2d:8f:a0:0f:13:af:bd:b3:aa:8c:37:c4:22:cf:23:fb:56:bc:4e:55:ae:3a:0a:e6:3e:b1:1a:22:71:7b:08:b8:00:41:14:26:f6:9b:9b:72:3f:eb:dc:dd:1b:db:a8:20:fd:54:75:ae:25:7f:80:e6
在下一步中,我们将配置您的应用程序以实际使用此新的证书资源。
公开和保护您的应用程序
现在我们已经签发了证书,我们可以使用 Kubernetes Ingress 资源公开我们的应用程序。
创建一个名为 application-ingress.yaml
的文件,并将以下内容保存到其中,用您自己的域名替换 example.com
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: frontend-ingressnamespace: demospec:ingressClassName: nginxtls:- hosts:- example.comsecretName: example-com-tlsrules:- host: example.comhttp:paths:- path: /pathType: Exactbackend:service:name: kuardport:number: 80
然后,您可以使用以下命令应用此资源
$ kubectl apply -n demo -f application-ingress.yaml
创建后,您应该能够在配置的 URL 上访问您的应用程序,这里是 example.com
!
在您的网络浏览器中导航到该地址,您应该会看到通过 Venafi 获取的证书用于保护应用程序流量。