Certifications · ICA

ICA Study Plan

The ICA blueprint lays out the four official domains, their weights, and the two resource pairs — VirtualService + DestinationRule, PeerAuthentication + AuthorizationPolicy — you'll be asked to write from memory. This page turns that into a calendar. Four weeks, twenty-one study days, and a day count derived straight from the published weights instead of an even four-way split: Traffic Management is 35% of the exam — worth more than Securing Workloads and Troubleshooting combined — and it claims the widest block on the schedule below, spanning most of weeks one and two. But day count alone isn't the whole story here, because the ICA is the one hybrid credential on this entire shelf. Every domain in this plan also carries an hours-on-a-keyboard budget, because a performance-based exam does not reward a candidate who has only ever read about a DestinationRule. Add up all four domains and roughly two-thirds of this plan's total hours are spent hands-on a real cluster, not a screen of prose.

☺ Explain it like I'm 10

A flight school doesn't hand out a license for passing a written test alone. Student pilots log a minimum number of real flight hours before they're allowed to sit the practical check — and those hours aren't spread evenly across every maneuver. Instructors spend far more logged time on maneuvers that come up constantly in the real world, and comparatively little on the rare ones. This plan runs the same way. Four weeks, and the calendar isn't cut into four equal slices: the domain worth more than a third of the exam gets more than a third of the calendar, and inside every week, roughly two hours strapped into a real cluster for every one hour spent reading about it. Reading tells you what a maneuver looks like. Only logged hours tell you whether your hands know how to fly it.

🦉🦫Your hosts for this topic: Professor Owl & Benny the Beaver — Owl already hosts the ICA blueprint and knows the mesh's architecture cold; Benny turns every study plan on this course into hands actually on a cluster, which is exactly what a hybrid performance-based exam rewards.

Twenty-one days, weighted like the exam — not the calendar

☺ Like you're 10: Don't give every domain the same number of days, and don't spend all your time reading either. Give the big domain more days, and give every domain more hands-on time than reading time.

The CNCF publishes four weighted domains for the ICA, and this plan does nothing cleverer than turning that percentage straight into a day count and an hours budget. Read the full domain table and competency list on the ICA blueprint first if you haven't already — this page assumes you already know roughly what each domain covers and spends its words purely on pacing it, and on how much of that pacing happens with your hands on a keyboard.

🦫Installation, Upgrades & Configuration
20%
🐘Troubleshooting
20%

hours for a domain = total domain-study hours × that domain's weight.

This plan spends 30 hours of domain study across twenty study days — a little over seven hours a week, realistic for an exam that puts you at a real command line, not the lighter load a pure knowledge test needs. Applying that formula to the four published weights, and splitting each domain's hours into keyboard time versus reading time:

DomainWeightDaysHours (of 30)Hands-onReading
🐦 Traffic Management35%710.5h6.8h3.7h
🐢 Securing Workloads25%57.5h4.1h3.4h
🦫 Install, Upgrades & Config20%46.0h3.6h2.4h
🐘 Troubleshooting20%46.0h4.5h1.5h
Total100%2030.0h19.0h11.0h
Traffic Mgmt 65% hands-on 35% reading Securing 55% hands-on 45% reading Install 60% hands-on 40% reading Troubleshoot 75% hands-on 25% reading Hands-on cluster time Reading / reference
◆ Key idea

Look at the hands-on column, not just the hours column. Troubleshooting has the smallest hours budget of any domain but the highest hands-on share (75%) — you cannot read your way to recognizing NO_HEALTHY_UPSTREAM at two in the morning; you have to have broken something and watched the message appear. Traffic Management earns both the most days and, in absolute hours, the most keyboard time (6.8h) of anything on this plan. Reading percentages hardest is exactly backwards from where the ICA actually tests you.

Before day one — the Kubernetes you need already, and picking your pace

☺ Like you're 10: Twenty-one days is a guess that fits most people who already know their way around a cluster. If Kubernetes itself is still new, give yourself more runway before you start the clock on this plan.

The ICA lists no formal prerequisite, but nearly every task on the exam assumes you already move through kubectl, a Deployment and a Service without thinking about it — this plan does not re-teach that ground. If any of it is still shaky, this course's own Kubernetes Baseline You Need or the sibling Kubernetes course's CKA track is worth a detour before day one here.

