Skip to content

OpenShift Service Mesh 2.x Cheatsheet

OpenShift Service Mesh 2.x Cheatsheet

Cheatsheet pratica per OpenShift Service Mesh (OSSM 2.x) su OpenShift, orientata a:

  • replica di uno ServiceMeshControlPlane (SMCP) su un cluster nuovo
  • ingress gateway con NodePort fissi 30001 e 30002
  • variante senza nodeSelector/tolerations infra
  • variante con scheduling dei pod sui nodi infra
  • rimozione di additionalIngress di backend
  • disabilitazione di Jaeger nel control plane
  • verifica e troubleshooting operativo

Esempi pensati per namespace di control plane istio-system.


1. Prerequisiti minimi

Verifica gli operator installati:

Terminal window
oc get csv -A | egrep 'service-mesh|kiali|jaeger|tempo|distributed-tracing'
oc get crd | egrep 'servicemeshcontrolplanes|servicemeshmemberrolls|jaegers|tempostacks'

Verifica le API disponibili:

Terminal window
oc api-resources | egrep 'ServiceMeshControlPlane|ServiceMeshMemberRoll|Istio'
oc explain servicemeshcontrolplane --api-version=maistra.io/v2

Crea il namespace del control plane se manca:

Terminal window
oc new-project istio-system

2. Ispezione veloce del mesh esistente

SMCP corrente:

Terminal window
oc -n istio-system get smcp
oc -n istio-system get smcp basic -o yaml
oc -n istio-system get smcp basic -o yaml | kubectl-neat

Stato sintetico:

Terminal window
oc -n istio-system get smcp basic -o jsonpath='{.status.conditions[*].type}{"\n"}{.status.conditions[*].status}{"\n"}{.status.conditions[*].message}{"\n"}'

Gateway e service creati:

Terminal window
oc -n istio-system get svc
oc -n istio-system get deploy
oc -n istio-system get pods -o wide

Verifica porte ingress:

Terminal window
oc -n istio-system get svc istio-ingressgateway -o jsonpath='{range .spec.ports[*]}{.name}{" port="}{.port}{" nodePort="}{.nodePort}{" targetPort="}{.targetPort}{"\n"}{end}'

3. Manifest completo SMCP “target” pulito

Caratteristiche:

  • version: v2.6
  • mode: ClusterWide
  • policy/telemetry: Istiod
  • Jaeger disabilitato
  • nessun nodeSelector infra
  • nessuna additionalIngress
  • ingress principale NodePort
  • 30001 per HTTP
  • 30002 per HTTPS
  • openshiftRoute.enabled: false

Salva come smcp-basic.yaml:

apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
metadata:
name: basic
namespace: istio-system
spec:
version: v2.6
mode: ClusterWide
profiles:
- default
policy:
type: Istiod
telemetry:
type: Istiod
security:
certificateAuthority:
type: Istiod
istiod:
type: PrivateKey
privateKey:
rootCADir: /etc/cacerts
dataPlane:
mtls: true
addons:
grafana:
enabled: true
install:
service:
ingress:
enabled: true
metadata:
annotations:
service.alpha.openshift.io/serving-cert-secret-name: grafana-tls
kiali:
enabled: true
name: kiali
install:
dashboard:
viewOnly: false
service:
ingress:
enabled: true
prometheus:
enabled: true
install:
service:
ingress:
enabled: true
metadata:
annotations:
service.alpha.openshift.io/serving-cert-secret-name: prometheus-tls
gateways:
enabled: true
openshiftRoute:
enabled: false
ingress:
enabled: true
runtime:
deployment:
autoScaling:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi
service:
type: NodePort
ports:
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30001
- name: https
port: 443
protocol: TCP
targetPort: 8443
nodePort: 30002
egress:
enabled: true
runtime:
deployment:
autoScaling:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi
service: {}
runtime:
components:
pilot:
deployment:
autoScaling:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi
defaults:
deployment:
podDisruption:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi

Applica:

Terminal window
oc apply -f smcp-basic.yaml

Controlla il rollout:

Terminal window
oc -n istio-system get smcp basic
oc -n istio-system get pods
oc -n istio-system get deploy
oc -n istio-system get svc istio-ingressgateway

