Kubernetes: Istio + Cert-Manager + GKE


Install Cert-Manager

If you haven’t already, install Cert-Manager.

Enable Istio in GKE

Verify

{
  kubectl get service -n istio-system
  kubectl get pods -n istio-system
}

Enable Istio on namespace

kubectl label ns itsmetommy istio-injection=enabled

Create Certificate

cat <<EOF > itsmetommy-certificate.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: itsmetommy-yourdomain-com-tls
  namespace: istio-system
spec:
  secretName: itsmetommy-yourdomain-com-tls
  commonName: '*.itsmetommy.yourdomain.com'
  issuerRef:
    name: acme-clusterissuer
    kind: ClusterIssuer
EOF

Apply.

kubectl apply -f itsmetommy-certificate.yaml

Describe and get.

{
  kubectl describe certificate itsmetommy-yourdomain-com-tls -n istio-system
  kubectl get secret itsmetommy-yourdomain-com-tls -n istio-system
}

Update istio-ingressgateway

Update the istio-ingressgateway deployment within the istio-system namespace with a new VolumeMount and volume. Once edited, the istio-ingressgateway pods will automatically update.

kubectl edit deployment istio-ingressgateway -n istio-system
        volumeMounts:
        - mountPath: /etc/istio/itsmetommy-yourdomain-com-tls
          name: itsmetommy-yourdomain-com-tls
...
      volumes:
      - name: itsmetommy-yourdomain-com-tls
        secret:
          defaultMode: 420
          optional: true
          secretName: itsmetommy-yourdomain-com-tls

Enable Istio on namespace

kubectl label namespace itsmetommy istio-injection=enabled

Create deployment and service

Create.

kubectl create deployment nginx --image=nginx -n itsmetommy

Expose.

kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort -n itsmetommy

Create Gateway & VirtualService

The Gateway and VirtualService need to be in the same namespace.

Create Gateway.

cat <<EOF > itsmetommy-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: itsmetommy-gateway
  namespace: itsmetommy
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*.itsmetommy.yourdomain.com"
    tls:
      httpsRedirect: true # sends 301 redirect for http requests
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*.itsmetommy.yourdomain.com"
    tls:
      mode: SIMPLE # enables HTTPS on this port
      serverCertificate: /etc/istio/itsmetommy-yourdomain-com-tls/tls.crt
      privateKey: /etc/istio/itsmetommy-yourdomain-com-tls/tls.key
EOF

Apply.

kubectl apply -f itsmetommy-gateway.yaml

Create VirtualService.

cat <<EOF > itsmetommy-virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: itsmetommy-virtualservice
  namespace: itsmetommy
spec:
  gateways:
  - itsmetommy-gateway
  hosts:
  - istio.itsmetommy.yourdomain.com
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: nginx
        port:
          number: 80
EOF

Apply.

kubectl apply -f itsmetommy-virtualservice.yaml

View VirtualService

kubectl get virtualservices -n itsmetommy

Add DNS

Add a-record *.itsmetommy.yourdomain.com.

kubectl get svc istio-ingressgateway -n istio-system | awk '{print $4}' | tail -1