一、基础环境
| ip地址 | 作用 |
|---|
| 192.168.2.101 | K8S集群 |
| 192.168.2.104 | Harbor |
| jenkins.xxx.com | Jenkins |
| gitea.xxx.com | Gitea |
二、环境准备
2.1、Jenkins安装插件
需要安装如下插件
Kubernetes
2.2、配置凭据
进入Jenkins,进入系统管理–凭据管理,进入后点击添加,添加如下两个凭据,类型都是Username with Password
id:gitea-creds 和 harbor-creds,用户名和密码分别是harbor及gitea的用户名和密码

2.3、配置云
在Jenkins的系统管理–云,点击添加,
- 名称:随意设置
- Kubernetes 地址:https://kubernetes.default.svc.cluster.local
- 禁用 HTTPS 证书检查 :勾选
- Kubernetes 命名空间:devops
- Jenkins 地址:http://jenkins.devops.svc.cluster.local:8080
- Jenkins 通道:jenkins.devops.svc.cluster.local:50000

2.4、gitea准备及代码
在gitea创建一个仓库,并克隆到本地计算机,使用vscode打开后,写入如下几个文件,文件名称及内容如下
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
| from flask import Flask
import socket
app = Flask(__name__)
@app.route('/')
def hello():
hostname = socket.gethostname()
# 核心测试点:你以后可以把 v1 改成 v2、v3,看网页会不会变!
return f"<h1>Hello K8s! This is Version: v2</h1><p>Running on Pod: {hostname}</p>"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8080)
|
requirements.txt
1
2
| flask==3.0.0
werkzeug==3.0.0
|
Dockerfile
1
2
3
4
5
6
7
| FROM 192.168.2.104/library/python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY app.py .
EXPOSE 8080
CMD ["python", "app.py"]
|
k8s-deploy.yaml
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
| apiVersion: apps/v1
kind: Deployment
metadata:
name: my-python-app
namespace: devops
spec:
replicas: 2 # 给你搞两个 Pod 跑,感受一下负载均衡
selector:
matchLabels:
app: my-python-app
template:
metadata:
labels:
app: my-python-app
spec:
containers:
- name: web
# 你的 Harbor 地址
image: 192.168.2.104/library/my-python-app:IMAGE_TAG_PLACEHOLDER
imagePullPolicy: Always
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-python-app-svc
namespace: devops
spec:
selector:
app: my-python-app
ports:
- port: 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-python-app-ingress
namespace: devops
spec:
ingressClassName: nginx
rules:
- host: myapp.xxx.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-python-app-svc
port:
number: 8080
|
将上述几个文件提交并推送到gitea即可

2.5、镜像准备
在192.168.2.104上执行如下命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 1. 同步隐藏的 JNLP 通信代理镜像
docker pull jenkins/inbound-agent:latest
docker tag jenkins/inbound-agent:latest 192.168.2.104/library/inbound-agent:latest
docker push 192.168.2.104/library/inbound-agent:latest
# 2. 同步 Kaniko 打包引擎镜像 (如果 gcr.io 拉不动,可以用 dockerhub 的镜像源)
docker pull gcr.io/kaniko-project/executor:debug # 或者 pull bitnami/kaniko:latest 视你的网络而定
docker tag gcr.io/kaniko-project/executor:debug 192.168.2.104/library/kaniko:debug
docker push 192.168.2.104/library/kaniko:debug
# 3. 同步 Kubectl 部署工具镜像
docker pull bitnami/kubectl:latest
docker tag bitnami/kubectl:latest 192.168.2.104/library/kubectl:latest
docker push 192.168.2.104/library/kubectl:latest
docker pull python:3.9-slim
docker tag docker.io/library/python:3.9-slim 192.168.2.104/library/python:3.9-slim
docker push 192.168.2.104/library/python:3.9-slim
|
三、配置部署任务
进入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
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
| pipeline {
// 1. 定义动态构建节点 (K8s Pod)
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
serviceAccountName: jenkins-admin
containers:
# 强行覆盖默认的隐藏通信容器,让它走本地 Harbor!
- name: jnlp
image: 192.168.2.104/library/inbound-agent:latest
# Kaniko (负责在 Containerd 环境下无 Docker 引擎打镜像)
- name: kaniko
image: 192.168.2.104/library/kaniko:debug
command: ['sleep']
args: ['99d']
tty: true
securityContext:
runAsUser: 0
# Kubectl (负责把镜像更新到 K8s)
- name: kubectl
image: 192.168.2.104/library/kubectl:latest
command: ['sleep']
args: ['99d']
tty: true
securityContext:
runAsUser: 0
"""
}
}
// 2. 定义全局环境变量
environment {
HARBOR_REGISTRY = "192.168.2.104"
IMAGE_NAME = "library/my-python-app"
// 使用 Jenkins 自带的构建次数作为版本号,如 v1, v2, v3
IMAGE_TAG = "v${BUILD_NUMBER}"
}
stages {
// 第 1 阶段:拉取代码
stage('Checkout Code') {
steps {
checkout scmGit(
branches: [[name: '*/main']],
userRemoteConfigs: [[
// 【核心修改】:抛弃外网域名,直接写 K8s 内部的服务调用地址!
url: 'http://gitea.default.svc.cluster.local:3000/admin/Test1.git',
credentialsId: 'gitea-creds'
]]
)
}
}
// 第 2 阶段:构建并推送镜像
stage('Build & Push Image') {
steps {
container('kaniko') {
// 调取你在 Jenkins 里存的 Harbor 账号密码
withCredentials([usernamePassword(credentialsId: 'harbor-creds', passwordVariable: 'HARBOR_PWD', usernameVariable: 'HARBOR_USER')]) {
// 使用单引号 ''' 保护 Shell 脚本,让内部环境变量生效
sh '''
echo "🚀 开始配置 Harbor 认证..."
mkdir -p /kaniko/.docker
# 生成 Kaniko 专属的 auths 认证文件
echo "{\\"auths\\":{\\"${HARBOR_REGISTRY}\\":{\\"username\\":\\"${HARBOR_USER}\\",\\"password\\":\\"${HARBOR_PWD}\\"}}}" > /kaniko/.docker/config.json
echo "🚀 开始构建并推送到 Harbor..."
# --insecure 和 --skip-tls-verify 专门应对 HTTP 协议或自签证书的 Harbor
/kaniko/executor \
--context `pwd` \
--dockerfile `pwd`/Dockerfile \
--destination ${HARBOR_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \
--insecure \
--skip-tls-verify
'''
}
}
}
}
// 第 3 阶段:部署到 K8s
stage('Deploy to K8s') {
steps {
container('kubectl') {
sh '''
echo "🚀 开始更新 K8s 部署文件..."
# 将 yaml 文件里的 IMAGE_TAG_PLACEHOLDER 替换为本次真实的 IMAGE_TAG (如 v3)
sed -i "s|IMAGE_TAG_PLACEHOLDER|${IMAGE_TAG}|g" k8s-deploy.yaml
echo "🚀 正在发布到 K8s 集群..."
kubectl apply -f k8s-deploy.yaml
echo "🎉 部署完成!"
'''
}
}
}
}
}
|
点击保存即可,点击立即构建
查看日志之后,将该地址写入到DNS之后,在浏览器打开,看到网页即可
