diff --git a/2_traffic_management/README.md b/2_traffic_management/README.md index 4954819..54028a0 100644 --- a/2_traffic_management/README.md +++ b/2_traffic_management/README.md @@ -13,67 +13,647 @@ [Task - Exam](https://istio.io/latest/docs/tasks/traffic-management/) +## Controlling network traffic flows within a service mesh + +[Understanding Traffic Routing](https://istio.io/latest/docs/ops/configuration/traffic-management/traffic-routing/) + +[Traffic Management](https://istio.io/latest/docs/concepts/traffic-management/) + +### Ex1: Request Routing: Route to version 1 + +**Deploy BookingInfo app** + +This task shows you how to route requests dynamically to multiple versions of a microservice. +To route to one version only, you configure route rules that send traffic to default versions for the microservices. + +
+ Solution + + [Task - Request Routing](https://istio.io/latest/docs/tasks/traffic-management/request-routing/) + + ```bash + # Get the version labels from the deployments + $ kubectl get deploy -n default --show-labels +NAME READY UP-TO-DATE AVAILABLE AGE LABELS +details-v1 1/1 1 1 17m app=details,version=v1 +ratings-v1 1/1 1 1 17m app=ratings,version=v1 +reviews-v3 1/1 1 1 17m app=reviews,version=v3 +reviews-v1 1/1 1 1 17m app=reviews,version=v1 +reviews-v2 1/1 1 1 17m app=reviews,version=v2 +productpage-v1 1/1 1 1 17m app=productpage,version=v1 + + # Create a DR to create the Subsets for each service/version + $ kubectl apply -f - < + + +### Ex2: Route based on user identity + +Change the route configuration so that all traffic from a specific user is routed to a specific service version. +In this case, all traffic from a user named Jason will be routed to the service reviews:v2. + +
+ Solution + + ```bash + + # Update the DR to add the Subset version 2 for reviews service. + $ kubectl apply -f - < + +### Ex3: TCP Traffic Shifting: Weight-based TCP routing + + +You will send 100% of the TCP traffic to tcp-echo:v1. Then, you will route 20% of the TCP traffic to tcp-echo:v2 using Istio’s weighted routing feature. + +
+ Solution + + [Task - TCP Traffic Shifting](https://istio.io/latest/docs/tasks/traffic-management/tcp-traffic-shifting/) + + ```bash + # We need to create a Gateway to configure our TCP routing traffic. + # Since we installed istioctl install --set profile=demo we have already a istio ingress gateway up and running. + $ kubectl apply -f - < + +### Ex4: Traffic Shifting: Weight-based HTTP routing + +**Deploy BookingInfo app** + +You will use send 50% of traffic to reviews:v1 and 50% to reviews:v3. Then, you will complete the migration by sending 100% of traffic to reviews:v3. + +
+ Solution + + [Task - Traffic Shifting](https://istio.io/latest/docs/tasks/traffic-management/traffic-shifting/) + + ```bash + # Create a DR for the reviews service to specify all the subset versions + $ kubectl apply -f - < + ## Configuring sidecar injection -[Docs](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/) +[Setup - Installing the Sidecar](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/) + + +### Ex5:Automatic sidecar injection + +#### Ex5.1: Inject httpbin service automatically at namespace level. + +
+ Solution + + [Setup - Installing the Sidecar](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection) + + ```bash + # Label the default namespace with istio-injection=enabled + $ kubectl label namespace default istio-injection=enabled --overwrite + # Deploy httpbin service to injected automatically + $ kubectl apply -f samples/httpbin/httpbin.yaml + # Get the httpbin pods, we should see 2 READY containers where istio-proxy will be running with the main application. + $ kubectl get po -l app=httpbin +NAME READY STATUS RESTARTS AGE +httpbin-65975d4c6f-9v5kr 2/2 Running 0 59s + ``` +
+ +#### Ex5.2: Inject httpbin service automatically at workload level. Only httpbin service should be automatically injected inside the default namespace. + +
+ Solution + + [Setup - Installing the Sidecar](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection) + + ```bash + # Disable injection for the default namespace + $ kubectl label namespace default istio-injection- + # Remove httpbin service + $ kubectl delete -f samples/httpbin/httpbin.yaml + # Modify httpbin deployment yaml to add the Pod label injection + $ kubectl apply -f - < -```bash +### Manual sidecar injection + +#### Ex5.3: Inject httpbin service manually. + +
+ Solution -# Label the default namespace with istio-injection=enabled + #### istioctl kube-inject --help (Check - Examples:) -$ kubectl label namespace default istio-injection=enabled --overwrite + [Setup - Manual sidecar injection](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#manual-sidecar-injection) + + ```bash + # Manual sidecar injection using cluster configurations + $ istioctl kube-inject -f ./samples/httpbin/httpbin.yaml | kubectl apply -f - + ``` +
-# Disable injection for the default namespace -$ kubectl label namespace default istio-injection- +#### Ex5.4: Inject httpbin service manually persisting the injection file. -# Manual sidecar injection using cluster configurations +
+ Solution -$ istioctl kube-inject -f samples/sleep/sleep.yaml | kubectl apply -f - + #### istioctl kube-inject --help (Check - Examples:) -# Create a persistent version of the deployment with Istio sidecar injected. -$ istioctl kube-inject -f samples/sleep/sleep.yaml -o sleep-injected.yaml + [Setup -Installing the Sidecar](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection) + + ```bash + # Create a persistent version of the deployment with Istio sidecar injected. + $ istioctl kube-inject -f ./samples/httpbin/httpbin.yaml -o httpbin-injected.yaml + ``` +
-# Update an existing deployment. -$ kubectl get deployment -o yaml | istioctl kube-inject -f - | kubectl apply -f - -# Manual sidecar injection using local configurations -# This can be get it from istioctl kube-inject --help -$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.config}' > inject-config.yaml -$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.values}' > inject-values.yaml -$ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml +#### Ex5.5: Inject httpbin service already running manually -$ istioctl kube-inject \ - --injectConfigFile inject-config.yaml \ - --meshConfigFile mesh-config.yaml \ - --valuesFile inject-values.yaml \ - --filename samples/sleep/sleep.yaml \ - | kubectl apply -f - -``` +
+ Solution -## Using the Gateway resource to configure ingress and egress traffic + #### istioctl kube-inject --help (Check - Examples:) + + [Setup -Installing the Sidecar](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection) + + ```bash + $ kubectl get po -n default +NAME READY STATUS RESTARTS AGE +httpbin-6fcb98998c-h9ss8 1/1 Running 0 21s + # Update an existing deployment. + $ kubectl get deploy -n default -oyaml | ./istio-1.18.2/bin/istioctl kube-inject -f - |kubectl apply -f - +deployment.apps/httpbin configured + $ kubectl get po -n default +NAME READY STATUS RESTARTS AGE +httpbin-5fd75cf66-7hcnp 2/2 Running 0 14s + ``` +
+ +#### Ex5.6: Inject httpbin service manually using local configuration files. + +
+ Solution + + #### istioctl kube-inject --help (Check - Examples:) + + [Setup -Installing the Sidecar](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection) + + ```bash + # Capture cluster configuration for later use with kube-inject + kubectl -n istio-system get cm istio-sidecar-injector -o jsonpath="{.data.config}" > /tmp/inj-template.tmpl + kubectl -n istio-system get cm istio -o jsonpath="{.data.mesh}" > /tmp/mesh.yaml + kubectl -n istio-system get cm istio-sidecar-injector -o jsonpath="{.data.values}" > /tmp/values.json + + # Use kube-inject based on captured configuration + $ istioctl kube-inject -f ./istio-1.18.2/samples/httpbin/httpbin.yaml \ + --injectConfigFile /tmp/inj-template.tmpl \ + --meshConfigFile /tmp/mesh.yaml \ + --valuesFile /tmp/values.json \ +| kubectl apply -f - + ``` +
+ +## Ex6: Using the Gateway resource to configure ingress and egress traffic [Docs Gateway](https://istio.io/latest/docs/reference/config/networking/gateway/) -### Gateway: Ingress +#### Ex6.1 Gateway: Ingress - Create an Ingress Gateway and expose the routes: /status and /delay from the httpbin service. [Task - Ingress](https://istio.io/latest/docs/tasks/traffic-management/ingress/) -```bash +
+ Solution + + ```bash + # Create a Istio ingress gateway envoy service + # Minimal profile include the Ingress and the Egress gateway. + $ istioctl install --set profile=minimal -# Deploy demo app httbin -$ kubectl apply -f samples/httpbin/httpbin.yaml + # Enable automatic ns default Isito injection + $ kubectl label ns default istio-injection=enabled -# Create Istio Ingress Gateway -$ kubectl apply -f - < GET /status/200 HTTP/1.1 +> Host: httpbin.example.com +> User-Agent: curl/8.4.0 +> Accept: */* +> +< HTTP/1.1 200 OK +< server: istio-envoy +< date: Fri, 26 Jan 2024 17:53:34 GMT +< content-type: text/html; charset=utf-8 +< access-control-allow-origin: * +< access-control-allow-credentials: true +< content-length: 0 +< x-envoy-upstream-service-time: 2 +< + ``` +
+ +#### Ex6.2 Gateway: Egress - Call edition.cnn.com through a dedicated Istio Egress [Task - Egress](https://istio.io/latest/docs/tasks/traffic-management/egress/egress-gateway/) -```bash - -# Deploy the sleep sample app to use as a test source for sending requests. -# Manual sidecar injection since automatic injection is not enabled. -$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) +Configure Istio to allow access to external HTTP and HTTPS services from applications inside the mesh. -# Set the SOURCE_POD environment variable to the name of your source pod: -$ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) +Requirements: +* Host: edition.cnn.com +* The Egress Gateway name: edition-egressgateway -# Enable Envoy's access logging -# https://istio.io/latest/docs/tasks/observability/logs/access-log/#enable-envoys-access-logging +
+ Solution + + ```bash + # Install Istio and customize the IstioOperator CRD to set the proper Egress naming. +cat <>istio-edition-egressgateway.yaml +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + profile: minimal + components: + egressGateways: + - name: edition-egressgateway + enabled: true +EOF + $ istioctl install -f istio-edition-egressgateway.yaml +This will install the Istio 1.18.2 minimal profile with ["Istio core" "Istiod" "Egress gateways"] components into the cluster. Proceed? (y/N) + + # Label the default ns to autoinject the pods. + $ kubectl label ns default istio-injection=enabled + # Deploy Sleep app to use it as a client to perform the request + $ kubectl apply -f samples/sleep/sleep.yaml + + # Enable access logs on the proxies +cat <>istio-edition-egressgateway.yaml +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + profile: minimal + meshConfig: + accessLogFile: /dev/stdout # It's enable access logs. + components: + egressGateways: + - name: edition-egressgateway + enabled: true +EOF + $ istioctl upgrade -f istio-edition-egressgateway.yaml -# Using Telemetry API -kubectl apply -f - < -``` - -## Understanding how to use ServiceEntry resources for adding entries to internal service registry +## Ex7: Understanding how to use ServiceEntry resources for adding entries to internal service registry [Docs](https://istio.io/latest/docs/reference/config/networking/service-entry/) -```bash - -# Istio maintains an internal service registry which can be observed through a debug endpoint /debug/registryz exposed by istiod -$ kubectl exec -n istio-system deploy/istiod -- curl -s localhost:15014/debug/registryz - -# The following example declares a few external APIs accessed by internal applications over HTTPS. The sidecar inspects the SNI value in the ClientHello message to route to the appropriate external service. +### Ex7.1: Add api.dropboxapi.com to the mesh [MESH_EXTERNAL] + +Requirements: +* Validate api.dropboxapi.com: is part of the mesh and it's working as expected. + +
+ Solution + + ```bash + # Label default ns for automaticaly inject Istio sidecar + $ kubectl label ns default istio-injection=enabled + # Deploy sleep on the default ns + $ kubectl apply -f samples/sleep/sleep.yaml + # Enable access logs for the proxies + $ cat <>istio-logs.yaml +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + profile: minimal + meshConfig: + accessLogFile: /dev/stdout # It's enable access logs. +EOF + # Upgrade Istio with that changes + $ istioctl upgrade -f istio-logs.yaml + + # Let's perform a request from sleep service to the api.dropboxapi.com and check the logs. + $ kubectl -n default exec $(kubectl get pod -n default -l app=sleep -ojsonpath='{.items[0].metadata.name}') -- curl -vvv -L -I http://api.dropboxapi.com + [2024-01-27T10:39:54.925Z] "HEAD / HTTP/1.1" 301 - via_upstream - "-" 0 0 31 30 "-" "curl/8.5.0" "aa2f8365-4721-4094-a070-1de2a14c4f7f" "api.dropboxapi.com" "162.125.68.19:80" PassthroughCluster 10.42.0.7:36682 162.125.68.19:80 10.42.0.7:36676 - allow_any + [2024-01-27T10:39:54.959Z] "- - -" 0 - - - "-" 808 4758 345 - "-" "-" "-" "-" "162.125.68.19:443" PassthroughCluster 10.42.0.7:44654 162.125.68.19:443 10.42.0.7:44638 - - + [2024-01-27T10:39:55.240Z] "- - -" 0 - - - "-" 816 3700 65 - "-" "-" "-" "-" "162.125.68.18:443" PassthroughCluster 10.42.0.7:47158 162.125.68.18:443 10.42.0.7:47150 - - + # We can see on the output of the proxy: PassthroughCluster meaning that host is not part of the mesh since it didn't match any Envoy configuration. + + # Let's create a SE with location: MESH_EXTERNAL since it's an external API + $ kubectl apply -f - < -# Check the external APIs are part of the registry as external services "MeshExternal": true -$ kubectl exec -n istio-system deploy/istiod -- \ - curl -s localhost:15014/debug/registryz | jq '.[] | select( .hostname | contains("mymongodb.somedomain"))' +### Ex7.2: Add mymongodb.somedomain to the mesh [MESH_INTERNAL] -# MESH_INTERNAL -# The following configuration adds a set of MongoDB instances running on unmanaged VMs to Istio’s registry, so that these services can be treated as any other service in the mesh. The associated DestinationRule is used to initiate mTLS connections to the database instances. +Requirements: +* Validate mymongodb.somedomain: is part of the mesh and it's working as expected. +
+ Solution + + ```bash +# Create the SE to add the Mongodb as part of the mesh as location: MESH_INTERNAL $ kubectl apply -f - <>istio-logs-dns.yaml +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + profile: minimal + meshConfig: + accessLogFile: /dev/stdout # It's enable access logs. + defaultConfig: + proxyMetadata: + # Enable basic DNS proxying + ISTIO_META_DNS_CAPTURE: "true" + # Enable automatic address allocation, optional + ISTIO_META_DNS_AUTO_ALLOCATE: "true" +EOF + $ istioctl upgrade -f istio-logs-dns.yaml + # Check the MongoDB SE service resolve the fake domain + $ kubectl -n default exec $(kubectl get pod -n default -l app=sleep -ojsonpath='{.items[0].metadata.name}') -- nc -v mymongodb.somedomain 27018 + mymongodb.somedomain (240.240.40.99:27018) open + # Check the logs from the sleep istio-proxy + # You can see that the response flag in the logs: + # UF: UpstreamConnectionFailure + # URX: UpstreamRetryLimitExceeded + # It's expected since we don't have a real mongodb listening on that port. + [2024-01-27T14:15:24.881Z] "- - -" 0 UF,URX - - "-" 0 0 10000 - "-" "-" "-" "-" "10.43.0.1:27018" outbound|27018||mymongodb.somedomain - 240.240.40.99:27018 10.42.0.10:34145 - - + + ``` +
+ +## Ex8: Define traffic policies using DestinationRule [Docs](https://istio.io/latest/docs/reference/config/networking/destination-rule/) -### Load balancing - -[Load balancing](https://tetratelabs.github.io/istio-0to60/discovery/#load-balancing) - -```bash - -# Deploy helloworld application -$ kubectl apply -f samples/helloworld/helloworld.yaml +### Ex8.1: Change the Load balancing mechanissim on the helloworld service to : RANDOM -# Make repeated calls to the helloworld service from the sleep pod -$ for i in {1..6}; do - kubectl exec deploy/sleep -- curl -s helloworld:5000/hello -done +Requirements: +* Validate that the new load balancing mechanissim is working as expected. -# Examine the helloworld "cluster" definition in a sample client to see what load balancing policy is in effect: -$ istioctl proxy-config cluster deploy/sleep \ - --fqdn helloworld.default.svc.cluster.local -o yaml | grep lbPolicy - lbPolicy: LEAST_REQUEST +[Load balancing](https://tetratelabs.github.io/istio-0to60/discovery/#load-balancing) -# To influence the load balancing algorithm that Envoy uses when calling helloworld, we can define a traffic policy, like so: -$ kubectl apply -f - < + Solution + + ```bash + # Deploy a client http service: sleep app + $ kubectl label ns default istio-injection=enabled + $ kubectl apply -f istio-1.18.2/samples/sleep/sleep.yaml + # We deploy the server app: Helloworld + $ kubectl apply -f istio-1.18.2/samples/helloworld/helloworld.yaml + # Let's check the default load balancing mechanissim. + $ istioctl pc cluster $(kubectl get pod -n default -l app=helloworld -ojsonpath='{.items[0].metadata.name}') --fqdn "helloworld.default.svc.cluster.local" -ojson |grep lbPolicy + "lbPolicy": "LEAST_REQUEST", + # Let's make some test to validate that behaviour + $ for i in {1..6}; do kubectl exec deploy/sleep -- curl -s helloworld:5000/hello; done + Hello version: v1, instance: helloworld-v1-867747c89-6sqrw + Hello version: v1, instance: helloworld-v1-867747c89-6sqrw + Hello version: v1, instance: helloworld-v1-867747c89-6sqrw + Hello version: v1, instance: helloworld-v1-867747c89-6sqrw + Hello version: v1, instance: helloworld-v1-867747c89-6sqrw + Hello version: v1, instance: helloworld-v1-867747c89-6sqrw + # Now let's change the load balancing mechanissim to RANDOM + # Create a DR for helloworld + $ kubectl apply -f - < + +### Ex8.2: Traffic distribution spread proportially 50%/50% for helloworld service between v1 & v2 version + +Requirements: +* Validate that the traffic is spread proportially 50%/50% for helloworld service between v1 & v2 version [Traffic distribution](https://tetratelabs.github.io/istio-0to60/discovery/#traffic-distribution) -```bash +
+ Solution -# We can go a step further and control how much traffic to send to version v1 and how much to v2 -# First, define the two subsets, v1 and v2 -$ kubectl apply -f - < + + +## Ex9: Configure traffic mirroring capabilities for helloworld service +[Docs](https://istio.io/latest/docs/tasks/traffic-management/mirroring/) -## Configure traffic mirroring capabilities +Requirements: +* Send a proportion of mirror traffic to v2 of helloworld service -[Docs](https://istio.io/latest/docs/tasks/traffic-management/mirroring/) +
+ Solution ```bash -# In this task, you will first force all traffic to v1 of a test service. Then, you will apply a rule to mirror a portion of traffic to v2. -# Start by deploying two versions of the httpbin service that have access logging enabled. -# httpbin-v1 -$ cat <>istio-logs.yaml +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator spec: - replicas: 1 - selector: - matchLabels: - app: sleep - template: - metadata: - labels: - app: sleep - spec: - containers: - - name: sleep - image: curlimages/curl - command: ["/bin/sleep","3650d"] - imagePullPolicy: IfNotPresent + profile: minimal + meshConfig: + accessLogFile: /dev/stdout EOF -# Create a default route rule to route all traffic to v1 of the service -$ kubectl apply -f - < - -# Mirroring traffic to v2 -# Change the route rule to mirror traffic to v2: -$ kubectl apply -f - < diff --git a/5_advanced_scenarios/README.md b/5_advanced_scenarios/README.md new file mode 100644 index 0000000..24261d0 --- /dev/null +++ b/5_advanced_scenarios/README.md @@ -0,0 +1,317 @@ +# Advanced Scenarios 13% + +* [Understand how to onboard non-Kubernetes workloads to the mesh](https://istio.io/latest/docs/ops/deployment/vm-architecture/) +* [Troubleshoot configuration issues](https://istio.io/latest/docs/ops/common-problems/) + +## Understand how to onboard non-Kubernetes workloads to the mesh + +[Docs](https://istio.io/latest/docs/ops/deployment/vm-architecture/) + +### Onboard non-Kubernetes workloads to the mesh + +[Task](https://istio.io/latest/docs/setup/install/virtual-machine/) + +```bash +# This example application running on a virtual machine (VM), and illustrates how to control this infrastructure as a single mesh. + +# You have already a candidate Virtual Machine created to onboard on the Istio Mesh + +# Prepare the guide environment +# Set the environment variables VM_APP, WORK_DIR , VM_NAMESPACE, and SERVICE_ACCOUNT on your machine that you’re using to set up the cluster. (e.g., WORK_DIR="${HOME}/vmintegration"): +$ export VM_APP="vm-mysqldb" +$ export VM_NAMESPACE="vm-mysqldb" +$ export WORK_DIR="/tmp" +$ export SERVICE_ACCOUNT="vm-mysqldb" +$ export CLUSTER_NETWORK="" +$ export VM_NETWORK="" +$ export CLUSTER="Kubernetes" + +# Create the working directory on your machine that you’re using to set up the cluster: +$ mkdir -p "${WORK_DIR}" + +# We assume that you have already installed Istio. + +# Deploy the east-west gateway. We'll use an empty profile to create it as new component. +$ samples/multicluster/gen-eastwest-gateway.sh --single-cluster | ./bin/istioctl install -y -f - +✔ Ingress gateways installed +✔ Installation complete +Thank you for installing Istio 1.16. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/99uiMML96AmsXY5d6 + +# Expose services inside the cluster via the east-west gateway: Gateway & VirtualService +$ kubectl apply -n istio-system -f samples/multicluster/expose-istiod.yaml + +# Configure the VM namespace +# Create the namespace that will host the virtual machine: +$ kubectl create namespace "${VM_NAMESPACE}" + +# Create a serviceaccount for the virtual machine: +$ kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${VM_NAMESPACE}" + +# Create files to transfer to the virtual machine +# First, create a template WorkloadGroup for the VM(s): +$ cat < workloadgroup.yaml +apiVersion: networking.istio.io/v1beta1 +kind: WorkloadGroup +metadata: + name: "${VM_APP}" + namespace: "${VM_NAMESPACE}" +spec: + metadata: + labels: + app: "${VM_APP}" + template: + serviceAccount: "${SERVICE_ACCOUNT}" + network: "${VM_NETWORK}" +EOF + +# Before proceeding to generate the istio-token, as part of istioctl x workload entry, you should verify third party tokens are enabled in your cluster by following the steps describe here. If third party tokens are not enabled, you should add the option --set values.global.jwtPolicy=first-party-jwt to the Istio install commands. +# If this returns no response, then the feature is not supported: +$ kubectl get --raw /api/v1 | jq '.resources[] | select(.name | index("serviceaccounts/token"))' +{ + "name": "serviceaccounts/token", + "singularName": "", + "namespaced": true, + "group": "authentication.k8s.io", + "version": "v1", + "kind": "TokenRequest", + "verbs": [ + "create" + ] +} + +# Use the istioctl x workload entry command to generate: + +# cluster.env: Contains metadata that identifies what namespace, service account, network CIDR and (optionally) what inbound ports to capture. +# istio-token: A Kubernetes token used to get certs from the CA. +# mesh.yaml: Provides ProxyConfig to configure discoveryAddress, health-checking probes, and some authentication options. +# root-cert.pem: The root certificate used to authenticate. +# hosts: An addendum to /etc/hosts that the proxy will use to reach istiod for xDS.* +$ istioctl x workload entry configure -f workloadgroup.yaml -o "${WORK_DIR}" --clusterID "${CLUSTER}" +Warning: a security token for namespace "vm-mysqldb" and service account "vm-mysqldb" has been generated and stored at "/tmp/istio-token" +2024-01-11T15:42:54.729859Z warn Could not auto-detect IP for istiod.istio-system.svc/istio-system. Use --ingressIP to manually specify the Gateway address to reach istiod from the VM. +Configuration generation into directory /tmp was successful + +# Configure the virtual machine +# Run the following commands on the virtual machine you want to add to the Istio mesh: + +# Securely transfer the files from "${WORK_DIR}" to the virtual machine. How you choose to securely transfer those files should be done with consideration for your information security policies. For convenience in this guide, transfer all of the required files to "${HOME}" in the virtual machine. + +# Install the root certificate at /etc/certs: +$ sudo mkdir -p /etc/certs +$ sudo cp "${HOME}"/root-cert.pem /etc/certs/root-cert.pem + +# Install the token at /var/run/secrets/tokens: +$ sudo mkdir -p /var/run/secrets/tokens +$ sudo cp "${HOME}"/istio-token /var/run/secrets/tokens/istio-token + +# Install the package containing the Istio virtual machine integration runtime: +$ curl -LO https://storage.googleapis.com/istio-release/releases/1.18.2/deb/istio-sidecar.deb +$ sudo dpkg -i istio-sidecar.deb + +# Install cluster.env within the directory /var/lib/istio/envoy/: +$ sudo cp "${HOME}"/cluster.env /var/lib/istio/envoy/cluster.env + +# Install the Mesh Config to /etc/istio/config/mesh: +$ sudo cp "${HOME}"/mesh.yaml /etc/istio/config/mesh + +# Add the istiod host to /etc/hosts: +$ sudo sh -c 'cat $(eval echo ~$SUDO_USER)/hosts >> /etc/hosts' + +# Transfer ownership of the files in /etc/certs/ and /var/lib/istio/envoy/ to the Istio proxy: +$ sudo chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem + +# Start Istio within the virtual machine +# Start the Istio agent: +$ sudo systemctl start istio + +# Verify Istio Works Successfully +$ tail /var/log/istio/istio.err.log /var/log/istio/istio.log -Fq -n 100 + +2024-01-11T18:42:00.412798Z info FLAG: --concurrency="0" +2024-01-11T18:42:00.412834Z info FLAG: --domain="" +2024-01-11T18:42:00.412842Z info FLAG: --help="false" +2024-01-11T18:42:00.412847Z info FLAG: --log_as_json="false" +2024-01-11T18:42:00.412851Z info FLAG: --log_caller="" +2024-01-11T18:42:00.412857Z info FLAG: --log_output_level="default:info" +2024-01-11T18:42:00.412861Z info FLAG: --log_rotate="" +2024-01-11T18:42:00.412866Z info FLAG: --log_rotate_max_age="30" +2024-01-11T18:42:00.412871Z info FLAG: --log_rotate_max_backups="1000" +2024-01-11T18:42:00.412876Z info FLAG: --log_rotate_max_size="104857600" +2024-01-11T18:42:00.412882Z info FLAG: --log_stacktrace_level="default:none" +2024-01-11T18:42:00.412893Z info FLAG: --log_target="[stdout]" +2024-01-11T18:42:00.412900Z info FLAG: --meshConfig="./etc/istio/config/mesh" +2024-01-11T18:42:00.412904Z info FLAG: --outlierLogPath="" +2024-01-11T18:42:00.412908Z info FLAG: --proxyComponentLogLevel="" +2024-01-11T18:42:00.412913Z info FLAG: --proxyLogLevel="warning,misc:error" +2024-01-11T18:42:00.412918Z info FLAG: --serviceCluster="istio-proxy" +2024-01-11T18:42:00.412928Z info FLAG: --stsPort="0" +2024-01-11T18:42:00.412932Z info FLAG: --templateFile="" +2024-01-11T18:42:00.412938Z info FLAG: --tokenManagerPlugin="GoogleTokenExchange" +2024-01-11T18:42:00.412948Z info FLAG: --vklog="0" +2024-01-11T18:42:00.412953Z info Version 1.16.1-f6d7bf648e571a6a523210d97bde8b489250354b-Clean +2024-01-11T18:42:00.414107Z info Maximum file descriptors (ulimit -n): 1024 +2024-01-11T18:42:00.414242Z info Proxy role ips=[10.10.10.10] type=sidecar id=ip-10-10-10-10.vm-mysqldb domain=vm-mysqldb.svc.cluster.local +2024-01-11T18:42:00.414290Z info Apply mesh config from file defaultConfig: + discoveryAddress: istiod.istio-system.svc:15012 + holdApplicationUntilProxyStarts: true + proxyMetadata: + CANONICAL_REVISION: latest + CANONICAL_SERVICE: vm-mysqldb + ISTIO_META_AUTO_REGISTER_GROUP: vm-mysqldb + ISTIO_META_CLUSTER_ID: Kubernetes + ISTIO_META_DNS_CAPTURE: "true" + ISTIO_META_MESH_ID: "" + ISTIO_META_NETWORK: "" + ISTIO_META_WORKLOAD_NAME: vm-mysqldb + ISTIO_METAJSON_LABELS: '{"app":"vm-mysqldb","service.istio.io/canonical-name":"vm-mysqldb","service.istio.io/canonical-revision":"latest"}' + POD_NAMESPACE: vm-mysqldb + SERVICE_ACCOUNT: vm-mysqldb + TRUST_DOMAIN: cluster.local + terminationDrainDuration: 30s + +2024-01-11T18:42:00.416075Z info Apply proxy config from env +serviceCluster: vm-mysqldb.vm-mysqldb +controlPlaneAuthPolicy: MUTUAL_TLS + +2024-01-11T18:42:00.416630Z info Effective config: binaryPath: /usr/local/bin/envoy +concurrency: 2 +configPath: ./etc/istio/proxy +controlPlaneAuthPolicy: MUTUAL_TLS +discoveryAddress: istiod.istio-system.svc:15012 +drainDuration: 45s +holdApplicationUntilProxyStarts: true +parentShutdownDuration: 60s +proxyAdminPort: 15000 +proxyMetadata: + CANONICAL_REVISION: latest + CANONICAL_SERVICE: vm-mysqldb + ISTIO_META_AUTO_REGISTER_GROUP: vm-mysqldb + ISTIO_META_CLUSTER_ID: Kubernetes + ISTIO_META_DNS_CAPTURE: "true" + ISTIO_META_MESH_ID: "" + ISTIO_META_NETWORK: "" + ISTIO_META_WORKLOAD_NAME: vm-mysqldb + ISTIO_METAJSON_LABELS: '{"app":"vm-mysqldb","service.istio.io/canonical-name":"vm-mysqldb","service.istio.io/canonical-revision":"latest"}' + POD_NAMESPACE: vm-mysqldb + SERVICE_ACCOUNT: vm-mysqldb + TRUST_DOMAIN: cluster.local +serviceCluster: vm-mysqldb.vm-mysqldb +statNameLength: 189 +statusPort: 15020 +terminationDrainDuration: 30s +tracing: + zipkin: + address: zipkin.istio-system:9411 + +2024-01-11T18:42:00.416651Z info JWT policy is third-party-jwt +2024-01-11T18:42:00.416657Z info using credential fetcher of JWT type in cluster.local trust domain +2024-01-11T18:42:00.417947Z info Opening status port 15020 +2024-01-11T18:42:00.418004Z info dns Starting local udp DNS server on 127.0.0.1:15053 +2024-01-11T18:42:00.418065Z info dns Starting local tcp DNS server on 127.0.0.1:15053 +2024-01-11T18:42:00.418480Z info Workload SDS socket not found. Starting Istio SDS Server +2024-01-11T18:42:00.418498Z info CA Endpoint istiod.istio-system.svc:15012, provider Citadel +2024-01-11T18:42:00.418508Z info Using CA istiod.istio-system.svc:15012 cert with certs: ./etc/certs/root-cert.pem +2024-01-11T18:42:00.418588Z info citadelclient Citadel client using custom root cert: ./etc/certs/root-cert.pem +2024-01-11T18:42:00.435960Z info ads All caches have been synced up in 24.85206ms, marking server ready +2024-01-11T18:42:00.436245Z info xdsproxy Initializing with upstream address "istiod.istio-system.svc:15012" and cluster "Kubernetes" +2024-01-11T18:42:00.437929Z info Pilot SAN: [istiod.istio-system.svc] +2024-01-11T18:42:00.459561Z info sds Starting SDS grpc server +2024-01-11T18:42:00.459723Z info starting Http service at 127.0.0.1:15004 +2024-01-11T18:42:00.459731Z info Starting proxy agent +2024-01-11T18:42:00.459801Z info starting +2024-01-11T18:42:00.459860Z info Envoy command: [-c etc/istio/proxy/envoy-rev.json --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ %l envoy %n %v -l warning --component-log-level misc:error --concurrency 2] +2024-01-11T18:42:00.612029Z info cache generated new workload certificate latency=171.806201ms ttl=23h59m59.387981926s +2024-01-11T18:42:00.612077Z info cache Root cert has changed, start rotating root cert +2024-01-11T18:42:00.612102Z info ads XDS: Incremental Pushing:0 ConnectedEndpoints:0 Version: +2024-01-11T18:42:00.612554Z info cache returned workload trust anchor from cache ttl=23h59m59.387451322s +2024-01-11T18:42:00.615161Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012 +2024-01-11T18:42:00.646047Z info ads ADS: new connection for node:ip-10-10-10-10.vm-mysqldb-1 +2024-01-11T18:42:00.646138Z info cache returned workload trust anchor from cache ttl=23h59m59.353866864s +2024-01-11T18:42:00.646365Z info ads SDS: PUSH request for node:ip-10-10-10-10.vm-mysqldb resources:1 size:924B resource:ROOTCA +2024-01-11T18:42:00.647065Z info ads ADS: new connection for node:ip-10-10-10-10.vm-mysqldb-2 +2024-01-11T18:42:00.647141Z info cache returned workload certificate from cache ttl=23h59m59.352862206s +2024-01-11T18:42:00.647261Z info ads SDS: PUSH request for node:ip-10-10-10-10.vm-mysqldb resources:1 size:5.7kB resource:default + +# Deploy the httpbin service on the default namespace: +$ kubectl apply -n default -f samples/httpbin/httpbin.yaml + +# Perform a request to the httpbin service on Kubernetes from the Virtual Machine instance to validate that works. +$ root@ip-10-10-10-10:~# curl -vvv httpbin.istio-system.svc.cluster.local:8000/headers +* Expire in 0 ms for 6 (transfer 0x55d6d483afb0) +* Expire in 1 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 1 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 1 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 1 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Expire in 0 ms for 1 (transfer 0x55d6d483afb0) +* Trying 172.20.89.176... +* TCP_NODELAY set +* Expire in 200 ms for 4 (transfer 0x55d6d483afb0) +* Connected to httpbin.istio-system.svc.cluster.local (172.20.89.176) port 8000 (#0) +> GET /headers HTTP/1.1 +> Host: httpbin.istio-system.svc.cluster.local:8000 +> User-Agent: curl/7.64.0 +> Accept: */* +> +< HTTP/1.1 200 OK +< server: envoy +< date: Thu, 11 Jan 2024 18:45:05 GMT +< content-type: application/json +< content-length: 1019 +< access-control-allow-origin: * +< access-control-allow-credentials: true +< x-envoy-upstream-service-time: 1 +< +{ + "headers": { + "Accept": "*/*", + "Host": "httpbin.istio-system.svc.cluster.local:8000", + "User-Agent": "curl/7.64.0", + "X-B3-Sampled": "0", + "X-B3-Spanid": "xxxxxxxx", + "X-B3-Traceid": "xxxxxxxx", + "X-Envoy-Attempt-Count": "1", + "X-Envoy-Decorator-Operation": "httpbin.istio-system.svc.cluster.local:8000/*", + "X-Envoy-Peer-Metadata": "xxxxxxxx", + "X-Envoy-Peer-Metadata-Id": "sidecar~10.10.10.10~ip-10-10-10-10.vm-mysqldb~vm-mysqldb.svc.cluster.local" + } +} +* Connection #0 to host httpbin.istio-system.svc.cluster.local left intact + +``` + +## Troubleshoot configuration issues + +[Docs](https://istio.io/latest/docs/ops/common-problems/) + +## Common Problems + +**Read extreamly carefully the following Istio pages to undertand it properly** + +1. [Traffic Management Problems](https://istio.io/latest/docs/ops/common-problems/network-issues/) +2. [Sidecar Injection Problems](https://istio.io/latest/docs/ops/common-problems/injection/) +3. [Security Problems](https://istio.io/latest/docs/ops/common-problems/security-issues/) +4. [Configuration Validation Problems](https://istio.io/latest/docs/ops/common-problems/validation/) +5. [Observability Problems](https://istio.io/latest/docs/ops/common-problems/observability-issues/) +6. [Upgrade Problems](https://istio.io/latest/docs/ops/common-problems/upgrade-issues/) + +## Diagnostic Tools + +[Docs](https://istio.io/latest/docs/ops/diagnostic-tools/) + +1. [Using the Istioctl Command-line Tool](https://istio.io/latest/docs/ops/diagnostic-tools/istioctl/) +2. [Diagnose your Configuration with Istioctl Analyze](https://istio.io/latest/docs/ops/diagnostic-tools/istioctl-analyze/) +3. [Component Logging](https://istio.io/latest/docs/ops/diagnostic-tools/component-logging/) +4. [Troubleshooting the Istio CNI plugin](https://istio.io/latest/docs/ops/diagnostic-tools/cni/) +5. [Debugging Envoy and Istiod](https://istio.io/latest/docs/ops/diagnostic-tools/proxy-cmd/) +6. [Verifying Istio Sidecar Injection with Istioctl Check-Inject](https://istio.io/latest/docs/ops/diagnostic-tools/check-inject/) +7. [Debugging Virtual Machines](https://istio.io/latest/docs/ops/diagnostic-tools/virtual-machines/) +8. [Understand your Mesh with Istioctl Describe](https://istio.io/latest/docs/ops/diagnostic-tools/istioctl-describe/) +9. [Istiod Introspection](https://istio.io/latest/docs/ops/diagnostic-tools/controlz/) +10. [Troubleshooting Multicluster](https://istio.io/latest/docs/ops/diagnostic-tools/multicluster/) diff --git a/README.md b/README.md index b2289ec..83ed9d7 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,19 @@ # Istio Certified Associate (ICA) -Istio Certified Associate exam preparation repository +Istio Certified Associate exam preparation repository. + +This repository is created to help me and anyone interested to prepare the Istio Certified Associate (ICA) exam. https://training.linuxfoundation.org/blog/istio-certified-associate-ica/ https://training.linuxfoundation.org/certification/istio-certified-associate-ica/ -## Domains & Competencies: Practice exercices +## Domains & Competencies: [Preparation Exam Material] * [Istio Installation, Upgrade & Configuration 7%](./1_istio_installation_upgrade_configuration/README.md) * [Traffic Management 40%](./2_traffic_management/README.md) * [Resilience and Fault Injection 20%](./3_resilience_and_fault_injection/README.md) * [Securing Workloads 20%](./4_securing_workloads/README.md) +* [Advanced Scenarios 13%](./5_advanced_scenarios/README.md) ## Pre-Requirements @@ -56,5 +59,9 @@ $ ./istio-1.18.2/bin/istioctl version -s --remote=false * [Istio 0 to 60 workshop: Exercices](https://tetratelabs.github.io/istio-0to60) * [Mesh week](https://github.com/solo-io/mesh-week) * [Mesh week: How to prepare for Istio Certified associate exam (ICA)](https://learncloudnative.com/blog/2023-10-10-meshweek) +* [Mesh week: Mock Istio Certified Associate Exam](https://docs.google.com/forms/d/e/1FAIpQLSfD4BLLQfdUwnIyiTBSGC_OzmSbiyrIlNp5Am61fTOhRbfiLw/viewform) * [Istio Security Problems](https://istio.io/latest/docs/ops/common-problems/security-issues/) * [Istio Security Best Practices](https://istio.io/latest/docs/ops/best-practices/security/) +* [Life of a packet through Istio by Matt Turner](https://www.youtube.com/watch?v=cB611FtjHcQ) +* [Matt Turner - Life of a Packet through Istio III - WTF is SRE 2023](https://www.youtube.com/watch?v=qsTK4o189_I) +* [Killercoda Istio ICA](https://github.com/killercoda/scenarios-ica) diff --git a/mock_exam/1.yaml b/mock_exam/1.yaml new file mode 100644 index 0000000..8decf35 --- /dev/null +++ b/mock_exam/1.yaml @@ -0,0 +1,23 @@ +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + profile: minimal + components: + pilot: + k8s: + resources: + requests: + cpu: 750m + memory: 4096Mi + ingressGateways: + - name: payments-ingress + enabled: true + namespace: payments + - name: frontend-ingress + enabled: true + namespace: frontend + egressGateways: + - name: cluster-egress + enabled: true + namespace: egress + diff --git a/mock_exam/2.yaml b/mock_exam/2.yaml new file mode 100644 index 0000000..de530b8 --- /dev/null +++ b/mock_exam/2.yaml @@ -0,0 +1,38 @@ +apiVersion: networking.istio.io/v1beta1 +kind: Gateway +metadata: + name: my-ingress +spec: + selector: + app: my-ingressgateway # No specified + servers: + - port: + number: 80 + name: http2 + protocol: HTTP2 + hosts: + - "*" + +--- +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: payments +spec: + hosts: + - mycompany.com + gateways: + - my-ingress + http: + - name: "payments" + match: + - uri: + prefix: "/payments" + route: + - destination: + host: payments.default.svc.cluster.local + + - name: "frontend" + route: + - destination: + host: frontend.default.svc.cluster.local diff --git a/mock_exam/3.yaml b/mock_exam/3.yaml new file mode 100644 index 0000000..b47fd33 --- /dev/null +++ b/mock_exam/3.yaml @@ -0,0 +1,29 @@ +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +spec: + hosts: + - orders + http: + - route: + - destination: + host: orders + subset: v1 + weight: 30 + - destination: + host: orders + subset: v2 + weight: 70 +--- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: orders +spec: + host: orders + subsets: + - name: orders-v1 + labels: + version: v1 + - name: orders-v2 + labels: + version: v2 diff --git a/mock_exam/4.yaml b/mock_exam/4.yaml new file mode 100644 index 0000000..35982c7 --- /dev/null +++ b/mock_exam/4.yaml @@ -0,0 +1,34 @@ +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +spec: + hosts: + - backend + http: + - fault: + delay: + fixedDelay: 5s + percentage: + value: 100 + match: + - uri: + prefix: "/delay" + route: + - destination: + host: backend.default.svc.cluster.local + + - fault: + abort: + httpStatus: 403 + percentage: + value: 100 + match: + - uri: + prefix: "/fault" + route: + - destination: + host: backend.default.svc.cluster.local + + - route: + - destination: + host: backend.default.svc.cluster.local + diff --git a/mock_exam/5.yaml b/mock_exam/5.yaml new file mode 100644 index 0000000..ba1d5f5 --- /dev/null +++ b/mock_exam/5.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: default + namespace: default +spec: + selector: + matchLabels: + mtls: strict + mtls: + mode: STRICT + portLevelMtls: + 9000: + mode: DISABLE diff --git a/mock_exam/6.yaml b/mock_exam/6.yaml new file mode 100644 index 0000000..32c9353 --- /dev/null +++ b/mock_exam/6.yaml @@ -0,0 +1,20 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + namespace: default + name: customers +spec: + selector: + matchLabels: + app: customers + action: ALLOW + rules: + - from: + - source: + principals: + - "cluster.local/ns/default/sa/payments" + - "cluster.local/ns/default/sa/orders" + - to: + - operation: + methods: ["GET"] + paths: ["/api"] diff --git a/mock_exam/7.yaml b/mock_exam/7.yaml new file mode 100644 index 0000000..182c239 --- /dev/null +++ b/mock_exam/7.yaml @@ -0,0 +1,7 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + namespace: payments + name: payments +spec: + {} diff --git a/mock_exam/README.md b/mock_exam/README.md new file mode 100644 index 0000000..c630a70 --- /dev/null +++ b/mock_exam/README.md @@ -0,0 +1,4 @@ +# Mock exam - Mesh Week + +https://docs.google.com/forms/d/e/1FAIpQLSfD4BLLQfdUwnIyiTBSGC_OzmSbiyrIlNp5Am61fTOhRbfiLw/viewform +