Istio Certified Associate (ICA): Study Notes

Dave Watts
11 min readApr 19, 2024

--

The intent of these study notes was for a brain dump of things I found useful as I was studying and could look back over for revision. Definitely not complete but will be able to complement your study.

Foundational Istio CRDs

A VirtualService in Istio defines how traffic is routed to a set of destination services based on matching criteria such as HTTP paths, headers, or destination hosts, enabling advanced traffic management and control within the service mesh.

A DestinationRule in Istio defines policies that apply to traffic intended for a specific service version, such as load balancing, connection pool settings, outlier detection, and TLS settings, allowing fine-grained control over how traffic is handled by the service.

A ServiceEntry in Istio defines how services located outside the mesh can be accessed and enables them to be treated as if they were part of the mesh, allowing Istio features such as traffic management, security, and monitoring to be applied to external services.

A Gateway in Istio defines a load balancer operating at the edge of the mesh that enables external traffic to enter the mesh and routes traffic to the appropriate services based on rules defined in VirtualServices, allowing external clients to access services within the mesh.

AuthorizationPolicy in Istio enables fine-grained access control for services within the mesh, allowing or denying traffic based on defined rules such as source IP, request headers, and more. It provides a flexible and powerful way to enforce security policies in the service mesh.

PeerAuthentication in Istio configures mutual TLS (mTLS) for secure communication between services, specifying how clients and servers authenticate each other and whether communication is encrypted. It ensures that all traffic within the mesh is secure and authenticated.

RequestAuthentication in Istio is used to configure authentication policies for incoming requests to services within the mesh, specifying how clients are authenticated before accessing a service. It provides security by ensuring that only authenticated clients can access the services, helping to protect against unauthorized access.

Sidecar configuration in Istio defines how the sidecar proxy manages inbound and outbound communication for a workload. It allows fine-tuning of which ports and protocols the proxy accepts for forwarding traffic and can restrict the set of services the proxy can reach for outbound traffic.

The IstioOperator resource is used with the Istio Operator to configure the Istio control plane on Kubernetes. It defines settings like the Istio version, components to install, and customizations. This resource simplifies Istio management by providing a declarative way to define and apply configurations.

Istio Common Terms

TLS origination in Istio involves decrypting incoming TLS traffic at the gateway and forwarding it to services within the mesh in plaintext. This process is configured using Gateway and DestinationRule resources. The Gateway specifies TLS settings for terminating TLS at the gateway, while the DestinationRule specifies traffic policies, including TLS origination settings for services within the mesh. Also see TLS origination through Egress Gateway

Sidenote:httpbin.org is a website that provides HTTP request and response testing. It offers various endpoints that simulate different HTTP methods and behaviours, making it useful for testing and debugging HTTP client implementations.

Very Useful Istio Doco Pages

Prace Resources

  • Killr.sh Scenarios: Many of the examples here are from my solutions after doing the Killer Shell Scanrios.
  • Traffic Management Tasks: Great reference for solutions outside of just looking are a particular CRD from above.
  • Security Tasks: Again great resource of usage of common security tasks.

Istio Installation, Upgrade & Configuration (3) 7%

1. Using the Istio CLI to install a basic cluster

# Force traffic through egress TODO need to check and more details
istioctl install --set profile=demo -y --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
# Egress: Istio Documentation. Talks about allowing meshConfig.outboundTrafficPolicy.mode set to either ALLOW_ANY or REGISTRY_ONLY using istioctl

# Create an istioOperator config file - using IstioOperation Options
istioctl install -f istioplay.yaml

# uninstall
istioctl uninstall --purge -y

# verify
istioctl verify-install

2. Customizing the Istio installation with the IstioOperator API


# Dumps the istio operator state information - config tree under spec:
istioctl profile dump external --config-path components.cni

# Generates manifests that can be modifed and applied
istioctl manifest generate --set profile=external
istioctl manifest generate --set profile=external --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY

3. Using overlays to manage Istio component settings

