Istio Service Mesh Workshop: Setup Requirements

This page is for the instructor or cluster administrator who prepares the lab environment. It lists everything that the exercises rely on, derived from the commands and manifests in the modules. It has two audiences: the admin preparation (cluster, operators, attendee projects, roles and images, which need cluster-admin permissions and are done once before the lab) and the attendee workstation (the command-line tools that each attendee runs, as a project user without cluster-level permissions). Attendees can skip to Attendee Workstation and Verification Checklist.

The exercises are written for Red Hat OpenShift Service Mesh 3.4, which is based on Istio 1.30. Attendees work as project users in their own namespace <user>-sandbox on a shared cluster.

Cluster

  • OpenShift version: an OpenShift Container Platform 4 release that OpenShift Service Mesh 3.4 supports (see the OpenShift Service Mesh 3.4 release notes for the supported versions). The content does not depend on a specific OpenShift minor version.

  • Topology and size: the exercises do not need a specific number of worker nodes. No exercise depends on pods running on different nodes, so a compact or single-node cluster works if it has capacity for all attendees. Plan capacity per attendee: when an attendee has completed all modules, the attendee namespace runs about 24 pods (Module 1: 3, Module 2: 7 including the ingress gateway, Module 3: 12, Module 4: 2), each with an Envoy sidecar. With the default Istio sidecar resource requests (100m CPU and 128Mi memory per proxy), this is roughly 2.4 CPU cores and 3 GiB of memory requested per attendee, before the application containers. If the attendee projects have a ResourceQuota or LimitRange, size them accordingly or ask attendees to delete the workloads of earlier modules.

  • Cluster features: the exercises use only the Kubernetes API and the Envoy sidecars. They do not need the metrics API, user workload monitoring, an external load balancer, Routes or the Kubernetes Gateway API. The ingress gateway Service is of type ClusterIP, and attendees reach it with oc port-forward.

  • Security context constraints: the attendee workloads run under the default restricted-v2 SCC. The workshop uses the nginx-unprivileged image (port 8080) for that reason, and Istio CNI removes the need for privileged init containers.

  • Network policies: if the attendee projects get default NetworkPolicy objects (for example from a project template), they must allow traffic between pods in the same namespace, ingress from the sidecars of the same namespace on the application and gateway ports, and egress to istiod in istio-system (port 15012).

Operators and Cluster Components

Component Install source Namespace Configuration needed Used in

Red Hat OpenShift Service Mesh 3 Operator (servicemeshoperator3)

OperatorHub, redhat-operators catalog, channel stable (or the version channel for 3.4). Tested with OpenShift Service Mesh 3.4.

openshift-operators (all namespaces)

Default subscription.

All modules

Istio resource (control plane, istiod)

Created from the Service Mesh operator (sailoperator.io/v1)

istio-system

Named default, Istio 1.30. The default mesh configuration is sufficient: the exercises use the built-in envoy access log provider (Module 1, Module 4) and the default Prometheus metrics endpoint of the sidecars on port 15020 (Module 4). Do not restrict the mesh with discoverySelectors that exclude the attendee namespaces. The update strategy determines the revision name; see Control Plane Revision.

All modules

IstioCNI resource (Istio CNI node agent)

Created from the Service Mesh operator (sailoperator.io/v1)

istio-cni

Named default. Runs as a DaemonSet on every node.

All modules (Module 1, Exercise 1 checks it)

Sidecar injector (part of istiod)

Included in the Istio resource

istio-system

Injects sidecars into namespaces labeled istio.io/rev=<revision>, and gateway proxies into Deployments annotated with inject.istio.io/templates: gateway (each attendee deploys an ingress gateway in their own namespace in Module 2).

All modules

Kiali, Prometheus, Grafana, Tempo and Jaeger are described in Module 4 (Content) as options, but no exercise uses them. You do not need to install them. The ingress gateway is not installed by the administrator: each attendee deploys their own with gateway injection in Module 2.

Install the Control Plane

After you install the operator, create the namespaces and the Istio and IstioCNI resources:

oc create namespace istio-system
oc create namespace istio-cni
oc apply -f - <<EOF
apiVersion: sailoperator.io/v1
kind: Istio
metadata:
  name: default
spec:
  namespace: istio-system
  updateStrategy:
    type: InPlace
---
apiVersion: sailoperator.io/v1
kind: IstioCNI
metadata:
  name: default
spec:
  namespace: istio-cni
EOF

Without spec.version, the operator installs its default Istio version. If the operator offers several versions, set spec.version in both resources to an Istio 1.30 version.

Cluster That Already Runs Istio

