Rancher + K3s + Harbor + GitLab + Jenkins CI/CD 实战部署笔记
本文完整记录一次 DevOps CI/CD 平台搭建全过程
整体规划
本实验共使用 3 台服务器
主机
IP
角色
系统
配置
node1
192.168.1.121
GitLab + Jenkins
Debian12
2C8G
node2
192.168.1.122
Harbor 私有镜像仓库
Debian12
2C8G
node3
192.168.1.123
Rancher + K3s Kubernetes
Debian12
2C8G
基础环境安装
每台主机都需要做
1 2 3 4 5 6 7 8 9 apt update apt upgrade -y apt install -y qemu-guest-agent systemctl enable qemu-guest-agent systemctl start qemu-guest-agent apt install -y curl wget vim sudo git net-tools docker.io tar
123主机
K3S安装
1 2 3 4 5 6 7 8 9 10 11 12 sudo swapoff -a sudo sed -i '/ swap / s/^/#/' /etc/fstab curl -sfL https://get.k3s.io | sh - kubectl get nodes sudo chmod 644 /etc/rancher/k3s/k3s.yaml kubectl run nginx --image=nginx kubectl get pods
Rancher安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 services: rancher: image: rancher/rancher:v2.7.9 container_name: rancher restart: unless-stopped privileged: true ports: - "8088:80" - "8443:443" volumes: - rancher-data:/var/lib/rancher volumes: rancher-data:
Rancher 配置
点击 “☰” → Cluster Management → Create Cluster
选择 “Import”(导入已有集群)
输入集群名称,比如:cicd-demo-cluster
点击 Create,Rancher 会生成一个 命令行脚本。
切换到 123 主机(已经安装 K3s 的主机)。
在终端执行 Rancher 提供的 Import 命令,一般是类似下面的:
kubectl apply -f https://<rancher-ip>/v3/import/<token>.yaml
Rancher 把自签证书加到系统信任
1 2 3 sudo cat /etc/rancher/k3s/k3s.yaml | grep certificate-authority-data echo "<base64证书>" | base64 -d > /usr/local /share/ca-certificates/k3s-ca.crtsudo update-ca-certificates
kubeconfig配置
1 2 3 4 5 cat /etc/rancher/k3s/k3s.yaml cp /etc/rancher/k3s/k3s.yaml ~/kubeconfig.yaml sz ~/kubeconfig.yaml
配置Jenkins中的Kube凭证kubeconfig凭证
122主机
Harbor
1 2 3 4 5 6 mkdir /opt/harbor cd /opt/harborwget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz tar -xzf harbor-offline-installer-v2.10.0.tgz cd harborcp harbor.yml.tmpl harbor.yml
修改harbor中的几个关键配置项
1 2 3 4 5 6 hostname: 192.168 .1 .122 http: port: 8080 harbor_admin_password: Harbor12345 data_volume: /data/harbor
运行./install.sh 自动安装
Harbor成功后配置与测试
创建镜像仓库项目
Name: cicd-demo
Access: Public
测试Harbor可用性
1 2 docker login 192.168.1.122:8080
配置其他主机daemon
1 2 3 4 5 # /etc/docker/daemon.json { "insecure-registries" : ["192.168.1.122:8080" ] } systemctl restart docker
121主机
GitLab
1 2 3 mkdir -p /opt/gitlab mkdir -p /opt/jenkins
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 services: gitlab: image: gitlab/gitlab-ce:16.2.1-ce.0 container_name: gitlab restart: unless-stopped hostname: 192.168 .1 .121 ports: - "80:80" - "443:443" - "2222:22" volumes: - gitlab-config:/etc/gitlab - gitlab-logs:/var/log/gitlab - gitlab-data:/var/opt/gitlab - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://192.168.1.121:80' gitlab_rails['gitlab_shell_ssh_port'] = 2222 volumes: gitlab-config: gitlab-logs: gitlab-data:
GitLab 创建 Access Token
User Avatar → Preferences → Access Tokens
Name: jenkins
Expiration:随意
Scopes: 勾选read_repository
将生成的Token设置到Jenkins里Jenkins凭证
Jenkins
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 services: jenkins: image: jenkins/jenkins:lts container_name: jenkins user: root privileged: true restart: unless-stopped ports: - "8080:8080" - "50000:50000" volumes: - jenkins-data:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro volumes: jenkins-data:
Jenkins插件安装
搜不到说明是自带的,不需要额外安装
Docker Pipeline
GitLab Plugin
Pipeline
Credentials Binding
Kubernetes CLI Plugin
Jenkins添加凭证
Manage Jenkins → Credentials → System → Global credentials → Add Credentials
Harbor凭证
Type: Username with password
Username: admin
Password: Harbor12345
Id: harbor-admin
Jenkins凭证
Type: Username with password
Username: root
Password: Gitlab生成的Access Token
Id: gitlab-token
kubeconfig凭证
Type: Secret file
Select File: kubeconfig.yamlkubeconfig配置
访问测试
查看Jenkins默认密码(默认用户 admin) docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
查看Gitlab默认密码(默认用户root) docker exec gitlab cat /etc/gitlab/initial_root_password
Jenkins 访问地址 http://192.168.1.121:8080
Gitlab 准备测试仓库
创建仓库cicd-demo
1 2 3 4 5 cicd-demo ├ Dockerfile ├ index.html └ k8s └ deployment.yaml
1 2 3 FROM nginx:alpineCOPY index.html /usr/share/nginx/html/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: cicd-demo namespace: default labels: app: cicd-demo spec: replicas: 2 selector: matchLabels: app: cicd-demo template: metadata: labels: app: cicd-demo spec: imagePullSecrets: - name: harbor-secret containers: - name: cicd-demo-container image: 192.168 .1 .122 :8080/cicd-demo/app:latest imagePullPolicy: Always ports: - containerPort: 80 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "512Mi" livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 2 failureThreshold: 3 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 2 failureThreshold: 3 --- apiVersion: v1 kind: Service metadata: name: cicd-demo-service namespace: default spec: type: NodePort selector: app: cicd-demo ports: - name: http port: 80 targetPort: 80 nodePort: 30080
1 <h1 > DevOps CI/CD Demo</h1 >
Jenkins中添加Pipeline
Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 pipeline { agent any environment { REGISTRY = "192.168.1.122:8080" PROJECT = "cicd-demo" IMAGE = "app" TAG = "${BUILD_NUMBER}" // 使用 Jenkins Build Number 作为镜像 TAG } stages { stage('Checkout') { steps { git branch: 'main', credentialsId: 'gitlab-token', url: 'http://192.168.1.121/root/cicd-demo.git' } } stage('Build Image') { steps { sh ''' echo "Building Docker image: $REGISTRY/$PROJECT/$IMAGE:$TAG" docker build -t $REGISTRY/$PROJECT/$IMAGE:$TAG . ''' } } stage('Push Image') { steps { withCredentials([usernamePassword( credentialsId: 'harbor-admin', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD' )]) { sh ''' echo "Logging into Harbor" docker login $REGISTRY -u $USERNAME -p $PASSWORD echo "Pushing Docker image: $REGISTRY/$PROJECT/$IMAGE:$TAG" docker push $REGISTRY/$PROJECT/$IMAGE:$TAG ''' } } } stage('Deploy to K3s') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh ''' echo "Updating Deployment with new image tag: $TAG" kubectl set image deployment/cicd-demo cicd-demo-container=$REGISTRY/$PROJECT/$IMAGE:$TAG --record ''' } } } } }