fix: repair stale reference solutions and Q33's grading check
tracks/cka/solutions.py had drifted out of sync with the actual current task text for several questions (Q06, 11, 12, 13, 14, 22, 32, 40, 109, 110, 120, 122) - wrong namespaces/resource names, missing required steps, or output files that were never actually written. Rewrote each to match its task's real requirements. tracks/cka/bank_extra.py's Q33 grading check queried `.spec.aggregationRule` on a ClusterRole, but ClusterRole has no `.spec` field - `aggregationRule` and `rules` are top-level. Fixed the jsonpath so a correct answer actually passes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fqcio9TXkEXH35UHebTgoL
This commit is contained in:
parent
fb8cb2a649
commit
595003e377
@ -96,7 +96,7 @@ for x in %{cr} %{cr}-pods %{cr}-services; do $K delete clusterrole $x --ignore-n
|
|||||||
$K delete clusterrolebinding %{cr}-binding --ignore-not-found >/dev/null
|
$K delete clusterrolebinding %{cr}-binding --ignore-not-found >/dev/null
|
||||||
""",
|
""",
|
||||||
"checks": [
|
"checks": [
|
||||||
C("%{cr} has an aggregationRule with the right label", 1, r"""j clusterrole %{cr} '{.spec.aggregationRule.clusterRoleSelectors[*].matchLabels}' | grep -q 'aggregate-to-%{cr}":"true'"""),
|
C("%{cr} has an aggregationRule with the right label", 1, r"""j clusterrole %{cr} '{.aggregationRule.clusterRoleSelectors[*].matchLabels}' | grep -q 'aggregate-to-%{cr}":"true'"""),
|
||||||
C("aggregation populated rules from the two labelled roles", 2, r"""j clusterrole %{cr} '{.rules[*].resources}' | grep -q pods && j clusterrole %{cr} '{.rules[*].resources}' | grep -q services"""),
|
C("aggregation populated rules from the two labelled roles", 2, r"""j clusterrole %{cr} '{.rules[*].resources}' | grep -q pods && j clusterrole %{cr} '{.rules[*].resources}' | grep -q services"""),
|
||||||
C("%{user} can list pods and services cluster-wide", 1, r"""eq "$($K auth can-i list pods -A --as=%{user} 2>/dev/null)" yes && eq "$($K auth can-i list services -A --as=%{user} 2>/dev/null)" yes"""),
|
C("%{user} can list pods and services cluster-wide", 1, r"""eq "$($K auth can-i list pods -A --as=%{user} 2>/dev/null)" yes && eq "$($K auth can-i list services -A --as=%{user} 2>/dev/null)" yes"""),
|
||||||
C("%{user} cannot delete pods", 1, r"""eq "$($K auth can-i delete pods -A --as=%{user} 2>/dev/null || true)" no"""),
|
C("%{user} cannot delete pods", 1, r"""eq "$($K auth can-i delete pods -A --as=%{user} 2>/dev/null || true)" no"""),
|
||||||
|
|||||||
@ -139,11 +139,9 @@ EOF
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
S[6] = """# Part A: Check certificate expiration on control plane
|
S[6] = """# Part A: Check certificate expiration on control plane
|
||||||
# Step 1: Access control plane
|
# {WS} is a path on your own machine, so run the remote check and redirect its
|
||||||
{SHELL_CP}
|
# output locally - don't try to write {WS} from inside the node's own shell.
|
||||||
|
podman exec cka-sim-control-plane kubeadm certs check-expiration | grep '^apiserver ' > {WS}/q06/apiserver-expiry.txt
|
||||||
# Step 2: Inspect kubeadm cert expiration and extract the apiserver expiry line
|
|
||||||
kubeadm certs check-expiration | grep '^apiserver ' > {WS}/q06/apiserver-expiry.txt
|
|
||||||
|
|
||||||
# Part B: Issue and approve CertificateSigningRequest (CSR) for user Jane
|
# Part B: Issue and approve CertificateSigningRequest (CSR) for user Jane
|
||||||
# Step 3: Generate private key and CSR
|
# Step 3: Generate private key and CSR
|
||||||
@ -226,18 +224,13 @@ spec:
|
|||||||
EOF
|
EOF
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[40] = """# Step 1: Access the control plane node
|
S[40] = """# Generate a new kubeadm join token with the specified TTL and print-join-command,
|
||||||
{SHELL_CP}
|
# writing the output straight into the required workspace file (run from the host, not the node,
|
||||||
|
# since {WS} is a path on your machine)
|
||||||
|
podman exec cka-sim-control-plane kubeadm token create --ttl %{ttl} --print-join-command > {WS}/q40/join.sh
|
||||||
|
|
||||||
# Step 2: Generate a new kubeadm join token with specified TTL and print join command
|
# Verify active tokens
|
||||||
kubeadm token create --ttl %{ttl} --print-join-command
|
podman exec cka-sim-control-plane kubeadm token list
|
||||||
|
|
||||||
# Step 3: Save the join command into the required workspace script
|
|
||||||
# (e.g., kubeadm join <control-plane-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>)
|
|
||||||
# Copy the printed command into {WS}/q40/join.sh
|
|
||||||
|
|
||||||
# Step 4: Verify active tokens
|
|
||||||
kubeadm token list
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[41] = """# Step 1: Check Kubernetes Server version (API server)
|
S[41] = """# Step 1: Check Kubernetes Server version (API server)
|
||||||
@ -440,9 +433,11 @@ mv /etc/kubernetes/manifests/*.yaml /tmp/ && sleep 20 && mv /tmp/*.yaml /etc/kub
|
|||||||
|
|
||||||
# Step 4: Update admin kubeconfig from newly generated credentials
|
# Step 4: Update admin kubeconfig from newly generated credentials
|
||||||
cp /etc/kubernetes/admin.conf ~/.kube/config
|
cp /etc/kubernetes/admin.conf ~/.kube/config
|
||||||
|
exit
|
||||||
|
|
||||||
# Step 5: Confirm new expiration dates
|
# Step 5: Back on your own machine now - {WS} is a path on your machine, not the node,
|
||||||
kubeadm certs check-expiration | grep '^apiserver '
|
# so capture the expiry report from out here and redirect it into the required file
|
||||||
|
podman exec cka-sim-control-plane kubeadm certs check-expiration | grep '^apiserver ' > {WS}/q122/expiry.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[124] = """# Step 1: On the control-plane node, create a fresh bootstrap token
|
S[124] = """# Step 1: On the control-plane node, create a fresh bootstrap token
|
||||||
@ -769,19 +764,21 @@ k -n %{ns} create quota %{ns}-quota --hard=pods=%{pods},requests.cpu=1,limits.me
|
|||||||
cat <<EOF | k apply -f -
|
cat <<EOF | k apply -f -
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: LimitRange
|
kind: LimitRange
|
||||||
metadata: {name: %{ns}-limitrange, namespace: %{ns}}
|
metadata: {name: %{ns}-defaults, namespace: %{ns}}
|
||||||
spec:
|
spec:
|
||||||
limits:
|
limits:
|
||||||
- type: Container
|
- type: Container
|
||||||
default: {cpu: 200m, memory: 256Mi}
|
default: {cpu: 500m, memory: 256Mi}
|
||||||
defaultRequest: {cpu: 100m, memory: 128Mi}
|
defaultRequest: {cpu: %{dcpu}, memory: 64Mi}
|
||||||
max: {cpu: 500m, memory: 512Mi}
|
|
||||||
min: {cpu: 50m, memory: 64Mi}
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Step 3: Verify quota and limits
|
# Step 3: Create the Deployment without specifying resources - it picks up the LimitRange defaults
|
||||||
|
k -n %{ns} create deploy worker --image=nginx:1.25 --replicas=2
|
||||||
|
|
||||||
|
# Step 4: Verify quota, limits and the defaulted pod resources
|
||||||
k -n %{ns} describe quota %{ns}-quota
|
k -n %{ns} describe quota %{ns}-quota
|
||||||
k -n %{ns} describe limitrange %{ns}-limitrange
|
k -n %{ns} describe limitrange %{ns}-defaults
|
||||||
|
k -n %{ns} get pod -l app=worker -o jsonpath='{.items[0].spec.containers[0].resources}'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Hard Workload Tasks
|
# Hard Workload Tasks
|
||||||
@ -834,40 +831,49 @@ k -n %{ns} rollout pause deploy %{dep}
|
|||||||
k -n %{ns} get deploy %{dep}
|
k -n %{ns} get deploy %{dep}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[109] = """# Step 1: Deploy Pod with native sidecar (restartPolicy: Always inside initContainers)
|
S[109] = """# Step 1: Deploy Pod with a native sidecar (restartPolicy: Always inside initContainers),
|
||||||
|
# a shared emptyDir the sidecar writes into and the main container reads from
|
||||||
cat <<EOF | k apply -f -
|
cat <<EOF | k apply -f -
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata: {name: %{pod}, namespace: %{ns}}
|
metadata: {name: %{pod}, namespace: %{ns}}
|
||||||
spec:
|
spec:
|
||||||
|
terminationGracePeriodSeconds: 5
|
||||||
|
volumes:
|
||||||
|
- name: logs
|
||||||
|
emptyDir: {}
|
||||||
initContainers:
|
initContainers:
|
||||||
- name: proxy
|
- name: agent
|
||||||
image: busybox:1.36
|
image: busybox:1.36
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
command: [sh, -c, "while true; do sleep 5; done"]
|
command: [sh, -c, "while true; do date >> /var/log/agent.log; sleep 1; done"]
|
||||||
readinessProbe:
|
volumeMounts:
|
||||||
exec: {command: [true]}
|
- {name: logs, mountPath: /var/log}
|
||||||
initialDelaySeconds: 1
|
|
||||||
containers:
|
containers:
|
||||||
- name: main
|
- name: app
|
||||||
image: nginx:1.27
|
image: nginx:1.27
|
||||||
livenessProbe:
|
readinessProbe:
|
||||||
httpGet: {path: /, port: 80}
|
httpGet: {path: /, port: 80}
|
||||||
initialDelaySeconds: 5
|
periodSeconds: 5
|
||||||
periodSeconds: 10
|
livenessProbe:
|
||||||
|
tcpSocket: {port: 80}
|
||||||
|
volumeMounts:
|
||||||
|
- {name: logs, mountPath: /var/log}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Step 2: Verify both containers are running
|
# Step 2: Once Running, write the exact report files
|
||||||
k -n %{ns} get pod %{pod}
|
k -n %{ns} get pod %{pod} -o jsonpath='{.spec.initContainers[*].name} {.spec.containers[*].name}' \\
|
||||||
|
| tr ' ' '\\n' | sort > {WS}/q109/containers.txt
|
||||||
|
k -n %{ns} get pod %{pod} -o jsonpath='{.status.podIP}' > {WS}/q109/ip.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[110] = r"""# Step 1: Filter pods outside kube-system with custom output
|
S[110] = r"""# Step 1: pods outside kube-system whose FIRST container has no readiness probe
|
||||||
k get pods -A -o json | jq -r '.items[] | select(.metadata.namespace!="kube-system") | select(.spec.restartPolicy=="Always") | "\(.metadata.namespace) \(.metadata.name)"' > {WS}/q110/always.txt
|
k get pods -A -o json | jq -r '.items[] | select(.metadata.namespace!="kube-system") | select(.spec.containers[0].readinessProbe == null) | "\(.metadata.namespace)/\(.metadata.name)"' | sort > {WS}/q110/no-readiness.txt
|
||||||
|
|
||||||
# Step 2: Count Running pods per node
|
# Step 2: count of Running pods per node ("<node> <count>", node first)
|
||||||
k get pods -A --field-selector=status.phase=Running -o jsonpath='{range .items[*]}{.spec.nodeName}{"\n"}{end}' | sort | uniq -c > {WS}/q110/per-node.txt
|
k get pods -A --field-selector=status.phase=Running -o jsonpath='{range .items[*]}{.spec.nodeName}{"\n"}{end}' | sort | uniq -c | awk '{print $2, $1}' | sort > {WS}/q110/per-node.txt
|
||||||
|
|
||||||
# Step 3: Extract sorted unique container images used across kube-system
|
# Step 3: sorted unique container images used across kube-system
|
||||||
k -n kube-system get pods -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u > {WS}/q110/images.txt
|
k -n kube-system get pods -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u > {WS}/q110/images.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -885,38 +891,38 @@ k expose deploy %{dep} --port=80 --target-port=80
|
|||||||
# Domain 3: Services & Networking (20%)
|
# Domain 3: Services & Networking (20%)
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
||||||
S[11] = """# Step 1: Create NetworkPolicy in namespace 'marketing'
|
S[11] = """# Step 1: Create NetworkPolicy in namespace 'netpol'
|
||||||
# Allow Ingress on port 80 only from pods labeled 'role: frontend'
|
# Allow Ingress on port 8080 only from pods labeled 'app: frontend', no egress restriction
|
||||||
cat <<EOF | k apply -f -
|
cat <<EOF | k apply -f -
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: NetworkPolicy
|
kind: NetworkPolicy
|
||||||
metadata: {name: allow-frontend, namespace: marketing}
|
metadata: {name: backend-policy, namespace: netpol}
|
||||||
spec:
|
spec:
|
||||||
podSelector: {matchLabels: {app: api}}
|
podSelector: {matchLabels: {app: backend}}
|
||||||
policyTypes: [Ingress]
|
policyTypes: [Ingress]
|
||||||
ingress:
|
ingress:
|
||||||
- from:
|
- from:
|
||||||
- podSelector: {matchLabels: {role: frontend}}
|
- podSelector: {matchLabels: {app: frontend}}
|
||||||
ports:
|
ports:
|
||||||
- protocol: TCP
|
- protocol: TCP
|
||||||
port: 80
|
port: 8080
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Step 2: Verify NetworkPolicy configuration
|
# Step 2: Verify NetworkPolicy configuration
|
||||||
k -n marketing describe netpol allow-frontend
|
k -n netpol describe netpol backend-policy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[12] = """# Step 1: Expose deployment as NodePort service using dry-run
|
S[12] = """# Step 1: Expose deployment as NodePort service using dry-run
|
||||||
k -n web expose deploy web-server --type=NodePort --port=80 --target-port=80 $do > svc.yaml
|
k -n svc expose deploy shop --name=shop-svc --type=NodePort --port=80 --target-port=80 $do > svc.yaml
|
||||||
|
|
||||||
# Step 2: Set specific nodePort 30080 in spec.ports[0].nodePort
|
# Step 2: Set specific nodePort 30080 in spec.ports[0].nodePort
|
||||||
cat <<EOF | k apply -f -
|
cat <<EOF | k apply -f -
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata: {name: web-server, namespace: web}
|
metadata: {name: shop-svc, namespace: svc}
|
||||||
spec:
|
spec:
|
||||||
type: NodePort
|
type: NodePort
|
||||||
selector: {app: web-server}
|
selector: {app: shop}
|
||||||
ports:
|
ports:
|
||||||
- port: 80
|
- port: 80
|
||||||
targetPort: 80
|
targetPort: 80
|
||||||
@ -924,35 +930,56 @@ spec:
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Step 3: Verify NodePort service and endpoints
|
# Step 3: Verify NodePort service and endpoints
|
||||||
k -n web get svc web-server
|
k -n svc get svc shop-svc
|
||||||
k -n web get endpoints web-server
|
k -n svc get endpointslices -l kubernetes.io/service-name=shop-svc
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[13] = """# Step 1: Create Ingress resource routing host to backend service
|
S[13] = """# Step 1: Create the Ingress with both path rules under one host
|
||||||
k -n web create ingress web-ingress \\
|
cat <<EOF | k apply -f -
|
||||||
--class=nginx \\
|
apiVersion: networking.k8s.io/v1
|
||||||
--rule="order.example.com/api*=order-service:8080"
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: app-ingress
|
||||||
|
namespace: ingress-app
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
rules:
|
||||||
|
- host: shop.example.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /api
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service: {name: api, port: {number: 8080}}
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service: {name: web, port: {number: 80}}
|
||||||
|
EOF
|
||||||
|
|
||||||
# Step 2: Verify Ingress rules
|
# Step 2: Verify Ingress rules
|
||||||
k -n web describe ingress web-ingress
|
k -n ingress-app describe ingress app-ingress
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[14] = """# Step 1: Run temporary debug pod to query DNS
|
S[14] = """# Step 1: Create a long-running pod (not --rm) so it still exists for the check
|
||||||
# Query A-record for a Service: <service>.<namespace>.svc.cluster.local
|
k -n dns-check run dns-test --image=busybox:1.36 --restart=Never -- sleep 3600
|
||||||
k -n default run dns-test --image=busybox:1.36 --rm -it --restart=Never -- \\
|
|
||||||
nslookup web-service.apps.svc.cluster.local
|
|
||||||
|
|
||||||
# Step 2: Query Pod DNS (IP with dashes): <ip-with-dashes>.<namespace>.pod.cluster.local
|
# Step 2: Save the FQDN you're resolving
|
||||||
k -n default run dns-test --image=busybox:1.36 --rm -it --restart=Never -- \\
|
echo "hello.dns-check.svc.cluster.local" > workspace/q14/svc-fqdn.txt
|
||||||
nslookup 10-244-1-5.apps.pod.cluster.local
|
|
||||||
|
# Step 3: Resolve it from inside the pod and save the full output
|
||||||
|
k -n dns-check exec dns-test -- nslookup hello.dns-check.svc.cluster.local > workspace/q14/nslookup.txt
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[22] = """# Step 1: Apply GatewayClass and Gateway resources
|
S[22] = """# Step 1: Install the Gateway API standard-channel CRDs
|
||||||
|
k apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
|
||||||
|
|
||||||
|
# Step 2: Apply GatewayClass, Gateway (with the listener hostname) and HTTPRoute
|
||||||
cat <<EOF | k apply -f -
|
cat <<EOF | k apply -f -
|
||||||
apiVersion: gateway.networking.k8s.io/v1
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
kind: GatewayClass
|
kind: GatewayClass
|
||||||
metadata: {name: %{gc}}
|
metadata: {name: %{gc}}
|
||||||
spec: {controllerName: example.com/gateway-controller}
|
spec: {controllerName: example.com/gateway}
|
||||||
---
|
---
|
||||||
apiVersion: gateway.networking.k8s.io/v1
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
kind: Gateway
|
kind: Gateway
|
||||||
@ -963,18 +990,21 @@ spec:
|
|||||||
- name: http
|
- name: http
|
||||||
protocol: HTTP
|
protocol: HTTP
|
||||||
port: 80
|
port: 80
|
||||||
|
hostname: %{host}.example.com
|
||||||
---
|
---
|
||||||
apiVersion: gateway.networking.k8s.io/v1
|
apiVersion: gateway.networking.k8s.io/v1
|
||||||
kind: HTTPRoute
|
kind: HTTPRoute
|
||||||
metadata: {name: %{route}, namespace: %{ns}}
|
metadata: {name: %{host}-route, namespace: %{ns}}
|
||||||
spec:
|
spec:
|
||||||
parentRefs: [{name: %{gw}}]
|
parentRefs: [{name: %{gw}}]
|
||||||
rules:
|
rules:
|
||||||
- matches: [{path: {type: PathPrefix, value: /api}}]
|
- matches: [{path: {type: PathPrefix, value: /api}}]
|
||||||
backendRefs: [{name: %{svc}, port: 8080}]
|
backendRefs: [{name: api, port: 8080}]
|
||||||
|
- matches: [{path: {type: PathPrefix, value: /}}]
|
||||||
|
backendRefs: [{name: web, port: 80}]
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Step 2: Verify Gateway and HTTPRoute status
|
# Step 3: Verify Gateway and HTTPRoute status
|
||||||
k -n %{ns} get gateway,httproute
|
k -n %{ns} get gateway,httproute
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -1554,20 +1584,21 @@ k -n %{ns} get deploy %{dep}
|
|||||||
k -n %{ns} get endpoints %{dep}
|
k -n %{ns} get endpoints %{dep}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[120] = """# Step 1: Query cluster CIDR from kube-controller-manager pod spec
|
S[120] = r"""# Gather each fact and append it directly to the report file, one key=value line at a time
|
||||||
k -n kube-system get pod -l component=kube-controller-manager -o yaml | grep cluster-cidr
|
pc=$(k -n kube-system get pod -l component=kube-controller-manager -o jsonpath='{.items[0].spec.containers[0].command}' | grep -o 'cluster-cidr=[^,"]*' | cut -d= -f2)
|
||||||
|
echo "pod-cidr=$pc" > {WS}/q120/facts.txt
|
||||||
|
|
||||||
# Step 2: Query service CIDR from kube-apiserver pod spec
|
sc=$(k -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].spec.containers[0].command}' | grep -o 'service-cluster-ip-range=[^,"]*' | cut -d= -f2)
|
||||||
k -n kube-system get pod -l component=kube-apiserver -o yaml | grep service-cluster-ip-range
|
echo "service-cidr=$sc" >> {WS}/q120/facts.txt
|
||||||
|
|
||||||
# Step 3: Query CoreDNS ClusterIP
|
d=$(k -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}')
|
||||||
k -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}'
|
echo "dns-ip=$d" >> {WS}/q120/facts.txt
|
||||||
|
|
||||||
# Step 4: Query kube-proxy operating mode from ConfigMap
|
# Empty mode in the ConfigMap means kube-proxy defaults to iptables
|
||||||
k -n kube-system get cm kube-proxy -o yaml | grep '^ *mode:' # Empty string indicates default: iptables
|
m=$(k -n kube-system get cm kube-proxy -o jsonpath='{.data.config\.conf}' | grep '^mode:' | awk '{print $2}' | tr -d '"')
|
||||||
|
echo "proxy-mode=${m:-iptables}" >> {WS}/q120/facts.txt
|
||||||
|
|
||||||
# Step 5: Query individual node Pod CIDR
|
echo "%{node}-pod-cidr=$(k get node %{node} -o jsonpath='{.spec.podCIDR}')" >> {WS}/q120/facts.txt
|
||||||
k get node %{node} -o jsonpath='{.spec.podCIDR}'
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S[123] = """# Step 1: Confirm nothing works through kubectl at all
|
S[123] = """# Step 1: Confirm nothing works through kubectl at all
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user