3-bis. Manifest completo SMCP “target” con scheduling sui nodi infra

Red Hat documenta esplicitamente che, per eseguire i componenti del control plane su nodi infrastrutturali, vanno aggiunti nodeSelector e tolerations in:

  • spec.runtime.defaults.pod
  • spec.runtime.components.pilot.pod
  • spec.gateways.ingress.runtime.pod
  • spec.gateways.egress.runtime.pod

Questa è la variante pratica del manifest precedente, adattata al tuo caso:

  • version: v2.6
  • tracing.type: None
  • niente additionalIngress
  • ingress principale NodePort
  • 30001 per HTTP
  • 30002 per HTTPS
  • scheduling su nodi infra

Nota: le tolerations dipendono dai taint reali dei tuoi nodi infra. Nel tuo ambiente hai già verificato che funzionano queste:

  • NoSchedule su node-role.kubernetes.io/infra
  • NoExecute su node-role.kubernetes.io/infra
  • NoSchedule su node.ocs.openshift.io/storage

Salva come smcp-basic-infra.yaml:

apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
metadata:
name: basic
namespace: istio-system
spec:
version: v2.6
mode: ClusterWide
profiles:
- default
policy:
type: Istiod
telemetry:
type: Istiod
tracing:
type: None
security:
certificateAuthority:
type: Istiod
istiod:
type: PrivateKey
privateKey:
rootCADir: /etc/cacerts
dataPlane:
mtls: true
addons:
grafana:
enabled: true
install:
service:
ingress:
enabled: true
metadata:
annotations:
service.alpha.openshift.io/serving-cert-secret-name: grafana-tls
kiali:
enabled: true
name: kiali
install:
dashboard:
viewOnly: false
service:
ingress:
enabled: true
prometheus:
enabled: true
install:
service:
ingress:
enabled: true
metadata:
annotations:
service.alpha.openshift.io/serving-cert-secret-name: prometheus-tls
gateways:
enabled: true
openshiftRoute:
enabled: false
ingress:
enabled: true
runtime:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
deployment:
autoScaling:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi
service:
type: NodePort
ports:
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30001
- name: https
port: 443
protocol: TCP
targetPort: 8443
nodePort: 30002
egress:
enabled: true
runtime:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
deployment:
autoScaling:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi
service: {}
runtime:
components:
pilot:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
deployment:
autoScaling:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi
defaults:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
deployment:
podDisruption:
enabled: false
container:
resources:
requests:
cpu: 10m
memory: 128Mi

Applica:

Terminal window
oc apply -f smcp-basic-infra.yaml

Verifica che i pod del control plane siano finiti sui nodi infra:

Terminal window
oc -n istio-system get pods -o wide
oc get nodes --show-labels | grep node-role.kubernetes.io/infra

Filtro utile:

Terminal window
oc -n istio-system get pod -o wide | egrep 'istiod|istio-ingress|istio-egress|grafana|prometheus|kiali'

Patch rapida per aggiungere scheduling infra a uno SMCP già esistente

Terminal window
oc -n istio-system patch smcp basic --type=merge -p '
spec:
gateways:
ingress:
runtime:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
egress:
runtime:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
runtime:
components:
pilot:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
defaults:
pod:
nodeSelector:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/infra
- effect: NoExecute
key: node-role.kubernetes.io/infra
- effect: NoSchedule
key: node.ocs.openshift.io/storage
'

4. Verifica veloce dei NodePort

Terminal window
oc -n istio-system get svc istio-ingressgateway -o jsonpath='{range .spec.ports[*]}{.name}{" port="}{.port}{" nodePort="}{.nodePort}{"\n"}{end}'

Output atteso:

status-port port=15021 nodePort=<assegnato dal cluster oppure vuoto se non fissato>
http port=80 nodePort=30001
https port=443 nodePort=30002

Verifica completa del service:

Terminal window
oc -n istio-system describe svc istio-ingressgateway

5. ServiceMeshMemberRoll minimo

Il control plane esiste, ma per fare entrare namespace applicativi nella mesh devi aggiungerli al ServiceMeshMemberRoll.

Salva come smmr-default.yaml:

apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
name: default
namespace: istio-system
spec:
members:
- my-app-ns
- my-api-ns

Applica:

Terminal window
oc apply -f smmr-default.yaml

Verifica:

Terminal window
oc -n istio-system get smmr default -o yaml

6. Sidecar injection

Controlla i namespace membri:

Terminal window
oc -n istio-system get smmr default -o jsonpath='{.spec.members[*]}'

Per deployment specifico, annota o etichetta il pod template.

Annotazione sul Deployment

Terminal window
oc -n my-app-ns patch deploy myapp \
--type='json' \
-p='[{"op":"add","path":"/spec/template/metadata/annotations","value":{"sidecar.istio.io/inject":"true"}}]'

Label sul Deployment

Terminal window
oc -n my-app-ns label deploy myapp sidecar.istio.io/inject=true --overwrite

Verifica che il pod abbia 2 container:

Terminal window
oc -n my-app-ns get pods
oc -n my-app-ns get pod <pod> -o jsonpath='{.spec.containers[*].name}{"\n"}'

Controlla l’injection:

Terminal window
oc -n my-app-ns describe pod <pod> | egrep -i 'istio-proxy|sidecar.istio.io/inject'

7. Gateway + VirtualService di esempio

Gateway

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: public-gateway
namespace: my-app-ns
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com

VirtualService

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp-vs
namespace: my-app-ns
spec:
hosts:
- app.example.com
gateways:
- public-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
host: myapp.my-app-ns.svc.cluster.local
port:
number: 8080

Applica:

Terminal window
oc -n my-app-ns apply -f gateway.yaml
oc -n my-app-ns apply -f virtualservice.yaml

Verifica:

Terminal window
oc -n my-app-ns get gateway,virtualservice
oc -n istio-system logs deploy/istio-ingressgateway -c istio-proxy --tail=100

8. Accesso tramite NodePort

Trova un node IP raggiungibile:

Terminal window
oc get nodes -o wide

Test HTTP:

Terminal window
curl -H 'Host: app.example.com' http://<NODE_IP>:30001/

Test HTTPS:

Terminal window
curl -k -H 'Host: app.example.com' https://<NODE_IP>:30002/

9. Patch utili

Disabilitare Jaeger su uno SMCP già esistente

Terminal window
oc -n istio-system patch smcp basic --type=json \
-p='[
{"op":"remove","path":"/spec/tracing"},
{"op":"remove","path":"/spec/addons/jaeger"}
]'

Impostare NodePort 30001/30002 sull’ingress esistente

Terminal window
oc -n istio-system patch smcp basic --type=merge -p '
spec:
gateways:
ingress:
service:
type: NodePort
ports:
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30001
- name: https
port: 443
protocol: TCP
targetPort: 8443
nodePort: 30002
'

Disabilitare l’OpenShift route management

Terminal window
oc -n istio-system patch smcp basic --type=merge -p '
spec:
gateways:
openshiftRoute:
enabled: false
'

10. Troubleshooting rapido

10.0 I pod non vanno sui nodi infra

Verifica i label dei nodi:

Terminal window
oc get nodes --show-labels | grep node-role.kubernetes.io/infra

Verifica eventuali taint:

Terminal window
oc describe node <infra-node> | egrep -A5 'Taints:|Roles:'

Verifica che lo SMCP contenga davvero i blocchi pod.nodeSelector / pod.tolerations:

Terminal window
oc -n istio-system get smcp basic -o yaml | egrep -A8 'defaults:|pilot:|ingress:|egress:|nodeSelector:|tolerations:'

Verifica dove sono schedulati i pod:

Terminal window
oc -n istio-system get pod -o wide

Cause tipiche:

  • i nodi hanno label infra ma anche taint diversi da quelli tollerati
  • hai messo runtime.defaults.pod, ma non pilot / ingress / egress
  • lo SMCP non è ancora stato reconciliato
  • stai applicando un dump completo invece di un manifest pulito

10.1 Errore metadata.resourceVersion must be specified for an update

Capita quando usi oc replace oppure stai cercando di aggiornare un dump completo senza resourceVersion valida.

