一、Jenkins安装k8s插件及其基础配置
1.1、在Jenkins中安装k8s插件
登录到Jenkins的Web管理界面,选择【管理Jenkins(Manage Jenkins)-->系统配置(System Configuration)-->插件管理(Manage Plugins)-->可用插件(Available plugins)下搜索Kubernetes-->接着勾选 Kubernetes-->点击安装(Download now and install after restart)】,安装完成后重启 Jenkins ;之后在【Installed plugins】下搜索Kubernetes显示下搜索Kubernetes plugin且已启用则表示安装完成了。如下图所示:





1.2、Jenkins对接k8s集群的凭据配置
由于Jenkins服务器在 kubernetes 集群之外,因此需要准备一些凭据内容,让Jenkins能够连接到k8s。具体操作是:
登录到Jenkins的Web管理界面,选择【管理Jenkins(Manage Jenkins)-->Security下的Credentials】即可进入到凭据管理界面,在该界面选择【Add Credentials-->Certificate】进入添加凭据界面:
| Credentials凭据界面配置k8s选项 | 说明 |
|---|---|
| 范围 | 选择【Global(Jenkins,nodes,items,all child items,etc)】 |
| 证书 | 选择【Upload PKCS#12 certificate and key】 |
| 密码 | 是上传的cert.pfx证书对应的密码 |
| 描述 | 是对该证书的描述(如:k8s-key) |
bash
#进入k8s的master节点制作pkcs12类型的证书
#1-进入k8s的配置路径获取到配置密钥内容
cd ~/.kube/
cat config
#2-使用config中【certificate-authority-data】【client-certificate-data】【client-key-data】后面的值制作证书
cd
mkdir k8skey
cd k8skey
echo "certificate-authority-data后的值"|base64 -d >ca.crt
echo "client-certificate-data后的值"|base64 -d >client.crt
echo "client-key-data后的值"|base64 -d >client.key
#3-正式生成jenkins所需的k8s对应的pkcs12类型证书【需要记住生成该cert.pfx证书时的密码,在上传到jenkins凭据中使用】
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt








1.3、Jenkins对接k8s集群配置
登录到Jenkins的Web管理界面,选择【管理Jenkins(Manage Jenkins)-->System Configuration下的Clouds】即可进入Clouds管理界面;在该界面选择【New cloud】即可进入配置界面(在配置界面输入【Cloud name(如:k8s-ck)】【Type选择Kubernetes】后点击【Create】按钮)进入到详细配置界面,需要配置如下表内容:
| New cloud界面配置内容 | 说明 |
|---|---|
| Kubernetes 地址 | 进入到k8s集群的master节点服务器中【/root/.kube/config】文件中server后的值。 也就是 apiserver 的地址,一般是master节点IP+6443 端口 |
| Kubernetes 服务证书 key | 在本文《1.2、Jenkins对接k8s集群的凭据配置》中在k8s集群master节点中生成的名为【ca.crt】文件内容。 |
| Kubernetes 命名空间 | 填写【default】。 |
| 凭据 | 在本文《1.2、Jenkins对接k8s集群的凭据配置》的名为k8s-key的凭据 |
| 连接类型 | 勾选【WebSocket】 |
| Jenkins 地址 | 填写我们当前使用的Jenkins地址即可(如:http://192.168.1.11:8080/) |
详细操作如下图所示:





像这样连接测试成功后,点击底部的【Save】保存一下配置。
二、k8s pod template 配置
Jenkins 的 kubernetes-plugin 在执行构建时会在 kubernetes 集群中自动创建一个 Pod,并在 Pod 内部创建一个名为 jnlp 的容器,该容器会连接 Jenkins 并运行 Agent 程序,形成一个 Jenkins 的 Master 和 Slave 架构,然后 Slave 会执行构建脚本进行构建。
但如果构建内容是要创建 Docker Image 就要实现 Docker In Docker 方案(在 Docker 里运行 Docker),如果要在k8s集群内部进行部署操作,就需要使用 kubectl 执行命令,因此,要解决 kubectl 的安装和权限分配问题。
在配置 kubernetes 连接内容的下面,还需要配置Pod Templates ,这里的模板名称和标签列表不是 Pod 的 name 和 label,这里的名称和标签列表只是 Jenkins 查找选择模板时使用的,Jenkins自动创建 Pod 的name是项目名称+随机字母的组合,所以我们填写jenkins-slave,命名空间填写对应的namespace,也可以不填写,不填写默认是default。
2.1、创建k8s pod template
Docker容器实践------搭建私有镜像仓库
https://blog.csdn.net/xiaochenxihua/article/details/160282561
Docker容器实践------私有镜像仓库(Harbor)的使用
https://blog.csdn.net/xiaochenXIHUA/article/details/160312595
Docker容器实践------使用Dockerfile构建docker镜像
https://blog.csdn.net/xiaochenXIHUA/article/details/160341844
选择Clouds下的【k8s-ck-->Pod Templates-->Add a pod template】进入pod的模板界面,需要配置的内容如下表:
| pod Templates填写内容 | 说明 |
|---|---|
| 名称 | pod模块的标识(如:jenkins-slave) 也可以不填写,则使用默认规则生成(生成以jenkins-agent-开头的名称) |
| 命名空间 | 命名空间要存在(一般不用填写,默认是default) 注意:一定不能填写不存在的命名空间 |
| 标签列表 | 十分重要(可与名称保持一致【如:jenkins-slave】) 后面在写pipelinie脚本时,node要和这个标签值保持一致 |
| 容器列表 | 可以给Pod Templates配置多个容器列表(如:要在容器中编译镜像,那么就需要一个有docker命令可用的镜像;要在容器中执行kubectl命令,那就需要创建一个有kubectl命令的镜像)。 需要【添加容器-->Container Template】: * 名称:jnlp-kubectl * Docker镜像:swr.cn-east-3.myhuaweicloud.com/coffeemilk/kubectl:1.29.1-almalinux9-mini * 总是拉取镜像:勾选 * 工作目录:/home/jenkins/agent * 运行命令:/bin/sh -c * 命令参数:cat * 分配伪终端:勾选 |
| 容器权限 | 有两种方法: 《1》直接采取hostPath 模式使用master节点的/root/.kube/config与/etc/kubernetes/pki(集群根证书目录)【需要给k8s集群的每个node节点都复制/root/.kube/config与/etc/kubernetes/pki这种方式强依赖宿主机的环境,权限泄露风险极大,且运维成本高,不推荐❌】。 《2》使用 K8s 内置 ServiceAccount 做认证,不再挂载宿主机任何 kube 配置,彻底解决权限、节点依赖、安全三大问题✅。 |



2.2、k8s pod template的容器列表创建与配置
bash
#Pod Templates下的容器列表创建镜像,并推送到镜像服务器
#1-创建对应的目录并进入
mkdir -p /data/imagetest
cd /data/imagetest/
#2-创建(AlmaLinux 9 Minimal + kubectl v1.29.1)的Dockerfile文件
cat>Dockerfile<<EOF
# 企业生产标准:AlmaLinux 9 官方最小化镜像
FROM docker.1ms.run/library/almalinux:9-minimal
# 生产标准化元数据
LABEL org.opencontainers.image.authors="运维团队-coffeemilk"
LABEL org.opencontainers.image.description="kubectl v1.29.1 生产镜像"
LABEL kubectl.version="v1.29.1"
# 安装依赖并下载 kubectl 二进制文件
RUN set -ex && \
microdnf update -y && \
microdnf install -y git && \
curl -LO "https://dl.k8s.io/release/v1.29.1/bin/linux/amd64/kubectl" && \
chmod +x kubectl && \
mv kubectl /usr/local/bin/ && \
microdnf clean all && \
rm -rf /var/cache/yum /tmp/* /var/tmp/*
# 切换为 root 用户
USER root
# 工作目录修改为 root 家目录
WORKDIR /root
CMD ["/bin/bash"]
EOF
#3-构建镜像
docker build -t kubectl:1.29.1-almalinux9-mini .
#4-查看当前的所有镜像(是否包含kubectl:1.29.1-almalinux9-mini镜像)
docker images
#4-镜像构建成功后的验证(若结果显示"Client Version: v1.29.1 Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3"类似这样的内容则表示构建成功了)
docker run --rm -it kubectl:1.29.1-almalinux9-mini kubectl version --client
#5-可将构建好的镜像上传到私有镜像仓库(可以是自己搭建的、也可以是各大厂商提供的(如:华为容器镜像服务 SWR、阿里云容器镜像服务ACR))
#这里以上传到华为容器镜像服务SWR为例
#注意:若是自动化环境需要登录镜像服务器则使用【echo "镜像服务器用户密码" | docker login -u {镜像服务器用户} --password-stdin swr.cn-east-3.myhuaweicloud.com】命令登录;【生产环境严禁使用:docker login -u 用户名 -p 密码 仓库地址 命令登录】
docker login -u {你自己的华为容器镜像服务的用户名称} swr.cn-east-3.myhuaweicloud.com
docker tag {镜像名称}:{版本名称} swr.cn-east-3.myhuaweicloud.com/{组织名称}/{镜像名称}:{版本名称}
docker push swr.cn-east-3.myhuaweicloud.com/{组织名称}/{镜像名称}:{版本名称}
#6-拉取刚才的镜像命令是
docker pull swr.cn-east-3.myhuaweicloud.com/coffeemilk/kubectl:1.29.1-almalinux9-mini







目前,这个pod中有两个容器,分别是jnlp-kubectl和jnlp。
2.3、k8s pod template的容器权限配置
生产标准最优方案(推荐)K8s ServiceAccount + RBAC(彻底抛弃 hostPath)进行授权
企业级 Jenkins + K8s 动态代理的标准做法:使用 K8s 内置 ServiceAccount 做认证,不再挂载宿主机任何 kube 配置,彻底解决权限、节点依赖、安全三大问题。
| K8s ServiceAccount + RBAC进行授权思路 |
|---|
《1》在 K8s default 命名空间创建 ServiceAccount(给 Jenkins Pod 使用); |
《2》创建 RBAC 权限规则,授权该 SA 拥有 deploy/apply 等操作权限; |
| 《3》修改 Jenkins Kubernetes Pod 模板,删除所有 hostPath 挂载,直接为 Pod 绑定上面的 SA; |
《4》Pipeline 中 kubectl 自动使用 Pod 内的 SA Token 认证,无需指定 --kubeconfig。 |
bash
#K8s ServiceAccount + RBAC进行授权操作
#1-在k8s的master节点(控制平面【control-plane】)创建授权资源文件jenkins-k8s-rbac.yaml
cat>jenkins-k8s-rbac.yaml<<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-deploy-sa
namespace: default
---
# 授权权限:管理 Deployment、Pod 等资源
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jenkins-deploy-role
rules:
- apiGroups: ["", "apps"]
resources: ["deployments", "pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
---
# 绑定 SA 和 角色(全局权限)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-deploy-binding
subjects:
- kind: ServiceAccount
name: jenkins-deploy-sa
namespace: default
roleRef:
kind: ClusterRole
name: jenkins-deploy-role
apiGroup: rbac.authorization.k8s.io
EOF
#2-创建指定资源
kubectl apply -f jenkins-k8s-rbac.yaml
# 查看 default 命名空间下所有 SA
kubectl get sa -n default
# 查看该 SA 的完整 YAML 配置(集群内真实配置)
kubectl get sa jenkins-deploy-sa -n default -o yaml
# 查看资源详细描述(事件、关联信息)
kubectl describe sa jenkins-deploy-sa -n default

**k8s集群的权限资源创建完成后,直接在k8s pod template界面的Service Account下输入jenkins-deploy-sa后保存,**如下图所示:

三、编写pipeline脚本实现部署应用到k8s集群
3.1、Jenkins pipeline 介绍
Pipeline,简单来说,就是一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。
| Jenkins Pipeline的核心概念 | 说明 |
|---|---|
| Node | 节点,一个 Node 就是一个 Jenkins 节点,Master 或者 Agent,是执行 Step 的具体运行环境。 |
| Stage | 阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作,比如:Build、Test、Deploy,Stage 是一个逻辑分组的概念,可以跨多个 Node |
| Step | 步骤,Step 是最基本的操作单元,可以是打印一句话,也可以是构建一个 Docker 镜像,由各类 Jenkins 插件提供,比如命令:sh 'make',就相当于我们平时 shell 终端中执行 make 命令一样。 |
| Pipeline的使用 | 说明 |
|---|---|
| Pipeline 支持两种语法 | Declarative(声明式)和 Scripted Pipeline(脚本式)语法 |
| Pipeline 有两种创建方法 | 可以直接在 Jenkins 的 Web UI 界面中输入脚本;也可以通过创建一个 Jenkinsfile 脚本文件放入项目源码库中 一般我们都推荐在 Jenkins 中直接从源代码控制(SCMD)中直接载入 Jenkinsfile Pipeline 这种方法;本次为了更直观的展示,我们在 Web UI 界面中输入脚本。 |
3.2、编写pipeline脚本实现部署应用到k8s集群
登录到Jenkins的Web管理界面,选择【新建Item-->输入任务名称(如:k8s-ck)-->流水线-->确定】进入流水线配置界面:
| jenkins的流水线配置内容 | 说明 |
|---|---|
| General | 通用配置填写该流水线的简介说明(可以一眼就知道这个流水线是做什么的); 勾选This project is parameterized(表示新增参数),参数类型是Choice Parameter(表示选择参数) * 名称:Method * 选项:apply ``delete |
| 流水线 | 在流水线的项目里选择Pipeline script,然后编写上需要在容器中执行的操作内容(本文演示就做了两个事情:1、从gitlab中下载了需创建资源的yml文件项目;2、进入资源yml文件项目中执行创建资源的命令)。 |




Git实践------GitLab服务器的部署与使用
https://coffeemilk.blog.csdn.net/article/details/160722357
首先需要在gitlab中创建一个名为k8symlfile的项目,将需要在k8s中部署的deployment与service的yml资源文件上传到该项目中,然后方便jenkins的流水线拉取部署操作。



bash
#httpd的deployment资源文件
cat>httpd-deployment.yml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
spec:
replicas: 3
selector:
matchLabels:
app: httpd_server
template:
metadata:
labels:
app: httpd_server
spec:
containers:
- name: httpd-web
image: library/httpd:2.4.67
ports:
- containerPort: 80
EOF
#httpd的service资源文件
cat>httpd-service.yml<<EOF
apiVersion: v1
kind: Service
metadata:
name: httpd-service
spec:
type: NodePort
selector:
app: httpd_server
ports:
- protocol: TCP
port: 80
nodePort: 30060
targetPort: 80
EOF
#nginx的deployment资源文件
cat>nginx-deployment.yml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx_server
template:
metadata:
labels:
app: nginx_server
spec:
containers:
- name: nginx-web
image: library/nginx:1.28.3
ports:
- containerPort: 80
EOF
#nginx的service资源文件
cat>nginx-service.yml<<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx_server
ports:
- protocol: TCP
port: 80
targetPort: 80
EOF
bash
#流水线脚本内容
#注:1:最开始node后面的名称一定要是我们创建clouds中k8s pod template界面中的标签列表名称!!!
#注意2:container后的名称必须是们创建clouds中k8s pod template界面中容器的名称!!!
node('jenkins-slave') {
container('jnlp-kubectl') {
stage('Clone YAML') {
echo "1. Git Clone YAML To Slave"
sh '''
rm -rf ./k8symlfile
git clone -c http.sslVerify=false https://192.168.1.39/root/k8symlfile.git
'''
}
stage('Deploy') {
echo "2. Deploy To K8s Stage"
dir('k8symlfile') {
sh "kubectl ${Method} -f httpd-deployment.yml"
sh 'kubectl get pod'
sh "kubectl ${Method} -f httpd-service.yml"
sh 'kubectl get svc'
}
}
}
}



