OpenShift OKD 实验手册:镜像构建与 ImageStream 管理实战

摘要:OpenShift (OKD) 最大的特色之一就是内置了完整的镜像构建与管理能力。本实验将通过“二进制构建 (Binary Build)”的方式,演示如何将本地的 Dockerfile 推送到集群,构建出镜像,并通过 ImageStream 自动触发部署更新。


1. 架构图解:从源码到上线

1. oc start-build (上传代码)
2. 启动构建 Pod
3. Pull 基础镜像
4. Push 构建好的镜像
5. 更新元数据
6. 触发更新 (Trigger)
7. 滚动升级

开发者

BuildConfig

Build Pod

Docker Hub

内部 Registry

ImageStream

Deployment

应用 Pod

2. 核心概念解析

  • ImageStream (IS)

    • 它不是镜像仓库本身,而是镜像的**“动态指针”“快捷方式”**。
    • 它可以指向 Docker Hub 的镜像,也可以指向内部 Registry 的镜像。
    • 核心能力:当它指向的镜像发生变化时,它能通知 Deployment 自动重新部署。
  • BuildConfig (BC)

    • 定义了**“怎么造镜像”**。
    • 包括:源码从哪来(Git/本地)、用什么策略(Docker/S2I)、输出到哪个 ImageStream。

3. 实战步骤:从零构建 Nginx 镜像

3.1 环境准备

# 创建实验项目
oc new-project image-lab

# 在节点上准备工作目录
mkdir -p ~/nginx-demo
cd ~/nginx-demo

3.2 编写应用代码与 Dockerfile

由于 OpenShift 默认使用非 Root 用户运行容器,我们需要修改 Nginx 配置以适配安全策略(这是生产环境常见坑点)。

# 1. 创建首页
echo "<h1>Hello OpenShift Build!</h1>" > index.html

# 2. 创建 Dockerfile (修正版:开启 8080 端口)
cat <<EOF > Dockerfile
FROM docker.io/library/nginx:latest

# 修改端口为 8080 (非特权端口)
RUN sed -i 's/listen       80;/listen       8080;/g' /etc/nginx/conf.d/default.conf && \
    sed -i '/user  nginx;/d' /etc/nginx/nginx.conf && \
    chmod -R 777 /var/cache/nginx /var/run /var/log/nginx

# 复制文件
COPY index.html /usr/share/nginx/html/index.html

# 暴露端口
EXPOSE 8080
EOF

3.3 创建 ImageStream 与 BuildConfig

我们需要先定义“容器”(IS)和“流水线”(BC)。

# 1. 创建 ImageStream (目标镜像流)
oc create imagestream my-nginx

# 2. 创建构建配置 (Binary 模式)
# --binary: 表示源码不是从 Git 拉,而是稍后从本地上传
# --to: 构建好的镜像存放到哪里
oc new-build --name=nginx-builder --strategy=docker --binary --to=my-nginx:latest

3.4 触发构建 (Start Build)

这一步会将当前目录下的文件打包上传到集群,并开始构建。

# 开始构建并跟踪日志
oc start-build nginx-builder --from-dir=. --follow

实战排障技巧:构建卡住怎么办?
在单节点 (SNO) 或网络受限环境中,Build Pod 可能会卡在 Pulling image 阶段导致超时。
解决方法:手动在节点上预拉取基础镜像。
podman pull docker.io/library/nginx:latest

3.5 部署应用

当构建成功后,镜像已经存在于 ImageStream 中。我们使用它来部署应用。

# 1. 使用 ImageStream 部署
# 注意:我们显式指定镜像流
oc new-app my-nginx --name=my-web

# 2. 暴露服务并指定正确的端口 (关键!)
# 我们的 Nginx 监听 8080,因此路由必须精准指向 8080
oc expose svc/my-web --port=8080

3.6 验证访问

# 获取路由域名
oc get route my-web

# 访问显示的 URL
# 预期结果:浏览器显示 "Hello OpenShift Build!"

避坑指南
默认情况下,oc expose 可能会尝试暴露 Service 的第一个端口(通常是 80)。由于我们在 Dockerfile 中已将 Nginx 改为 8080 端口运行,请务必在创建路由时加上 --port=8080,否则会由于后端端口不通导致 503 错误。


4. 进阶实验:体验“自动触发更新”

这是 ImageStream 最迷人的特性:改代码 -> 重新构建 -> 自动上线

  1. 修改代码
    echo "<h1>Version 2: Auto Update Success!</h1>" > index.html
    
  2. 再次构建
    oc start-build nginx-builder --from-dir=. --follow
    
  3. 观察 Pod
    不需要执行任何 oc applyoc rollout,你会发现旧 Pod 自动终止,新 Pod 自动启动。
    oc get pods -w
    

5. 进阶:S2I (Source-to-Image) 构建模式

如果说 Docker Build 还需要开发者懂 Linux 命令,那么 S2I 就是完全面向代码的“黑魔法”。

  • 特点:无需编写 Dockerfile。
  • 原理Builder镜像 + 源代码 = 应用镜像

5.1 准备纯净代码

我们只需要一个 HTML 文件,不需要 Dockerfile。

mkdir -p ~/s2i-demo
echo "<h1>Built with S2I - No Dockerfile!</h1>" > ~/s2i-demo/index.html
cd ~/s2i-demo

5.2 创建 S2I 构建

我们使用官方的 Nginx S2I 镜像作为“底座”。

# new-build 自动检测策略
# --image-stream=openshift/nginx: 指定使用集群自带的 Nginx S2I 镜像
# --binary: 依然使用本地上传模式
oc new-build --name=s2i-web --image-stream=openshift/nginx --binary

5.3 触发构建

oc start-build s2i-web --from-dir=. --follow

观察日志:您会发现这次没有执行 yum installsed,而是显示 Assembler 在处理您的代码。

5.4 部署

oc new-app s2i-web
oc expose svc/s2i-web

6. 总结

本实验展示了 OpenShift “Build once, Deploy anywhere” 的核心理念。无论是传统的 Dockerfile 模式,还是更高级的 S2I 模式,OpenShift 都提供了闭环的自动化流水线。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