Correzione pratica:

  • usa un manifest pulito con solo apiVersion, kind, metadata.name, metadata.namespace, spec
  • usa oc apply -f ...
  • non includere status, managedFields, uid, creationTimestamp, resourceVersion

Comando corretto:

Terminal window
oc apply -f smcp-basic.yaml

10.2 Errore Dependency "Jaeger CRD" is missing

Succede se nello SMCP hai:

spec:
tracing:
type: Jaeger

oppure:

spec:
addons:
jaeger:
...

ma nel cluster non hai Jaeger Operator / CRD.

Correzioni possibili:

  • installare Jaeger Operator
  • oppure rimuovere spec.tracing e spec.addons.jaeger

Verifiche:

Terminal window
oc get crd | grep jaeger
oc get csv -A | grep -i jaeger

10.3 Il service istio-ingressgateway non ha i NodePort attesi

Verifica:

Terminal window
oc -n istio-system get svc istio-ingressgateway -o yaml

Possibili cause:

  • SMCP non ancora reconciled
  • operator che ha rifiutato il campo
  • altra configurazione del gateway ancora presente

Controlla stato SMCP:

Terminal window
oc -n istio-system get smcp basic -o yaml | egrep -A5 'conditions:|message:|reason:'

Controlla eventi:

Terminal window
oc -n istio-system get events --sort-by=.metadata.creationTimestamp

10.4 I pod applicativi non ricevono il sidecar

Checklist:

Terminal window
oc -n istio-system get smmr default -o yaml
oc -n my-app-ns get deploy myapp -o yaml | egrep -A3 'sidecar.istio.io/inject|labels:|annotations:'
oc -n my-app-ns get pod <pod> -o jsonpath='{.spec.containers[*].name}{"\n"}'

Cause tipiche:

  • namespace non presente nel ServiceMeshMemberRoll
  • deployment/pod senza injection abilitata
  • pod non ricreati dopo la modifica

Forza rollout:

Terminal window
oc -n my-app-ns rollout restart deploy/myapp
oc -n my-app-ns rollout status deploy/myapp

11. Comandi utili “day 2”

Pods e controllo rapido:

Terminal window
oc -n istio-system get pods -o wide
oc -n istio-system top pod
oc -n istio-system describe pod <pod>

Log ingress gateway:

Terminal window
oc -n istio-system logs deploy/istio-ingressgateway -c istio-proxy --tail=200

Log pilot:

Terminal window
oc -n istio-system logs deploy/istiod --tail=200

Lista risorse mesh namespace applicativo:

Terminal window
oc -n my-app-ns get gateway,virtualservice,destinationrule,peerauthentication,authorizationpolicy,requestauthentication

Dump completo namespace mesh:

Terminal window
oc -n istio-system get all,cm,secret,sa,role,rolebinding

12. Cleanup

Rimuovere SMCP:

Terminal window
oc -n istio-system delete smcp basic

Rimuovere SMMR:

Terminal window
oc -n istio-system delete smmr default

Rimuovere namespace di test:

Terminal window
oc delete project my-app-ns

13. Note operative

  • Per SMCP esistenti, preferisci oc apply o oc patch; evita oc replace su YAML esportati al volo.
  • Se non ti servono route OpenShift gestite automaticamente, tieni spec.gateways.openshiftRoute.enabled: false.
  • Se vuoi solo accesso da F5 / VIP / nodi, i NodePort fissi sono spesso la soluzione più semplice.
  • Se il cluster è nuovo, parti dal control plane minimale e aggiungi dopo SMMR, Gateway e VirtualService.
  • Se hai installato Tempo ma non Jaeger, non lasciare spec.tracing.type: Jaeger nello SMCP.

14. Riferimenti ufficiali da tenere aperti

  • OpenShift Container Platform 4.16 - Service Mesh
  • OpenShift Container Platform 4.19 - Service Mesh 2.x
  • Red Hat OpenShift Service Mesh 3 - Migrating from Service Mesh 2 to 3

15. Schema visivo: come funziona OSSM

15.1 Vista logica end-to-end