If the cluster already has a Service Mesh control plane, do not run the install block above: applying it would overwrite the existing Istio resource. Attendees can use the existing mesh instead. Check these points first:

  • Discovery selectors: if the Istio resource sets spec.values.meshConfig.discoverySelectors, the control plane ignores namespaces that do not match. Label each attendee namespace to match (for example istio-discovery=enabled) when you create it in Attendee Accounts, Projects and Roles; attendees cannot label their own namespaces.

  • Revision: use the existing revision for istio.io/rev and set the istio_revision attribute to it (see Control Plane Revision). Do not add an istio-injection label as well.

  • Access log format: the exercises read the default text access-log format. If spec.values.meshConfig.accessLogEncoding is JSON, the log lines in Modules 1 and 4 look different, and the grep and awk filters in Module 4, Exercises 3 and 4 print nothing.

  • Mesh-wide Telemetry: a Telemetry resource in the root namespace (istio-system) can filter access logs or disable metrics. The namespace-level Telemetry from Module 4 overrides the access-log settings; check that istio_requests_total is still reported.

  • Multi-cluster meshes: in a multi-cluster mesh, attendee services also become visible to the other clusters in the mesh.

To find these settings:

oc get istio -o yaml
oc get telemetry -n istio-system

Control Plane Revision

Attendee namespaces are labeled with the revision of the control plane (istio.io/rev). Look up the revision name:

oc get istiorevisions

With the InPlace update strategy the revision is named after the Istio resource, default. With the RevisionBased strategy the name includes the version, for example default-v1-30-5. Set the istio_revision attribute (see Content Attributes) to this name.

Content Attributes

The following AsciiDoc attributes control the values that the pages show. Set them in both content/antora.yml, which the full site uses, and workshops/istio/antora.yml, which applies when this workshop is built alone:

Attribute Default Purpose

istio_version

1.30

Istio version in prose and in links to the Istio repository (release-{istio_version}). Keep it in line with ossm_version.

ossm_version

3.4

OpenShift Service Mesh version in prose.

istio_revision

default

Control plane revision that attendee namespaces are labeled with (istio.io/rev).

user

user1

Attendee username. Showroom sets it per attendee. The pages derive the namespace ({user}-sandbox), the ingress gateway label (istio: ingressgateway-{user}) and the host names (myapp-{user}.example.com) from it, so that the Gateways of different attendees do not select each other’s gateway pods or share host names.

Attendee Accounts, Projects and Roles

