Start from a minimal installation of Ubuntu Server 22.04.
In this case, I've set up a VM with two network interfaces, one NAT for connection to the internet, and one bridged network interface to connect from the host to the guest VM.
The Netplan configuration in /etc/netplan looks like this:
network:
ethernets:
enp1s0:
dhcp4: true
enp7s0:
dhcp4: false
addresses:
- 192.168.122.10/24
routes:
- to: 192.168.122.0/24
via: 192.168.122.1
metric: 200
version: 2After making changes to the YML configuration, apply the changes with sudo netplan apply.
We are going to use MicroK8s from Canonical as our Kubernetes distribution. It can be installed as a snap package.
sudo snap install microk8s --classicMicroK8s bundles its own version of kubectl. You can run it through MicroK8s using microk8s kubectl. To avoid having to prefix all kubectl commands with microk8s, you can create an alias like this:
sudo snap alias microk8s.kubectl kubectlOnly users in the microk8s group can access the Kubernetes cluster using kubectl, so to avoid having to use sudo, add yourself to the group.
sudo usermod -aG microk8s $(whoami)Enable DNS in the Kubernetes cluster. In MicroK8s, this is very simple:
microk8s enable dnsWe can enable Istio in a similar fashion.
microk8s enable community
microk8s enable istioThis will deploy the Istio control plane in the istio-system namespace.
To visualise the traffic sent between pods, you can use Kiali. Kiali requires Prometheus to be deployed in the istio-system namespace to work out of the box. The easiest way to get it to work is to use the sample deployment files provided by Istio.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/kiali.yamlTo make the Kiali dashboard accessible from the host, replace the ClusterIP service with a NodePort service like this:
$ kubectl patch svc kiali -n istio-system --type='json' -p '[{"op":"replace","path":"/spec/type","value":"NodePort"}]'
$ kubectl get svc -n demo istio-system -l app=kiali
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kiali NodePort 10.152.183.38 <none> 20001:<NodePort>/TCP,9090:30423/TCP 6h28mThe Kiali dashboard should now be available in the browser from the host on the port <NodePort>.
Create a namespace called demo and enable injection of the Envoy sidecar for all pods started in this namespace.
kubectl create namespace demo
kubectl label namespace demo istio-injection=enabledDeploy the Bookinfo sample application provided on Istio's website.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/bookinfo/platform/kube/bookinfo.yaml -n demoBy default, Istio enables, but does not enforce mutual TLS authentication (mTLS) between pods.
To enforce mTLS for a particular namespace, set a PeerAuthentication policy:
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "test-mtls"
namespace: "demo"
spec:
mtls:
mode: STRICT
EOFIf you list the containers in one of the pods we deployed in the demo namespace, for example the pod hosting the product page, you can see that Istio has injected an Envoy proxy (istio-proxy) as a sidecar.
istioctl provides a command for describing a pod, which shows the containers inside the pod as well as the active PeerAuthenticationPolicy for that pod.
$ microk8s istioctl experimental describe pod $(kubectl get pod -n demo -l app=productpage -o jsonpath='{.items[0].metadata.name}') -n demo
Pod: productpage-v1-d4f8dfd97-54kgk
Pod Revision: default
Pod Ports: 9080 (productpage), 15090 (istio-proxy)
--------------------
Service: productpage
Port: http 9080/HTTP targets pod port 9080
--------------------
Effective PeerAuthentication:
Workload mTLS mode: STRICT
Applied PeerAuthentication:
test-mtls.demoSend an HTTP GET request to the Bookinfo product page to be able to see something interesting in Kiali.
We can do this by running curl inside the ratings container.
$ kubectl exec "$(kubectl get pod -n demo -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -n demo -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>In the Kiali dashboard, follow these steps to check the security status of the request you made in the previous step:
- Click on Graph in the menu on the left.
- Choose the demo namespace in the Namespace dropdown.
- Enable the Security option in the Display dropdown.
You should now see a graph where the edges are labelled with locks, as shown in the screenshot below. This means that the traffic between the pods was encrypted using TLS.
By default, Istio creates its own self-signed X.509 CA certificate which it uses to sign the TLS certificates for pods.
The TLS certificate is issued to the Envoy proxy and used to authenticate pods to each other, and contains a SPIFFE identifier in the SAN extension which uniquely identifies a pod in the cluster.
To inspect the certificate, we can run OpenSSL in the istio-proxy sidecar and connect to the main container using openssl s_client.
$ kubectl exec "$(kubectl get pod -n demo -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -n demo -c istio-proxy -- openssl s_client -showcerts -connect productpage:9080 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' | openssl x509 -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
69:09:36:3b:80:c3:1c:d6:40:66:ab:4c:33:f4:69:a7
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = cluster.local
Validity
Not Before: Feb 14 12:24:26 2023 GMT
Not After : Feb 15 12:26:26 2023 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
<snip>
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
8E:F6:7C:D4:C8:A4:A7:87:95:45:64:D7:0E:03:E3:81:A6:BE:6B:15
X509v3 Subject Alternative Name: critical
URI:spiffe://cluster.local/ns/demo/sa/bookinfo-productpage
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
<snip>Delete the demo namespace to remove the Bookinfo sample application.
kubectl delete ns demoIf you don't want to use Istio further, remove the istio-system namespace as well.
kubectl delete ns istio-system
Thank you great job works out of the box