目录
一、结果展示

最终建成的架构
bash
本机 Windows
│ git push
▼
GitLab
│ Jenkins 拉取
▼
Jenkins(容器)
打包 → SSH/SCP → 触发部署
│ 凭据 my-deploy-key
▼
ECS (CentOS 7)
deploy 用户 + Podman
容器 cicd-demo 监听 8090
│
▼
ECS 本机可访问:http://127.0.0.1:8090/
二、完整流程
阶段 0:目标和环境摸清
- 目标:Jenkins 流水线把服务用 Podman 部署到 ECS
- 机器:ECS (干净)+ 已有 Jenkins 网站(跑在容器里)
- 明确:ECS 不需要再装 Jenkins,只做部署机
阶段 1:准备 ECS
- 系统是 CentOS 7,使用
yum安装所需的软件包 - 安装Podman(约 1.6.4)
- 直连
docker.m.daocloud.io镜像源 - 验证:
podman run ... alpine echo ok成功 - 创建
deploy用户、/opt/cicd-demo、sudo 权限、预拉 nginx 镜像
bash
# 1) 基础软件
sudo yum -y install podman git curl tar
# 测试Podman的连通性
sudo podman pull docker.m.daocloud.io/library/alpine:3.20
sudo podman run --rm docker.m.daocloud.io/library/alpine:3.20 echo ok
# 2) 部署用户
sudo useradd -m deploy || true
sudo mkdir -p /opt/cicd-demo
sudo chown deploy:deploy /opt/cicd-demo
# 3) 让 deploy 可用 podman(学习环境)
echo 'deploy ALL=(ALL) NOPASSWD: /usr/bin/podman, /usr/bin/tar, /usr/bin/mkdir, /usr/bin/chown, /usr/bin/tee' \
| sudo tee /etc/sudoers.d/deploy-cicd
sudo chmod 440 /etc/sudoers.d/deploy-cicd
# 4) 准备 SSH 目录
sudo -u deploy mkdir -p /home/deploy/.ssh
sudo -u deploy chmod 700 /home/deploy/.ssh
sudo -u deploy touch /home/deploy/.ssh/authorized_keys
sudo -u deploy chmod 600 /home/deploy/.ssh/authorized_keys
# 5) 预拉基础镜像(避免构建时再超时)
sudo podman pull docker.m.daocloud.io/library/nginx:1.27-alpine
# 6) 放行业务端口(若开了 firewalld)
systemctl status firewalld # 检查 firewalld 的状态
sudo firewall-cmd --permanent --add-port=8090/tcp
sudo firewall-cmd --reload
安全组也要放行:
22:Jenkins 机器 → ECS8090:浏览器 → ECS
阶段 2:Jenkins 与 ECS 的 SSH 打通
- 在 ECS 上生成公私密钥对
- 公钥放到 ECS:
/home/deploy/.ssh/authorized_keys - Jenkins 凭据 ID 为:
my-deploy-key(用户deploy)
bash
#1)生成密钥对
ssh-keygen -t ed25519 -N "" -f ~/ecs_deploy -C "jenkins-to-ecs"
#2)查看
# 公钥
cat ~/ecs_deploy.pub
# 私钥(稍后粘贴到 Jenkins 网页凭据里)
cat ~/ecs_deploy
#3)公钥放到 ECS 上的 deploy 用户
cat ~/ecs_deploy.pub | sudo tee -a /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
打开 Jenkins 网址,用网页添加凭据:
- 登录 Jenkins 网站
- Manage Jenkins → Credentials → System → Global credentials → Add Credentials
- 填写:
- Kind:
SSH Username with private key- ID:my-deploy-key
- Username:
deploy- Private Key:选 Enter directly,粘贴私钥全文
- 保存
阶段 3:示例代码进 GitLab
- 本地项目:
D:\test\jenkins-cicd-demo - Windows 上安装 Git for Windows
- 在本地
git push 代码文件到gitlab - 成功推到 gitlab 仓库
- 仓库内关键文件:
index.html、Dockerfile、deploy.sh、Jenkinsfile
安装 Git for Windows(以后推代码方便)
- 打开:https://git-scm.com/download/win
- 安装(一路 Next 即可,勾选 "Git from the command line...")
- 关掉并重新打开 PowerShell
- 验证:git --version(在终端 / PowerShell 输入)
bash
#1)推送代码到gitlab(在终端 / PowerShell 上执行)
cd jenkins-cicd-demo # 实际的脚本文件夹路径
git init
git add index.html Dockerfile deploy.sh Jenkinsfile
git commit -m "feat(cicd): init jenkins cicd demo"
git branch -M main
git remote add origin <GitLab的HTTPS地址>
git push -u origin main
阶段 4:Jenkins 建任务
在 Jenkins 创建流水线任务:
(1)打开 Jenkins 网址
(2)新建 Item → 名称:cicd-demo → 选 Pipeline → 确定
(3)拉到 Pipeline 区域填写:
| 项 | 填什么 |
|---|---|
| Definition | Pipeline script from SCM |
| SCM | Git |
| Repository URL | GitLab的HTTPS地址 |
| Credentials | 公开仓库可选 none;私有则选 GitLab 用户名密码/Token |
| Branch Specifier | */main |
| Script Path | Jenkinsfile |
(4)保存
立即构建
进入任务 cicd-demo → 立即构建 → 打开 Console Output。
正常应看到:
Checkout → Package → Upload to ECS → Deploy on ECS → SUCCESS
阶段 5:验证结果
- ECS 上:
podman ps有cicd-demo,curl 127.0.0.1:8090返回 200 - Windows:可查看内容
bash
#1)在本机 ECS 上检查
sudo podman ps
curl -I http://127.0.0.1:8090/
curl -s http://127.0.0.1:8090/ | head
sudo podman logs cicd-demo --tail 50
三、阶段详细讲解(Build #4)
流水线 Stage View:
Checkout SCM → Checkout → Package → Upload to ECS → Deploy on ECS → Post Actions
| 文件 | 主要作用 |
|---|---|
Jenkinsfile |
定义流水线阶段(在 Jenkins 上跑) |
deploy.sh |
ECS 上真正构建/启动 Podman |
Dockerfile |
告诉 Podman 怎么打镜像 |
index.html |
网站页面内容 |
Declarative: Checkout SCM / Post Actions 是 Jenkins 声明式流水线自动加的,不完全写在业务 stage 里,但仍由 Jenkinsfile 触发。
bash
Declarative: Checkout SCM ← Jenkins 读任务 + Jenkinsfile 存在于仓库
Checkout ← Jenkinsfile 里 stage('Checkout')
Package ← Jenkinsfile 里 stage('Package') (打进 tgz 的是后 3 个文件)
Upload to ECS ← Jenkinsfile 里 stage('Upload...')
Deploy on ECS ← Jenkinsfile 调用 deploy.sh
deploy.sh 再用 Dockerfile + index.html
Declarative: Post Actions ← Jenkinsfile 里 post { ... }
1. Declarative: Checkout SCM(约 4s)
任务: Jenkins 按任务配置,从 GitLab 拉取代码。
对应配置:
- 仓库:
.../cicd-demo.git - 分支:
main - 脚本路径:
Jenkinsfile
产物: Jenkins 工作空间里有一份完整项目代码。
失败常见原因: 地址错、分支名错(遇到过找 master)、GitLab 认证失败。
2. Checkout(约 165ms)
任务: Jenkinsfile 里显式写的 checkout scm 再拉/确认一次源码。
和上一阶段功能接近,属于流水线里的业务阶段;Declarative 外层也会自动做 SCM checkout,所以你会看到两个 Checkout 相关格。
意义: 保证后续 Package 用的是本次构建对应的提交。
3. Package(约 366ms)
任务: 在 Jenkins 容器里打包要发给 ECS 的文件。
对应命令逻辑:
bash
tar czf app.tgz Dockerfile index.html deploy.sh
产物: app.tgz
为什么打包: Jenkins(容器)负责编排;真正 podman build 在 ECS 上做,所以先把构建所需文件传过去。
4. Upload to ECS(约 1s)
任务: 用 SSH 私钥把包传到 ECS,并解压。
对应逻辑:
- 取出凭据
my-deploy-key scp app.tgz deploy@ECS IP:/tmp/ssh到 ECS:解压到/opt/cicd-demo,赋权,chmod +x deploy.sh
产物: ECS 上 /opt/cicd-demo 有最新代码与脚本。
踩过的坑: 凭据 ID 不一致;sshagent 不可用;后改 withCredentials 成功。
5. Deploy on ECS(约 4s)
任务: SSH 到 ECS 执行 deploy.sh,完成真正发布。
deploy.sh 内部大致:
- 把页面里的
__BUILD_TAG__换成b4(构建号) podman build打镜像localhost/cicd-demo:b4(基础镜像来自 DaoCloud)- 停旧容器 → 删旧容器 →
podman run -p 8090:80 curl 127.0.0.1:8090健康检查
产物: 运行中的容器 cicd-demo,对外端口 8090。
耗时相对最长: 因为包含构建镜像和启动容器。
6. Declarative: Post Actions(约 63ms)
任务: 流水线结束后的收尾(post { success / failure })。
成功时会打印类似:可访问 http://ECS IP:8090/、版本号等提示。
失败时会提示去看 Console / podman logs。
注意: Post 只负责通知/收尾,不再部署。
四、一次成功构建对应的数据流(结合 #4)
GitLab 最新 commit
→ Jenkins Checkout(拿到代码)
→ Package(app.tgz)
→ Upload(scp 到 ECS /opt/cicd-demo)
→ Deploy(podman build/run,tag 如 b4)
→ Post(打印成功信息)
→ ECS: cicd-demo 容器 Up,8090→80
ECS 上看到的:
- 镜像:
localhost/cicd-demo:b4 - 端口:
0.0.0.0:8090->80/tcp - 本机访问:HTTP 200 + 标题 "Jenkins CI/CD Demo"
哪些是自动的,哪些是手动做的
| 类型 | 内容 |
|---|---|
| 手动完成(一次性) | 装 Podman、配 deploy/SSH、建 GitLab 仓、建 Jenkins 任务、配凭据、改分支/凭据排错 |
| 流水线自动完成(每次构建) | 拉代码、打包、上传、远程构建镜像、启停容器、健康检查 |
| 仍受环境影响 | 本机浏览器能否打开内网 |
**总结:**完成的是一条标准迷你 CI/CD
代码进 GitLab → Jenkins 自动拉取并部署到 ECS → Podman 跑 nginx 演示站