
Kubernetes和容器的出现,使得软件开发测试变得相当繁琐,程序员修改代码以后,还需要经过很多步骤,才能看到修改的结果。
于是CI/CD工具应需而生。Jenkins是使用最广泛的CI/CD工具。Jenkins利用流水线的概念,把代码推送和拉取、镜像构建、容器部署等过程串在一起,通过代码推送自动触发,程序员修改好代码后,一推送到github,容器镜像就自动打包完成部署,程序员马上就可以看到结果,大大提高了开发效率。
不过,随着Kubernetes的底层组件从docker改为containerd,Jenkins在Kubernetes上的部署和使用,也变得非常复杂,所以建议尽可能部署在裸机或者docker里面。
讲一下Jenkins的安装、部署和使用过程。Jenkins 2.440.2 ,操作系统Debian12 , Docker 26.0.0 ,Kubernetes 1.28.4。
一、安装
- 在一台单独的主机上安装docker
运行
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2. 安装Jenkins Docker镜像
运行,部署dind镜像
docker run --name jenkins-docker --rm --detach \
--privileged --network jenkins --network-alias docker \
--env DOCKER_TLS_CERTDIR=/certs \
--volume jenkins-docker-certs:/certs/client \
--volume jenkins-data:/var/jenkins_home \
--publish 2376:2376 \
docker:dind --storage-driver overlay2
创建Dockerfile文件,内容如下
FROM jenkins/jenkins:2.440.2-jdk17
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"
运行下列命令,生成Jenkins镜像
docker build -t myjenkins-blueocean:2.440.2-1 .
部署Jenkins镜像
docker run --name jenkins-blueocean --restart=on-failure --detach \
--network jenkins --env DOCKER_HOST=tcp://docker:2376 \
--env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 \
--publish 8080:8080 --publish 50000:50000 \
--volume jenkins-data:/var/jenkins_home \
--volume jenkins-docker-certs:/certs/client:ro \
myjenkins-blueocean:2.440.2-1
3. 初步配置Jenkins
运行docker logs jenkins-blueocean,可以看到初始管理员密码。
浏览器打开 http://jenkins-server-ip:8080/ , jenkins-server-ip是jenkins主机的IP地址。
输入初始管理员密码,安装建议插件,设置用户名、口令、全名和邮件地址,完成初始设置。
4. 安装插件
到dashborad->系统管理->插件管理栏目下,安装Docker pipeline、Kubernetes、Multibranch scan webhook triger 这几个插件。
5. 安装kubectl文件
在Jenkins主机上,运行
docker exec -u root -it jenkins-blueocean sh
登录到Jenkins容器内部,然后运行
cd /usr/local/bin
curl -LO "https://dl.k8s.io/v1.29.3/bin/linux/amd64/kubectl"
chmod a+x ./kubectl
exit
把kubectl下载安装到Jenkins容器内部。
二、设置
1.设置dockerhub和github账号
到dashboard->系统管理->凭据管理->全局下面,点击Add Credentials ,类型选择Username with password ,范围选择全局,输入dockerhub的账号和密码,ID输入dockerhub-credentials,描述输入dockerhub credentials,点击create,完成dockerhub账号设置。
再点击Add Credentials ,类型选择Username with password ,范围选择全局,输入github的账号和密码,ID输入github-credentials,描述输入github credentials,点击create,完成github账号设置。
2. 设置Kubernetes
到Dashboard->系统管理->Clouds,点击New Cloud,输入名字k8s,type选择Kubernetes,在Kubernetes Cloud Details下面,输入Kubernetes地址,服务证书Key和凭据后,点击save保存。其中:
登录到Kubernetes集群的master主机上,运行
cat /etc/kubernetes/admin.conf
可以看到Kubernetes地址。
运行
cat /etc/kubernetes/admin.conf | grep certificate-authority-data
把上面运行的结果用base64解码
echo "LS0tLS1C....省略....CBDRVJUSUZJQ0FURS0tLS0tCg==" | base64 -d
就可以得到服务证书key。
再把master主机主目录下的~/.kube/config文件拷贝出来。凭据类型选择为secret file ,把config文件上传,设置为凭据。
3. 设置github对接
登录到github账号中,点击右上角的用户图标,点击setting,点击左下角的Developer setting->Personal access tokens->Tokens(classic),点击Generate new token(classic),Note 输入 Jenkins Intergration for CI/CD, Expiration选择No Expiration,Select scopes 选择repo 和admin:org_hook,点击底下的Generate token,生成令牌,把令牌复制到粘贴板。
进入Jenkins的管理页面,到Dashborad->系统管理->凭据管理->全局,点击 Add Credentials,类型选择Secret text,Secret中把令牌粘贴进去,ID输入Github_person_access_token,描述输入Github person access token,点击Create。
到Dashborad->系统管理->系统配置->github,点击添加github服务器->github server,名称输入github_server, 凭据选择github access token,点击连接测试,测试通过后,点击保存。
三、测试和使用
1. 部署测试案例
在github上新建一个公用Repository,名为Jenkins-kubernetes-deployment。
在Jenkins主机上运行下列命令,安装nodejs
curl -fsSL https://deb.nodesource.com/setup_21.x | sudo -E bash -
sudo apt-get install -y nodejs
运行下列命令,新建一个react.js应用。
npx create-react-app jenkins-kubernetes-deployment
运行
cd jenkins-kubernetes-deployment
进入jenkins-kubernetes-deployment目录
创建Dockerfile文件,内容如下
#It will use node:21-alpine3.19 as the parent image for
#building the Docker image
FROM node:21-alpine3.19
#It will create a working directory for Docker. The Docker
#image will be created in this working directory.
WORKDIR /react-app
#Copy the React.js application dependencies from the
#package.json to the react-app working directory.
COPY package.json .
COPY package-lock.json .
#install all the React.js application dependencies
RUN npm i
COPY . .
#Expose the React.js application container on port 3000
EXPOSE 3000
#The command to start the React.js application container
CMD ["npm", "start"]
创建deployment.yaml文件,内容如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment #The name of the Kubernetes
#Deployment to be created in the Kubernetes cluster
labels:
app: react-app
spec:
replicas: 2 #The number of pods to be created in the
#Kubernetes cluster for the React.js application container
selector:
matchLabels:
app: react-app
template:
metadata:
labels:
app: react-app
spec:
containers:
- name: react-app #The name of the react.js application container
#The Docker image for building the React.js application container
image: dockerhub-username/react-app:latest
ports:
- containerPort: 3000 #The port for the React.js application container
创建service.yaml文件,内容如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment #The name of the Kubernetes
#Deployment to be created in the Kubernetes cluster
labels:
app: react-app
spec:
replicas: 2 #The number of pods to be created in the
#Kubernetes cluster for the React.js application container
selector:
matchLabels:
app: react-app
template:
metadata:
labels:
app: react-app
spec:
containers:
- name: react-app #The name of the react.js application container
#The Docker image for building the React.js application container
image: dockerhub-username/react-app:latest
ports:
- containerPort: 3000 #The port for the React.js application container
创建Jenkinsfile,内容如下
pipeline {
environment {
dockerimagename = "dockerhub-username/react-app"
dockerImage = ""
}
agent any
stages {
stage('Checkout Source') {
steps {
git branch: 'main',
credentialsId: 'github-credentials',
url: 'https://github.com/GITHUB-USERNAME/jenkins-kubernetes-deployment.git'
}
}
stage('Build image') {
steps{
script {
dockerImage = docker.build dockerimagename
}
}
}
stage('Pushing Image') {
environment {
registryCredential = 'dockerhub-credentials'
}
steps{
script {
docker.withRegistry( 'https://registry.hub.docker.com', registryCredential ) {
dockerImage.push("latest")
}
}
}
}
stage('Deploying React.js container to Kubernetes') {
steps {
withKubeConfig([credentialsId: 'dcf2c18c-a6b0-474c-b6be-683002feeda5', serverUrl: 'https://192.168.234.30:6443']) {
sh 'kubectl apply -f deployment.yaml -f service.yaml'
sh 'kubectl rollout restart deployment/deployment'
}
}
}
}
上面几个文件里面,dockerhub-username是你在dockerhub的用户名,GITHUB-USERNAME是你在github的用户名,按照实际情况修改。
dcf2c18c-a6b0-474c-b6be-683002feeda5是kubernetes的凭证标识,可以在dashboard->系统管理->凭证管理里面找到,根据实际情况修改。
https://192.168.234.30:6443是kubernete服务器地址,可以在kubernetes master主机的config文件中找到,根据实际情况修改。
运行下列命令,把代码同步到github
echo "# Jenkins Kubernetes Deployment." >> README.md
git init
git add -A
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:GITHUB-USERNAME/jenkins-kubernetes-deployment.git
git push -u origin main
其中GITHUB-USERNAME是你在github上的账号,按照实际情况修改。
2. 建立多分支流水线
选择dashborad->新建任务->多分支流水线,任务名输入jinkins-kubernetes-deployment,点击确定。
选择配置->分支源->增加源->github,选择凭据github-credentials, 输入仓库的HTTP地址 https://github.com/GITHUB_USERNAME/jenkins-kubernetes-deployment.git,点击保存。其中GITHUB-USERNAME是你在github上的账号,按照实际情况修改。
3.测试多分支流水线
选择Dashboard->Jenkins-kubernetes-deployment->立刻扫描仓库,点击扫描仓库日志,可以看到Jenkinsfile被扫描检出,并且自动执行了。
选择Dashboard->Jenkins-kubernetes-deployment->main,点击页面左下方的构建历史号码,点击Console Output,可以看到流水线的执行过程。
如果发生错误,可以根据错误输出,分析错误来源,排除问题。
如果流水线执行顺利完成,登录到Kubernetes的master主机,运行
kubectl get deployment
kubectl get svc
可以看到kubernetes上新增了一个deployment ,名为deployment,也新增了一个service,名为service。
react app程序已经成功部署到了kubernete集群上面。
4. 设置自动触发功能
选择Dashboard->Jenkins-kubernetes-deployment->配置->扫描仓库触发器,选中scan by webhook,Trigger token中填入web-tkn,点击保存。
在很多情况下,Jenkins主机没有外网IP,可以通过smee进行内网转发。
访问网站smee.io,点击start a new channel,得到一个URL链接,类似于https://smee.io/hmLjcRNC2XkvfZM5
在Jenkins主机上,运行
npm install --global smee-client
新建文件/etc/systemd/system/smee.service,内容如下
[Unit]
Description=smee.io webhook delivery from GitHub
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
ExecStart=/usr/bin/smee --url https://smee.io/hmLjcRNC2XkvfZM5 --path /multibranch-webhook-trigger/invoke?token=web-tkn --port 8080
[Install]
WantedBy=multi-user.target
其中https://smee.io/hmLjcRNC2XkvfZM5是从smee网站获得的URL链接,根据实际情况修改。
运行下列命令,开启smee转发功能。
systemctl daemon-reload
systemctl start smee
systemctl enable smee
访问https://github.com/GITHUB-USERNAME/jenkins-kubernetes-deployment/settings ,选择webhooks,点击Add webhook。其中GITHUB-USERNAME是你在github上的账号,按照实际情况修改。
在Payload URL中输入从smee获得的URL链接。Content type选择application/json,触发事件选择just the push event,点击Add webhook保存。
5. 测试自动触发功能
在jenkins-kubernetes-deployment目录下,运行
echo "# test " >> README.md
git add -A
git commit -m "new commit"
git push -u origin main
修改代码后,把代码推送到github。
到Dashboard->Jenkins-kubernetes-deployment->main,点击页面左下方的构建历史号码,点击Console Output,可以看到流水线再次自动执行。
自动触发功能已经成功起效。
Jenkins安装部署完成,只要把程序代码push到github,流水线就会自动执行,完成同步代码、构建镜像、向dockerhub推送镜像、最后在kubernetes集群中部署deployment和service的整个过程。
参考:
https://www.jenkins.io/doc/book/installing/docker