考试全知识点详解与避坑指南CKA2026

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、Skopeooc 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 高级操作(不下载即可查看)
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

# 容器间通信(通过容器名 DNS 解析)
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   # 暴露 Containerfile 中所有 EXPOSE 端口

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
# :Z 标签用于 SELinux,让容器可读写
# :z 用于多容器共享
# :ro 只读

# tmpfs 挂载
podman run -d --tmpfs /tmp:rw,noexec,nosuid,size=100m nginx:1.27

2.7 Podman Pod(多容器应用栈)

# 创建 Pod
podman pod create --name myapp -p 8080:80 -p 8443:443

# 查看 Pod
podman pod ls
podman pod inspect myapp

# 向 Pod 添加容器
podman run -d --pod myapp --name web nginx:1.27
podman run -d --pod myapp --name sidecar busybox:1.36 sleep 3600

# Pod 生命周期
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 与配置

# 创建 secret
printf "mysecretpassword" | podman secret create db_password -
podman secret ls
podman secret inspect db_password

# 在容器中使用 secret
podman run -d --secret db_password --name db registry.redhat.io/rhel9/mysql-80

# 在 Containerfile 中使用(Buildah)

2.9 容器安全与权限

# 以非 root 运行
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

# SELinux
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 集成(持久化)

# 生成 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

# 允许 linger(用户退出后容器继续运行)
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

# 项目(Project)管理
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

# 从源代码创建(S2I)
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

# 创建 Route
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

# 从字面量创建 ConfigMap
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

# 创建 Secret
oc create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=RedHat123

# 从文件创建 TLS Secret
oc create secret tls app-tls --cert=tls.crt --key=tls.key

# Docker Registry Secret
oc create secret docker-registry regcred \
  --docker-server=registry.redhat.io \
  --docker-username=user \
  --docker-password=pass \
  --docker-email=user@example.com

# 链接到 Deployment
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

# 环境变量注入(指定 key)
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 持久化存储

# 创建 PVC
oc create -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard
EOF

# 挂载到 Deployment
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

# 创建 LimitRange
oc create limitrange app-limits \
  --max=cpu=2,memory=1Gi \
  --min=cpu=100m,memory=128Mi \
  --default=cpu=500m,memory=256Mi

# 创建 ResourceQuota
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)

# 创建 HPA
oc autoscale deployment/web --min=2 --max=10 --cpu-percent=80

# 查看
oc get hpa
oc describe hpa web

# 手动设置 YAML
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: []    # 必须允许 DNS,否则服务名解析失败
    ports:
    - protocol: UDP
      port: 53
oc apply -f networkpolicy.yaml
oc get networkpolicy
oc describe networkpolicy api-policy

3.10 ServiceAccount 与 RBAC

# 创建 ServiceAccount
oc create sa app-sa
oc get sa
oc get sa app-sa -o yaml

# 将 SA 绑定到 Deployment
oc set serviceaccount deployment/web app-sa

# Role 与 RoleBinding
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

# ClusterRole 与 ClusterRoleBinding
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

# 给 SA 添加 SCC(安全上下文约束)
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)深度

# 基础 S2I 构建
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#develop --context-dir=src

# 使用私有 Git 仓库
oc new-app https://github.com/example/private.git --source-secret=git-secret

# 查看 S2I 构建器镜像
oc get is -n openshift
oc get is -n openshift | grep nodejs

# 自定义 S2I 脚本
# 在源代码仓库中放置 .s2i/bin/assemble 和 .s2i/bin/run 覆盖默认行为

# 查看构建日志
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 与触发器

# 获取 GitHub webhook URL
oc describe bc myapp | grep -i webhook

# 示例输出:
# Webhook GitHub:
#   URL: https://api.cluster.example.com:6443/apis/build.openshift.io/v1/namespaces/myproject/buildconfigs/myapp/webhooks/<secret>/github

# 配置 Generic 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

# 处理模板(不创建,仅输出 YAML)
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 =====
# 安装 Helm 客户端
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

# ===== Kustomize =====
# 目录结构
# base/
#   deployment.yaml
#   service.yaml
#   kustomization.yaml
# overlays/
#   production/
#     replica-patch.yaml
#     kustomization.yaml

# kustomization.yaml 示例
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)

