@raishin/vanguard-frontier-agentic 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/kubernetes/README.md +10 -1
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/AGENT.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/references/least-privilege-rbac.yaml +98 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/references/rbac-pre-flight.md +108 -0
- package/agents/kubernetes/kubernetes-live-admission-policy-guard-agent/references/refusal-list.md +112 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/AGENT.md +13 -1
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/references/least-privilege-rbac.yaml +92 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/references/rbac-pre-flight.md +108 -0
- package/agents/kubernetes/kubernetes-live-argocd-sync-guard-agent/references/refusal-list.md +112 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/AGENT.md +13 -1
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/references/least-privilege-rbac.yaml +101 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/references/rbac-pre-flight.md +106 -0
- package/agents/kubernetes/kubernetes-live-mesh-policy-guard-agent/references/refusal-list.md +102 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/AGENT.md +71 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/claude-code.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/codex.toml +38 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/copilot.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/cursor.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/gemini.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/harnesses/kiro-ide.agent.md +54 -0
- package/agents/kubernetes/kubernetes-live-network-architecture-mutation-guard-agent/metadata.json +44 -0
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/AGENT.md +14 -2
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/claude-code.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/copilot.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/cursor.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/gemini.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/harnesses/kiro-ide.agent.md +13 -1
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/metadata.json +5 -3
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/references/least-privilege-rbac.yaml +101 -0
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/references/rbac-pre-flight.md +106 -0
- package/agents/kubernetes/kubernetes-live-network-policy-guard-agent/references/refusal-list.md +102 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/AGENT.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/claude-code.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/copilot.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/cursor.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/gemini.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/harnesses/kiro-ide.agent.md +12 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/metadata.json +6 -3
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/references/least-privilege-rbac.yaml +92 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/references/rbac-pre-flight.md +115 -0
- package/agents/kubernetes/kubernetes-live-rbac-mutation-guard-agent/references/refusal-list.md +132 -0
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/AGENT.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/claude-code.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/codex.toml +2 -2
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/copilot.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/cursor.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/gemini.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/kiro-cli.agent.json +1 -1
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/harnesses/kiro-ide.agent.md +15 -3
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/metadata.json +6 -4
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/references/least-privilege-rbac.yaml +92 -0
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/references/rbac-pre-flight.md +109 -0
- package/agents/kubernetes/kubernetes-live-velero-restore-guard-agent/references/refusal-list.md +122 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/AGENT.md +65 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/claude-code.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/codex.toml +37 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/copilot.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/cursor.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/gemini.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/kiro-cli.agent.json +5 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/harnesses/kiro-ide.agent.md +48 -0
- package/agents/kubernetes/kubernetes-network-architecture-review-agent/metadata.json +44 -0
- package/catalog/agents.json +78 -12
- package/catalog/install-roles.json +8 -4
- package/catalog/skill-manifest.json +111 -12
- package/catalog/skills.json +67 -0
- package/package.json +1 -1
- package/skills/kubernetes/README.md +5 -1
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/SKILL.md +82 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/metadata.json +33 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/least-privilege-rbac.yaml +210 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/official-sources.md +41 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/permitted-mutations.md +173 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/rbac-pre-flight.md +252 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/refusal-list.md +313 -0
- package/skills/kubernetes/kubernetes-live-network-architecture-mutation-guard/references/rollback-patterns.md +103 -0
- package/skills/kubernetes/kubernetes-maestro/references/safety-checklist.md +1 -1
- package/skills/kubernetes/kubernetes-maestro/references/workflow-and-output.md +57 -5
- package/skills/kubernetes/kubernetes-network-architecture-review/SKILL.md +84 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/metadata.json +34 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/dataplane-and-cni.md +89 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/dns-and-discovery.md +120 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/mcp-and-evidence.md +53 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/multi-cluster-and-egress.md +69 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/official-sources.md +54 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/service-gateway-routing.md +108 -0
- package/skills/kubernetes/kubernetes-network-architecture-review/references/troubleshooting-playbook.md +100 -0
- package/skills/velero/velero-backup-restore-guard/SKILL.md +2 -2
- package/skills/velero/velero-backup-restore-guard/references/safety-checklist.md +1 -1
- package/skills/velero/velero-backup-restore-guard/references/workflow-and-output.md +17 -8
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Multi-Cluster Topology and Egress
|
|
2
|
+
|
|
3
|
+
This reference is about *topology* — how clusters discover and address each other, and how pods leave the cluster — not about cross-cluster *policy*. Cross-cluster policy semantics (e.g. Cilium ClusterMesh `policy-default-local-cluster`) belong to `cilium-network-policy-review`.
|
|
4
|
+
|
|
5
|
+
## Step 1 — Capture the multi-cluster posture
|
|
6
|
+
|
|
7
|
+
- Number of clusters and their relationship: peers (mesh), hub-and-spoke, hierarchical.
|
|
8
|
+
- Pod CIDRs per cluster and Service CIDRs per cluster — non-overlap is the prerequisite for every multi-cluster scheme.
|
|
9
|
+
- Cross-cluster discovery mechanism in use: Cilium ClusterMesh, Submariner, Linkerd multi-cluster, Istio multi-primary or primary-remote, KEP-1645 Multi-Cluster Services API (MCS-API), or hand-rolled `ExternalName` chains.
|
|
10
|
+
- Identity boundary: shared OIDC (workload identity federation), per-cluster identities with explicit trust, or no shared identity (in which case workload-identity review is required before cross-cluster authn is meaningful).
|
|
11
|
+
- Underlay reachability: are pods directly routable across clusters (BGP, AWS VPC peering, VPN), or is traffic gateway-mediated (Submariner gateway, Istio east-west gateway)?
|
|
12
|
+
|
|
13
|
+
## Step 2 — Stress-test pod / service CIDR overlap
|
|
14
|
+
|
|
15
|
+
The first failure of every multi-cluster scheme is overlapping CIDRs. Reject any design that does not declare:
|
|
16
|
+
|
|
17
|
+
- Per-cluster Pod CIDR ranges that do not intersect any peer's Pod CIDR.
|
|
18
|
+
- Per-cluster Service CIDR ranges that do not intersect any peer's Service CIDR (relevant for ClusterMesh and MCS-API where a Service IP from cluster A may be routed from cluster B).
|
|
19
|
+
- A reservation plan with documented headroom — adding a third cluster later usually requires rebuilding overlapping clusters.
|
|
20
|
+
|
|
21
|
+
If overlap is unavoidable (e.g. existing brownfield clusters), the only correct answer is per-cluster NAT — Submariner's Globalnet and Istio's east-west gateway both implement variants of this, at the cost of losing client-IP visibility cross-cluster.
|
|
22
|
+
|
|
23
|
+
## Step 3 — Stress-test the discovery mechanism choice
|
|
24
|
+
|
|
25
|
+
| Mechanism | Strength | Real failure mode |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| Cilium ClusterMesh | eBPF-direct, no extra hops; identity propagation; Hubble flow visibility cross-cluster. | Requires Cilium on every cluster; CA trust setup; the `policy-default-local-cluster` flag flip is a documented landmine (see `cilium-network-policy-review`). **Silent-failure mode 1**: KVStoreMesh `--clustermesh-cache-ttl` defaults to `0s` which per upstream docs means "the cache is never revoked" — when connectivity to a remote cluster is lost, stale `ServiceImports` continue to serve removed endpoints indefinitely. Set a non-zero TTL explicitly. **Silent-failure mode 2**: `--global-ready-timeout` defaults to `10m` — clusters report ready even if remote sync has not converged. Verify with `cilium clustermesh status` and `cilium-dbg troubleshoot clustermesh` (direct mode) or `kubectl -n kube-system exec deploy/clustermesh-apiserver -c kvstoremesh -- clustermesh-apiserver kvstoremesh-dbg troubleshoot` (KVStoreMesh mode). |
|
|
28
|
+
| Submariner | CNI-agnostic, can stitch heterogeneous clusters; Globalnet handles CIDR overlap. | Gateway nodes are choke points (single tunnel pair per gateway); MTU subtraction for the IPsec tunnel must be planned; service discovery via Lighthouse adds DNS hops. |
|
|
29
|
+
| Istio multi-primary / primary-remote | Mesh-native; mTLS-everywhere; locality-aware load balancing. | Operationally complex; East-West Gateway is another L7 hop; cross-cluster health-checking depends on Istio version. |
|
|
30
|
+
| Linkerd multi-cluster | Simple model (mirrored Services); no central control. | Mirror Service per cross-cluster Service grows the API server load; pod identity federation requires explicit trust setup. |
|
|
31
|
+
| KEP-1645 MCS-API (`ServiceExport`, `ServiceImport`) | Vendor-neutral; standardized. | Implementations vary in maturity; check that the chosen controller (mcs-api-controller, AWS Cloud Map MCS, GKE Multi-Cluster Services) actually supports the channel needed. |
|
|
32
|
+
| Hand-rolled `ExternalName` chains | No new infra. | No identity propagation; no health awareness; DNS rotation is the only failover; this is a smell, not a design. |
|
|
33
|
+
|
|
34
|
+
## Step 4 — Stress-test egress topology
|
|
35
|
+
|
|
36
|
+
How pods leave the cluster shapes IAM scoping, firewall rules, and observability.
|
|
37
|
+
|
|
38
|
+
Patterns:
|
|
39
|
+
|
|
40
|
+
- **Default node SNAT** — pods exit via the node's primary interface, source IP is the node IP. Simple, but every pod looks the same to external systems; firewall allowlists must allow the entire node range.
|
|
41
|
+
- **CiliumEgressGatewayPolicy** — selected pods SNAT through a designated gateway node with a stable egress IP. Allows fine-grained external allowlisting. Stress-tests for this pattern belong to `cilium-network-policy-review`.
|
|
42
|
+
- **AWS VPC CNI / Azure CNI native** — pods get VPC IPs and route directly to a NAT Gateway / NAT Router; egress IP is the NAT GW's. IAM must be scoped on a workload-identity basis since the source IP is shared.
|
|
43
|
+
- **Per-namespace egress proxy** — an outbound HTTP/SOCKS proxy in each namespace; pods are forced through it via `HTTP_PROXY` env or NetworkPolicy. Adds a single audit point but is a single failure point.
|
|
44
|
+
- **No egress** — air-gapped clusters where every external dependency is mirrored inside the cluster (registries, package mirrors, time servers). The only safe IAM posture for highly regulated workloads, but operationally heavy.
|
|
45
|
+
|
|
46
|
+
Stress-tests the review must apply:
|
|
47
|
+
|
|
48
|
+
- A pod with `HTTP_PROXY` set but `NO_PROXY` not configured to include `.svc.cluster.local` and the cluster CIDR — every in-cluster call goes through the egress proxy and back, doubling east-west latency.
|
|
49
|
+
- An egress NAT Gateway shared across clusters in the same VPC — billing is per-GB on AWS; cross-AZ egress through a single AZ's NAT GW is a documented cost trap.
|
|
50
|
+
- A managed cluster that disables NodeLocalDNS *and* uses VPC DNS — DNS queries become the dominant egress traffic; NAT GW cost spikes proportionally.
|
|
51
|
+
- A workload that does TLS to an external service through the egress proxy without the proxy being a CONNECT-method TLS proxy — the proxy can only see SNI, not L7, and policy claims of "L7 control" are false.
|
|
52
|
+
|
|
53
|
+
## Step 5 — East-west vs north-south
|
|
54
|
+
|
|
55
|
+
Keep the language honest in any review:
|
|
56
|
+
|
|
57
|
+
- **North-south** — traffic crossing the cluster boundary. Owners: Ingress / Gateway / LoadBalancer Service / egress topology.
|
|
58
|
+
- **East-west** — traffic between pods in the same cluster (or cross-cluster but inside the multi-cluster trust domain). Owners: kube-proxy / Cilium dataplane / Service mesh.
|
|
59
|
+
- **Diagonal** — a pod calling out to a managed cloud service (RDS, Cosmos DB, OCI Autonomous DB) or a SaaS API. This is north-south even though it does not feel like it; cloud network policy applies, not just NetworkPolicy.
|
|
60
|
+
|
|
61
|
+
Many reviews conflate these. Naming the direction explicitly clarifies which controllers, which policy formats, and which observability pane apply.
|
|
62
|
+
|
|
63
|
+
## Output for this section
|
|
64
|
+
|
|
65
|
+
- Cluster relationship map and CIDR plan (no overlap),
|
|
66
|
+
- discovery mechanism and identity boundary,
|
|
67
|
+
- egress topology and source-IP plan,
|
|
68
|
+
- findings on overlap, gateway choke points, IAM scoping for shared egress,
|
|
69
|
+
- explicit handoffs: policy correctness → `cilium-network-policy-review` or `istio-ambient-mesh-review`; IAM scoping → workload-identity-review; cloud-side network architecture → AWS/Azure/OCI network architect agents.
|
package/skills/kubernetes/kubernetes-network-architecture-review/references/official-sources.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Official Sources
|
|
2
|
+
|
|
3
|
+
Load these only when needed.
|
|
4
|
+
|
|
5
|
+
## Kubernetes upstream
|
|
6
|
+
|
|
7
|
+
- [Services, Load Balancing, Networking concepts](https://kubernetes.io/docs/concepts/services-networking/) — the canonical entry point and topic taxonomy.
|
|
8
|
+
- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) — Service types, selectors, ports.
|
|
9
|
+
- [EndpointSlices](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) — replaces the legacy Endpoints object; powers kube-proxy and Cilium socket-LB.
|
|
10
|
+
- [Service Internal Traffic Policy](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/) — `internalTrafficPolicy: Cluster | Local` semantics.
|
|
11
|
+
- [Topology Aware Routing](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/) — `service.kubernetes.io/topology-mode: Auto`.
|
|
12
|
+
- [Dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/) — `ipFamilies` and `ipFamilyPolicy`.
|
|
13
|
+
- [Virtual IPs and Service Proxies (kube-proxy reference)](https://kubernetes.io/docs/reference/networking/virtual-ips/) — iptables, IPVS, nftables, kernelspace modes.
|
|
14
|
+
- [DNS for Services and Pods](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/) — canonical DNS naming, search-list construction.
|
|
15
|
+
- [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) — DaemonSet architecture, conntrack rationale, OOM risks.
|
|
16
|
+
- [Pod Network](https://kubernetes.io/docs/concepts/cluster-administration/networking/) — cluster networking model.
|
|
17
|
+
- [Network Plugins reference](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) — CNI integration.
|
|
18
|
+
|
|
19
|
+
## Gateway API (sig-network)
|
|
20
|
+
|
|
21
|
+
- [Gateway API home](https://gateway-api.sigs.k8s.io/) — resource taxonomy, role-oriented model, conformance.
|
|
22
|
+
- [API stability and channels (Standard / Experimental)](https://gateway-api.sigs.k8s.io/concepts/versioning/) — what's GA vs experimental.
|
|
23
|
+
- [GAMMA service mesh (Standard since v1.1.0)](https://gateway-api.sigs.k8s.io/mesh/gamma/) — routes attached directly to Services.
|
|
24
|
+
- [Implementations](https://gateway-api.sigs.k8s.io/implementations/) — controller list and conformance reports.
|
|
25
|
+
|
|
26
|
+
## Cilium
|
|
27
|
+
|
|
28
|
+
- [Cilium documentation home](https://docs.cilium.io/en/stable/).
|
|
29
|
+
- [Networking concepts (routing, IPAM, masquerading, MTU)](https://docs.cilium.io/en/stable/network/concepts/).
|
|
30
|
+
- [Kube-proxy replacement](https://docs.cilium.io/en/stable/network/kube-proxy-replacement/) — eBPF socket-LB, requirements, mode (Strict / Probe), fallback paths.
|
|
31
|
+
- [System requirements](https://docs.cilium.io/en/stable/operations/system-requirements/) — kernel feature matrix.
|
|
32
|
+
- [ClusterMesh](https://docs.cilium.io/en/stable/network/clustermesh/) — multi-cluster service discovery and identity.
|
|
33
|
+
- [Hubble Observability](https://docs.cilium.io/en/stable/observability/hubble/).
|
|
34
|
+
|
|
35
|
+
## CoreDNS
|
|
36
|
+
|
|
37
|
+
- [Plugin index (Corefile structure)](https://coredns.io/plugins/) — every plugin and its options.
|
|
38
|
+
- [`kubernetes` plugin](https://coredns.io/plugins/kubernetes/) — `pods insecure | verified`, `endpoint_pod_names`, `ttl`, `fallthrough`, `autopath`.
|
|
39
|
+
- [`forward` plugin](https://coredns.io/plugins/forward/) — `max_concurrent`, health-checking, policy.
|
|
40
|
+
- [`cache` plugin](https://coredns.io/plugins/cache/) — TTL, success/denial/prefetch.
|
|
41
|
+
|
|
42
|
+
## Multi-cluster
|
|
43
|
+
|
|
44
|
+
- [KEP-1645: Multi-Cluster Services API](https://github.com/kubernetes/enhancements/blob/master/keps/sig-multicluster/1645-multi-cluster-services-api/README.md) — `ServiceExport`, `ServiceImport`.
|
|
45
|
+
- [Submariner](https://submariner.io/) — CNI-agnostic multi-cluster gateway and Globalnet.
|
|
46
|
+
- [Istio multi-cluster](https://istio.io/latest/docs/setup/install/multicluster/) — primary-remote, multi-primary topologies.
|
|
47
|
+
|
|
48
|
+
## Cluster autoscaling for DNS
|
|
49
|
+
|
|
50
|
+
- [`cluster-proportional-autoscaler`](https://github.com/kubernetes-sigs/cluster-proportional-autoscaler) — the canonical CoreDNS replica autoscaler.
|
|
51
|
+
|
|
52
|
+
## Status of the Linux Foundation Kubernetes Network Engineer program
|
|
53
|
+
|
|
54
|
+
As of 2026-05-07, the Linux Foundation's "[Kubernetes Network Engineer Program](https://training.linuxfoundation.org/kubernetes-network-engineer-program/)" page reports that the CNCF and Linux Foundation Education are *starting to work on* a Certified Kubernetes Network Engineer (CKNE) certification. **The published page does not yet list curriculum domains, learning objectives, or course modules.** This skill is therefore grounded in upstream Kubernetes / Gateway API / Cilium / CoreDNS documentation and not in the (unpublished) CKNE blueprint. When the LF publishes the CKNE domain list, the skill should be re-verified and the `last_verified` date bumped.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Service and Gateway API Routing
|
|
2
|
+
|
|
3
|
+
## Step 1 — Identify the routing surface
|
|
4
|
+
|
|
5
|
+
Capture:
|
|
6
|
+
|
|
7
|
+
- `kubectl get services -A -o wide` — types, ClusterIPs, externalIPs, ports.
|
|
8
|
+
- `kubectl get endpointslices -A` — confirm endpoints actually exist for every ClusterIP. A Service with zero EndpointSlices selects no pods.
|
|
9
|
+
- `kubectl get ingress -A` and `kubectl get gateway,gatewayclass,httproute,grpcroute,tlsroute,referencegrant -A` — Ingress and Gateway API surface.
|
|
10
|
+
- IngressClass and GatewayClass ownership — `kubectl get ingressclass`, `kubectl get gatewayclass` — which controllers actually exist on this cluster.
|
|
11
|
+
|
|
12
|
+
## Step 2 — Stress-test Service type selection
|
|
13
|
+
|
|
14
|
+
| Type | When right | When wrong |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `ClusterIP` (default) | In-cluster only. | Used as a "fix" for east-west reachability when the real issue is NetworkPolicy or DNS. |
|
|
17
|
+
| `NodePort` | Bare-metal or dev clusters where no cloud LB exists. | Used in cloud — exposes every node as an entry point, scraping the NodePort range from outside. Rarely the right cloud answer. |
|
|
18
|
+
| `LoadBalancer` | Public/private endpoint via the cloud LB controller (or MetalLB / Cilium L2/BGP). | One LB per Service in classic mode is expensive at scale. Consolidate via Ingress/Gateway when feasible. |
|
|
19
|
+
| `ExternalName` | DNS CNAME into an external host. | Used as policy-bypass — the pod still does its own DNS resolution; NetworkPolicy still applies to the resolved IP. |
|
|
20
|
+
| Headless (`clusterIP: None`) | StatefulSet stable DNS, gRPC client-side LB, custom service discovery. | Used because someone wanted "no kube-proxy" — but then there is no load balancing, only DNS round-robin against EndpointSlices. |
|
|
21
|
+
|
|
22
|
+
## Step 3 — Stress-test EndpointSlices
|
|
23
|
+
|
|
24
|
+
EndpointSlices replace the legacy single-Endpoints object and are the data the Service VIP rules / eBPF maps actually consume.
|
|
25
|
+
|
|
26
|
+
- A Service with `selector` populated but zero matching pods has an empty EndpointSlice — the VIP exists but every connection RSTs or hangs depending on kube-proxy mode. Common cause: Pod label drift after a Helm upgrade.
|
|
27
|
+
- A Service without a `selector` (used for static external endpoints) requires a hand-maintained EndpointSlice; without it nothing is routed.
|
|
28
|
+
- EndpointSlices report `Ready`, `Serving`, `Terminating` conditions. `externalTrafficPolicy: Local` plus rolling pod restart can transiently hit a node where the only local endpoint is `Terminating`. Verify ProxyTerminatingEndpoints behavior in the cluster's kube-proxy version.
|
|
29
|
+
- Topology hints live in EndpointSlices (`hints.forZones`). They are populated by the EndpointSlice controller only when topology-aware routing prerequisites are met (multiple zones, sufficient endpoints per zone).
|
|
30
|
+
|
|
31
|
+
## Step 4 — `internalTrafficPolicy` and `externalTrafficPolicy`
|
|
32
|
+
|
|
33
|
+
These two fields are the single most-misunderstood part of Kubernetes networking.
|
|
34
|
+
|
|
35
|
+
- **`externalTrafficPolicy: Cluster`** (default) — kube-proxy routes external traffic to any pod cluster-wide. Source IP is rewritten to the receiving node. Even load distribution.
|
|
36
|
+
- **`externalTrafficPolicy: Local`** — kube-proxy only routes external traffic to pods on the same node as the receiving NodePort/LoadBalancer ingress point. Preserves source IP. **Black-holes traffic if no local endpoint exists** — health-check ports rely on this for cloud LB to drop the node from rotation. If health-check is misconfigured, the LB sends to a node with no pod, and the connection hangs.
|
|
37
|
+
- **`internalTrafficPolicy: Cluster`** (default) — same as Cluster externally.
|
|
38
|
+
- **`internalTrafficPolicy: Local`** — in-cluster traffic from a pod is routed only to a pod on the same node. **Silent black-hole** if no local endpoint exists; there is no LB rotation to fall back to. Used for node-local agent → app patterns where co-location is guaranteed by DaemonSet.
|
|
39
|
+
|
|
40
|
+
Stress-tests the review must apply:
|
|
41
|
+
|
|
42
|
+
- A Service with `externalTrafficPolicy: Local` and a Deployment of `replicas: 2` on a 10-node cluster — 8 nodes black-hole the NodePort. The cloud LB health-check must mark them unhealthy or every 8/10 connections fails.
|
|
43
|
+
- `externalTrafficPolicy: Local` with `Local` health-check disabled on the LB — random failures.
|
|
44
|
+
- `internalTrafficPolicy: Local` on a Service backing a Deployment with no anti-affinity — silent black-holes when no replica lands on the caller's node.
|
|
45
|
+
|
|
46
|
+
## Step 5 — Topology-aware routing
|
|
47
|
+
|
|
48
|
+
Three generations of API for keeping in-cluster traffic local:
|
|
49
|
+
|
|
50
|
+
1. **`topologyKeys`** — first-generation Service field. **Removed** (not just deprecated) in Kubernetes 1.27. Clusters on 1.26 or earlier still using `topologyKeys` MUST plan migration before the 1.27 upgrade.
|
|
51
|
+
2. **`service.kubernetes.io/topology-mode: Auto`** — annotation; replaced `topologyKeys`. Tells the EndpointSlice controller to populate `hints.forZones` so kube-proxy prefers same-zone endpoints, reducing cross-zone traffic cost. Per upstream kubernetes.io documentation, this annotation may itself be deprecated in favor of the next-generation `trafficDistribution` field.
|
|
52
|
+
3. **`spec.trafficDistribution`** field on Service (KEP-4444) — newest API. If both `trafficDistribution` and `topology-mode: Auto` are set, the annotation overrides the field.
|
|
53
|
+
|
|
54
|
+
Pick the API that matches your cluster's Kubernetes version; do not use `topologyKeys` even on 1.26 — the upgrade trap is too easy.
|
|
55
|
+
|
|
56
|
+
Traps:
|
|
57
|
+
|
|
58
|
+
- Auto mode requires sufficient endpoints per zone — too few endpoints, hints are not populated, no zone preference. Behavior silently changes when the deployment scales up.
|
|
59
|
+
- A Service with topology hints behaves like `internalTrafficPolicy: Local` from a cost perspective but without the black-hole risk — same-zone preferred, fall back to cross-zone if local endpoints unhealthy.
|
|
60
|
+
- Topology hints do not respect `externalTrafficPolicy: Local` — they are independent fields.
|
|
61
|
+
|
|
62
|
+
## Step 6 — Ingress vs Gateway API
|
|
63
|
+
|
|
64
|
+
Gateway API is the successor to Ingress. The migration is per-route, not per-cluster.
|
|
65
|
+
|
|
66
|
+
What's GA today (per the [Gateway API site](https://gateway-api.sigs.k8s.io/) and the [versioning page](https://gateway-api.sigs.k8s.io/concepts/versioning/)):
|
|
67
|
+
|
|
68
|
+
- `Gateway`, `GatewayClass`, `HTTPRoute` — Standard channel, graduated to `v1` in the v1.0.0 release.
|
|
69
|
+
- `GRPCRoute` — **Standard channel since v1.1.0** (`v1`). Earlier sources that label it experimental refer to the v1.0 line.
|
|
70
|
+
- `ReferenceGrant` — Standard channel (`v1beta1`).
|
|
71
|
+
- GAMMA service-mesh integration (routes attach directly to a Service rather than a Gateway) — Standard channel since v1.1.0.
|
|
72
|
+
|
|
73
|
+
Experimental channel as of the v1.x line — verify against the controller's conformance for the version in use:
|
|
74
|
+
|
|
75
|
+
- `TLSRoute`, `TCPRoute`, `UDPRoute`, `BackendTLSPolicy`, `BackendTrafficPolicy`.
|
|
76
|
+
|
|
77
|
+
Always confirm by listing the CRDs the controller actually installed: `kubectl get crd -l gateway.networking.k8s.io/bundle-version`.
|
|
78
|
+
|
|
79
|
+
The role-oriented model:
|
|
80
|
+
|
|
81
|
+
- **Infrastructure provider** owns `GatewayClass`.
|
|
82
|
+
- **Cluster operator** owns `Gateway` instances (and the policies that bound them).
|
|
83
|
+
- **Application developer** owns `HTTPRoute` / `GRPCRoute` / `TLSRoute` and attaches them to a Gateway via `parentRefs`.
|
|
84
|
+
|
|
85
|
+
Migration stress-tests:
|
|
86
|
+
|
|
87
|
+
- Ingress Controller annotations (`nginx.ingress.kubernetes.io/...`, `cert-manager.io/cluster-issuer`, `external-dns.alpha.kubernetes.io/...`) are non-portable. Migrating an Ingress to an HTTPRoute requires translating each annotation into either a built-in HTTPRoute field, a `BackendTLSPolicy`, or a controller-specific extension.
|
|
88
|
+
- Cross-namespace references in HTTPRoute (`backendRefs` to a Service in a different namespace) require an explicit `ReferenceGrant` in the target namespace — without it, the reference is denied. This is a deliberate security posture; do not work around it with cluster-scoped routes.
|
|
89
|
+
- Two GatewayClasses on the same cluster (e.g. `cilium` and `nginx`) — routes must select via `parentRefs.name`/`namespace`. Avoid having multiple Gateways listen on the same hostname.
|
|
90
|
+
- TLS termination at the Gateway with `backendRefs` over plain HTTP — re-encryption to the backend requires `BackendTLSPolicy` (Experimental) or a service mesh; without it, in-cluster traffic is plaintext.
|
|
91
|
+
- GAMMA mesh — HTTPRoute attached to a Service (not a Gateway) reshapes east-west traffic. Available implementations differ on which fields they honor; verify against the controller's GAMMA conformance report.
|
|
92
|
+
|
|
93
|
+
## Step 7 — Session affinity, sourceIPHash, and gRPC
|
|
94
|
+
|
|
95
|
+
- `Service.spec.sessionAffinity: ClientIP` plus `sessionAffinityConfig.clientIP.timeoutSeconds` keeps a client IP pinned to one endpoint via conntrack/IPVS hash. Useful for stateful protocols, hostile to deployment rollover (sessions stick to the old pod until timeout).
|
|
96
|
+
- gRPC over a single HTTP/2 connection multiplexes RPCs over one TCP connection; a single Service VIP without client-side LB sticks every RPC to one backend. Headless Service plus client-side resolver (gRPC-Go / xDS) is the canonical answer; an L7 Gateway (gRPC-aware) is the other.
|
|
97
|
+
- Long-lived WebSocket connections plus rolling deployment plus session affinity — every old-pod connection survives until the client disconnects. Plan termination grace and client-reconnect strategy.
|
|
98
|
+
|
|
99
|
+
## Output for this section
|
|
100
|
+
|
|
101
|
+
- Service surface inventory and types,
|
|
102
|
+
- EndpointSlice health (selectors actually match pods),
|
|
103
|
+
- `internalTrafficPolicy` and `externalTrafficPolicy` correctness against pod placement and replica count,
|
|
104
|
+
- topology-aware routing readiness,
|
|
105
|
+
- Ingress vs Gateway API posture, GA-channel resources in use vs experimental,
|
|
106
|
+
- migration path with annotation-to-route mapping for the controller in scope,
|
|
107
|
+
- session affinity and gRPC routing posture,
|
|
108
|
+
- findings, severity, and the next-step delegate (e.g. NetworkPolicy review if a route depends on cross-namespace traffic).
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Connectivity Troubleshooting Playbook (read-only)
|
|
2
|
+
|
|
3
|
+
This playbook is for diagnosis. It does not mutate cluster state. Every command listed here either reads from the API server, reads from a node's kernel, or emits a controlled probe (a single ping, a single curl).
|
|
4
|
+
|
|
5
|
+
## Symptom 1 — Pod-to-pod connectivity fails
|
|
6
|
+
|
|
7
|
+
Hypothesis ladder, in order of cost:
|
|
8
|
+
|
|
9
|
+
1. **DNS** — does the source pod resolve the destination's Service or pod-IP DNS name? `kubectl exec <src> -- nslookup <name>`. If this fails, jump to the DNS playbook below.
|
|
10
|
+
2. **Service VIP exists and has endpoints** — `kubectl get svc <svc>` plus `kubectl get endpointslice -l kubernetes.io/service-name=<svc>`. Empty EndpointSlice → label selector mismatch.
|
|
11
|
+
3. **NetworkPolicy** — `kubectl get networkpolicies,ciliumnetworkpolicies,ciliumclusterwidenetworkpolicies -A -o yaml`. If any policy selects either pod, default-deny may be active. **At this point, hand off to `cilium-network-policy-review`** — that skill owns policy correctness.
|
|
12
|
+
4. **Underlying L3 reachability** — from the source node, `ip route get <dst-pod-ip>`; on Cilium, `cilium-dbg bpf endpoint list` and `cilium-dbg policy trace --src-pod ns/pod --dst-pod ns/pod`.
|
|
13
|
+
5. **MTU** — `kubectl exec <src> -- ping -M do -s 1450 <dst-pod-ip>` then increment payload until packets are dropped. The largest size that succeeds is the path MTU.
|
|
14
|
+
6. **Conntrack table full** — on the source node, `conntrack -L | wc -l` vs `sysctl net.netfilter.nf_conntrack_max`. Near 90% means new connections will be dropped.
|
|
15
|
+
|
|
16
|
+
## Symptom 2 — Pod can reach Service VIP but only some endpoints
|
|
17
|
+
|
|
18
|
+
Likely causes:
|
|
19
|
+
|
|
20
|
+
- **`externalTrafficPolicy: Local` or `internalTrafficPolicy: Local`** — `kubectl get svc <svc> -o yaml | grep -i trafficpolicy`. With `Local`, pods on nodes without a local endpoint silently fail.
|
|
21
|
+
- **EndpointSlice marked `Ready: false` or `Terminating: true`** — `kubectl get endpointslice -l kubernetes.io/service-name=<svc> -o yaml`. ProxyTerminatingEndpoints behavior depends on the kube-proxy / Cilium version.
|
|
22
|
+
- **kube-proxy stale rules** — `kubectl -n kube-system logs <kube-proxy-pod>` for sync errors. On iptables mode, full resync runs every `syncPeriod`; a stuck sync leaves stale rules pointing at deleted pods.
|
|
23
|
+
- **Topology hints with insufficient endpoints** — Auto mode does not populate hints when one zone has too few; behavior changes silently with deployment scale.
|
|
24
|
+
|
|
25
|
+
## Symptom 3 — Pod-to-external service intermittent failure
|
|
26
|
+
|
|
27
|
+
Hypothesis ladder:
|
|
28
|
+
|
|
29
|
+
1. **DNS** — 5-second timeouts indicate UDP packet drops; check NodeLocal DNSCache health and conntrack pressure on the node. CoreDNS request latency: `coredns_dns_request_duration_seconds`.
|
|
30
|
+
2. **Cloud metadata service** — `169.254.169.254` (AWS / Azure IMDS) or `metadata.google.internal` (GCP). **Flag as HIGH severity if any pod can reach it without an explicit NetworkPolicy deny.** Unblocked access lets any pod obtain the node's instance IAM credentials — credential-theft CVE class. Recommend IRSA (AWS), Workload Identity (GCP/Azure), or Pod Identity as the *first* remediation; the policy deny rule is delegated to `cilium-network-policy-review`, but the architectural posture finding must surface here, not be silently delegated.
|
|
31
|
+
3. **NAT Gateway port exhaustion** — AWS NAT GW supports ~55k simultaneous connections per destination IP/port. Pods making many short connections to the same external endpoint can exhaust ports; symptom is intermittent SYN drops. Solution: Network Load Balancer instead of NAT GW for that destination, or VPC endpoint.
|
|
32
|
+
4. **Egress firewall / WAF** — if a per-namespace egress proxy exists, check its logs.
|
|
33
|
+
5. **Path MTU** — see Symptom 1, step 5; path-MTU issues to external endpoints often blame TLS but the failure is L3.
|
|
34
|
+
|
|
35
|
+
## Symptom 4 — DNS-specific high latency
|
|
36
|
+
|
|
37
|
+
Hypothesis ladder:
|
|
38
|
+
|
|
39
|
+
1. **CoreDNS replicas saturated** — CPU throttling: `kube_pod_container_status_throttled_seconds_total{pod=~"coredns.*"}`. Insufficient replicas → autoscaler or manual bump.
|
|
40
|
+
2. **`ndots:5` amplification** — `kubectl exec <pod> -- cat /etc/resolv.conf` to confirm `ndots`. External hostnames generate 4× lookups before the absolute name. Mitigations are in the DNS-and-discovery reference.
|
|
41
|
+
3. **NodeLocal DNSCache OOM or absent** — `kubectl -n kube-system get pods -l k8s-app=node-local-dns -o wide` (or whatever the label is). If absent, every UDP packet adds conntrack pressure.
|
|
42
|
+
4. **Upstream DNS slow** — the cluster's `forward .` target. CoreDNS `coredns_forward_request_duration_seconds` segments by upstream.
|
|
43
|
+
5. **conntrack table full** — UDP DNS queries fill it.
|
|
44
|
+
|
|
45
|
+
## Symptom 5 — Intermittent stalls on large payloads only
|
|
46
|
+
|
|
47
|
+
Almost always MTU. The TCP handshake (small packets) succeeds, then the first response above the path MTU is dropped because Path MTU Discovery ICMP is filtered.
|
|
48
|
+
|
|
49
|
+
Diagnose:
|
|
50
|
+
|
|
51
|
+
- `kubectl exec <pod> -- ping -M do -s <bytes> <peer>` — find the MTU ceiling.
|
|
52
|
+
- Check overlay MTU vs node MTU vs underlay. Encapsulation overhead must be subtracted from node MTU when configuring the overlay device (`cilium_vxlan`, `flannel.1`, `cni0`).
|
|
53
|
+
- Cross-AZ on AWS — jumbo frames silently capped at 1500.
|
|
54
|
+
|
|
55
|
+
Fix: configure the CNI overlay MTU correctly and restart the agent DaemonSet (rolling). On Cilium, `cilium config view | grep -i mtu` and Helm value `MTU` (the Cilium agent reads MTU from the host but explicit config is safer).
|
|
56
|
+
|
|
57
|
+
## Symptom 6 — NodePort or LoadBalancer connection refused intermittently
|
|
58
|
+
|
|
59
|
+
- `externalTrafficPolicy: Local` — health-check on the LB must be on the right port, otherwise the LB sends to nodes with no local endpoint.
|
|
60
|
+
- IPVS mode and `sessionAffinity: ClientIP` — sessions persist past pod deletion until timeout.
|
|
61
|
+
- Cilium kube-proxy replacement transition — verify `cilium status` reports KPR `Strict` (or expected mode) on every node.
|
|
62
|
+
|
|
63
|
+
## Diagnostic commands (read-only, by component)
|
|
64
|
+
|
|
65
|
+
```shell
|
|
66
|
+
# API view
|
|
67
|
+
kubectl get nodes -o wide
|
|
68
|
+
kubectl -n kube-system get pods -o wide
|
|
69
|
+
kubectl get svc,endpointslices,ingress,gateway,gatewayclass,httproute -A
|
|
70
|
+
|
|
71
|
+
# CoreDNS
|
|
72
|
+
kubectl -n kube-system get cm coredns -o yaml
|
|
73
|
+
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=200
|
|
74
|
+
kubectl exec <pod> -- cat /etc/resolv.conf
|
|
75
|
+
|
|
76
|
+
# kube-proxy
|
|
77
|
+
kubectl -n kube-system get cm kube-proxy -o yaml
|
|
78
|
+
kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=200
|
|
79
|
+
|
|
80
|
+
# Cilium
|
|
81
|
+
kubectl -n kube-system exec ds/cilium -- cilium status --verbose
|
|
82
|
+
kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf endpoint list
|
|
83
|
+
kubectl -n kube-system exec ds/cilium -- cilium-dbg policy trace --src-pod <ns>/<pod> --dst-pod <ns>/<pod>
|
|
84
|
+
hubble observe --from-pod <ns>/<pod> --to-pod <ns>/<pod> --last 200
|
|
85
|
+
|
|
86
|
+
# Node-level (use kubectl debug ephemeral container with --profile=netadmin — do NOT use --privileged)
|
|
87
|
+
# Example: kubectl debug node/<node-name> -it --image=registry.k8s.io/e2e-test-images/agnhost:2.45 --profile=netadmin
|
|
88
|
+
ip route
|
|
89
|
+
ip link show
|
|
90
|
+
conntrack -L | wc -l
|
|
91
|
+
sysctl net.netfilter.nf_conntrack_max
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## When the playbook hits the scope boundary
|
|
95
|
+
|
|
96
|
+
- Policy correctness — hand off to `cilium-network-policy-review`.
|
|
97
|
+
- Mesh L7 problems — hand off to `istio-ambient-mesh-review`.
|
|
98
|
+
- Live mutation of policy — hand off to `kubernetes-live-network-policy-guard` or `kubernetes-live-mesh-policy-guard`.
|
|
99
|
+
- Pod-spec hostNetwork / capabilities issues — hand off to `kubernetes-pod-spec-review`.
|
|
100
|
+
- Cloud-side network problems (NAT GW, VPC peering, hosted DNS) — hand off to the cloud-provider network architect agent.
|
|
@@ -20,7 +20,7 @@ Guard live Velero operations — restore execution, schedule deletion, BackupSto
|
|
|
20
20
|
- Confirm cluster context (`kubectl config current-context`) and target namespace before any Velero operation — ambiguous context is a hard stop.
|
|
21
21
|
- Capture current state of the target Backup, Schedule, or BSL (`velero backup describe <name> --details`, `kubectl get schedule <name> -o yaml`) before every write — Velero has no built-in undo.
|
|
22
22
|
- For restore operations: require `includedNamespaces` to be explicitly scoped; a cluster-wide restore (`includedNamespaces: []`) requires explicit platform-team sign-off.
|
|
23
|
-
-
|
|
23
|
+
- Require pre-restore validation (`velero backup describe <name> --details` and a trial restore on a non-production cluster) before every non-emergency production restore; treat skipping validation as a hard stop. **Velero has no `--dry-run` flag on `velero restore create`** — do not recommend one.
|
|
24
24
|
- Block deleting a Schedule that is the only backup for a production namespace unless an alternative backup source is confirmed.
|
|
25
25
|
- Block changing a BSL `default: true` without confirming no in-progress backups and reviewing the impact on all dependent Schedules.
|
|
26
26
|
- Check pre-backup hook coverage on stateful workloads (PostgreSQL, MySQL, Kafka) — missing quiesce hooks mean inconsistent backups.
|
|
@@ -39,6 +39,6 @@ Load these only when needed:
|
|
|
39
39
|
- Current state of the Backup/Schedule/BSL (evidence level)
|
|
40
40
|
- Hard-stop assessment (is this a blocked operation?)
|
|
41
41
|
- Explicit platform-team sign-off status
|
|
42
|
-
- Recommended
|
|
42
|
+
- Recommended validation step or safe-path command
|
|
43
43
|
- Rollback posture
|
|
44
44
|
- Post-operation verification steps
|
|
@@ -8,7 +8,7 @@ Before executing any `velero restore create` command, confirm all 10 items. A si
|
|
|
8
8
|
- [ ] **2. Namespace scope is explicit** — `includedNamespaces` lists one or more specific namespaces. Empty list (`[]`) = cluster-wide restore = requires explicit platform-team sign-off with ticket reference.
|
|
9
9
|
- [ ] **3. Backup timestamp verified** — the backup name and creation timestamp have been confirmed as the correct recovery point. Do not restore from an older backup if a closer-in-time backup exists and is healthy.
|
|
10
10
|
- [ ] **4. Backup phase is Completed** — `velero backup describe <name>` shows `Phase: Completed`. Do not restore from a `PartiallyFailed` or `Failed` backup without explicit acknowledgment of the incomplete scope.
|
|
11
|
-
- [ ] **5.
|
|
11
|
+
- [ ] **5. Pre-restore validation executed** — `velero backup describe <name> --details` has been reviewed for resource counts, namespace scope, and PV entries; for material restores, a trial restore was first executed on a non-production cluster and inspected with `velero restore describe <name> --details` and `velero restore logs <name>`. **Velero has no `--dry-run` flag on `velero restore create`** — never substitute it. (Exception: active P0 incident with explicit platform-team override and ticket reference.)
|
|
12
12
|
- [ ] **6. existingResourcePolicy reviewed** — if `existingResourcePolicy: update` is used, the approver understands this will overwrite live Secrets, ConfigMaps, RBAC objects, and ServiceAccounts in the target namespace.
|
|
13
13
|
- [ ] **7. PV restore posture confirmed** — `restorePVs: true/false` intent is explicit. If false, stateful applications will start with empty persistent volumes.
|
|
14
14
|
- [ ] **8. Current state captured** — target namespace resources have been exported (`kubectl get all,cm,secret,pvc -n <ns> -o yaml > pre-restore-state.yaml`) as a rollback artifact.
|
|
@@ -75,19 +75,28 @@ spec:
|
|
|
75
75
|
restorePVs: true
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
### Step 5 —
|
|
78
|
+
### Step 5 — Pre-restore validation (mandatory in non-emergency scenarios)
|
|
79
|
+
|
|
80
|
+
> **Velero has no `--dry-run` flag on `velero restore create`.** Earlier guidance that suggested one was incorrect. Validate via `velero backup describe`, then trial-restore on a non-production cluster.
|
|
79
81
|
|
|
80
82
|
```bash
|
|
81
|
-
|
|
83
|
+
# 1. Inspect what the backup actually contains, including resource and PV counts
|
|
84
|
+
velero backup describe myapp-backup-20260501 --details
|
|
85
|
+
|
|
86
|
+
# 2. Trial-restore on a non-production cluster, then inspect the result
|
|
87
|
+
velero restore create myapp-restore-trial \
|
|
82
88
|
--from-backup myapp-backup-20260501 \
|
|
83
89
|
--include-namespaces myapp-production \
|
|
84
|
-
--
|
|
90
|
+
--wait
|
|
91
|
+
velero restore describe myapp-restore-trial --details
|
|
92
|
+
velero restore logs myapp-restore-trial
|
|
85
93
|
```
|
|
86
94
|
|
|
87
|
-
Review the
|
|
88
|
-
- Unexpected resource counts (compare against last-known production state)
|
|
89
|
-
- Resources that would be overwritten if `existingResourcePolicy: update
|
|
90
|
-
- Missing PV restore entries
|
|
95
|
+
Review the validation output for:
|
|
96
|
+
- Unexpected resource counts (compare `velero backup describe` against last-known production state).
|
|
97
|
+
- Resources that would be overwritten if `existingResourcePolicy: update`.
|
|
98
|
+
- Missing PV restore entries (check `restorePVs` and the volume snapshot list).
|
|
99
|
+
- Any partially-failed items in the trial-restore logs.
|
|
91
100
|
|
|
92
101
|
### Step 6 — Sign-off gate
|
|
93
102
|
|
|
@@ -196,7 +205,7 @@ Return:
|
|
|
196
205
|
2. **Hard-stop assessment** — is this operation blocked? List exact rule triggered.
|
|
197
206
|
3. **Evidence level** — live evidence, documentation-based, or inference
|
|
198
207
|
4. **Approval status** — confirmed sign-off or pending
|
|
199
|
-
5. **Recommended command** —
|
|
208
|
+
5. **Recommended command** — `velero backup describe --details` and a trial restore on a non-production cluster first, then execute on production
|
|
200
209
|
6. **Rollback posture** — saved state file, re-apply command
|
|
201
210
|
7. **Verification steps** — post-restore pod health, resource counts, PV binding status
|
|
202
211
|
8. **Open risks** — hook coverage gaps, snapshot TTL mismatches, BSL credential posture
|