cert-manager is a certificate lifecycle management system that can be used to issue and deploy certificates. You can use cert-manager to issue certificates for Service Mesh (ASM) gateways. This way, you can use the ASM gateways to access services over HTTPS. This ensures data transmission security. This topic describes how to use cert-manager to manage certificates for ASM gateways.
Background information
cert-manager allows you to issue self-signed certificates and DNS certificates. You can load the certificates on ASM gateways and use the ASM gateways to access services over HTTPS. The two types of certificates have the following differences:
Self-signed certificate: Self-signed certificates can be used only for encryption. They cannot be used for authentication. You can use an ASM gateway on which a self-signed certificate is loaded to access services over HTTPS in command-line tools. However, a self-signed certificate is not trusted by web browsers. A web browser marks HTTPS connections that use a self-signed certificate and displays an error message indicating that the connections have potential risks. Therefore, you cannot use an ASM gateway on which a self-signed certificate is loaded to access services over HTTPS in web browsers.
DNS certificate: DNS certificates are issued by Certificate Authorities (CAs) and can be used for both encryption and authentication. Compared with self-signed certificates, DNS certificates provide higher security and are trusted by web browsers. You can use an ASM gateway on which a DNS certificate is loaded to access services over HTTPS in both command-line tools and web browsers.
If an error occurs when you use cert-manager, you can visit cert-manager > Issues on GitHub, handle the issue on your own by referring to the relevant cases, or join the DingTalk group 30421250 for consultation.
Install cert-manager in your cluster
Install Helm on your computer. For more information, see Helm.
Use kubectl to connect to your cluster. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.
Run the following command to create the cert-manager namespace:
kubectl create namespace cert-manager
Run the following command to add the cert-manager chart:
helm repo add jetstack https://charts.jetstack.io
Run the following command to obtain the latest information about the cert-manager chart:
helm repo update
Run the following command to install cert-manager:
NoteThe version of cert-manager must be compatible with the Kubernetes version. For more information about the mapping between cert-manager versions and Kubernetes versions, see Supported Releases.
helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --version v1.1.0 \ --set installCRDs=true
Use cert-manager to issue a self-signed certificate
Step 1: Create a self-signed certificate in your cluster
Create an issuer.yaml file that contains the following content:
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
Run the following command to create a self-signed CA and issue a certificate for workloads:
kubectl apply -f issuer.yaml -n istio-system
Run the following command to view the certificate:
kubectl get secret -n istio-system
Expected output:
NAME TYPE DATA AGE istio-ingressgateway-certs kubernetes.io/tls 3 68m
Step 2: Create a volume that is mounted with the certificate and private key on an ingress gateway
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
On the Ingress Gateway page, find the ingress gateway and click YAML.
In the Edit dialog box, add the following content to the
spec
field.secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs
The following code provides an example of an edited YAML file:
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
Step 3: Check the configurations of the ingress gateway in the cluster
After you create a volume that is mounted with the certificate and private key on an ingress gateway, the ingress gateway loads the certificate and private key.
Run the following command to check whether the tls.crt and tls.key files are loaded in the ingress gateway 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
Expected output:
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
Run the following command to check whether the value of the
Subject
field is correct in the certificate loaded on the ingress gateway: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:'
Expected output:
Subject: O = cert-manager + O = cluster.local, CN = istio-ingressgateway-certs
Run the following command to check whether the proxy of the ingress gateway can access the certificate:
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
Expected output:
{ "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" } ], ...........
Step 4: Verify that you can access a service over HTTPS
Create a service in the cluster.
Create a myexample-nginx.conf file that contains the following content.
In this example, a service whose domain name is aliyun.com is implemented based on NGINX. You need to create a configuration file for the NGINX server. The following content specifies that the message
Welcome to aliyun.com!
and the status code200
are returned for requests to the root path of the service.events { } http { log_format main '$remote_addr - $remote_user [$time_local] $status ' '"$request" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; server { listen 80; location / { return 200 'Welcome to aliyun.com!'; add_header Content-Type text/plain; } } }
Run the following command to create a ConfigMap for the NGINX server:
kubectl create configmap myexample-nginx-configmap --from-file=nginx.conf=./myexample-nginx.conf
Run the following command to enable automatic sidecar proxy injection for the default namespace:
kubectl label namespace default istio-injection=enabled
Create a myexampleapp.yaml file that contains the following content:
apiVersion: v1 kind: Service metadata: name: myexampleapp labels: app: myexampleapp spec: ports: - port: 80 protocol: TCP selector: app: myexampleapp --- apiVersion: apps/v1 kind: Deployment metadata: name: myexampleapp spec: selector: matchLabels: app: myexampleapp replicas: 1 template: metadata: labels: app: myexampleapp spec: containers: - name: nginx image: nginx ports: - containerPort: 80 volumeMounts: - name: nginx-config mountPath: /etc/nginx readOnly: true volumes: - name: nginx-config configMap: name: myexample-nginx-configmap
Run the following command to create the myexampleapp service whose domain name is aliyun.com:
kubectl apply -f myexampleapp.yaml
Use kubectl to connect to your ASM instance. For more information, see Use kubectl on the control plane to access Istio resources.
Create an Istio gateway in the ASM instance.
Create an istio-myexample-customingressgateway.yaml file that contains the following content:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-myexample-customingressgateway spec: selector: istio: ingressgateway servers: - hosts: - '*.aliyun.com' port: name: http number: 80 protocol: HTTP tls: httpsRedirect: true - hosts: - '*.aliyun.com' port: name: https number: 443 protocol: HTTPS tls: mode: SIMPLE privateKey: /etc/istio/ingressgateway-certs/tls.key serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
Run the following command to create an Istio gateway:
kubectl apply -f istio-myexample-customingressgateway.yaml
Create a virtual service in the ASM instance.
Create an istio-myexample-customvirtualservice.yaml file that contains the following content:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: istio-myexample-customvirtualservice spec: hosts: - "www.aliyun.com" gateways: - istio-myexample-customingressgateway http: - route: - destination: host: myexampleapp.default.svc.cluster.local port: number: 80
Run the following command to create a virtual service:
kubectl apply -f istio-myexample-customvirtualservice.yaml
Run the following command to obtain the IP address of the ingress gateway in the cluster:
kubectl get svc -n istio-system -l istio=ingressgateway
Run the following command to access aliyun.com over HTTPS:
curl -k -H Host:www.aliyun.com --resolve www.aliyun.com:443:{IP address of the ingress gateway} https://www.aliyun.com
Expected output:
Welcome to aliyun.com!