Set up certificates for ingress gateways in Istio using cert-manager ACME Issuer

This article will take the Bookinfo application as an example to set a real TLS/SSL certificate for the Istio ingress gateway. We will use Let’s Encrypt, cert-manager to manage certificates for the ingress gateway in Istio.

Prepare

Please refer to the Istio documentation first
Install Istio and Bookinfo application
, I installed Istio 1.16 in GKE.

The version information of each component installed in this article is as follows:

  • Kubernetes 1.24.7
  • Istio 1.16
  • Gateway API 0.5.1
  • cert-manager 1.10.1

architecture

The following key components are included in this lab:

  • Use Cloudflare to provide DNS resolution
  • Create a certificate using Let’s Encrypt
  • Use cert-manager to automatically apply for and renew certificates
  • Use the Gateway API to create an ingress gateway
  • All components are deployed in GKE

Figure 1 shows the architecture of this experiment and the traffic routing process.

image

Figure 1: Istio ingress gateway certificate mount mode

The traffic routing process is as follows:

  1. After the Gateway is created, expose the gateway IP through LoadBalancer, and configure the IP in the DNS resolution record;
  2. Gateway references ACME Issuer through annotations
    ;
  3. ACME Issuer sends request certificate to cert-manager (order and challenge
    ), and use the DNS01 Challenge Provider
    ;
  4. cert-manager requests a certificate from the ACME server Let’s Encrypt and creates a Kubernetes Secret;
  5. Mount the TLS certificate through the application Secret in the Gateway;
  6. HTTPRoute routes ingress traffic to the productpage service;

ACME Issuer

Istio includes mTLS support out of the box, you can also use a custom CA
or SPIRE
To manage the certificates in the cluster, but for the certificate of the ingress gateway, we need to set it separately. You can manually configure certificates for the ingress gateway
, but it will be more troublesome to manage, because you need to be responsible for the rotation of the certificate to prevent the certificate from expiring, or use Let’s Encrypt
Such ACME Issuer to automate certificate management.

ACME (Automated Certificate Management Environment) Issuer is a certification authority that can use the ACME protocol to apply for and manage certificates for clients. ACME is an open protocol for automating SSL/TLS certificate issuance and management. It is commonly used in certificate management for websites or other online services to ensure secure connections.

Let’s Encrypt is a non-profit ACME Issuer that provides free SSL/TLS certificates for websites. Its goal is to democratize encryption and help improve cybersecurity. Let’s Encrypt uses the ACME protocol to communicate with the client, and can apply for and manage certificates for the client. The ACME protocol is open, so any organization can become an ACME Issuer as long as they comply with the ACME protocol.

detailed steps

  1. Install the Gateway API:

     kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.1/standard-install.yaml
  2. Install cert-manager

     kubectl apply -f https://gist.githubusercontent.com/rootsongjc/78487acdea70a3c27c1a1b794546d031/raw/0df08b91dfaff6412bbd891ccedffaa882a9a99f/cert-manager.yaml

    It adds the following startup items for cert-manager Deployment:

     args: - --feature-gates = ExperimentalGatewayAPISupport = true
  3. at cloudflare
    Create an API token called lets-encrypt-token in , and set the custom template as follows:

    Permissions:

    • Zone - DNS - Edit
    • Zone - Zone - Read

    Zone Resources:

    • Include - All Zones

    Store the token in a Secret:

     kubectl apply -n default -f - <<EOF  
    apiVersion : v1  
    kind : Secret  
    metadata :  
      name : cloudflare-api-token-secret  
      namespace : istio-system  
    type : Opaque  
    stringData :  
      api-token : <API Token>  
    EOF  
    
    Notice
    In this experiment, the Token does not actually play a role. Normally, cert-manager will interact with Cloudflare through the Cloudflare API to configure DNS records for us. This issue needs further investigation.
  4. Configure Let’s Encrypt Issuer:

     kubectl apply -n default -f - <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt spec: acme: email: [email protected] server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: lets-encrypt-issuer-account-key solvers: - dns01: cloudflare: apiTokenSecretRef: name: cloudflare-api-token-secret key: api-token selector: dnsNames: - 'bookinfo.jimmysong.io' EOF
  5. Configure Gateway:

     kubectl apply -n default -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway annotations: cert-manager.io/issuer: letsencrypt spec: gatewayClassName: istio listeners: - name: http hostname: bookinfo.jimmysong.io port: 443 protocol: HTTPS allowedRoutes: namespaces: from: Same tls: mode: Terminate certificateRefs: kind: Secret group: "" name: bookinfo-tls EOF

    After the Gateway is created, a Gateway Pod and a LoadBalancer resource service will be created in the default namespace.

    Check the Secret in the default namespace, you will find bookinfo-tls , which was created by cert-manager, check the certificate saved in the Secret, you will see the certificate trust chain issued by Let’s Encrypt:

    • bookinfo.jimmysong.io
    • ISRG Root X1
    • DST Root CA X3
  6. Configure HTTPRoute:

     kubectl apply -n default -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: bookinfo spec: parentRefs: - name: bookinfo-gateway rules: - matches: - path: type: Exact value: /productpage - path: type: PathPrefix value: /static - path: type: Exact value: /login - path: type: Exact value: /logout - path: type: PathPrefix value: /api/v1/products backendRefs: - name: productpage port: 9080 EOF
  7. Configure domain name records in Cloudflare: Add the external network IP of the gateway service and the domain name bookinfo.jimmysong.io to the DNS records of Cloudflare to realize domain name resolution.

    Notice
    In this experiment, it is found that the gateway Pod does not mount the certificate in bookinfo-tls Secret, so we have to configure the TLS certificate through Cloudflare: enable full (strict) SSL/TLS for the website, which will use the TLS certificate issued by Cloudflare.
  8. Visit https://bookinfo.jimmysong.io/productpage in your browser
    You can access the bookinfo application.

Summarize

Although this experiment implements the TLS encryption of the gateway and generates a TLS certificate for the gateway, the gateway actually uses a certificate issued by Cloudflare. This is not our original goal, which is to use ACME Server (Let’s Encrypt) issued certificates for gateways. Why the Gateway Pod did not mount the certificate in the Secret of our application, and why the Cloudflare DNS01 Challenge Provider did not take effect, these two issues require further investigation.

refer to

This article is transferred from https://jimmysong.io/blog/secure-ingress-gateway-of-istio/
This site is only for collection, and the copyright belongs to the original author.