# 安装 OpenShift Pipelines Operator(通过 Web Console 或 CLI)

# tkn CLI
tkn version
tkn pipeline list
tkn task list
tkn clustertask list

# 创建 Task
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

# 创建 Pipeline
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

# 运行 Pipeline
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

# 查看 PipelineRun
tkn pipelinerun list
tkn pipelinerun logs app-pipeline-run-xyz -f

# 创建 Trigger(Webhook 自动触发)
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

# 查看已安装 Operator
oc get operators
oc get csv -n openshift-operators
oc get subscriptions -n openshift-operators

# 通过 CLI 安装 Operator
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

# 使用 Operator 创建 CR
oc get crd
oc get <custom-resource> -n myproject

3.17 Route 与 Ingress

# Route 类型
oc create route edge --service=web --hostname=app.example.com          # 边缘终止 TLS
oc create route passthrough --service=api --hostname=api.example.com   # 透传 TLS
oc create route reencrypt --service=secure-app --hostname=secure.example.com  # 重新加密

# 查看 Route
oc get route
oc describe route web

# TLS 配置
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 调度控制

# nodeSelector
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

# Taint 与 Toleration(管理员操作,开发需了解)
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: {}
# 查看 init container 日志
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 启动失败排错(通用流程)

# Step 1: 查看 Pod 状态
oc get pods
oc get pod <name> -o wide

# Step 2: 查看事件(最关键)
oc describe pod <name>
# 重点关注 Events 部分的 Warning 和 Error

# Step 3: 根据状态分类处理

# === CrashLoopBackOff ===
oc logs <pod> --previous          # 查看上次崩溃日志
oc logs <pod> -c <container>      # 指定容器
# 常见原因:启动命令错误、端口冲突、缺少依赖文件

# === ImagePullBackOff ===
oc describe pod <name> | grep -i "Failed to pull"
# 检查:镜像名/标签是否正确、私有仓库是否已创建 secret、网络是否可达
oc get secrets | grep docker
oc set serviceaccount deployment/<name> <sa-with-pull-secret>

# === Pending ===
oc describe pod <name> | grep -i "Insufficient"
# 常见原因:资源不足(CPU/内存)、PVC 未绑定、节点有污点、网络策略阻止调度
oc get nodes
oc get pvc
oc get pv
oc describe node <node>

# === ErrImagePull ===
# 镜像不存在或权限不足
oc get events --field-selector reason=Failed | grep image

# === CreateContainerConfigError ===
# ConfigMap/Secret 引用错误、SCC 权限不足
oc get configmap
oc get secret
oc get sa
oc adm policy scc-subject-review -u system:serviceaccount:myproject:default -f pod.yaml

# === RunContainerError ===
# 容器运行时问题,检查 CRI-O / containerd 状态
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
# 检查内部 registry 是否可用
oc get route -n openshift-image-registry
oc get svc -n openshift-image-registry

4.3 服务访问失败排错

# 服务 → Endpoint → Pod 链路检查
oc get svc <name>
oc get endpoints <name>          # 必须有 IP:PORT,否则说明 selector 不匹配或 Pod 未就绪
oc get pods -l app=<label>       # 确认标签匹配

# 测试服务连通性(从 Pod 内)
oc exec <pod> -- curl -s http://<svc-name>:<port>/health

# Route 访问失败
oc get route
oc describe route <name>
# 检查:Route 是否指向正确的 Service、TLS 终止类型是否匹配、Path 是否正确

# DNS 解析失败
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
# 检查 CoreDNS Pod 状态
oc get pods -n kube-system -l k8s-app=kube-dns

4.4 节点 NotReady 排错

# 查看节点状态
oc get nodes
oc describe node <node>

# SSH 到故障节点
ssh core@<node-ip>   # OpenShift 4 默认用户 core

# 检查 kubelet
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>

# 查看所有 NetworkPolicy
oc get networkpolicy --all-namespaces

# 临时删除 NetworkPolicy 测试(仅限排错)
oc delete networkpolicy <name>

# 检查 DNS 是否被策略阻止
oc exec <pod> -- nslookup kubernetes.default
# 如果网络策略启用了 Egress,必须显式允许 UDP 53

4.6 权限不足排错(RBAC / SCC)