Your starting pointLaneWhat to change
Comfortable with core Kubernetes objects; haven't run Istio or any mesh specificallyStandard — 4 weeks (21 days)Run the plan exactly as written.
Solid Kubernetes fundamentals, but mesh concepts — sidecars, mTLS, workload identity — are genuinely newExtended — 5–6 weeksMultiply every hours figure by 1.3, and read this course's Service Mesh Architecture lesson before Day 1 so the vocabulary isn't brand new mid-plan.
Already run Istio, Linkerd or another mesh in production, or hold CKA/CKSCompressed — 2.5–3 weeksMultiply every hours figure by 0.6, and skip straight to the warning callouts inside each week's section instead of a full first read.

The 21-day schedule at a glance

☺ Like you're 10: Here's the whole four weeks on one strip — which days belong to which domain, sized by how much of the test they're actually worth.

The bar below is the table that follows it, drawn to scale. Block width is day count, not domain count — Traffic Management's block alone is nearly a third of the entire strip, the same claim its 35% weight makes on the real paper. Installation opens the plan even though it isn't the biggest domain, for one practical reason: nothing else in weeks two through four can be practiced hands-on without a mesh already running.

Install 20% · 1–4 Traffic Management 35% · days 5–11 Securing Workloads 25% · 12–16 Troubleshooting 20% · 17–20 🏁 123456789101112131415161718192021 Week 1 · 1–5 Week 2 · 6–10 Week 3 · 11–15 Week 4 · 16–21 Traffic Management (indigo) is nearly a third of the whole strip — the same claim its 35% weight makes
DaysDomain (weight)What to do
1–4Install, Upgrades & Config (20%)Install with istioctl, then again with Helm's three charts; enrol a namespace sidecar and ambient; do a full canary upgrade with revisions and tags.
5–6Traffic Management (35%)Write a VirtualService from memory: host/header/path match, then a weighted route that sums to 100.
7Traffic Management (35%)Add a DestinationRule's subsets underneath it; break the pairing on purpose and watch the 503.
8Traffic Management (35%)Resilience by name: timeouts, retries, then circuit breaking via connectionPool and outlier detection.
9Traffic Management (35%)Fault injection — delay and abort — on a live request path; watch your own latency and error rate bend.
10Traffic Management (35%)Ingress: a Gateway plus a VirtualService naming it in gateways, then the Gateway API form.
11Traffic Management (35%)ServiceEntry for an external workload, plus outboundTrafficPolicy.mode: REGISTRY_ONLY.
12Securing Workloads (25%)PeerAuthentication: roll a namespace from PERMISSIVE to STRICT and watch what it actually breaks.
13Securing Workloads (25%)RequestAuthentication for a JWT issuer — and prove to yourself it rejects invalid tokens, not missing ones.
14Securing Workloads (25%)Write the empty-spec AuthorizationPolicy deny-all, then add one ALLOW on principals and watch traffic return.
15Securing Workloads (25%)The AND/OR trap: one - source: block versus two, and what each actually enforces.
16Securing Workloads (25%)Edge TLS: a Gateway with tls.mode and a credentialName Secret in the gateway's own namespace.
17Troubleshooting (20%)istioctl analyze as the first move, always — lint before you blame anything else.
18Troubleshooting (20%)Control plane: istioctl proxy-status, and what SYNCED, STALE and NOT SENT each mean.
19Troubleshooting (20%)Data plane: proxy-config route|cluster|endpoint|secret against one specific proxy.
20Troubleshooting (20%)Symptom map: RBAC: access denied vs. NO_HEALTHY_UPSTREAM vs. a pod with no sidecar at all.
21Readiness gate & mockWork the practice tasks & question bank, then sit Mock Exam · Set 1 under real time pressure.

Days 1–4 — Install, Upgrades & Configuration, the foundation everything else needs

☺ Like you're 10: Before you can practice steering, someone has to put the ship on the launch pad. That's week one — and it's a fifth of the real exam too, not just a warm-up.

This plan opens with the smallest-tied domain (20%) instead of the biggest one, and the reason is purely practical: none of the traffic, security or troubleshooting practice in weeks two through four works without a mesh already installed and a namespace already enrolled in it. Install with istioctl first — the fast route, built on profiles (default, demo, minimal, ambient) customized with --set or an IstioOperator-shaped file — then tear the cluster down and reinstall with Helm's three charts in order: base for CRDs, istiod for the control plane, gateway per ingress or egress gateway. Doing both is the point; the exam names both paths, and most GitOps setups use Helm precisely because the mesh then arrives through the same reconciler as everything else.

# --- Always run this first ---
istioctl x precheck

# --- Path A: istioctl, a profile, then customized ---
istioctl install --set profile=demo -y
istioctl install --set profile=ambient -y                # ztunnel + CNI agent
istioctl profile diff default demo                       # what a profile changes

