Problems with Istio Ingress and Cert-Manager

Hi, I found that if you create the Ingress last, there is no need to delete and re-create it. The complete, working instructions are below.

# Digital Ocean Kubernetes v1.16.6 cluster - 3 nodes x 2vCPUs 4GB RAM each - total 6vCPUs 12GB RAM.
# (Set it to autoscale under "Nodes" to min 3, max 8 nodes just in case)

# Install Istio per the instructions here https://istio.io/docs/tasks/traffic-management/ingress/ingress-certmgr/
$ istioctl manifest apply \
  --set values.gateways.istio-ingressgateway.sds.enabled=true \
  --set values.global.k8sIngress.enabled=true \
  --set values.global.k8sIngress.enableHttps=true \
  --set values.global.k8sIngress.gatewayName=ingressgateway
  
# Wait until all Istio pods are ready...
$ kubectl get pods -n istio-system

# Wait a few minutes for the LoadBalancer which was created by the 
# Istio install to be ready and show 3/3 pods.
# Create a DNS A record that points to the load balancer external IP - like host.example.com

# Set the $INGRESS_DOMAIN environment variable equal to the hostname of your cluster you 
# created the DNS A record earlier.
$ INGRESS_DOMAIN=host.example.com

# Install Cert-Manager 0.13.0
$ kubectl create namespace cert-manager
$ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.13.0/cert-manager.yaml

# Wait for all 3 cert-manager pods to be running
$ kubectl get pods -n cert-manager

# Patch the Istio Gateway per the instructions.
$ kubectl -n istio-system \
  patch gateway istio-autogenerated-k8s-ingress --type=json \
  -p='[{"op": "replace", "path": "/spec/servers/1/tls", "value": {"credentialName": "ingress-cert", "mode": "SIMPLE", "privateKey": "sds", "serverCertificate": "sds"}}]'

# Now RESTART ISTIO and CERT-MANAGER or else they won't be able to resolve your new DNS entry.
# First, restart Istio

$ kubectl delete pods --all -n istio-system

# Wait and confirm that Istio is all up and running 
$ kubectl get pods -n istio-system

# Restart Cert Manager
$ kubectl delete pods --all -n cert-manager

# Wait until Cert Manager is all back up and running again
$ kubectl get pods -n cert-manager

# Setup the helloworld application. Note this uses the $INGRESS_DOMAIN variable.
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: helloworld
  labels:
    app: helloworld
spec:
  ports:
  - port: 5000
    name: http
  selector:
    app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld
spec:
  selector:
    matchLabels:
      app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
      - name: helloworld
        image: istio/examples-helloworld-v1
        resources:
          requests:
            cpu: "100m"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5000
---
EOF

# Create the Cluster Issuer.  Update the email address to your email address.
$ cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: admin@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: istio-ingressgateway-certs
    solvers:
      - http01:
          ingress:
            class: istio
---
EOF

# Wait for helloworld to be ready
$ kubectl get pods

# Create the certificate.
$ cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
  name: ingress-cert
  namespace: istio-system
spec:
  secretName: ingress-cert
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: 'host.example.com'
  dnsNames:
    - 'host.example.com'
---
EOF

# Create the Ingress.
$ cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: istio
  name: helloworld-ingress
spec:
  rules:
    - host: "$INGRESS_DOMAIN"
      http:
        paths:
          - path: /hello
            backend:
              serviceName: helloworld
              servicePort: 5000
---
EOF

# Wait for the certificate to be ready:
$ kubectl -n istio-system describe certificate ingress-cert 

# Wait for the Certificate Request (the cert id comes from the output of the above command)
$ kubectl -n istio-system describe certificaterequest ingress-cert-4051514424 

# Wait for the Certificate Order (The order id comes from output of the above command)
$ kubectl -n istio-system describe order ingress-cert-4051514424-3229718444 

# Wait for the challenge (the challenge id comes from the output of the above command)
$ kubectl -n istio-system describe challenge ingress-cert-4051514424-3229718444-3565931193
1 Like