Repo to collect the things I do to practice with Istio.
This guide is written with the assumption that the reader already understands and uses Docker and Kubernetes.
The guide has been developed using Linux and MacOS. Not so sure about Windows. Your mileage may vary.
This guide uses a kubernetes cluster in AWS EKS. For a version that uses your local dev machine, go here
You need the following tools installed. Links have been provided to documentation on how to install them.
git clone https://github.com/RothAndrew/istio-practice.git
cd istio-practice
Note: This requires real money and access to an AWS account where you can provision resources. It will create a VPC, subnets, the cluster, EC2 resources, and IAM resources. See main.tf for full details.
Make sure your AWS CLI is configured to point at the right profile. aws sts get-caller-identity
without specifying a profile should point to where you want to deploy to.
cd eks
terraform init
terraform apply
If you get Error running command 'curl ...'
, just rerun terraform apply
, the script that waits for the cluster to come up timed out.
Next, generate a kubeconfig context
aws eks update-kubeconfig --name "istio-practice-test-eks-cluster" --alias "istio-practice"
Your kubectl context should automatically switch. Run kubectl get nodes
to be sure.
-
Install the operator
istioctl operator init
-
Install the Istio
demo
configuration profilekubectl create ns istio-system kubectl apply -f - <<EOF apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: istio-system name: example-istiocontrolplane spec: profile: demo EOF
-
Deploy the app
kubectl create ns bookinfo kubectl label ns bookinfo "istio-injection=enabled" kubectl -n bookinfo apply -f "https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml"
-
Create a Gateway and VirtualService
kubectl -n bookinfo apply -f "https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/networking/bookinfo-gateway.yaml"
-
Ensure the app is reachable from the internet by going to
http://<YourELBUrl>/productpage
. Use the Elastic Load Balancer URL associated with theistio-ingressgateway
service. -
Refresh the page a few times. Notice that the stars ratings change from black to red and disappear. This is because there are 3 versions of the "reviews" service. Later we will use destination rules to fix that.
-
Delete the Gateway and VirtualService. We will create a new one once we have enabled HTTPS.
kubectl -n bookinfo delete -f "https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/networking/bookinfo-gateway.yaml"
To force mTLS cluster-wide for all services managed in the istio mesh, run
kubectl apply -n istio-system -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
name: "default"
spec:
mtls:
mode: STRICT
EOF
Next, let's configure Istio to accept HTTPS traffic, and to redirect all HTTP traffic to HTTPS.
-
Update istio's configuration to turn on SDS and HTTPS
kubectl apply -f - <<EOF apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: istio-system name: example-istiocontrolplane spec: profile: demo values: gateways: istio-ingressgateway: sds: enabled: true global: k8sIngress: enabled: true enableHttps: true gatewayName: ingressgateway EOF
-
Modify the Gateway
istio-autogenerated-k8s-ingress
to use STS and to redirect all HTTP traffic to HTTPSkubectl -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"}},{"op": "replace", "path": "/spec/servers/0/tls", "value": {"httpsRedirect": true}}]'
-
Install
cert-manager
arkade install cert-manager
-
Create a Route53 Record Set that points at the Elastic Load Balancer that got created for Istio's IngressGateway.
-
Create the ClusterIssuers for cert-manager
[email protected] kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1alpha2 kind: ClusterIssuer metadata: name: letsencrypt-staging namespace: istio-system spec: acme: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: "$EMAIL_ADDRESS" # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: istio --- apiVersion: cert-manager.io/v1alpha2 kind: ClusterIssuer metadata: name: letsencrypt-prod namespace: istio-system spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: "$EMAIL_ADDRESS" # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: istio EOF
-
Create a Certificate
INGRESS_DOMAIN=foo.example.com kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1alpha2 kind: Certificate metadata: name: ingress-cert namespace: istio-system spec: secretName: ingress-cert issuerRef: name: letsencrypt-staging kind: ClusterIssuer commonName: $INGRESS_DOMAIN dnsNames: - $INGRESS_DOMAIN EOF
If you want the
istio-autogenerated-k8s-ingress
Gateway to accept HTTPS traffice for multiple FQDNs, Add more FQDNs to thednsNames
property in the Certificate -
Create a new VirtualService that uses the correct DNS name
kubectl apply -n bookinfo -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - $INGRESS_DOMAIN gateways: - istio-autogenerated-k8s-ingress.istio-system.svc.cluster.local http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080 EOF
-
Navigate to https://$INGRESS_DOMAIN/productpage. You should get the product page with a good HTTPS cert if you used
letsencrypt-prod
, or an untrusted one signed by "Fake LE" if you usedletsencrypt-staging
ClusterIssuer -
Navigate to http://$INGRESS_DOMAIN/productpage. Verify that it automatically redirects you to HTTPS.
-
Delete the Terraform resources
cd eks terraform destroy
-
Delete the leftover Elastic Load Balancer in AWS EC2
-
Delete the Route53 Record Set(s) that you created