+-----------------------------------+
| Namespace istio-system |
|-----------------------------------|
| ServiceMeshControlPlane (SMCP) |
| - definisce il control plane |
| - configura ingress/egress |
| - abilita telemetry / policy |
| - imposta mTLS / tracing |
| |
| Istiod |
| - distribuisce config ai proxy |
| - service discovery / xDS |
| - cert/mTLS per i sidecar |
| |
| Prometheus / Grafana / Kiali |
| - metriche / dashboard / topology |
+----------------+------------------+
|
| config / cert / policy
v
+------------------+ NodePort 30001/30002 +--+-----------------------+
| Client / F5 / LB | ----------------------------> | istio-ingressgateway |
| / consumer est. | | (Envoy gateway) |
+------------------+ +------------+-------------+
|
| match Gateway + VirtualService
v
+------------------+------------------+
| Namespace applicativo nel mesh |
| (presente nello SMMR) |
|-------------------------------------|
| Service |
| | |
| v |
| Pod app + sidecar Envoy |
| - traffico intercettato dal sidecar |
| - mTLS / policy / metrics |
+------------------+------------------+
|
| east-west traffic
v
+------------------+------------------+
| Altro namespace / altro servizio |
| Pod app + sidecar Envoy |
+------------------+------------------+
|
| traffico esterno opzionale
v
+---------+-----------+
| istio-egressgateway |
| (uscita controllata)|
+---------+-----------+
|
v
External service

15.2 Vista “chi fa cosa”

SMCP
└─ è la CR principale del mesh
decide come installare e configurare il control plane
SMMR / ServiceMeshMember
└─ decide quali namespace applicativi entrano nel mesh
Istiod
├─ scopre servizi e workload
├─ genera/distribuisce configurazione ai proxy Envoy
├─ gestisce identità e certificati per mTLS
└─ applica routing, resilienza e policy
Ingress Gateway
├─ riceve traffico dall'esterno
├─ espone Service NodePort / LoadBalancer / Route
└─ inoltra ai servizi interni in base a Gateway + VirtualService
Egress Gateway
├─ opzionale
├─ centralizza l'uscita verso sistemi esterni
└─ utile per auditing, policy e percorsi di rete controllati
Sidecar Envoy nei pod applicativi
├─ intercetta il traffico in ingresso/uscita del pod
├─ applica mTLS, retry, timeout, circuit breaking, metriche
└─ parla con Istiod per ricevere configurazione
Kiali
└─ vista topologica del mesh, health, route, policy
Prometheus / Grafana
└─ raccolta metriche e dashboard

15.3 Flusso pratico di una richiesta HTTP

1. Client arriva su NodePort 30001 o 30002
2. Il service istio-ingressgateway riceve la connessione
3. Envoy del gateway legge le regole Gateway / VirtualService
4. Il traffico viene inviato al service applicativo corretto
5. Il sidecar Envoy del pod target applica policy / mTLS / metriche
6. Se il servizio chiama un altro servizio mesh, il traffico passa sidecar -> sidecar
7. Se il servizio deve uscire all'esterno, opzionalmente passa da istio-egressgateway
8. Metriche e topologia finiscono in Prometheus / Grafana / Kiali

15.4 Dove mettere i manifest principali

istio-system
├─ ServiceMeshControlPlane
├─ ServiceMeshMemberRoll
├─ gateway resources del control plane
└─ componenti OSSM (istiod, ingress, egress, kiali, prometheus...)
namespace applicativi
├─ Deployment / Service dell'app
├─ Gateway / VirtualService / DestinationRule / PeerAuthentication
└─ pod con sidecar Envoy (se injection abilitata)

15.5 Come leggere il posizionamento sui nodi infra

SMCP
├─ runtime.defaults.pod
├─ runtime.components.pilot.pod
├─ gateways.ingress.runtime.pod
└─ gateways.egress.runtime.pod
Se qui imposti:
nodeSelector:
node-role.kubernetes.io/infra: ""
...e aggiungi le tolerations corrette,
allora i pod del control plane e dei gateway vengono schedulati sui nodi infra.

15.6 Riassunto

SMCP = installa e governa il mesh
SMMR = decide quali namespace stanno nel mesh
Istiod = cervello / control plane
Envoy sidecar = enforcement locale su ogni pod
Ingress gateway = ingresso da fuori
Egress gateway = uscita controllata verso fuori
Kiali/Prometheus/Grafana = osservabilità