Istio is a service mesh for your microservices, which is designed for observability, routing, and resilience to traffic. It secures both north-south traffic and east-west traffic. North-south traffic is traffic entering (ingress) and exiting (egress) the service mesh. Istio handles north-south traffic through ingress and egress gateways, and traffic routing is managed by virtual services.
East-west traffic is traffic within the mesh, typically service-to-service. Istio’ s Envoy proxy manages east-west traffic, running as a sidecar in the Kubernetes pod of the service it is protecting.
There are two types of authentication provided by Istio.
- Peer Authentication
For service-to-service authentication.
- Request Authentication
For end-user authentication. Using JSON Web Tokens (JWT)
In this article we will be exploring Istio peer authentication .
- Cluster Environment created with EKS or KOPS
- Kubectl installed
- Istio installed
- Need Public key to access the cluster nodes
The above diagram depicts the workflow of our sample microservice.
Deploy application into four different namespaces namely istio-servicea, istio-serviceb, servicec and istio-serviced.
* istio-servicea→ pods with manually injected istio sidecars
* istio-serviceb → pods with manually injected istio sidecars
* servicec → pods with no istio sidecar
* istio-serviced→ pods with manually injected istio sidecars
service-b,service-c,service-d running on different namespaces invoke service-a running on istio-servicea namespace.
Also service-e running on different namespaces invoke welcome-app running on istio-servicea namespace.
kubectl create ns istio-servicea
kubectl create ns istio-serviceb
kubectl create ns servicec
kubectl create ns istio-serviced
kubectl get namespaces
Verify that Namespace is created properly by executing the following command.
Side Car Injection
This will instruct Istio to automatically inject Envoy proxy when we deploy our application in the same namespace.
kubectl label namespace istio-servicea istio-injection=enabled
kubectl label namespace istio-serviceb istio-injection=enabled
kubectl label namespace istio-serviced istio-injection=enabled
kubectl create -f serviceaccount.yaml
kubectl create -f service-a.yaml
kubectl create -f welcome-app.yaml
kubectl create -f service-b.yaml
kubectl create -f service-c.yaml
kubectl create -f service-d.yaml
kubectl create -f service-e.yaml
kubectl create -f serviced-ns-istio-serviceb.yaml
kubectl create -f servicee-ns-servicec.yaml
# The YAML files required for this setup is available in the GitHUB repository
#You need to run the kubectl commands from within the folder where YAML files are present.
Or else please do provide the appropriate folder path while running the kubectl commands.
After deploying the application, we can see that Istio has added a sidecar for every pod created.
To get the details of the container run the following command.
kubectl describe pod podname -n namespace
kubectl describe pod service-a-58479bc7bd-vf4mz -n istio-servicea
Now we will be able to see both application container as well as proxy container in our pod.
Before Peer Authentication
Both sidecar enabled and sidecar not enabled services can access all services where sidecar is enabled.
We used ClusterIP which is the simplest type, and default one in kubernetes cluster.
ClusterIP will not enable the application to be accessed from internet. So to run the application we need to login to the particular node where service is being deployed.
Use the public key to connect to the EKS cluster node and access the application using curl command as shown below.
Policy to allow mTLS traffic for all workloads under namespace istio-servicea.
kubectl create -f mtlspolicy.yaml
kubectl get peerauthentication.security.istio.io/default -n istio-servicea
Note: mTLS STRICT mode is enabled globally, for namespace istio-servicea.
Since servicec namespace has no sidecar, plain text is sent which is rejected by namespace istio-servicea.
Policies to allow both mTLS & plaintext traffic for all workloads under namespace istio-servicea, but require mTLS for workload service-a.
kubectl create -f peer.yaml
Note: mTLS STRICT mode is enabled globally, for workload service-a running on namespace istio-servicea.
Except service-a all other workload running on this namespace can be accessed by both sidecar enabled and sidecar not enabled services running
on different namespaces.
Istio Authorization Policy enables access control on workloads in the mesh.
In our example, we have 2 services namely service-b and service-d running on namespace istio-service-b where side car is injected.
Both services can access service-a running on namespace istio-service-a where side car is enabled. In certain cases, we need particular service can access our workload, but all other services should not.
For that we need to enable Istio Authorization Policy .
In our case we allows requests from
service account “cluster.local/ns/istio-serviceb/sa/auth-test-sa”
to access the workload with “GET” method.
kubectl create -f peer.yaml
kubectl create -f AuthorizationPolicy.yaml
kubectl get authorizationpolicy -n istio-servicea
Specify service account in your deployment yaml file under spec section.
We have now successfully enabled Istio PeerAuthentication for our application , we will see how to implement Request Authentication for external request in next article.