cert-manager是一个证书生命周期管理系统,支持证书的申请、部署等功能。您可以使用cert-manager颁发ASM网关的证书,从而可以使用HTTPS协议通过ASM网关访问服务,保证数据传输的安全。本文介绍如何使用cert-manager管理网关的证书。
背景信息
cert-manager支持签发自签名证书和DNS域名证书,从而可以使用HTTPS协议通过ASM网关访问服务。这两种证书的区别如下:- 自签名证书:自签名证书仅具有加密功能,无身份验证功能。您可以在命令行工具中使用HTTPS协议访问ASM网关,但是自签名证书不受Web浏览器的信任,Web浏览器检查HTTPS连接会标记为潜在风险并弹出错误消息,即无法在Web浏览器中使用HTTPS协议通过ASM网关访问服务。
- DNS域名证书:DNS域名证书由受信任的CA机构颁发,兼具加密和身份验证功能。相比自签名证书,DNS域名证书具有更高的安全性,受到Web浏览器的信任。您可以同时在命令行工具和Web浏览器中使用HTTPS协议通过ASM网关访问服务。
在集群中安装cert-manager
- 在本地安装Helm。具体操作,请参见Helm。
- 使用kubectl连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
- 执行以下命令,创建cert-manager命名空间。
kubectl create namespace cert-manager
- 执行以下命令,添加cert-manager Chart。
helm repo add jetstack https://charts.jetstack.io
- 执行以下命令,获取cert-manager Chart的最新信息。
helm repo update
- 执行以下命令,安装cert-manager。说明 cert-manager的版本需要和Kubernetes版本保持兼容。关于cert-manager和Kubernetes版本的对应关系,请参见Supported Releases。
helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --version v1.1.0 \ --set installCRDs=true
场景一:使用cert-manager签发自签名证书
步骤一:在集群中生成自签证书
- 使用以下内容,创建issuer.yaml。
apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: istio-ingressgateway-certs spec: isCA: true duration: 2160h # 90d secretName: istio-ingressgateway-certs commonName: istio-ingressgateway-certs subject: organizations: - cluster.local - cert-manager issuerRef: name: selfsigned kind: Issuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: istio-ingressgateway-certs spec: ca: secretName: istio-ingressgateway-certs
- 执行以下命令,创建自签名CA来颁发工作负载证书。
kubectl apply -f issuer.yaml -n istio-system
- 执行以下命令,查看证书。
kubectl get secret -n istio-system
预期输出:
NAME TYPE DATA AGE istio-ingressgateway-certs kubernetes.io/tls 3 68m
步骤二:添加证书和私钥挂载卷到入口网关
- 登录ASM控制台,在左侧导航栏,选择 。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
- 在入口网关页面的目标网关右侧,单击查看YAML。
- 在编辑对话框,添加如下信息到
spec
字段。secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs
添加之后的YAML文件示例如下:
apiVersion: istio.alibabacloud.com/v1beta1 kind: IstioGateway metadata: name: ingressgateway namespace: istio-system spec: clusterIds: - c58638b491a5248669b59609e0a17**** cpu: {} externalTrafficPolicy: Local maxReplicas: 1 minReplicas: 1 ports: - name: status-port port: 15020 targetPort: 15020 - name: http2 nodePort: 31380 port: 80 targetPort: 80 - name: https nodePort: 31390 port: 443 targetPort: 443 - name: tls port: 15443 targetPort: 15443 replicaCount: 1 secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs serviceAnnotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small serviceType: LoadBalancer
步骤三:在集群中检查入口网关配置
添加证书和私钥挂载卷到入口网关后,入口网关会加载证书与密钥。
- 执行以下命令,验证tls.crt与tls.key已被挂载到入口网关Pod中。
kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-certs
预期输出:
lrwxrwxrwx 1 root root 14 May 9 01:14 tls.crt -> ..data/tls.crt lrwxrwxrwx 1 root root 14 May 9 01:14 tls.key -> ..data/tls.key
- 执行以下命令,检查Ingress gateway证书中的
Subject
字段的正确性。kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- cat /etc/istio/ingressgateway-certs/tls.crt | openssl x509 -text -noout | grep 'Subject:'
预期输出:
Subject: O = cert-manager + O = cluster.local, CN = istio-ingressgateway-certs
- 执行以下命令,检查Ingress gateway的代理能够正确访问证书。
kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- curl 127.0.0.1:15000/certs
预期输出:
{ "certificates": [ { "ca_cert": [ { "path": "\u003cinline\u003e", "serial_number": "4edcf3", "subject_alt_names": [], "days_until_expiration": "7251", "valid_from": "2022-01-06T06:17:00Z", "expiration_time": "2042-01-01T06:22:03Z" } ], ...........
步骤四:验证使用HTTPS协议访问服务是否成功
- 在集群中创建服务。
- 通过kubectl连接ASM。具体操作,请参见通过控制面kubectl访问Istio资源。
- 在ASM中创建网关规则。
- 在ASM中创建虚拟服务。
- 执行以下命令,在集群中获取入口网关服务的地址。
kubectl get svc -n istio-system -l istio=ingressgateway
- 执行以下命令,通过HTTPS协议访问aliyun.com服务。
curl -k -H Host:www.aliyun.com --resolve www.aliyun.com:443:{替换成真实的入口网关IP地址} https://www.aliyun.com
预期输出:
Welcome to aliyun.com!
场景二:使用cert-manager签发DNS域名证书
准备工作
- 已有阿里云域名,且该域名已备案。
- 已在集群中配置Webhook,用于添加DNS记录。您可以使用alidns-webhook配置Webhook。本文通过在集群中执行以下命令,配置Webhook。
https://gitee.com/godu/helminit/raw/master/cert-manager/alidns-cm-webhook.yaml
步骤一:为Webhook创建Secret
- 创建RAM用户。
- 授予RAM用户AliyunDNSFullAccess策略。
- 在用户页面,单击上文创建的RAM用户右侧操作列下的添加权限。
- 在添加权限面板系统策略下,输入AliyunDNSFullAccess,单击AliyunDNSFullAccess,单击确定。
- 授予RAM用户自定义策略。
- 在Base64执行以下命令,为步骤1中的AccessKey ID和AccessKey Secret进行Base64编码。
echo -n <AccessKey ID> | base64
echo -n <AccessKey Secret> | base64
- 在集群中创建Secret。
步骤二:在集群中创建ClusterIssuer和Certificate
- 创建ClusterIssuer。
- 创建Certificate。
步骤三:添加证书和私钥挂载卷到入口网关
- 登录ASM控制台,在左侧导航栏,选择 。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
- 在入口网关页面的目标网关右侧,单击查看YAML。
- 在编辑对话框,添加如下信息到
spec
字段。secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs
添加之后的YAML文件示例如下:
apiVersion: istio.alibabacloud.com/v1beta1 kind: IstioGateway metadata: name: ingressgateway namespace: istio-system spec: clusterIds: - c58638b491a5248669b59609e0a17**** cpu: {} externalTrafficPolicy: Local maxReplicas: 1 minReplicas: 1 ports: - name: status-port port: 15020 targetPort: 15020 - name: http2 nodePort: 31380 port: 80 targetPort: 80 - name: https nodePort: 31390 port: 443 targetPort: 443 - name: tls port: 15443 targetPort: 15443 replicaCount: 1 secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs serviceAnnotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small serviceType: LoadBalancer
步骤四:在集群中检查入口网关配置
- 执行以下命令,验证tls.crt与tls.key已被挂载到入口网关Pod中。
kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/ingressgateway-certs
预期输出:
lrwxrwxrwx 1 root root 14 May 9 01:14 tls.crt -> ..data/tls.crt lrwxrwxrwx 1 root root 14 May 9 01:14 tls.key -> ..data/tls.key
- 执行以下命令,检查Ingress gateway证书中的
Subject
字段的正确性。kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- cat /etc/istio/ingressgateway-certs/tls.crt | openssl x509 -text -noout | grep 'Subject:'
预期输出:
Subject: O = cert-manager + O = cluster.local, CN = istio-ingressgateway-certs
- 执行以下命令,检查Ingress gateway的代理能够正确访问证书。
kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') -- curl 127.0.0.1:15000/certs
预期输出:
{ "certificates": [ { "ca_cert": [ { "path": "\u003cinline\u003e", "serial_number": "4edcf3", "subject_alt_names": [], "days_until_expiration": "7251", "valid_from": "2022-01-06T06:17:00Z", "expiration_time": "2042-01-01T06:22:03Z" } ], ...........
步骤五:验证使用HTTPS协议访问服务是否成功
- 在集群中创建服务。
- 通过kubectl连接ASM。具体操作,请参见通过控制面kubectl访问Istio资源。
- 在ASM中创建网关规则。
- 在ASM中创建虚拟服务。
- 在浏览器中输入域名,例如example.com。返回以下页面,说明使用HTTPS协议访问服务成功。