Configure SSL certificates in kubernetes with cert-manager istio ingress and LetsEncrypt

3/5/2019

I'm trying to configure SSL certificates in kubernetes with cert-manager, istio ingress and LetsEncrypt. I have installed istio with helm, cert-manager, created ClusterIssuer and then I'm trying to create a Certificate. The acme challenge can't be validated, i'm trying to do it with http01 and can't figure it out how to use istio ingress for this. Istio is deployed with following options:

helm install --name istio install/kubernetes/helm/istio `
--namespace istio-system `
--set global.controlPlaneSecurityEnabled=true `
--set grafana.enabled=true`
--set tracing.enabled=true 
--set kiali.enabled=true `
--set ingress.enabled=true

Certificate configuration:

apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: example.com
  namespace: istio-system
spec:
  secretName: example.com
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
  commonName: 'example.com'
  dnsNames:
  - example.com
  acme:
    config:
    - http01:
        ingress: istio-ingress
      domains:
      - example.com

When trying this way, for some reason, istio-ingress can't be found, but when trying to specify ingressClass: some-name, instead of ingress: istio-ingress, I get 404 because example.com/.well-known/acme-challenge/token can't be reached. How can this be solved? Thank you!

-- Raducu Ilie Radu
cert-manager
istio
kubernetes
kubernetes-ingress
ssl

2 Answers

3/6/2019

Istio ingress has been deprecated, you can use the Ingress Gateway with the DNS challenge.

Define a generic public ingress gateway:

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

Create an issuer using one of the DNS providers supported by cert-manager. Here is the config for GCP CloudDNS:

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@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    dns01:
      providers:
      - name: cloud-dns
        clouddns:
          serviceAccountSecretRef:
            name: cert-manager-credentials
            key: gcp-dns-admin.json
          project: my-gcp-project

Create a wildcard cert with:

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"

It takes of couple of minutes for cert-manager to issue the cert:

kubectl -n istio-system describe certificate istio-gateway

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

You can find a step-by-step guide on setting up Istio ingress on GKE with Let's Encrypt here https://docs.flagger.app/install/flagger-install-on-google-cloud#cloud-dns-setup

-- Stefan P.
Source: StackOverflow

3/13/2019

The solution was to move DNS to azure and use dns validation for generating the certificate. I also used istio-1.1.0-rc.3 and configured the gateway in the following way:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mygateway
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - hosts:
    - 'mydomain.com'
    port:
      name: http-bookinfo
      number: 80
      protocol: HTTP
    tls:
      httpsRedirect: true
  - hosts:
    - 'mydomain.com'
    port:
      name: https-bookinfo
      number: 443
      protocol: HTTPS
    tls:      
      mode: SIMPLE
      serverCertificate: "use sds" #random string, because serverCertificate and 
      #privateKey are required for tls.mode=SIMPLE
      privateKey: "use sds" 
      credentialName: "istio-bookinfo-certs-staging" #this must match the secret name 
      #from the certificate

In order to work enable SDS at ingress gateway:

helm template install/kubernetes/helm/istio/ --name istio `
--namespace istio-system -x charts/gateways/templates/deployment.yaml `
--set gateways.istio-egressgateway.enabled=false `
--set gateways.istio-ingressgateway.sds.enabled=true > `
$HOME/istio-ingressgateway.yaml

 kubectl apply -f $HOME/istio-ingressgateway.yaml
-- Raducu Ilie Radu
Source: StackOverflow