# --- Path B: Helm, three charts, in this order ---
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm install istio-base istio/base -n istio-system --create-namespace
helm install istiod     istio/istiod -n istio-system --wait
helm install istio-ingressgateway istio/gateway -n istio-ingress --create-namespace

# --- Enrol a namespace: pick ONE mode, they are mutually exclusive ---
kubectl label namespace launch istio-injection=enabled     # sidecar, default rev
kubectl label namespace launch istio.io/dataplane-mode=ambient
kubectl rollout restart deployment -n launch                # sidecars need a restart

# --- Then a full canary upgrade, revisions AND tags — don't skip this ---
istioctl install --set revision=1-27-0 -y                   # second control plane
istioctl tag set launch-stable --revision 1-27-0            # stable alias for a fleet
kubectl label ns launch istio.io/rev=1-27-0 --overwrite      # move ONE namespace
kubectl rollout restart deployment -n launch
istioctl proxy-status                                        # confirm it actually moved
⚠ The trap this exam sets on purpose

Sidecar injection happens only at pod creation — existing pods are never retrofitted, so a label with no kubectl rollout restart after it changes nothing for anything already running. And if a namespace somehow carries both istio-injection=enabled and istio.io/rev at once, the plain label wins — remove it before moving that namespace onto a revision, or your canary upgrade silently does nothing. Both of these are one-line fixes candidates lose Installation-domain marks over anyway, because the failure is invisible until you specifically check for it.

🦫 Benny's Day 4 drill

Do the whole canary upgrade twice before moving on. First pass: install a second istiod under a revision, move the launch namespace onto it, confirm with istioctl proxy-status that every column reads SYNCED against the new revision. Second pass: relabel back to the old revision and restart again — that's your rollback, and it should take under two minutes once you've done it once. If either pass needs the docs open, that's a sign this domain needs another day before week two starts.

Days 5–11 — Traffic Management, the 35% that decides your result

☺ Like you're 10: Almost forty cents of every dollar this exam is worth lives in two resources working together: one that decides where a request goes, and one that decides what happens to it once it gets there.

A VirtualService decides where a request goes: match on host, header, path or method, then route, split by weight, retry, time out, mirror or inject a fault. A DestinationRule decides what happens after routing: named subsets plus a trafficPolicy — load balancer, connection pools, outlier detection, TLS mode. Weights in one route must sum to 100, and a subset a VirtualService names but no DestinationRule defines is a 503 — the single most common self-inflicted wound on this domain. Write this pair from memory on Days 5–7, then diff your version against the reference below field by field:

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: mission-api
  namespace: launch
spec:
  host: mission-api.launch.svc.cluster.local
  subsets:
    - name: v1
      labels: { version: v1 }
    - name: v2
      labels: { version: v2 }
  trafficPolicy:
    loadBalancer: { simple: LEAST_REQUEST }
    connectionPool:                    # ---- circuit breaking ----
      tcp:  { maxConnections: 100 }
      http:
        http2MaxRequests: 200
        maxRequestsPerConnection: 10
        http1MaxPendingRequests: 32    # queue depth before requests are shed
    outlierDetection:                  # ---- eject unhealthy endpoints ----
      consecutive5xxErrors: 5
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: mission-api
  namespace: launch
spec:
  hosts: ["mission-api"]               # short name = in-mesh (east-west) traffic
  gateways: ["mesh"]                   # omit this and edge rules never apply here
  http:
    - fault:                           # ---- fault injection, Day 9 ----
        delay: { percentage: { value: 5 }, fixedDelay: 3s }
        abort: { percentage: { value: 1 }, httpStatus: 503 }
      timeout: 2s                      # ---- timeout, Day 8 ----
      retries:                         # ---- retries, Day 8 ----
        attempts: 3
        perTryTimeout: 500ms
        retryOn: 5xx,reset,connect-failure
      route:                           # ---- traffic shifting: must total 100 ----
        - destination: { host: mission-api, subset: v1 }
          weight: 90
        - destination: { host: mission-api, subset: v2 }
          weight: 10

Days 10–11 move to the mesh's edges. Ingress is a Gateway — a listener bound to a gateway deployment by pod labels — plus a VirtualService that names it in the gateways field; leave that field off (or forget it defaults to mesh for in-cluster traffic only) and edge rules never take effect, the classic "why is my route being ignored?" The project's stated direction is the vendor-neutral Gateway API (Gateway + HTTPRoute, gatewayClassName: istio), so practice writing both forms of the same route. For workloads outside the mesh, a ServiceEntry registers them as if they were in it, usually paired with outboundTrafficPolicy.mode: REGISTRY_ONLY so anything not explicitly declared simply cannot leave.

