CKA 2026 / Red Hat Cloud-native(EX188 + EX288)考试全知识点详解与避坑指南
声明 :本文面向 2026 年红帽云原生应用认证方向(考试组合:EX188 + EX288)。该方向属于 RHCE 五大技术分支中的 Cloud-native applications ,需红帽数据中心环境支持。全文基于 RHEL 9、Podman v4.4、OpenShift 4.14+ 版本整理,命令行均可直接复制使用。
一、考试基本信息
项目 EX188(容器基础) EX288(OpenShift 应用开发) 考试形式 100% 实操 100% 实操 考试时长 约 2 小时 3 小时 满分/及格 300 分 / 210 分(70%) 300 分 / 210 分(70%) 前置条件 无强制要求,建议具备 RHCSA 基础 强烈建议先通过 EX188 考试环境 单机 RHEL 9 + Podman 完整 OpenShift 4 集群(需红帽数据中心) 核心工具 Podman、Buildah、Skopeo oc CLI、OpenShift Web Console、Tekton
二、EX188 知识点全景(容器专家)
2.1 Podman 基础命令速查
podman --version
podman info
podman info --format json
podman search nginx --limit 5
podman search registry.redhat.io/rhel9/nginx-120
podman pull docker.io/library/nginx:1.27
podman pull registry.redhat.io/rhel9/httpd-24:latest
podman images
podman images --filter dangling = true
podman rmi nginx:1.27
podman rmi -f $( podman images -q )
podman image prune -f
podman run -d --name web -p 8080 :80 nginx:1.27
podman run -it --rm registry.redhat.io/rhel9/bash /bin/bash
podman run -d --name db -e MYSQL_ROOT_PASSWORD = redhat registry.redhat.io/rhel9/mysql-80
podman ps
podman ps -a
podman ps --format "table {{.Names}}\t {{.Status}}\t {{.Ports}}"
podman start web
podman stop web
podman restart web
podman kill web
podman rm web
podman rm -f web
podman rm -a -f
podman exec -it web /bin/bash
podman exec web ps aux
podman attach web
podman logs web
podman logs -f web
podman logs --tail 50 web
podman top web
podman stats web
podman diff web
podman inspect web
podman inspect web --format '{{.NetworkSettings.IPAddress}}'
podman port web
podman cp web:/usr/share/nginx/html/index.html ./index.html
podman cp ./new.html web:/usr/share/nginx/html/
podman generate systemd --name web --files
podman generate systemd --name web --new --files
2.2 Containerfile / Dockerfile 全指令详解
# 基础镜像
FROM registry.redhat.io/rhel9/nginx-120:latest
# 元数据
LABEL maintainer="dev@example.com" \
version="1.0" \
description="Cloud-native app"
# 构建参数(仅在构建时可用)
ARG APP_VERSION=1.0
ARG BUILD_ENV=prod
# 环境变量(构建+运行时均可用)
ENV APP_HOME=/opt/app \
APP_PORT=8080 \
LOG_LEVEL=info
# 工作目录
WORKDIR ${APP_HOME}
# 复制文件(推荐用于本地文件,不支持远程URL和自动解压)
COPY ./src ./src
COPY --chown=1001:0 ./config/app.conf ./config/
# 添加文件(支持远程URL和自动解压tar)
ADD https://example.com/package.tar.gz ./packages/
ADD ./local.tar.gz ./extracted/
# 运行命令(每行产生一个新层)
RUN dnf install -y java-17-openjdk && \
dnf clean all && \
rm -rf /var/cache/dnf
# 创建卷(声明挂载点,不强制映射)
VOLUME ["/opt/app/data", "/opt/app/logs"]
# 暴露端口(仅声明,不实际映射)
EXPOSE 8080
EXPOSE 8443/tcp
# 创建普通用户(安全最佳实践)
RUN useradd -u 1001 -r -g 0 -s /sbin/nologin appuser
USER 1001
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# 停止信号
STOPSIGNAL SIGTERM
# 启动命令(可被 docker run 后面的参数覆盖)
CMD ["nginx", "-g", "daemon off;"]
# 入口点(不易被覆盖,配合 CMD 提供默认参数)
ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]
2.3 镜像构建与多阶段构建
podman build -t myapp:1.0 -f Containerfile .
podman build -t myapp:1.0 --no-cache .
podman build -t myapp:1.0 --layers = false .
# 多阶段构建示例
FROM registry.redhat.io/rhel9/nodejs-18:latest AS builder
WORKDIR /build
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM registry.redhat.io/rhel9/nginx-120:latest
COPY --from=builder /build/dist /usr/share/nginx/html
EXPOSE 8080
USER 1001
CMD ["nginx", "-g", "daemon off;"]
2.4 镜像仓库操作
podman login -u username -p password registry.redhat.io
podman login --authfile /tmp/auth.json registry.example.com
podman tag myapp:1.0 registry.example.com/project/myapp:1.0
podman push registry.example.com/project/myapp:1.0
podman push --tls-verify= false registry.example.com/project/myapp:1.0
podman pull registry.example.com/project/myapp:1.0
podman save -o myapp.tar myapp:1.0
podman save --format oci-archive -o myapp-oci.tar myapp:1.0
podman load -i myapp.tar
podman export -o container-fs.tar web
podman import container-fs.tar imported-image:latest
skopeo inspect docker://registry.redhat.io/rhel9/nginx-120:latest
skopeo copy docker://source.registry.com/img:tag docker://dest.registry.com/img:tag
skopeo sync --src docker --dest dir registry.redhat.io/rhel9/nginx-120 ./backup
2.5 Podman 网络
podman network ls
podman network inspect podman
podman network create --subnet 10.88 .10.0/24 --gateway 10.88 .10.1 app-net
podman run -d --name app1 --network app-net nginx:1.27
podman run -d --name app2 --network app-net nginx:1.27
podman exec app1 ping app2
podman run -d -p 8080 :80 -p 8443 :443 --name web nginx:1.27
podman run -d -P --name web nginx:1.27
2.6 Podman 存储与卷
podman volume create app-data
podman volume ls
podman volume inspect app-data
podman volume rm app-data
podman volume prune
podman run -d -v app-data:/data --name db registry.redhat.io/rhel9/mysql-80
podman run -d -v /host/data:/container/data:Z --name web nginx:1.27
podman run -d --tmpfs /tmp:rw,noexec,nosuid,size= 100m nginx:1.27
2.7 Podman Pod(多容器应用栈)
podman pod create --name myapp -p 8080 :80 -p 8443 :443
podman pod ls
podman pod inspect myapp
podman run -d --pod myapp --name web nginx:1.27
podman run -d --pod myapp --name sidecar busybox:1.36 sleep 3600
podman pod start myapp
podman pod stop myapp
podman pod restart myapp
podman pod rm -f myapp
podman pod stats myapp
2.8 Podman Secret 与配置
printf "mysecretpassword" | podman secret create db_password -
podman secret ls
podman secret inspect db_password
podman run -d --secret db_password --name db registry.redhat.io/rhel9/mysql-80
2.9 容器安全与权限
podman run -d --user 1001 :0 nginx:1.27
podman run -d --privileged --name debug registry.redhat.io/rhel9/bash
podman run -d --cap-add= NET_ADMIN --cap-drop= ALL nginx:1.27
podman run -d --read-only -v /tmp:/tmp nginx:1.27
podman run -d -v /host/data:/data:Z nginx:1.27
podman run -d --uidmap = 0 :100000:65536 nginx:1.27
2.10 容器故障排查
podman events --since 10m
podman events --stream
podman inspect < container>
podman inspect --format = '{{.State.Status}}' < container>
podman inspect --format = '{{.Config.Env}}' < container>
podman stats --no-stream
podman top < container> aux
podman top < container> pid,hcpu,comm
podman logs --since 10m < container>
podman logs --until 1h < container>
podman exec -it < container> /bin/sh
podman exec -it < container> -c < cmd>
podman export < container> -o /tmp/container.tar
tar -tf /tmp/container.tar | grep -i config
2.11 systemd 集成(持久化)
mkdir -p ~/.config/systemd/user
podman generate systemd --name web --files --new
mv container-web.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now container-web.service
systemctl --user status container-web.service
loginctl enable-linger $USER
cat ~/.config/systemd/user/container-web.service
2.12 Buildah 高级镜像构建
buildah from scratch
buildah containers
ctr = $( buildah from rhel9:latest)
buildah run $ctr -- dnf install -y nginx
buildah copy $ctr ./index.html /usr/share/nginx/html/
buildah config --entrypoint '["nginx", "-g", "daemon off;"]' $ctr
buildah config --port 8080 $ctr
buildah commit $ctr mynginx:latest
buildah bud -t myapp:1.0 -f Containerfile .
三、EX288 知识点全景(OpenShift 应用开发)
3.1 OpenShift CLI (oc) 基础
oc login https://api.cluster.example.com:6443 -u developer -p password
oc login --token = < sha256~token> --server = https://api.cluster.example.com:6443
oc whoami
oc whoami --show-server
oc whoami --show-token
oc new-project my-project --display-name= "My App" --description = "Cloud native app"
oc project my-project
oc get projects
oc get project my-project -o yaml
oc delete project my-project
oc get all
oc get pods
oc get pods -o wide
oc get pods --show-labels
oc get pods -l app = frontend
oc get svc
oc get routes
oc get deployments
oc get deploymentconfigs
oc get buildconfigs
oc get builds
oc get imagestreams
oc get imagestreamtags
oc get templates
oc get configmaps
oc get secrets
oc get serviceaccounts
oc get persistentvolumeclaims
oc get networkpolicies
oc get resourcequotas
oc get limitranges
oc get hpa
oc get events --sort-by= '.lastTimestamp'
oc get events --field-selector reason = Failed
oc describe pod < pod-name>
oc describe node < node-name>
oc describe route < route-name>
oc describe build < build-name>
oc status
oc status --suggest
oc adm top nodes
oc adm top pods
oc create -f manifest.yaml
oc apply -f manifest.yaml
oc delete -f manifest.yaml
oc delete pod < pod-name>
oc delete all -l app = frontend
oc edit deployment < name>
oc patch deployment < name> -p '{"spec":{"replicas":3}}'
oc annotate pod < name> description = "test"
oc label pod < name> env = prod
3.2 应用部署核心
oc new-app registry.redhat.io/rhel9/nginx-120:latest --name = web
oc new-app nginx:1.27 --name = web -l app = frontend
oc new-app --docker-image= registry.example.com/app:v1 --name = api
oc new-app https://github.com/example/nodejs-app.git --name = nodejs-app
oc new-app nodejs:18~https://github.com/example/nodejs-app.git --name = nodejs-app
oc new-app --strategy = docker https://github.com/example/docker-app.git
oc new-app --template = nodejs-example -p APPLICATION_NAME = myapp
oc process openshift//nodejs-mongo-persistent -p DATABASE_SERVICE_NAME = mongodb | oc apply -f -
oc expose svc web
oc expose svc web --hostname = www.example.com
oc expose svc web --path = /api
oc expose deployment web --port = 8080
oc create route edge --service = web --hostname = app.example.com
oc create route passthrough --service = api --hostname = api.example.com
oc create route reencrypt --service = secure-app
oc scale deployment web --replicas = 5
oc scale dc web --replicas = 3
oc rollout status deployment/web
oc rollout history deployment/web
oc rollout undo deployment/web
oc rollout undo deployment/web --to-revision= 2
oc rollout pause deployment/web
oc rollout resume deployment/web
oc rollout latest dc/web
oc set triggers deployment/web --from-image= myapp:latest --containers = web
oc set triggers dc/web --manual
3.3 BuildConfig 与镜像流
oc get builds
oc logs build/myapp-1
oc logs -f build/myapp-1
oc start-build myapp
oc start-build myapp --follow
oc start-build myapp --from-dir= .
oc start-build myapp --from-file= app.jar
oc start-build myapp --env VAR = value
oc cancel-build myapp-2
oc get is
oc import-image rhel9/nginx-120 --from = registry.redhat.io/rhel9/nginx-120 --confirm
oc tag registry.redhat.io/rhel9/nginx-120:latest myproject/nginx:prod
oc tag myproject/myapp:latest myproject/myapp:stable
oc set triggers bc/myapp --from-image= myproject/myapp:latest
3.4 ConfigMap 与 Secret
oc create configmap app-config \
--from-literal= DB_HOST= postgres \
--from-literal= DB_PORT= 5432
oc create configmap app-config --from-file= application.properties
oc create configmap app-config --from-file= ./config/
oc create configmap app-config --from-env-file= env.txt
oc get cm app-config -o yaml
oc describe cm app-config
oc create secret generic db-secret \
--from-literal= username= admin \
--from-literal= password= RedHat123
oc create secret tls app-tls --cert = tls.crt --key = tls.key
oc create secret docker-registry regcred \
--docker-server= registry.redhat.io \
--docker-username= user \
--docker-password= pass \
--docker-email= user@example.com
oc set env deployment/web --from = configmap/app-config
oc set env deployment/web --from = secret/db-secret
oc set volume deployment/web --add --name = config-vol -m /etc/config --configmap-name= app-config
oc set volume deployment/web --add --name = secret-vol -m /etc/secret --secret-name= db-secret
oc set env deployment/web DB_HOST = postgres DB_PORT = 5432
oc set env deployment/web --from = secret/db-secret --keys = username --prefix = DB_
3.5 持久化存储
oc create -f - << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
EOF
oc set volume deployment/web --add --name = data -m /data --claim-name= app-pvc
oc get pvc
oc get pv
3.6 健康检查(Probes)
apiVersion : apps/v1
kind : Deployment
metadata :
name : web
spec :
replicas : 3
selector :
matchLabels :
app : web
template :
metadata :
labels :
app : web
spec :
containers :
- name : web
image : nginx: 1.27
ports :
- containerPort : 8080
livenessProbe :
httpGet :
path : /healthz
port : 8080
initialDelaySeconds : 10
periodSeconds : 10
timeoutSeconds : 5
failureThreshold : 3
readinessProbe :
httpGet :
path : /ready
port : 8080
initialDelaySeconds : 5
periodSeconds : 5
startupProbe :
httpGet :
path : /startup
port : 8080
initialDelaySeconds : 5
periodSeconds : 5
failureThreshold : 30
oc set probe deployment/web --liveness --get-url= http://:8080/healthz --initial-delay-seconds= 10
oc set probe deployment/web --readiness --get-url= http://:8080/ready
oc set probe deployment/web --remove --liveness
3.7 资源限制与配额
oc set resources deployment/web \
--requests = cpu= 100m,memory= 128Mi \
--limits = cpu= 500m,memory= 512Mi
oc create limitrange app-limits \
--max = cpu= 2 ,memory= 1Gi \
--min = cpu= 100m,memory= 128Mi \
--default = cpu= 500m,memory= 256Mi
oc create quota app-quota \
--hard = pods= 10 ,services= 5 ,requests.cpu= 2 ,limits.cpu= 4 ,requests.memory= 4Gi,limits.memory= 8Gi
oc describe quota app-quota
oc describe limitrange app-limits
3.8 自动扩缩容(HPA)
oc autoscale deployment/web --min = 2 --max = 10 --cpu-percent= 80
oc get hpa
oc describe hpa web
oc apply -f - << EOF
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
EOF
3.9 NetworkPolicy
apiVersion : networking.k8s.io/v1
kind : NetworkPolicy
metadata :
name : api- policy
namespace : production
spec :
podSelector :
matchLabels :
app : api
policyTypes :
- Ingress
- Egress
ingress :
- from :
- podSelector :
matchLabels :
app : frontend
ports :
- protocol : TCP
port : 8080
egress :
- to :
- podSelector :
matchLabels :
app : database
ports :
- protocol : TCP
port : 5432
- to : [ ]
ports :
- protocol : UDP
port : 53
oc apply -f networkpolicy.yaml
oc get networkpolicy
oc describe networkpolicy api-policy
3.10 ServiceAccount 与 RBAC
oc create sa app-sa
oc get sa
oc get sa app-sa -o yaml
oc set serviceaccount deployment/web app-sa
oc create role pod-reader --verb = get,list,watch --resource = pods -n myproject
oc create rolebinding read-pods --role = pod-reader --serviceaccount = myproject:app-sa -n myproject
oc create clusterrole node-reader --verb = get,list --resource = nodes
oc create clusterrolebinding read-nodes --clusterrole = node-reader --serviceaccount = myproject:app-sa
oc auth can-i list pods -n myproject --as = system:serviceaccount:myproject:app-sa
oc auth can-i list nodes --as = system:serviceaccount:myproject:app-sa
oc auth can-i create deployments -n myproject --as = system:serviceaccount:myproject:app-sa
oc adm policy add-scc-to-user anyuid -z app-sa
oc adm policy add-scc-to-user privileged -z app-sa
3.11 S2I(Source-to-Image)深度
oc new-app nodejs:18~https://github.com/sclorg/nodejs-ex.git --name = nodejs-app
oc new-app php:8.0~https://github.com/example/app.git
oc new-app https://github.com/example/private.git --source-secret= git-secret
oc get is -n openshift
oc get is -n openshift | grep nodejs
oc logs -f bc/nodejs-app
oc set triggers bc/nodejs-app --from-github
oc set triggers bc/nodejs-app --from-webhook
oc set triggers bc/nodejs-app --remove-all
oc set triggers bc/nodejs-app --manual
3.12 Webhook 与触发器
oc describe bc myapp | grep -i webhook
oc set triggers bc/myapp --from-webhook
oc describe bc myapp | grep -A 5 "Webhook Generic"
oc set triggers bc/myapp --from-image= myproject/base-image:latest
3.13 Template 模板
oc get templates -n openshift
oc describe template nodejs-mongo-persistent -n openshift
oc process openshift//nodejs-mongo-persistent -p DATABASE_SERVICE_NAME = mongodb -p MONGODB_USER = admin
oc process openshift//nodejs-mongo-persistent -p DATABASE_SERVICE_NAME = mongodb | oc create -f -
oc new-app --template = nodejs-mongo-persistent -p DATABASE_SERVICE_NAME = mongodb
oc export all --as-template= my-template -o yaml > my-template.yaml
oc create -f my-template.yaml
oc get templates
3.14 Helm 与 Kustomize
helm version
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm repo list
helm search repo nginx
helm show values bitnami/nginx
helm show readme bitnami/nginx
helm install my-nginx bitnami/nginx -n myproject --create-namespace
helm install my-nginx bitnami/nginx --set replicaCount = 3 ,service.type= NodePort
helm list
helm list -n myproject
helm status my-nginx
helm get values my-nginx
helm get manifest my-nginx
helm upgrade my-nginx bitnami/nginx --set replicaCount = 5
helm rollback my-nginx 1
helm history my-nginx
helm uninstall my-nginx
helm template my-nginx bitnami/nginx --set replicaCount = 3
cat << EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
images:
- name: nginx
newTag: 1.27
patches:
- target:
kind: Deployment
name: web
patch: |-
- op: replace
path: /spec/replicas
value: 5
EOF
kustomize build .
oc apply -k .
3.15 OpenShift Pipelines(Tekton CI/CD)
tkn version
tkn pipeline list
tkn task list
tkn clustertask list
oc apply -f - << EOF
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: build-app
spec:
params:
- name: source-repo
type: string
steps:
- name: clone
image: registry.redhat.io/openshift-pipelines/pipelines-git-init-rhel8:latest
script: |
git clone $( params.source-repo) /workspace/source
EOF
oc apply -f - << EOF
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: app-pipeline
spec:
params:
- name: source-repo
type: string
- name: image-name
type: string
tasks:
- name: fetch-source
taskRef:
name: build-app
params:
- name: source-repo
value: $( params.source-repo)
- name: build-image
taskRef:
name: buildah
kind: ClusterTask
params:
- name: IMAGE
value: $( params.image-name)
runAfter:
- fetch-source
workspaces:
- name: source
workspace: shared-workspace
workspaces:
- name: shared-workspace
EOF
tkn pipeline start app-pipeline \
--param source-repo= https://github.com/example/app.git \
--param image-name= image-registry.openshift-image-registry.svc:5000/myproject/app:latest \
--workspace name = shared-workspace,volumeClaimTemplateFile= pvc.yaml \
--showlog
tkn pipelinerun list
tkn pipelinerun logs app-pipeline-run-xyz -f
oc apply -f - << EOF
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: app-trigger-template
spec:
params:
- name: git-repo-url
resourcetemplates:
- apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: app-pipeline-run-
spec:
pipelineRef:
name: app-pipeline
params:
- name: source-repo
value: $( tt.params.git-repo-url)
EOF
3.16 Operator 与 OperatorHub
oc get operators
oc get csv -n openshift-operators
oc get subscriptions -n openshift-operators
oc create -f - << EOF
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: my-operator
namespace: openshift-operators
spec:
channel: stable
name: my-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
EOF
oc get crd
oc get < custom-resource> -n myproject
3.17 Route 与 Ingress
oc create route edge --service = web --hostname = app.example.com
oc create route passthrough --service = api --hostname = api.example.com
oc create route reencrypt --service = secure-app --hostname = secure.example.com
oc get route
oc describe route web
oc create route edge --service = web --cert = tls.crt --key = tls.key --ca-cert= ca.crt
oc create route edge --service = web --path = /web
oc create route edge --service = api --path = /api
3.18 Pod 调度控制
oc label nodes node1 disktype = ssd
oc patch deployment web -p '{"spec":{"template":{"spec":{"nodeSelector":{"disktype":"ssd"}}}}}'
oc apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: nginx:1.27
EOF
oc adm taint nodes node1 key = value:NoSchedule
oc adm taint nodes node1 key = value:NoExecute
3.19 多容器 Pod 与 Init Container
apiVersion : v1
kind : Pod
metadata :
name : multi- container- app
spec :
initContainers :
- name : init- myservice
image : busybox: 1.36
command : [ 'sh' , '-c' , 'until nslookup myservice; do echo waiting; sleep 2; done' ]
containers :
- name : app
image : myapp: latest
ports :
- containerPort : 8080
env :
- name : DB_HOST
value : localhost
- name : sidecar
image : fluentd: v1.17
volumeMounts :
- name : logs
mountPath : /var/log/app
volumes :
- name : logs
emptyDir : { }
oc logs multi-container-app -c init-myservice
oc logs multi-container-app -c sidecar
3.20 项目隔离与配额
oc new-project team-a
oc create quota team-a-quota --hard = pods= 20 ,services= 10 ,requests.cpu= 4 ,limits.cpu= 8
oc create limitrange team-a-limits \
--max = cpu= 2 ,memory= 2Gi \
--min = cpu= 100m,memory= 128Mi \
--default = cpu= 500m,memory= 256Mi
oc create networkpolicy deny-all -n team-a << EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
四、常见故障排错流程(考试救命指南)
4.1 Pod 启动失败排错(通用流程)
oc get pods
oc get pod < name> -o wide
oc describe pod < name>
oc logs < pod> --previous
oc logs < pod> -c < container>
oc describe pod < name> | grep -i "Failed to pull"
oc get secrets | grep docker
oc set serviceaccount deployment/< name> < sa-with-pull-secret>
oc describe pod < name> | grep -i "Insufficient"
oc get nodes
oc get pvc
oc get pv
oc describe node < node>
oc get events --field-selector reason = Failed | grep image
oc get configmap
oc get secret
oc get sa
oc adm policy scc-subject-review -u system:serviceaccount:myproject:default -f pod.yaml
oc describe pod < name>
4.2 构建失败排错
oc logs -f bc/< name>
oc logs build/< name> -1
oc cancel-build < name> -2
oc start-build < name>
oc get secrets | grep git
oc describe bc < name> | grep -i source
oc get is
oc describe build < name> -1 | grep -i push
oc get route -n openshift-image-registry
oc get svc -n openshift-image-registry
4.3 服务访问失败排错
oc get svc < name>
oc get endpoints < name>
oc get pods -l app = < label>
oc exec < pod> -- curl -s http://< svc-name> :< port> /health
oc get route
oc describe route < name>
oc exec < pod> -- nslookup kubernetes.default.svc.cluster.local
oc get svc -n kube-system kube-dns
oc get endpoints -n kube-system kube-dns
oc get pods -n kube-system -l k8s-app= kube-dns
4.4 节点 NotReady 排错
oc get nodes
oc describe node < node>
ssh core@< node-ip>
sudo systemctl status kubelet
sudo journalctl -u kubelet --no-pager | tail -50
sudo systemctl status crio
sudo crictl ps
sudo crictl pods
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates
df -h
sudo du -sh /var/lib/containers/
sudo du -sh /var/lib/etcd/
free -h
4.5 网络策略导致连通性问题
oc exec < source-pod> -- curl --connect-timeout 5 http://< target-pod-ip> :< port>
oc get networkpolicy --all-namespaces
oc delete networkpolicy < name>
oc exec < pod> -- nslookup kubernetes.default
4.6 权限不足排错(RBAC / SCC)
oc whoami
oc auth can-i create deployments
oc auth can-i list secrets -n < namespace>
oc auth can-i list pods -n < ns> --as = system:serviceaccount:< ns> :< sa>
oc get scc
oc describe scc restricted
oc describe scc anyuid
oc adm policy add-scc-to-user anyuid -z < sa-name>
oc adm policy add-role-to-user admin user1 -n < project>
4.7 etcd 备份与恢复(集群管理相关)
sudo ETCDCTL_API = 3 etcdctl snapshot save /var/lib/etcd-backup/snapshot.db \
--endpoints = https://127.0.0.1:2379 \
--cacert = /etc/kubernetes/static-pod-resources/etcd-certs/ca.crt \
--cert = /etc/kubernetes/static-pod-resources/etcd-certs/server.crt \
--key = /etc/kubernetes/static-pod-resources/etcd-certs/server.key
sudo ETCDCTL_API = 3 etcdctl --write-out= table snapshot status /var/lib/etcd-backup/snapshot.db
sudo mv /var/lib/etcd /var/lib/etcd.old
sudo ETCDCTL_API = 3 etcdctl snapshot restore /var/lib/etcd-backup/snapshot.db \
--data-dir= /var/lib/etcd
sudo systemctl restart kubelet
五、EX188 + EX288 全知识点速查清单
EX188 知识点总览
编号 知识点 掌握程度 1 Podman 基础命令(run/ps/stop/rm/exec/logs/inspect) ⭐⭐⭐ 必须熟练 2 Containerfile 全指令(FROM/RUN/CMD/ENTRYPOINT/COPY/ADD/ENV/WORKDIR/USER/EXPOSE/VOLUME/HEALTHCHECK) ⭐⭐⭐ 必须熟练 3 ADD vs COPY 区别 ⭐⭐⭐ 考试常考 4 CMD vs ENTRYPOINT 区别及组合使用 ⭐⭐⭐ 考试常考 5 多阶段构建(Multi-stage Build) ⭐⭐⭐ 必须掌握 6 镜像管理(pull/push/tag/rmi/save/load/prune) ⭐⭐⭐ 必须熟练 7 私有 Registry 认证(podman login) ⭐⭐⭐ 必须掌握 8 镜像备份(save vs export 区别) ⭐⭐ 理解即可 9 Podman 网络(自定义网络、容器间 DNS、端口映射) ⭐⭐⭐ 必须掌握 10 Podman 卷(volume create、bind mount、:Z/😒 标签) ⭐⭐⭐ 必须掌握 11 Podman Pod(多容器应用栈、pod create、共享网络/存储) ⭐⭐⭐ 考试重点 12 Secret 管理(podman secret create/use) ⭐⭐ 了解 13 容器安全(非 root 运行、–read-only、–cap-drop、SELinux :Z) ⭐⭐⭐ 考试重点 14 systemd 集成(podman generate systemd、linger) ⭐⭐⭐ 考试重点 15 容器故障排查(events/inspect/stats/top/diff/logs) ⭐⭐⭐ 必须掌握 16 Buildah 基础使用(from/run/commit/config) ⭐⭐ 了解 17 Skopeo 镜像操作(inspect/copy/sync) ⭐ 了解
EX288 知识点总览
编号 知识点 掌握程度 1 oc CLI 基础(login/new-project/get/describe/create/apply/delete/edit/patch)⭐⭐⭐ 必须熟练 2 应用部署(new-app、from-image、from-source、from-template) ⭐⭐⭐ 考试重点 3 Deployment / DeploymentConfig 管理(scale/rollout/status/history/undo) ⭐⭐⭐ 必须熟练 4 Service 暴露(expose svc、create route、ClusterIP/NodePort/LoadBalancer) ⭐⭐⭐ 必须掌握 5 Route 类型(edge/passthrough/reencrypt)与 TLS 配置 ⭐⭐⭐ 考试重点 6 BuildConfig 管理(start-build/cancel-build/logs、Webhook、触发器) ⭐⭐⭐ 考试重点 7 ImageStream 与镜像标签管理(import-image/tag) ⭐⭐⭐ 必须掌握 8 S2I 构建(new-app、builder 镜像选择、自定义脚本、私有仓库) ⭐⭐⭐ 考试重点 9 ConfigMap / Secret 创建与注入(env/volume、from-literal/from-file) ⭐⭐⭐ 必须熟练 10 持久化存储(PVC 创建、挂载到 Deployment) ⭐⭐⭐ 必须掌握 11 健康检查(Liveness/Readiness/Startup Probe) ⭐⭐⭐ 考试重点 12 资源限制(requests/limits、LimitRange、ResourceQuota) ⭐⭐⭐ 必须掌握 13 HPA 自动扩缩容 ⭐⭐ 了解配置 14 NetworkPolicy(Ingress/Egress、podSelector、namespaceSelector、DNS 放行) ⭐⭐⭐ 考试重点 15 ServiceAccount 与 RBAC(Role/ClusterRole/RoleBinding、auth can-i) ⭐⭐⭐ 考试重点 16 SCC 安全上下文约束(anyuid/privileged、add-scc-to-user) ⭐⭐ 了解 17 Template 模板(process/new-app --template、自定义模板导出) ⭐⭐⭐ 考试重点 18 Helm(install/upgrade/rollback/repo/values) ⭐⭐⭐ 必须掌握 19 Kustomize(base/overlay、patches、images、build/apply -k) ⭐⭐⭐ 必须掌握 20 OpenShift Pipelines / Tekton(Task/Pipeline/PipelineRun/tkn CLI/Trigger) ⭐⭐⭐ 考试重点 21 Operator 安装与使用(Subscription/CSV/CRD) ⭐⭐ 了解 22 节点调度(nodeSelector/affinity/taint/toleration) ⭐⭐ 了解 23 Init Container 与多容器 Pod ⭐⭐ 了解 24 项目级隔离与配额管理 ⭐⭐ 了解
六、易踩坑点总结(考试血泪教训)
🔴 EX188 易踩坑点
坑点 说明 避坑方法 1. podman run 后容器立即退出 前台进程结束导致容器停止 使用 -d 后台运行,或确保 CMD 是阻塞式进程 2. 端口映射写反 -p 主机:容器 顺序容易搞混记忆口诀:“外在前,内在后” → -p 8080:80 3. 忘记 :Z 或 :z SELinux 标签 挂载主机目录后容器无法读写 单容器用 :Z,多容器共享用 :z 4. COPY 与 ADD 混淆 ADD 支持 URL 和自动解压,COPY 仅本地文件本地文件一律用 COPY,远程/tar 才用 ADD 5. ENTRYPOINT + CMD 参数覆盖问题 docker run 后的参数会覆盖 CMD,但不会覆盖 ENTRYPOINT需要固定命令用 ENTRYPOINT,可变参数用 CMD 6. podman build 缓存导致旧层未更新 修改了文件但构建结果没变 使用 --no-cache 或修改 RUN 指令前的层 7. podman save 与 export 混淆 save 保存镜像(含层和元数据),export 仅导出容器文件系统备份镜像用 save,备份容器状态用 export 8. systemd 服务文件未启用 linger 用户退出后 systemd 停止,容器随之停止 执行 loginctl enable-linger $USER 9. 生成 systemd 时未加 --new 不带 --new 重启时不会重新创建容器 考试建议一律加 --new 10. 构建时 dnf install 未清理缓存 导致镜像体积过大 同一 RUN 指令内执行 dnf clean all && rm -rf /var/cache/dnf 11. 多阶段构建中 --from 阶段名写错 导致无法复制构建产物 确保 AS 声明的名称与 --from= 完全一致 12. podman pod 中容器端口未在 pod 级别暴露 Pod 内容器间可通信,但外部无法访问 在 podman pod create 时用 -p 暴露端口 13. Secret 在 Containerfile 中无法直接使用 Podman secret 主要用于运行时,Buildah 构建时另有机制 考试重点在运行时注入,非构建时
🔴 EX288 易踩坑点
坑点 说明 避坑方法 1. oc new-app 后忘记 oc expose svc 服务创建但无 Route,外部无法访问 new-app 后务必执行 oc expose svc <name>2. Route 的 Service 选择器不匹配 Route 指向了错误的 Service 或 Service 无 Endpoint oc get endpoints <svc> 必须有 IP,否则检查 label selector3. ImageStream 触发器导致意外滚动更新 镜像标签更新后自动触发部署 需要手动控制时用 oc set triggers dc --manual 4. ConfigMap/Secret 修改后 Deployment 未滚动更新 环境变量和卷挂载不会自动触发 rollout 修改后手动 oc rollout restart deployment/<name> 5. oc set env 覆盖而非追加 多次执行会覆盖之前的环境变量 使用 --overwrite=false 或一次性设置所有变量 6. NetworkPolicy 启用 Egress 后 DNS 失败 默认拒绝所有出站流量,包括 DNS 必须显式允许 UDP 53 到任意地址7. NetworkPolicy 的 from 多 selector 是 AND 关系 同一规则下的多个 selector 必须同时满足 需要 OR 关系时拆分为多个 - from: 规则 8. PVC 与 PV 的 storageClassName 大小写不匹配 manual ≠ Manual,导致 Pending严格检查大小写,建议直接复制已有 PV 的 class name 9. oc set resources 单位写错 Mi vs M、Gi vs G 含义不同内存用 Mi/Gi,CPU 用 m(毫核) 10. ServiceAccount 无镜像拉取权限 私有仓库需要 docker-registry secret 并绑定到 SA oc set serviceaccount deployment/<name> <sa> + oc secrets link11. oc auth can-i 测试 RBAC 时 SA 语法错误 --as=system:serviceaccount:ns:sa 容易漏写 system:完整格式:--as=system:serviceaccount:project:sa-name 12. Helm 安装时未指定 namespace 默认安装到当前项目,可能权限不足 使用 -n <namespace> --create-namespace 13. S2I 构建时 .s2i/bin/assemble 权限不足 自定义脚本未添加执行权限 chmod +x .s2i/bin/assemble 后提交到 Git14. BuildConfig 的 Git 仓库需要认证但无 secret 私有仓库拉取失败 创建 source-secret 并在 new-app 或 BC 中引用 15. HPA 需要 metrics-server 但未安装 oc autoscale 后 HPA 显示 <unknown>确认 openshift-monitoring 或 metrics-server 已启用 16. oc rollout undo 后忘记 oc rollout status 回滚操作异步执行,立即检查可能仍是旧版本 回滚后务必 oc rollout status deployment/<name> 17. 模板参数未传递导致默认值不符合要求 oc process 或 new-app --template 时漏传参数先用 oc describe template 查看参数列表 18. Tekton Pipeline 的 Workspace 未绑定 PipelineRun 失败,提示 workspace 未提供 tkn pipeline start 时必须 --workspace name=xxx,...19. 忘记 oc project 导致资源创建到错误命名空间 考试多个项目切换时极易出错 每道题先执行 oc project <指定项目> 20. oc create 与 oc apply 混用导致已存在报错 create 对已存在资源会报错,apply 不会不确定时用 oc apply -f,或先 oc delete -f 再 create 21. Route 的 TLS 终止类型与后端服务不匹配 edge 终止后后端是 HTTP,passthrough 要求后端是 HTTPS 根据后端协议选择正确的 Route 类型 22. oc set volume 重复挂载同名 volume 第二次执行会报错 volume 已存在 先 oc set volume deployment/<name> --remove --name=<vol> 23. 使用 oc export 导出模板时 API 版本过时 export 已被标记为废弃改用 oc get all -o yaml 手动整理,或使用 oc get + yq 24. 节点 drain 时未加 --ignore-daemonsets drain 卡住无法完成 标准命令:oc adm drain <node> --ignore-daemonsets --delete-emptydir-data 25. oc start-build 的 --from-dir 路径错误 相对路径基准是执行命令的目录,非项目目录 使用绝对路径或确认当前目录正确
七、考试时间管理建议
EX188(约 2 小时):
├── 容器运行与排查(30 min)
├── 镜像构建与推送(30 min)
├── 多容器 Pod / Podman Pod(20 min)
├── systemd 持久化(15 min)
└── 检查与验证(15 min)
EX288(3 小时):
├── 应用部署与暴露(30 min)
├── S2I / BuildConfig 配置(30 min)
├── ConfigMap / Secret / 存储(20 min)
├── NetworkPolicy / RBAC(25 min)
├── Helm / Kustomize(20 min)
├── Pipeline / Tekton(25 min)
├── 故障排查题(30 min)
└── 检查与验证(20 min)
八、考前 Checklist