istioctl install --dry-run -f istioplay.yaml -f istioplayoverlay.yaml

Traffic Management (6) 40%

1. Controlling network traffic flows within a service mesh

# Traffic Management - Request Routing
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: notification
spec:
hosts:
- notification-service
http:
- match:
- queryParams:
testing:
exact: "true"
route:
- destination:
host: notification-service
subset: v2
- match:
- headers:
testing:
exact: "true"
route:
- destination:
host: notification-service
subset: v2
- match:
- uri:
prefix: "/v2/notify"
rewrite:
uri: "/notify"
route:
- destination:
host: notification-service
subset: v2
- name: "reviews-v1-route"
route:
- destination:
host: notification-service
subset: v
# Traffic Management - Traffic Shifting
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: notification
spec:
hosts:
- notification-service
http:
- route:
- destination:
host: notification-service
subset: v1
weight: 0
- destination:
host: notification-service
subset: v2
weight: 100
---

2. Configuring sidecar injection

Can configure existing k8s deployment with sidecar injection.

# Manual
istioctl kube-inject -f deploy.yaml -o deploywithsidecard.yaml
kubectl apply -f <(istioctl kube-inject -f <resource.yaml>)

# Via namespace
kubectl label namespace default istio-injection=enabled

3. Using the Gateway resource to configure ingress and egress traffic.

# Creating a k8s secret type tls
kubectl create -n istio-system secret tls booking-credential \
--key=/root/certificates/booking.example.com.key \
--cert=/root/certificates/booking.example.com.crt
# Example of an standard k8s Ingress Setup (for comparision)
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: istio
spec:
controller: istio.io/ingress-controller
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: booking-ingress
spec:
ingressClassName: istio
tls:
- hosts:
- booking.example.com
secretName: booking-credential
rules:
- host: booking.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: booking-service
port:
number: 80
---
# TLS Termination using Istio 
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: booking-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- booking.example.com
name: booking
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: booking
spec:
hosts:
- booking.example.com
gateways:
- booking-gateway
http:
- route:
- destination:
host: booking-service
port:
number: 80
---
# Secure HTTPS Version
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: secure-booking-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: booking-credential
hosts:
- booking.example.com
name: booking
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: booking
spec:
hosts:
- booking.example.com
gateways:
- secure-booking-gateway
http:
- route:
- destination:
host: booking-service
port:
number: 80
---
# Creating for mutal TLS
kubectl create -n istio-system secret generic booking-credential-mutual \
--from-file=tls.key=/root/certificates/booking.example.com.key \
--from-file=tls.crt=/root/certificates/booking.example.com.crt \
--from-file=ca.crt=/root/certificates/example.com.crt
# Mutual TLS
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: secure-booking-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: MUTUAL
credentialName: booking-credential-mutual
hosts:
- booking.example.com
name: booking
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: booking
spec:
hosts:
- booking.example.com
gateways:
- secure-booking-gateway
http:
- route:
- destination:
host: booking-service
port:
number: 80
---
curl -v --cacert /root/certificates/example.com.crt \
--cert /root/certificates/client.example.com.crt \
--key /root/certificates/client.example.com.key \
https://booking.example.com:30443/bookings; \
echo;
# TLS Passthrough, eg. Example of HTTP in to internal HTTPS
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: booking-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- booking.example.com
name: booking
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: booking
spec:
hosts:
- booking.example.com
gateways:
- booking-gateway
http:
- route:
- destination:
host: booking-service
port:
number: 443
---
# Example call to check TLS
curl -v --cacert certificates/example.com.crt \
https://booking.example.com:30443/bookings; \
echo;
# TLS Passthrough
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: booking-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: PASSTHROUGH
hosts:
- booking.example.com
name: booking
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: booking
spec:
hosts:
- booking.example.com
gateways:
- booking-gateway
tls:
- match:
- port: 443
sniHosts:
- booking.example.com
route:
- destination:
host: booking-service
port:
number: 443
---
# Testing the HTTP egress
kubectl exec tester -- \
curl -sI http://httpbin.org/status/200 | \
grep "HTTP/";
--- 
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "httpbin.org"
name: httpbin
---
# Now configured the VirtualService to use said gateway.
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-httbin-through-egress-gateway
spec:
hosts:
- "httpbin.org"
gateways:
- httpbin-egressgateway
- mesh
http:
- name: "http1"
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 80
match:
- port: 80
gateways:
- mesh
- name: "http2"
route:
- destination:
host: httpbin.org
port:
number: 80
match:
- port: 80
gateways:
- httpbin-egressgateway
---

