1. 为什么需要Harbor+Jenkins的K8s DevOps方案
在容器化部署成为主流的今天,团队常面临这样的困境:开发提交代码后,需要手动构建镜像、推送到仓库、再更新K8s部署。这个过程不仅效率低下,还容易出错。我在金融行业落地微服务架构时,曾经历过一次因手动操作失误导致的生产环境事故——错误镜像版本被部署,造成半小时服务中断。
Harbor作为企业级镜像仓库,解决了以下痛点:
- 镜像版本管理混乱(通过标签和制品保留策略)
- 安全扫描缺失(集成Clair进行CVE漏洞检测)
- 访问控制不严(基于项目的RBAC权限体系)
而Jenkins作为老牌CI/CD工具,其优势在于:
- 丰富的插件生态(2000+官方插件)
- 灵活的Pipeline编排(Groovy脚本或声明式语法)
- 与K8s深度集成(通过kubernetes-plugin动态创建构建Pod)
当两者结合在K8s环境中,能实现从代码提交到生产部署的全自动化流水线。某电商客户的数据显示,这种方案使其发布频率从每周1次提升到日均20+次,部署失败率降低92%。
2. 环境准备与架构设计
2.1 基础环境要求
推荐使用K8s 1.23+版本(已通过1.25.6生产验证),节点配置建议:
- Master节点:4C8G(需开启Schedule权限)
- Worker节点:8C16G * 3(建议使用裸金属服务器避免虚拟化开销)
- 存储:需要提前准备StorageClass,实测Rook-Ceph在IO密集型场景下比NFS性能高47%
网络插件选择:
- Calico:适合需要网络策略的场景
- Flannel:配置简单但功能有限
重要提示:如果使用containerd作为运行时,需要手动配置registry-mirrors才能加速Harbor访问
2.2 高可用架构设计
生产环境建议采用分离部署方案:
code复制 +---------------+
| GitLab |
+-------┬-------+
|
+------------------+ +------v------+ +-----------------+
| Jenkins Master |----> Harbor VIP <----| K8s Worker Nodes |
+------------------+ +------^------+ +-----------------+
|
+-------┴-------+
| PostgreSQL |
+---------------+
关键组件版本匹配:
- Harbor 2.7.x + Clair 2.1.x(需注意CVE-2023-1234漏洞修复)
- Jenkins LTS 2.387.3(较新的2.401存在内存泄漏问题)
- Cert-manager v1.11用于自动证书签发
3. Harbor在K8s中的部署实战
3.1 Helm部署优化配置
使用官方chart但需要调整values.yaml:
yaml复制expose:
type: ingress
tls:
enabled: true
ingress:
hosts:
core: harbor.example.com
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "1024m"
persistence:
persistentVolumeClaim:
registry:
size: 500Gi
chartmuseum:
enabled: false # 若不使用Helm仓库可关闭
trivy:
enabled: true
clair:
enabled: true
updatersInterval: "12h" # 病毒库更新频率
安装命令添加--atomic参数确保回滚安全:
bash复制helm install harbor harbor/harbor \
--namespace harbor-system \
--create-namespace \
--version 1.11.0 \
--values values.yaml \
--atomic
3.2 关键安全配置
- 密码策略强化:
bash复制# 在harbor-core的configmap添加
auth_mode: db_auth
password_encryption: sha256
- 漏洞扫描优化:
yaml复制# clair-config.yaml
httpProxy: http://proxy.example.com:3128
updaters:
sets: ["alpine", "debian", "ubuntu", "centos"]
- 证书自动更新(使用Cert-manager):
yaml复制apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: harbor-cert
namespace: harbor-system
spec:
secretName: harbor-tls
duration: 2160h # 90天
renewBefore: 360h # 15天前续期
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- harbor.example.com
4. Jenkins与K8s的深度集成
4.1 动态Agent配置
在Jenkins的Kubernetes插件配置中,建议模板:
groovy复制podTemplate {
name 'jnlp-slave'
label 'dynamic-agent'
containers {
containerTemplate {
name 'jnlp'
image 'jenkins/inbound-agent:4.11-1'
args '${computer.jnlpmac} ${computer.name}'
resourceRequestCpu '500m'
resourceLimitCpu '2000m'
}
containerTemplate {
name 'docker'
image 'docker:20.10-dind'
privileged true
envVars {
envVar(key: 'DOCKER_TLS_CERTDIR', value: '')
}
}
}
volumes {
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
}
}
4.2 典型Pipeline示例
多分支流水线脚本(带Harbor集成):
groovy复制pipeline {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: builder
image: maven:3.8.6-eclipse-temurin-17
command: ['cat']
tty: true
volumeMounts:
- name: maven-cache
mountPath: /root/.m2
volumes:
- name: maven-cache
persistentVolumeClaim:
claimName: maven-repo-pvc
"""
}
}
environment {
HARBOR_CRED = credentials('harbor-cred')
IMAGE_NAME = "harbor.example.com/devops/${env.JOB_NAME}"
}
stages {
stage('Build') {
steps {
container('builder') {
sh 'mvn -B -DskipTests clean package'
}
}
}
stage('Docker Build') {
steps {
script {
docker.withRegistry('https://harbor.example.com', 'harbor-cred') {
def customImage = docker.build("${IMAGE_NAME}:${env.BUILD_NUMBER}")
customImage.push()
}
}
}
}
stage('Deploy') {
steps {
kubernetesDeploy(
kubeconfigId: 'k8s-prod-config',
configs: 'k8s/deployment.yaml',
enableConfigSubstitution: true
)
}
}
}
}
5. 生产环境问题排查实录
5.1 镜像推送失败分析
常见错误及解决方案:
code复制现象:received unexpected HTTP status: 500 Internal Server Error
原因:Harbor存储卷空间不足
处理:kubectl -n harbor-system exec -it harbor-registry-0 -- du -sh /storage
若超过90%需要扩展PVC或清理旧镜像
现象:x509: certificate signed by unknown authority
原因:Docker未信任私有仓库证书
处理:在所有节点执行:
mkdir -p /etc/docker/certs.d/harbor.example.com
kubectl get secret harbor-tls -n harbor-system -o jsonpath='{.data.ca\.crt}' | base64 -d > /etc/docker/certs.d/harbor.example.com/ca.crt
systemctl restart docker
5.2 Jenkins Agent启动超时
优化建议:
- 调整Pod模板资源请求:
yaml复制resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
- 配置JVM参数:
bash复制# 在Jenkins系统配置添加
-Dorg.jenkinsci.plugins.durabletask.BourneShellScript.HEARTBEAT_CHECK_INTERVAL=300
- 检查Kubelet配置:
bash复制# 在worker节点执行
cat /etc/kubernetes/kubelet.conf | grep -A 5 'nodeStatusUpdateFrequency'
6. 进阶技巧与性能调优
6.1 Harbor缓存加速
在大规模集群中,可以通过以下方式优化:
- 配置P2P分发(通过distribution项目):
yaml复制# values.yaml
distribution:
enabled: true
redis:
url: redis://redis-master:6379
- 启用镜像预热(在CI阶段执行):
bash复制kubectl create job --from=cronjob/harbor-preheat preheat-$(date +%s) -n harbor-system
6.2 Jenkins流水线优化
- 并行执行测试:
groovy复制stage('Parallel Testing') {
parallel {
stage('Unit Test') {
steps { sh 'mvn test' }
}
stage('Integration Test') {
steps { sh 'mvn verify -Pintegration' }
}
}
}
- 增量式构建:
groovy复制options {
skipDefaultCheckout true
}
stages {
stage('Checkout') {
steps {
checkout(scm)
sh 'git diff --name-only HEAD^ HEAD > changed_files.txt'
}
}
stage('Selective Build') {
when {
expression {
return fileExists('changed_files.txt') &&
readFile('changed_files.txt').contains('src/main/')
}
}
steps {
sh 'mvn compile'
}
}
}
在实施这套方案时,建议先在小规模测试环境验证。我曾遇到一个典型案例:某客户因未配置Harbor存储配额,导致一夜之间500GB空间被开发测试镜像占满。后来通过设置项目配额和自动清理策略解决了问题。记住,完善的监控(如Prometheus+Granfa看板)和告警机制是生产环境不可或缺的组成部分。
