Kubernetes: Install Istio using Helm with Secret Discovery Service (SDS) + Cert-Manager


Install Cert-Manager

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

Install Istio with SDS using Helm

Add repo and update

Add repo.

helm repo add istio.io https://storage.googleapis.com/istio-release/releases/1.2.6/charts/

Update.

helm repo update

Install CRD

helm install istio.io/istio-init --name istio-init --namespace istio-system

Install Istio

helm install istio.io/istio --name istio \
  --namespace istio-system \
  --set gateways.istio-egressgateway.enabled=false \
  --set gateways.istio-ingressgateway.sds.enabled=true

Verify

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

Enable Istio on namespace

kubectl label 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
}

Create deployment and service

{
  kubectl create deployment nginx --image=nginx -n itsmetommy
  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
      credentialName: itsmetommy-yourdomain-com-tls # fetches certs from kubernetes secret
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