4. Understanding how to use ServiceEntry resources for adding entries to internal service registry

Covered above also.

# Now to use HTTPS over HTTP. Updating the Service Entry.
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
location: MESH_EXTERNAL
ports:
- number: 443
name: tls
protocol: TLS
resolution: DNS
---
# The request will still go through side proxy and not egress. So updating the gateway.
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: tls
protocol: TLS
hosts:
- "httpbin.org"
name: httpbin
tls:
mode: PASSTHROUGH
---
# Now for the Virtual Service to route tratffic through the gateway
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-httbin-through-egress-gateway
spec:
hosts:
- "httpbin.org"
gateways:
- httpbin-egressgateway
- mesh
tls:
- route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 443
match:
- port: 443
sniHosts:
- httpbin.org
gateways:
- mesh
- route:
- destination:
host: httpbin.org
port:
number: 443
match:
- port: 443
sniHosts:
- httpbin.org
gateways:
- httpbin-egressgateway
---

For testing:

kubectl exec tester -c tester -- \
curl -sS -o /dev/null -D - https://httpbin.org/status/200 | \
grep HTTP/

kubectl logs -l istio=egressgateway -n istio-system

Output: [2024-03-02T08:54:09.346Z] "- - -" 0 - - - "-" 849 5727 513 - "-" "-" "-" "-" "X.Y.Z:443" outbound|443||httpbin.org X.Y.Z:58312 X.Y.Z:8443 X.Y.Z:34160 httpbin.org -
# Now full example for TLS origination through egress.
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: yahoo-ext
spec:
hosts:
- finance.yahoo.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: yahoo-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- finance.yahoo.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-tls-for-yahoo-com
spec:
host: finance.yahoo.com
trafficPolicy:
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-yahoo-through-egress-gateway
spec:
hosts:
- finance.yahoo.com
gateways:
- yahoo-egressgateway
- mesh
http:
- match:
- gateways:
- mesh
port: 80
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 80
- match:
- gateways:
- yahoo-egressgateway
port: 80
route:
- destination:
host: finance.yahoo.com
port:
number: 443
---

5. Define traffic policies using DestinationRule

Covered in various examples above.

6. Configure traffic mirroring capabilities

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: notification
spec:
hosts:
- notification-service
http:
- name: "default-route"
route:
- destination:
host: notification-service
subset: v1
mirror:
host: notification-service
subset: v2
mirrorPercentage:
value: 100

Resilience and Fault Injection (3) 20%

1. Configuring circuit breakers (with or without outlier detection)

# Destination Rule CR (without outlier detection)
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
subsets:
- name: default
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: notification
spec:
hosts:
- notification-service
http:
- name: "email note"
route:
- destination:
host: notification-service
subset: default
---
# Destination Rule CR (with outlier detection)
# The Virtual Service stays as it is for the without example.
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service
trafficPolicy:
outlierDetection:
baseEjectionTime: 3m
consecutive5xxErrors: 2
interval: 1m
maxEjectionPercent: 100
subsets:
- name: default
labels:
version: v3
---

2. Using resilience features

# Need ServicerEntry to allow calls to httpbin
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS

Now to create a virtual services so the follow will cause it to timeout.

kubectl exec tester -- curl -o /dev/null \
-sS -w "Response status code: %{http_code}\nTotal time: %{time_total}\n" \
http://httpbin.org/delay/5; \
echo;

