k8s平台基于Jenkins构建微服务发布平台-1
(1) nfs存储
(2) harbor镜像仓库
(3) gitlab代码仓库
(4) ingress-nginx
(5) nfs-subdir-external-provisioner
1 部署Jenkins
1.1 配置说明
1 Jenkins是一款开源的CI&CD系统,用于自动化各种任务,包括构建、测试和部署。
2 Jenkins官方提供了镜像"https://hub.docker.com/r/jenkins/jenkins"。
3 在"default"命名空间下使用"Deployment"方式来部署这个镜像,"kind: Service"使用"type: NodePort"暴露端口,Web内部访问端口80,
Web外部访问端口30006,Slave内部通信端口5000,容器启动后Jenkins数据存储在"/var/jenkins_home"目录,所以需要将该目录使用PV持久化
存储。
1.2 Jenkins.yml配置文件
[root@k8s-master1 ms_jenkins]# cat jenkins.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
labels:
name: jenkins
spec:
replicas: 1
selector:
matchLabels:
name: jenkins
template:
metadata:
name: jenkins
labels:
name: jenkins
spec:
terminationGracePeriodSeconds: 10
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins
imagePullPolicy: Always
ports:
- containerPort: 8080
- containerPort: 50000
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 0.2
memory: 200Mi
env:
- name: JAVA_OPTS
value: -Xmx1g
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
securityContext:
fsGroup: 1000
runAsUser: 0
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-home
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-home
spec:
storageClassName: "managed-nfs-storage"
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
spec:
selector:
name: jenkins
type: NodePort
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
nodePort: 30006
- name: agent
port: 50000
protocol: TCP
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins
rules:
- apiGroups: [""]
resources: ["pods","events"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets","events"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
[root@k8s-master1 ms_jenkins]#
1.3 部署Jenkins
# kubectl apply -f jenkins.yml
# kubectl get pod -l name=jenkins -n default
# kubectl get svc/jenkins -n default
# kubectl get ep/jenkins -n default
#
# kubectl get pv
# kubectl get pvc -n default
1.4 Jenkins UI界面安装步骤
1 获取Jenkins初始化安装密码
# kubectl logs -f pod/jenkins-578b57ddcb-dzn7n -n default
......(省略的内容)
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
72c0bc4c4a6748aba3fa39b0797eb08c
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
......(省略的内容)
2 解锁Jenkins
3 选择插件来安装
4 不安装任何的插件
5 创建管理员
6 Jenkins URL
7 Jenkins安装完成
8 Jenkins首页
1.5 安装插件
Manage Jenkins -> System Configuration -> Manage Plugins -> Available -> 分别搜索
Chinese/Git/Git Parameter/Pipeline/kubernetes/Config File Provider/Extended Choice Parameter -> 选中后点击
Install without restart
1 Chinese # 中文字体
2 Git # 拉取代码
3 Git Parameter # Git参数化构建
4 Pipeline # 流水线
5 kubernetes # 连接Kubernetes动态创建Slave代理
6 Config File Provider # 存储配置文件
7 Extended Choice Parameter # 扩展选择框参数,支持多选
插件安装完成后必须重启Jenkins,否则安装的插件无法正常使用,重启Jenkins的方法为: http://172.16.1.81:30006/restart
提示: Jenkins的UI界面上可能会提示Jenkins版本升级和一些警告信息,忽略即可。
2 Jenkins在kubernetes中动态创建代理
2.1 Jenkins主从架构介绍
1 Jenkins Master/Slave架构
Master(Jenkins本身)提供Web页面让用户来管理项目和从节点(Slave),项目任务可以运行在Master本机或者分配到从节点运行,一个Master可以关联多个Slave,这样的好处是可以让Slave分担Master工作压力和隔离构建环境。
2 当触发Jenkins任务时,Jenkins会调用Kubernetes API创建Slave Pod,Pod启动后会连接Jenkins,接受任务并处理。
2.2 kubernetes插件配置
1 kubernetes插件介绍
Kubernetes插件用于Jenkins在Kubernetes集群中运行动态代理,插件介绍"https://github.com/jenkinsci/kubernetes-plugin"。
2 配置插件
系统管理 -> 系统配置 -> 节点管理 -> Configure Clouds -> 配置集群 -> Add a new cloud -> Kubernetes ->
Kubernetes Cloud details
(1) Jenkins连接k8s配置
(2) jenkins slave连接jenkins master配置
2.3 自定义Jenkins Slave镜像
1 编排 jenkins slave 镜像所需的配置文件
[root@k8s-master1 ms_jenkins]# mkdir -p jenkins-slave/
[root@k8s-master1 ms_jenkins]# cd jenkins-slave/
(1) Dockerfile
# cat Dockerfile
FROM centos:7
LABEL maintainer lc
RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all && \
rm -rf /var/cache/yum/* && \
mkdir -p /usr/share/jenkins
COPY agent.jar /usr/share/jenkins/agent.jar
COPY jenkins-agent /usr/bin/jenkins-agent
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-agent
COPY helm kubectl /usr/bin/
ENTRYPOINT ["jenkins-agent"]
(2) helm
下载地址: https://get.helm.sh/helm-v3.4.2-linux-amd64.tar.gz
# chmod +x helm
(3) jenkins-agent
github开源地址: https://github.com/jenkinsci/docker-inbound-agent
下载代码库: https://github.com/jenkinsci/docker-inbound-agent/archive/refs/heads/master.zip
使用 "jenkins-agent" shell 脚本文件。
(4) kubectl
# cp -a /usr/bin/kubectl /root/ms_jenkins/jenkins-slave/
# chmod +x /root/ms_jenkins/jenkins-slave/kubectl
(5) settings.xml
下载地址: http://archive.apache.org/dist/maven/maven-3/3.5.0/binaries/apache-maven-3.5.0-bin.tar.gz
配置文档: https://developer.aliyun.com/article/512821
在 setttins.xml 文件中找到 <mirrors></mirrors> 标签对,添加如下内容:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
(6) agent.jar
# wget http://172.16.1.81:30006/jnlpJars/agent.jar
2 编排 jenkins slave 镜像所需的配置文件说明
[root@k8s-master1 jenkins-slave]# ls -l
total 81428
-rw-r--r-- 1 root root 1522173 Feb 10 10:00 agent.jar # jenkins agent 程序,接受 master 下发的任务
-rw-r--r-- 1 root root 423 Feb 10 17:02 Dockerfile # jenkins slave 镜像编排文件
-rwxr-xr-x 1 root root 41603072 Dec 9 2020 helm # helm 二进制文件,客户端工具
-rw-r--r-- 1 root root 5390 Feb 10 17:16 jenkins-agent # shell 脚本用于启动 agent.jar
-rwxr-xr-x 1 root root 40230912 Dec 9 2020 kubectl # kubectl 二进制文件,客户端工具
-rw-r--r-- 1 root root 10406 Feb 10 17:36 settings.xml # maven 配置文件
3 构建 jenkins slave 镜像并推送到镜像仓库
说明: 构建的 jenkins slave 镜像作为中间件镜像使用,因此将其放到公开项目 library 下
(1) 构建镜像
[root@k8s-master1 jenkins-slave]# docker build -t 172.16.1.61/library/jenkins-slave-jdk:1.8 .
(2) 推送到镜像仓库
[root@k8s-master1 jenkins-slave]# docker push 172.16.1.61/library/jenkins-slave-jdk:1.8
(3) 查看推送的镜像
2.4 测试Jenkins主从架构
1 新建项目 -> 项目名(jenkins-slave-test) -> 流水线 -> Pipeline script -> 生成示例[Declarative(Kubernetes)] 2 生成示例[Declarative(Kubernetes)] pipeline { agent { kubernetes { // 定义pod名称的前缀,如果不定义,pod名称的前缀为项目名 label "jenkins-agent" yaml ''' apiVersion: v1 kind: Pod spec: containers: # 这里容器名必须定义为jnlp - name: jnlp image: 172.16.1.61/library/jenkins-slave-jdk:1.8 ''' } } stages { stage('Main') { steps { sh 'hostname' } } } } 3 查看构建输出 pipeline 项目在执行的过程中会在 k8s 集群中创建 Jenkins slave pod,pipeline 项目运行结束后会自动销毁创建的 pod。 [root@k8s-master1 ~]# kubectl get pod -n default NAME READY STATUS RESTARTS AGE jenkins-578b57ddcb-6lfbw 1/1 Running 0 3h30m jenkins-agent-bddp0-q5pnh 1/1 Running 0 9s
3 Jenkins Pipeline流水线
3.1 Pipeline介绍
Jenkins Pipeline是一套运行工作流框架,将原本独立运行单个或者多个节点的任务链接起来,实现单个任务难以完成的复杂流程编排和可视化。
1 Jenkins Pipeline 是一套插件,支持在 Jenkins 中实现持续集成和持续交付。
2 Pipeline 通过特定语法对简单到复杂的传输管道进行建模。
3 Jenkins Pipeline 的定义被写入一个文本文件,称为Jenkinsfile。
3.2 Pipeline语法
pipeline 语法包括声明式和脚本式两种。
1 声明式
支持大部分Groovy,具有丰富的语法特性,易于编写和设计,pipeline {}
2 脚本式
遵循与Groovy相同的语法,node {}
3.3 Pipeline示例
1 jenkins example pipeline { agent any stages { stage('Build') { steps { echo 'build......' } } stage('Test') { steps { echo 'Test......' } } stage('Deploy') { steps { echo 'deploy......' } } } } 2 参数说明 (1) "stages" 是 Pipeline 中最主要的组成部分,Jenkins 将会按照 stages 中描述的顺序从上往下的执行。 (2) "stage" 是一个 Pipeline 可以划分为若干个 stage,每个 stage 代表一组操作,比如: Build、Test、Deploy。 (3) "steps" 步骤,steps 是最基本的操作单元,可以是打印一句话,也可以是构建一个 Docker 镜像,由各类 Jenkins 插件提供,比如命令: sh 'mvn',就相当于我们平时 shell 终端中执行 mvn 命令一样。
4 流水线自动发布微服务项目
4.1 发布需求
1 将微服务项目自动化部署到K8s平台的需求
(1) 尽量完全自动化部署,无需过多人工干预。
(2) 可以选择升级某个、某些微服务。
(3) 在部署、升级微服务时,可对微服务某些特性做配置,例如命名空间、副本数量。
2 发布过程
拉取代码 -> 代码编译 -> 构建镜像 -> 部署到 kubernetes -> 测试
4.2 实现思路
在微服务架构中,会涉及几个、几十个微服务,如果每个服务都创建一个item,会增加维护的成本,因此需要编写一个通用的Pipeline脚本,将这些
微服务部署差异化的部分使用Jenkins参数化,然后由人工交互确认发布微服务、环境配置等。但这只是解决了用户的交互层面,在K8s实际部署项目
时用YAML创建对应的资源,现在的问题是如何接收用户的交互参数,自动化生成 YAML 文件,这就会用到 Helm 完成 YAML 文件的高效复用和微服
务部署。
4.3 gitlab、harbor认证添加
1 启用 Harbor 的 Chart 仓库服务
[root@k8s_harbor ~]# cd /usr/local/harbor/
[root@k8s_harbor harbor]# ./install.sh --with-chartmuseum
# 启用后,默认创建的项目就带有 helm charts 功能了,不需要重启 harbor 服务。
2 推送微服务代码到 gitlab 的 microservice 仓库
[root@k8s-master1 ms_jenkins]# unzip simple-microservice.zip
[root@k8s-master1 ms_jenkins]# cd simple-microservice/
[root@k8s-master1 simple-microservice]# git config --global user.name "Administrator"
[root@k8s-master1 simple-microservice]# git config --global user.email "admin@example.com"
[root@k8s-master1 simple-microservice]# git init
Initialized empty Git repository in /root/ms_jenkins/simple-microservice/.git/
[root@k8s-master1 simple-microservice]# git remote add origin http://172.16.1.62:9999/dev/microservice.git
[root@k8s-master1 simple-microservice]# git add .
[root@k8s-master1 simple-microservice]# git commit -m "Initial commit"
[root@k8s-master1 simple-microservice]# git push -u origin master
Username for 'http://172.16.1.62:9999': root
Password for 'http://root@172.16.1.62:9999': # 密码: 12345678
3 将 gitlab 认证和 harbor 认证保存到 Jenkins 凭据
系统管理 -> 安全 -> 管理凭据 -> Jenkins -> 全局凭据(添加凭据) -> 类型(Username with password)
分别添加连接 gitlab 和 harbor 的用户名、密码到 Jenkins 凭据,然后获取该凭据 ID 替换到脚本中 git_auth 和
docker_registry_auth 变量的值。
图示(harbor认证): gitlab、harbor全局凭证ID:
gitlab ID: 26abeef4-acf8-4ba8-8e4e-454bc8a77513
harbor ID: a87872af-6fd5-45ed-a6b3-fb59ce0bcbf4
4 将 kubeconfig 存储在 Jenkins,用于 slave 镜像里 kubectl 连接 k8s 集群
系统管理 -> 系统配置 -> Managed files -> Add a new Config -> Custom file -> Next -> Content字段(填写内容是
kubeconfig,kubeadm 部署 k8s 默认路径在 master 节点 "/root/.kube/config",如果是二进制部署,需要自己生成),然后
复制 ID 替换脚本中 k8s_auth 变量的值。
说明: 将 kubectl、helm 工具封装到 Slave 镜像中,并通过 Config File Provider 插件存储连接 K8s 集群的 kubeconfig 认证
文件,然后挂载到 slave 容器中,这样就能使用 "kubectl apply deploy.yaml --kubeconfig=config" 命令管理 K8s 应用了,为
提高安全性,kubeconfig 文件可分配权限。
图示(k8s认证):
k8s_auth ID: 1f58f4c8-720f-4126-91c7-b4d919655737
注: 剩余内容请查看文章"基于Jenkins构建微服务发布平台-2"