Each attendee needs a user account (for example user1) and a namespace named <user>-sandbox (for example user1-sandbox). Attendees do not create the namespace; the exercises start by setting NAMESPACE=user1-sandbox. No provisioning files exist in this repository; run the following commands as a cluster administrator, with the list of attendee usernames.

  1. Create the attendee namespaces and make each attendee an admin of their own namespace. The exercises create Deployments, Services, ConfigMaps and Istio resources, delete AuthorizationPolicies, and use oc exec, oc logs and oc port-forward, which the admin (or edit) role allows:

    for u in user1 user2 user3; do
      oc create namespace "${u}-sandbox"
      oc adm policy add-role-to-user admin "${u}" -n "${u}-sandbox"
    done
  2. Label every attendee namespace for sidecar injection with the revision from Control Plane Revision. Project users cannot label namespaces or list IstioRevisions, so the attendees cannot do this themselves:

    REVISION=default
    for u in user1 user2 user3; do
      oc label namespace "${u}-sandbox" istio.io/rev="${REVISION}" \
        --overwrite
    done
  3. Grant every attendee the read-only view role in istio-system and istio-cni. Module 1, Exercise 1, Step 1 lists the pods and DaemonSets there to check that the mesh is running:

    for u in user1 user2 user3; do
      oc adm policy add-role-to-user view "${u}" -n istio-system
      oc adm policy add-role-to-user view "${u}" -n istio-cni
    done
  4. Check that the admin role in the attendee namespaces covers the Istio APIs. The exercises create resources in the API groups networking.istio.io (Gateway, VirtualService, DestinationRule), security.istio.io (PeerAuthentication, RequestAuthentication, AuthorizationPolicy) and telemetry.istio.io (Telemetry):

    for r in \
        gateways.networking.istio.io \
        virtualservices.networking.istio.io \
        destinationrules.networking.istio.io \
        peerauthentications.security.istio.io \
        requestauthentications.security.istio.io \
        authorizationpolicies.security.istio.io \
        telemetries.telemetry.istio.io; do
      echo -n "$r: "
      oc auth can-i create "$r" \
        -n user1-sandbox \
        --as=user1
    done

    Every line must print yes. If a line prints no, the cluster does not aggregate the Istio APIs into the admin role. Create a ClusterRole for them and bind it in every attendee namespace:

    oc apply -f - <<EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: workshop-istio-editor
    rules:
    - apiGroups: ["networking.istio.io", "security.istio.io", "telemetry.istio.io"]
      resources: ["*"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"]
    EOF
    for u in user1 user2 user3; do
      oc adm policy add-role-to-user workshop-istio-editor "${u}" \
        -n "${u}-sandbox"
    done

The following stays instructor-only: installing the operator, creating and changing the Istio and IstioCNI resources, listing IstioRevisions, labeling namespaces, and any change in istio-system and istio-cni. Attendees only read those two namespaces. Module 1, Exercise 1, Step 3 shows the labeling command for attendees who use their own cluster with cluster administrator permissions.

Attendee Workstation

Attendees need a shell with the following tools. The commands work in a web terminal or a tools pod in the cluster, as long as oc port-forward and the following curl http://localhost:... run in the same shell (Module 2, Exercises 3 and 5; Module 4, Exercises 1 and 7). In a Showroom environment that includes the shared OpenShift 102 CLI tools, the index page shows how to use that container.

Tool Version Where it is used

oc

Matching the cluster version (tested with OpenShift Service Mesh 3.4)

All modules. Must be logged in as the attendee user (oc login).

istioctl

Istio 1.30, matching the control plane (Red Hat build or upstream release)

Module 1, Exercise 3, Step 2 (proxy-config cluster, experimental describe pod); Module 3, Exercise 2, Step 4 (proxy-config endpoint, an alternative with pilot-agent is given); Module 4, Exercise 5 (proxy-config, experimental envoy-stats), which needs it. Optional in Modules 1 and 3.

curl

Any recent version

Module 2 (requests through the port-forwarded ingress gateway); Module 4 (port-forwarded Envoy metrics and admin endpoints). Requests inside the mesh run curl in the curl-client pod and need no local curl.

bash, awk, grep, sort, uniq, head, tail, pkill

Standard POSIX/GNU versions

Loops and log analysis in Modules 2 to 4 (for i in {1..20} needs bash); pkill -f stops port-forwards in Module 4.

Network and Image Access

The attendee workloads pull the following images:

Image Used by

quay.io/nginx/nginx-unprivileged:latest

Demo applications in all modules (test-app, frontend, backend, loadtest-service, failover-v1/v2, circuit-service, auth-service, secure-service, metrics-test)

quay.io/curl/curl:latest

Test clients (curl-client, test-app-2, circuit-client)

OpenShift Service Mesh proxy image (registry.redhat.io/openshift-service-mesh/…​)

Sidecars and the attendee ingress gateways (image: auto is replaced by the injector)

OpenShift Service Mesh operator, istiod and Istio CNI images (registry.redhat.io/openshift-service-mesh/…​)

Control plane, installed by the administrator

External URLs: the exercises do not fetch anything from the internet at run time. The JWT key set in Module 3 is inline in the RequestAuthentication (jwks), and the test token is part of the page. The link to the Istio repository (github.com/istio/istio, Module 3) is reference reading only. All other host names (myapp-{user}.example.com, auth.example.com) are only sent as Host headers or appear in examples that are not applied.

Disconnected or restricted-egress clusters:

  • Mirror the OpenShift Service Mesh 3 operator catalog and its images with oc-mirror, as for any Red Hat operator.

  • Mirror quay.io/nginx/nginx-unprivileged:latest and quay.io/curl/curl:latest and add an ImageDigestMirrorSet (or ImageTagMirrorSet, because the exercises use tags), or allow egress to quay.io.

  • Attendees need oc and, for Module 4, Exercise 5, istioctl on their workstation or in the web terminal before the lab.

Verification Checklist

Run as the instructor (cluster administrator):

oc get istio default            # Ready/Healthy, one revision in use
oc get istiocni default         # Ready/Healthy

oc get istiorevisions           # one revision, name equals
                                # istio_revision, READY True

oc get pods \
  -n istio-system \
  -l app=istiod                 # istiod pods Running

oc get daemonset -n istio-cni   # DESIRED equals READY
                                # (one pod per node)

oc get namespace -l istio.io/rev --show-labels |
  grep -- -sandbox              # every attendee namespace listed

oc auth can-i create virtualservices.networking.istio.io \
  -n user1-sandbox \
  --as=user1                    # yes

oc auth can-i create pods/portforward \
  -n user1-sandbox \
  --as=user1                    # yes

oc auth can-i list pods \
  -n istio-system \
  --as=user1                    # yes

oc auth can-i patch namespace/user1-sandbox --as=user1   # no

Run as an attendee (or as the instructor with one attendee namespace):

export NAMESPACE=user1-sandbox
oc whoami                       # user1

oc get namespace $NAMESPACE \
  --show-labels                 # contains
                                # istio.io/rev=default

oc get pods \
  -n istio-system \
  -l app=istiod                 # istiod pods Running (no Forbidden)

istioctl version --remote=false # client version 1.30.x
                                # (needed for Module 4, Exercise 5)

Then deploy the test application of Module 1, Exercise 1, Step 5. The pod must become Running with an istio-proxy container next to the application container (Step 6); this confirms the image pulls, the namespace label and the sidecar injection.