◆ Key idea

Notice how many of the seven Traffic Management competencies live on fields inside one trafficPolicy block — circuit breaking, outlier detection, and (if you go looking) locality failover all nest under DestinationRule.spec.trafficPolicy, while timeouts, retries and fault injection sit on the VirtualService instead. Knowing which resource owns which field is worth more marks here than knowing any single field's default value.

Days 12–16 — Securing Workloads, the 25%

☺ Like you're 10: One rule checks whether a caller is wearing the mesh's own ID badge. A second rule checks whether that badge is actually allowed through this particular door. Learning which rule answers which question is most of this domain.

PeerAuthentication answers "must the caller present a mesh certificate?" — workload identity, with mode: STRICT the zero-trust setting. RequestAuthentication answers "is this end user's JWT valid, and who issued it?" — on its own it rejects only invalid tokens, never missing ones. AuthorizationPolicy is where both identities actually get enforced.

apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: launch          # in istio-system with no selector = mesh-wide
spec:
  mtls:
    mode: STRICT              # STRICT | PERMISSIVE | DISABLE | UNSET
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-flight-console
  namespace: launch
spec:
  selector:
    matchLabels: { app: mission-api }
  action: ALLOW
  rules:
    - from:
        # Keys INSIDE one source are ANDed; separate `- source:` entries are ORed.
        # Both keys here: caller must be the flight-console SA *and* carry a valid JWT.
        - source:
            principals:               # workload identity (SPIFFE), NOT an IP
              - cluster.local/ns/launch/sa/flight-console
            requestPrincipals:        # end-user identity: "/"
              - "https://accounts.mission.example.com/*"
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/telemetry*"]
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: launch
spec:
  {}                          # empty spec = ALLOW with zero rules
                               # => nothing is permitted. Know this cold.
⚠ The AND/OR trap — Day 15

Splitting principals and requestPrincipals into two separate - source: entries — the commonest way to accidentally write the policy above — silently turns "service identity and valid token" into "service identity or valid token," which is a hole rather than a policy. Keys inside one source, from, to or when block are ANDed; separate list entries under from or to, and separate entries under rules, are all ORed. Spend Day 15 writing both versions side by side and testing each with a real request until this stops being something you have to think about.

🦆 Dot's-eye view

"Most days the mesh is invisible to me. I write my service, I ship it, and traffic just arrives. The one time I actually notice it exists is when I get RBAC: access denied on a call that used to work fine — and then I need someone who can read an AuthorizationPolicy the way I read a stack trace, because from where I sit the error message tells me nothing about which rule fired or why."

Days 17–21 — Troubleshooting, the readiness gate, and the mock

☺ Like you're 10: If something's broken, check three things in order: is the rule written correctly, did the rule actually reach the right place, and is this one proxy actually following it?

The final 20% splits into exactly the three things that can be wrong, named in a useful order: your configuration, the control plane, the data plane. Work them in that order and most failures fall out fast — this is also the domain with the highest hands-on share (75%) on this plan's budget, because recognizing a symptom under time pressure is a reflex you build by breaking things on purpose, not a fact you memorize.

# 1. CONFIGURATION — lint before you blame anything else
istioctl analyze -n launch

# 2. CONTROL PLANE — is istiod healthy, and did the push land?
kubectl -n istio-system get pods
istioctl proxy-status                # alias: ps. All columns SYNCED?
                                      # STALE = push stuck · NOT SENT = nothing to send

# 3. DATA PLANE — what does ONE proxy actually believe?
istioctl proxy-config route    mission-api-7d9f-abcde.launch --name 8080
istioctl proxy-config cluster  mission-api-7d9f-abcde.launch
istioctl proxy-config endpoint mission-api-7d9f-abcde.launch \
  --cluster "outbound|8080|v2|mission-api.launch.svc.cluster.local"
istioctl proxy-config secret   mission-api-7d9f-abcde.launch   # did the cert arrive?

# Plain-English summary: mTLS mode, policies and routes for one pod
istioctl x describe pod mission-api-7d9f-abcde.launch

Learn the symptoms that map to a single cause on Day 20, because recognition beats deduction under a clock: RBAC: access denied is an AuthorizationPolicy, not a network fault. 503 with NO_HEALTHY_UPSTREAM means the cluster exists but has no endpoints; a fresh 503 right after a routing change usually means a subset the VirtualService names and no DestinationRule defines. A pod with no sidecar at all is almost always a namespace label applied after the pod was already running — the same mistake from Days 1–4, showing up two weeks later.