# 确认当前用户权限
oc whoami
oc auth can-i create deployments
oc auth can-i list secrets -n <namespace>

# 确认 ServiceAccount 权限
oc auth can-i list pods -n <ns> --as=system:serviceaccount:<ns>:<sa>

# 查看 SCC
oc get scc
oc describe scc restricted
oc describe scc anyuid

# 给 SA 授权
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 备份与恢复(集群管理相关)

# 备份 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

# 恢复后重启静态 Pod
sudo systemctl restart kubelet

五、EX188 + EX288 全知识点速查清单

EX188 知识点总览

编号知识点掌握程度
1Podman 基础命令(run/ps/stop/rm/exec/logs/inspect)⭐⭐⭐ 必须熟练
2Containerfile 全指令(FROM/RUN/CMD/ENTRYPOINT/COPY/ADD/ENV/WORKDIR/USER/EXPOSE/VOLUME/HEALTHCHECK)⭐⭐⭐ 必须熟练
3ADD vs COPY 区别⭐⭐⭐ 考试常考
4CMD vs ENTRYPOINT 区别及组合使用⭐⭐⭐ 考试常考
5多阶段构建(Multi-stage Build)⭐⭐⭐ 必须掌握
6镜像管理(pull/push/tag/rmi/save/load/prune)⭐⭐⭐ 必须熟练
7私有 Registry 认证(podman login)⭐⭐⭐ 必须掌握
8镜像备份(save vs export 区别)⭐⭐ 理解即可
9Podman 网络(自定义网络、容器间 DNS、端口映射)⭐⭐⭐ 必须掌握
10Podman 卷(volume create、bind mount、:Z/😒 标签)⭐⭐⭐ 必须掌握
11Podman Pod(多容器应用栈、pod create、共享网络/存储)⭐⭐⭐ 考试重点
12Secret 管理(podman secret create/use)⭐⭐ 了解
13容器安全(非 root 运行、–read-only、–cap-drop、SELinux :Z)⭐⭐⭐ 考试重点
14systemd 集成(podman generate systemd、linger)⭐⭐⭐ 考试重点
15容器故障排查(events/inspect/stats/top/diff/logs)⭐⭐⭐ 必须掌握
16Buildah 基础使用(from/run/commit/config)⭐⭐ 了解
17Skopeo 镜像操作(inspect/copy/sync)⭐ 了解

EX288 知识点总览

编号知识点掌握程度
1oc CLI 基础(login/new-project/get/describe/create/apply/delete/edit/patch)⭐⭐⭐ 必须熟练
2应用部署(new-app、from-image、from-source、from-template)⭐⭐⭐ 考试重点
3Deployment / DeploymentConfig 管理(scale/rollout/status/history/undo)⭐⭐⭐ 必须熟练
4Service 暴露(expose svc、create route、ClusterIP/NodePort/LoadBalancer)⭐⭐⭐ 必须掌握
5Route 类型(edge/passthrough/reencrypt)与 TLS 配置⭐⭐⭐ 考试重点
6BuildConfig 管理(start-build/cancel-build/logs、Webhook、触发器)⭐⭐⭐ 考试重点
7ImageStream 与镜像标签管理(import-image/tag)⭐⭐⭐ 必须掌握
8S2I 构建(new-app、builder 镜像选择、自定义脚本、私有仓库)⭐⭐⭐ 考试重点
9ConfigMap / Secret 创建与注入(env/volume、from-literal/from-file)⭐⭐⭐ 必须熟练
10持久化存储(PVC 创建、挂载到 Deployment)⭐⭐⭐ 必须掌握
11健康检查(Liveness/Readiness/Startup Probe)⭐⭐⭐ 考试重点
12资源限制(requests/limits、LimitRange、ResourceQuota)⭐⭐⭐ 必须掌握
13HPA 自动扩缩容⭐⭐ 了解配置
14NetworkPolicy(Ingress/Egress、podSelector、namespaceSelector、DNS 放行)⭐⭐⭐ 考试重点
15ServiceAccount 与 RBAC(Role/ClusterRole/RoleBinding、auth can-i)⭐⭐⭐ 考试重点
16SCC 安全上下文约束(anyuid/privileged、add-scc-to-user)⭐⭐ 了解
17Template 模板(process/new-app --template、自定义模板导出)⭐⭐⭐ 考试重点
18Helm(install/upgrade/rollback/repo/values)⭐⭐⭐ 必须掌握
19Kustomize(base/overlay、patches、images、build/apply -k)⭐⭐⭐ 必须掌握
20OpenShift Pipelines / Tekton(Task/Pipeline/PipelineRun/tkn CLI/Trigger)⭐⭐⭐ 考试重点
21Operator 安装与使用(Subscription/CSV/CRD)⭐⭐ 了解
22节点调度(nodeSelector/affinity/taint/toleration)⭐⭐ 了解
23Init Container 与多容器 Pod⭐⭐ 了解
24项目级隔离与配额管理⭐⭐ 了解

