Skip to content

Latest commit

 

History

History
175 lines (140 loc) · 4.35 KB

05-letsencrypt-setup.md

File metadata and controls

175 lines (140 loc) · 4.35 KB

Configure Istio Gateway with Let's Encrypt wildcard certificate

istio-letsencrypt

Create a Istio Gateway in istio-system namespace with HTTPS redirect:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: public-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
    tls:
      httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

Save the above resource as istio-gateway.yaml and then apply it:

kubectl apply -f ./istio-gateway.yaml

Create a service account with Cloud DNS admin role (replace my-gcp-project with your project ID):

GCP_PROJECT=my-gcp-project

gcloud iam service-accounts create dns-admin \
--display-name=dns-admin \
--project=${GCP_PROJECT}

gcloud iam service-accounts keys create ./gcp-dns-admin.json \
--iam-account=dns-admin@${GCP_PROJECT}.iam.gserviceaccount.com \
--project=${GCP_PROJECT}

gcloud projects add-iam-policy-binding ${GCP_PROJECT} \
--member=serviceAccount:dns-admin@${GCP_PROJECT}.iam.gserviceaccount.com \
--role=roles/dns.admin

Create a Kubernetes secret with the GCP Cloud DNS admin key:

kubectl create secret generic cert-manager-credentials \
--from-file=./gcp-dns-admin.json \
--namespace=istio-system

Install cert-manager's CRDs:

CERT_REPO=https://raw.githubusercontent.com/jetstack/cert-manager

kubectl apply -f ${CERT_REPO}/release-0.7/deploy/manifests/00-crds.yaml

Create the cert-manager namespace and disable resource validation:

kubectl create namespace cert-manager

kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true

Install cert-manager with Helm:

helm repo add jetstack https://charts.jetstack.io && \
helm repo update && \
helm upgrade -i cert-manager \
--namespace cert-manager \
--version v0.7.0 \
jetstack/cert-manager

Create a letsencrypt issuer for CloudDNS (replace [email protected] with a valid email address and my-gcp-project with your project ID):

apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
  name: letsencrypt-prod
  namespace: istio-system
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    dns01:
      providers:
      - name: cloud-dns
        clouddns:
          serviceAccountSecretRef:
            name: cert-manager-credentials
            key: gcp-dns-admin.json
          project: my-gcp-project

Save the above resource as letsencrypt-issuer.yaml and then apply it:

kubectl apply -f ./letsencrypt-issuer.yaml

Create a wildcard certificate (replace example.com with your domain):

apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: istio-gateway
  namespace: istio-system
spec:
  secretName: istio-ingressgateway-certs
  issuerRef:
    name: letsencrypt-prod
  commonName: "*.example.com"
  acme:
    config:
    - dns01:
        provider: cloud-dns
      domains:
      - "*.example.com"
      - "example.com"

Save the above resource as of-cert.yaml and then apply it:

kubectl apply -f ./of-cert.yaml

In a couple of minutes cert-manager should fetch a wildcard certificate from letsencrypt.org:

kubectl -n istio-system describe certificate istio-gateway

Events:
  Type    Reason         Age    From          Message
  ----    ------         ----   ----          -------
  Normal  CertIssued     1m52s  cert-manager  Certificate issued successfully

Recreate Istio ingress gateway pods:

kubectl -n istio-system delete pods -l istio=ingressgateway

Note that Istio gateway doesn't reload the certificates from the TLS secret on cert-manager renewal. Since the GKE cluster is made out of preemptible VMs the gateway pods will be replaced once every 24h, if your not using preemptible nodes then you need to manually kill the gateway pods every two months before the certificate expires.

Next: Expose services outside the service mesh