Day 21 is the gate. Don't open Mock Exam · Set 1 until every box below is honestly true, not "true if I squint":

Five or more checked, spanning all three categories, is a reasonable green light. Fewer than that, don't force the calendar — return to the specific day range above, not a general re-read of everything. Once clear, work the ICA practice tasks & questions, then sit Mock Exam · Set 1 under real conditions — clock running, one documentation tab if that's what the current handbook permits, nothing else. If it's close but not comfortable, hold your booking, spend one more evening on whichever domain the mock exposed, and sit Set 2 and Set 3 before committing a date. One score near the line is noise; two or three consistent scores above it is signal.

⚠ Verify officially before booking

This is an independent, unofficial study resource — not affiliated with or endorsed by the CNCF or The Linux Foundation. As of writing in 2026, the Linux Foundation's own ICA listing describes a 2-hour, remote-proctored exam combining performance-based tasks with multiple-choice items, priced at roughly US$250 for the exam alone (training bundles cost more), including one free retake, a 12-month eligibility window in which to sit it, and 2-year certification validity once you pass. Neither the exact item count nor an official pass mark is published anywhere — treat any specific pass-mark figure you read on a study blog, including implicitly on any page of this course, as unverified community anecdote. Don't confuse the two clocks either: the eligibility window is how long you have to sit the exam after buying it, and validity is how long the credential lasts after you pass — for a version-pinned exam like this one, sitting early in your window is risk management, not just good discipline. Read the current official ICA page and candidate handbook before you register or pay for anything; if this page disagrees with them, they are right and this page is stale.

🎬 At Mission Control
🦊

Foxy: Four weeks, four domains — one a week? Feels almost generous.

🦉

Professor Owl: Try telling that to Traffic Management. It's worth more than a third of the paper on its own — it gets the better part of two weeks here, not one.

🦫

Benny: And every week, roughly two hours of my hands on a real cluster for every one hour of reading. This exam actually watches you type. Reading alone doesn't survive contact with that.

👺

Gizmo: Or — hot tip — just memorize the YAML shapes. It's basically a quiz with extra steps. 😈

🐢

Timmy: It is not "basically a quiz," Gizmo. A proctor watches a real terminal while you write it live. Memorizing the shape of a DestinationRule isn't the same skill as typing one correctly under a clock.

🦊

Foxy: Fine. Twenty-one days, mostly hands-on, front-loaded on the domain worth more than a third. I can work with that.

🐢 Timmy's checkpoint

1. How many of the twenty-one days does this plan give Traffic Management, and why is that more than a simple one-quarter-per-domain split would give it? 2. Roughly what fraction of this plan's total study hours are hands-on a cluster rather than reading, and which single domain has the highest hands-on share? 3. Why does this plan install the mesh in week one even though Installation is tied for the smallest domain weight? 4. In an AuthorizationPolicy, what happens if you split principals and requestPrincipals into two separate - source: entries instead of one? 5. Name the three-step troubleshooting ladder and the istioctl command at each step. 6. What two figures about the ICA does the Linux Foundation not publish at all, and what should you do instead of trusting a third-party number for them? 7. What is the difference between the ICA's eligibility window and its certification validity?

Check your answers
  1. Seven of the twenty-one days (Days 5–11) — close to a third of the whole plan, matching Traffic Management's 35% weight, which is worth more than Securing Workloads (25%) and Troubleshooting (20%) combined.
  2. Roughly two-thirds (19.0 of 30.0 hours). Troubleshooting has the highest hands-on share at 75%, despite having the smallest hours budget of any domain (6.0h) — because recognizing a failure symptom is a reflex you build by breaking things, not a fact you can memorize.
  3. Because nothing in weeks two through four — traffic management, security, or troubleshooting — can be practiced hands-on without a mesh already installed and a namespace already enrolled in it. Installation isn't the biggest domain, but it's the dependency everything else needs first.
  4. It silently turns "service identity and a valid token" into "service identity or a valid token" — a hole, not a policy. Keys inside one source block are ANDed; separate - source: entries are ORed.
  5. Configurationistioctl analyze. Control planeistioctl proxy-status, checking every column reads SYNCED. Data planeistioctl proxy-config route|cluster|endpoint|secret against one specific proxy.
  6. The exact item/task count and an official pass mark — neither is published by the Linux Foundation. Treat any specific number for either one, on this page or anywhere else, as unverified community anecdote, and confirm current guidance on the official ICA page and candidate handbook instead.
  7. The eligibility window (12 months, as of writing) is how long you have to sit the exam after buying it. Certification validity (2 years, as of writing) is how long the credential lasts after you pass it — two separate clocks that start at different moments.