Tekton 与 Harbor 集成:实现镜像扫描(Trivy)通过后才允许部署
核心目标
在 CI/CD 流水线中实现:
- 构建镜像并推送至 Harbor
- 自动触发 Trivy 漏洞扫描
- 仅当扫描结果无严重漏洞(CRITICAL)时才允许部署
实现步骤
1. 前置条件准备
- Harbor 配置
- 启用 Trivy 扫描器(Harbor ≥ 2.0)
- 创建机器人账户(Robot Account)用于 API 访问(需
Pull/Push/Scan权限)
- Tekton 环境
- 安装 Tekton Pipelines 和 Tekton Triggers
- 创建 Kubernetes Secret 存储 Harbor 凭证:
kubectl create secret generic harbor-creds \ --from-literal=username=<ROBOT_USERNAME> \ --from-literal=password=<ROBOT_PASSWORD>
2. 关键 Pipeline 设计
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: scan-before-deploy
spec:
params:
- name: image
type: string # 格式: harbor.example.com/project/repo:tag
workspaces:
- name: source-code
tasks:
# 阶段1: 构建并推送镜像到 Harbor
- name: build-and-push
taskRef:
name: kaniko
workspaces:
- name: source
workspace: source-code
params:
- name: IMAGE
value: "$(params.image)"
# 阶段2: 触发 Harbor Trivy 扫描
- name: trigger-scan
runAfter: ["build-and-push"]
taskRef:
name: trigger-harbor-scan
params:
- name: image
value: "$(params.image)"
# 阶段3: 验证扫描结果
- name: verify-scan
runAfter: ["trigger-scan"]
taskRef:
name: check-scan-result
params:
- name: image
value: "$(params.image)"
# 阶段4: 仅当扫描通过时部署
- name: deploy
runAfter: ["verify-scan"]
when:
- input: "$(tasks.verify-scan.status)"
operator: in
values: ["Succeeded"]
taskRef:
name: deploy-manifest
3. 核心 Task 实现
(1) 触发扫描 Task (trigger-harbor-scan)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: trigger-harbor-scan
spec:
params:
- name: image # 格式: harbor.example.com/project/repo:tag
type: string
steps:
- name: trigger
image: curlimages/curl
env:
- name: HARBOR_USER
valueFrom:
secretKeyRef:
name: harbor-creds
key: username
- name: HARBOR_PASS
valueFrom:
secretKeyRef:
name: harbor-creds
key: password
script: |
# 解析镜像地址
DOMAIN=$(echo $(params.image) | cut -d/ -f1)
PROJECT=$(echo $(params.image) | cut -d/ -f2)
REPO_TAG=$(echo $(params.image) | cut -d/ -f3)
REPO=$(echo $REPO_TAG | cut -d: -f1)
TAG=$(echo $REPO_TAG | cut -d: -f2)
# 调用 Harbor 扫描 API
curl -u $HARBOR_USER:$HARBOR_PASS -X POST \
"https://$DOMAIN/api/v2.0/projects/$PROJECT/repositories/$REPO/artifacts/$TAG/scan"
(2) 检查扫描结果 Task (check-scan-result)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: check-scan-result
spec:
params:
- name: image
type: string
steps:
- name: verify
image: alpine/curl
env: [...] # 同 trigger-scan 的凭证环境变量
script: |
# 解析镜像地址(同上)
...
# 轮询扫描结果(最大重试10次)
for i in {1..10}; do
REPORT=$(curl -s -u $HARBOR_USER:$HARBOR_PASS \
"https://$DOMAIN/api/v2.0/projects/$PROJECT/repositories/$REPO/artifacts/$TAG/additions/vulnerabilities")
# 检查扫描状态
STATUS=$(echo $REPORT | jq -r .scan_status)
case $STATUS in
"Success")
# 检查 CRITICAL 漏洞数量
CRITICALS=$(echo $REPORT | jq -r '.vulnerabilities[] | select(.severity=="Critical")' | jq -s length)
if [ $CRITICALS -gt 0 ]; then
echo "发现 $CRITICALS 个严重漏洞!"
exit 1
else
echo "扫描通过,无严重漏洞"
exit 0
fi
;;
"Running"|"Pending")
sleep 10
;;
*)
echo "扫描失败: $STATUS"
exit 1
;;
esac
done
echo "扫描超时未完成"
exit 1
4. 执行流程说明
- 镜像推送
使用 Kaniko 构建镜像并推送到 Harbor - 触发扫描
通过 Harbor API 启动 Trivy 扫描 - 结果验证
- 轮询扫描结果(约需 1-2 分钟)
- 检测到
CRITICAL漏洞时任务失败(exit 1)
- 条件部署
仅当verify-scan成功时才执行部署任务
关键优化建议
- 超时控制
在check-scan-resultTask 中增加timeout字段:spec: timeout: "10m" # 设置10分钟超时 - 通知机制
添加Task发送扫描失败通知(如 Slack/邮件) - 参数化安全阈值
扩展check-scan-result支持配置漏洞阈值:params: - name: max_critical type: number default: 0 # 默认不允许任何CRITICAL漏洞
注:Harbor API 响应格式需参考官方文档,实际部署前建议使用
curl测试 API 调用。
196

被折叠的 条评论
为什么被折叠?



