在前面的章節中,我們已經成功將非同步 S3 微服務搬上了 K8s,實作了雙探針自癒、HPA 自動水平擴充以及 PV/PVC 持久化掛載。
然而,在真實的軟體開發團隊中,隱藏著一個極度繁瑣且容易出錯的痛點:每次修改程式碼,都要手動 docker build、docker push,再連進 K8s 伺服器敲 kubectl apply,不僅耗時,還容易發生版控錯亂與人工操作失誤!
所以今天,我們要介紹現代雲端原生架構中不可或缺的一環持續整合與持續部署 CI/CD (Continuous Integration / Continuous Deployment)!帶大家建置 GitHub Actions 自動化流水線,搭配 AWS ECR (Elastic Container Registry),實現只需 git push,系統自動完成單元測試、鏡像打包、推送到 AWS ECR 的流程。

在傳統手動部署模式下,開發與營運之間存在著龐大的溝通牆與操作風險:

【傳統手動部署 (Manual Deployment)】:
修改 Code ──► 本地 Build ──► 手動 Docker Build ──► 手動 Tag ──► 手動 Apply K8s
⚠️ 痛點:耗時 15~30 分鐘、環境不一致 ("It works on my machine")、缺乏審核紀錄。
【自動化 CI/CD 流水線 (Automated Pipeline)】:
git push ──► GitHub Actions ──► 跑測試 ──► 打包 ECR ──► 自動 K8s 滾動更新 (0.00% 錯誤)
🚀 優勢:平均 2 分鐘完成上線、100% 稽核軌跡 (Audit Trail)、完全消滅人為失誤!
在 CI/CD 流水線中,Runner 打包出來的 Docker Image 必須推送到一個雲端鏡像倉庫 (Container Registry),供後續的 K8s 或伺服器拉取 (Pull) 部署。
常見的有以下三種方案:
| 方案名稱 | 費用與免費額度 | 優勢與特色 | 適用場景 |
|---|---|---|---|
GHCR (ghcr.io) |
免費 (包含每月 500MB 儲存與私有庫) | GitHub 內建,無需額外註冊,自動對接 GITHUB | 個人開源專案、極簡測試 |
| Docker Hub | 免費版提供 1 個私有庫 + 無限公有庫 | 全球最普及、社群範例最多,但有每小時下載次數限制 (Rate Limit) | 通用社群專案 |
| AWS ECR | AWS Free Tier 包含 500MB 免費私有儲存 | AWS 雲端原生代管,整合 IAM 權限控管,企業級對接 EKS/EC2 首選 | 企業級生產環境 |
本次實作內容選擇 AWS ECR :因為 AWS 免費額度包含了 500MB 的免費 ECR 儲存空間,對於我們這次的實作綽綽有餘,JAR 鏡像只有約 130MB,體驗真實的 AWS 雲端生態!
2026-ithome-s3-service。
git init
git add .
git commit -m "feat: initial commit for S3 async microservice with K8s YAMLs"
git remote add origin https://github.com/your-username/s3-async-microservice.git #剛剛複製的url
git push -u origin main
Elastic Container Registry (ECR)服務。建立儲存庫:
Private(私有倉庫,確保金鑰與架構不外洩)。<aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/s3-app-service)。
AmazonEC2ContainerRegistryPowerUser

為了讓 GitHub Actions 能代表你登入 AWS ECR 推送鏡像,我們必須在 GitHub 填入剛剛取得的ECR角色的accessKey, secretKey,來讓我們後續產生的image可順利推上雲端:
Settings ➔ Secrets and variables ➔ Actions。New repository secret,新增以下金鑰名稱,並輸入你自己的ak,sk:

在專案根目錄下建立 .github/workflows/deploy.yml 檔案,貼入自動化腳本:
name: Deploy S3 Microservice to K8s
on:
push:
branches: [ "main" ] # 當 main 分支有 git push 時自動觸發
env:
ECR_REPOSITORY: 2026ithome/s3-service # ECR URL 中 registry 後面的部分
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: 1. Checkout Code
uses: actions/checkout@v3
- name: 2. Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: 3. Build & Package (skip tests - no test cases defined)
# 如果之後補了測試,把 -DskipTests 拿掉改回 mvn test && mvn package -DskipTests
run: mvn package -DskipTests
working-directory: s3-service # ← Dockerfile 和 pom.xml 都在這個子目錄
- name: 4. Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1 # ECR 所在的 Region
- name: 5. Login to AWS ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: 6. Build & Push Docker Image to ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }} # 使用 Git Commit SHA 作為唯一版號
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f s3-service/Dockerfile s3-service
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
git add .
git commit -m 'add cicd'
git push
打開 GitHub 頁面的 Actions 標籤,看到亮綠燈就代表從單元測試、Docker Multi-stage 瘦身打包、AWS ECR 上傳都成功啦
進入AWS ECR就可以看到github已經將build好的image上傳啦!
剛剛已經透過cicd流程將檔案建立成image必且push上aws ecr上了,我們現在只完成cicd流程的一半,先回到本地端測試一下,能不能將雲端的image拉下來並且執行
ecr-secret(讓 Minikube 有權限下載 ECR 鏡像)因為 AWS ECR 是私有倉庫,Minikube 預設連不進去。我們要先去aws申請憑證,才能從本地拉image下來
CloudShell 圖示aws ecr get-login-password --region us-east-1 畫面上會印出一大串超長的亂碼字串(12 小時臨時 Token),將它完整複製起來
kubectl create secret docker-registry ecr-secret \
--docker-server=154993632692.dkr.ecr.us-east-1.amazonaws.com \
--docker-username=AWS \
--docker-password=貼上剛剛複製的那一大串Token
k8s/s3-app-deployment.yaml在 YAML 中加上 imagePullSecrets 指向 ecr-secret,並更新 image 網址:
apiVersion: apps/v1
kind: Deployment
metadata:
name: s3-app-deployment
spec:
# 💡 Day29:從 ECR 拉 image 需要 imagePullSecrets
imagePullSecrets:
- name: ecr-secret
containers:
- name: s3-service-container
# 💡 Day29:ECR image(CI/CD 自動更新這行的 tag)
# 本地測試時改回 image: my-app:latest 並移除 imagePullSecrets
image: 154993632692.dkr.ecr.us-east-1.amazonaws.com/2026ithome/s3-service:your_tag
imagePullPolicy: Always # 使用 ECR 時必須 Always,確保每次都拉最新 tag
# 1. 套用最新的 Deployment YAML
kubectl apply -f k8s/s3-app-deployment.yaml
# 2. 觀察 K8s 從 AWS ECR 拉取鏡像並完成 0 停機滾動更新
kubectl rollout status deployment/s3-app-deployment
透過 GitHub Actions 與 AWS ECR,我們縮短軟體交付週期,完成了現代 DevOps 架構中最重要的一塊拼圖:
明天,我們將迎來 30 天鐵人賽的最終章!目前只是本地的測試,明天會教大家如何使用AWS EC2來做到完整的CICD部署,後許只要程式碼有修改調整,推上github後,就會有完整的驗證、建立image和部署流程!