Lets create a VirtualService that will timeout after 3 seconds.

apiVersion: networking.istio.io/v1alpha3 pi
kind: VirtualService
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
http:
- timeout: 3s
route:
- destination:
host: httpbin.org
port:
number: 80

3. Creating fault injection

# Traffic Management - Fault Injection
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notification
spec:
host: notification-service
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: notification
spec:
hosts:
- notification-service
http:
- name: "reviews-v2-routes"
fault:
abort:
percentage:
value: 100
httpStatus: 500
# fault:
# delay:
# percentage:
# value: 100.0
# fixedDelay: 10s
route:
- destination:
host: notification-service
subset: v1
~

Securing Workloads (3) 20%

1. Understand Istio security features

Understanding PeerAuthentication, AuthorizationPolicy and RequestAuthentication CRDs and how they are used. See first section for more info and Security Tasks.

2. Set up Istio authorization for HTTP/TCP traffic in the mesh

#Security - Authorization - HTTP traffic
apiVersion: v1
kind: ServiceAccount
metadata:
name: booking-service-account
automountServiceAccountToken: true
#Note: edit a deployment to use this account.
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: booking-service-policy
namespace: default
spec:
selector:
matchLabels:
app: booking-service
action: ALLOW
rules:
- to:
- operation:
methods: ["POST"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: notification-service-policy
namespace: default
spec:
selector:
matchLabels:
app: notification-service
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/default/sa/booking-service-account"
to:
- operation:
methods: ["POST"]
# Security - Authorization - JWT Token
apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
name: booking-service
namespace: default
spec:
selector:
matchLabels:
app: booking-service
jwtRules:
- issuer: "testing@secure.istio.io"
jwksUri: https://raw.githubusercontent.com/lorenzo85/scenarios-ica/master/security-authorization-jwt-token/jwks.json
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: booking-service
namespace: default
spec:
selector:
matchLabels:
app: booking-service
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
when:
- key: request.auth.claims[groups]
values: ["group2"]
Configure mutual TLS at mesh, namespace, and workload levels
# Security - Authentication Policy - mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: cluster-wide-mtls
namespace: istio-system
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: namespace-wide-mtls
namespace: foo
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: workload-wide-mtls
namespace: foo
spec:
selector:
matchLabels:
app: booking-service
mtls:
mode: STRIC

3. Configure mutual TLS at mesh, namespace, and workload levels

TLS Origination: For HTTP internal traffic going outside, Istio can encrypt using a Service Entry and Destination

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: finance-yahoo-com
spec:
hosts:
- finance.yahoo.com
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: https-port
protocol: HTTPS
resolution: DNS
location: MESH_INTERNAL
kubectl exec tester -c tester -- \
curl -sSL -o /dev/null -D - http://finance.yahoo.com/crypto | \
grep -e HTTP/ -e location; \
echo;

Then need add port to forward to port entry: targetPort: 443, Then to add a DesinationRule

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: finance-yahoo-com
spec:
host: finance.yahoo.com
trafficPolicy:
portLevelSettings:
- port:
number: 80
tls:
mode: SIMPLE

To test:

kubectl exec tester -c tester -- \
curl -sS -o /dev/null -D - http://finance.yahoo.com/crypto | \
grep -e HTTP/ -e location; \
echo;

Advanced Scenarios 13%

Understand how to onboard non-Kubernetes workloads to the mesh

Understand WorkLoadGroups, WorkLoadEntries and SideCars

Troubleshoot configuration issues

istioctl -h
validate Validate Istio policy and rules files
verify-install Verifies Istio Installation Status
analyze Analyze Istio configuration and print validation messages

# Will run the command on the sidecard and show stats
kubectl exec -it pod/testdave -c istio-proxy -- pilot-agent request GET stats

# Istioctl details of a pod from istio perspect
istioctl x describe pod some-pod-name

# Query the proxy config for what routes it knows about, other proxy-config
# for
istioctl proxy-config routes deploy/istio-ingressgateway -n istio-system

--

--