六、易踩坑点总结(考试血泪教训)

🔴 EX188 易踩坑点

坑点说明避坑方法
1. podman run 后容器立即退出前台进程结束导致容器停止使用 -d 后台运行,或确保 CMD 是阻塞式进程
2. 端口映射写反-p 主机:容器 顺序容易搞混记忆口诀:“外在前,内在后”-p 8080:80
3. 忘记 :Z:z SELinux 标签挂载主机目录后容器无法读写单容器用 :Z,多容器共享用 :z
4. COPYADD 混淆ADD 支持 URL 和自动解压,COPY 仅本地文件本地文件一律用 COPY,远程/tar 才用 ADD
5. ENTRYPOINT + CMD 参数覆盖问题docker run 后的参数会覆盖 CMD,但不会覆盖 ENTRYPOINT需要固定命令用 ENTRYPOINT,可变参数用 CMD
6. podman build 缓存导致旧层未更新修改了文件但构建结果没变使用 --no-cache 或修改 RUN 指令前的层
7. podman saveexport 混淆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 无 Endpointoc get endpoints <svc> 必须有 IP,否则检查 label selector
3. 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 大小写不匹配manualManual,导致 Pending严格检查大小写,建议直接复制已有 PV 的 class name
9. oc set resources 单位写错Mi vs MGi vs G 含义不同内存用 Mi/Gi,CPU 用 m(毫核)
10. ServiceAccount 无镜像拉取权限私有仓库需要 docker-registry secret 并绑定到 SAoc set serviceaccount deployment/<name> <sa> + oc secrets link
11. 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 后提交到 Git
14. BuildConfig 的 Git 仓库需要认证但无 secret私有仓库拉取失败创建 source-secret 并在 new-app 或 BC 中引用
15. HPA 需要 metrics-server 但未安装oc autoscale 后 HPA 显示 <unknown>确认 openshift-monitoringmetrics-server 已启用
16. oc rollout undo 后忘记 oc rollout status回滚操作异步执行,立即检查可能仍是旧版本回滚后务必 oc rollout status deployment/<name>
17. 模板参数未传递导致默认值不符合要求oc processnew-app --template 时漏传参数先用 oc describe template 查看参数列表
18. Tekton Pipeline 的 Workspace 未绑定PipelineRun 失败,提示 workspace 未提供tkn pipeline start 时必须 --workspace name=xxx,...
19. 忘记 oc project 导致资源创建到错误命名空间考试多个项目切换时极易出错每道题先执行 oc project <指定项目>
20. oc createoc apply 混用导致已存在报错create 对已存在资源会报错,apply 不会不确定时用 oc apply -f,或先 oc delete -fcreate
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-daemonsetsdrain 卡住无法完成标准命令: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

  • 能不看文档手写完整 Containerfile(含多阶段构建)
  • 能 5 分钟内完成 podman build + push 全流程
  • 能熟练创建 Podman Pod 并添加多个容器
  • 能生成 systemd 单元文件并确保持久化
  • oc new-app + oc expose 能在 3 分钟内完成
  • 能独立编写 NetworkPolicy(含 Ingress + Egress + DNS)
  • 能独立编写 RBAC(Role + RoleBinding + SA + auth can-i 验证)
  • 能完成一次完整的 S2I 构建并配置 Webhook 触发器
  • 能独立编写 Helm values.yaml 并完成 install/upgrade/rollback
  • 能独立编写 Kustomize kustomization.yaml 并应用
  • 能使用 tkn 创建并运行 Pipeline
  • 能在 10 分钟内定位并修复一个 Pending/CrashLoopBackOff 的 Pod

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值