目录
一、jenkins配置kubernetes
1、安装kubernetes插件
2、配置Kubernetes 地址
二、配置Pod Templates
1、创建Pod Templates
2、配置jnlp-slave容器
3、制作tools-slave镜像
4、配置tools-slave容器
三、配置Jenkinsfile文件
1、配置动态slave构建
四、开始整活
一、jenkins配置kubernetes
Jenkins的slave端,没有任务的时候处于闲置状态,slave节点多的话造成资源浪费;是否可以利用kubernetes的Pod来启动slave,动态slave pod来执行构建任务,本文主要介绍利用kubernetes动态创建slave执行构建任务,执行完毕自动销毁。
1、安装kubernetes插件
[系统管理] -> [插件管理] -> [搜索kubernetes]->直接安装,报错是依赖无影响
2、配置Kubernetes 地址
[系统管理] -> [系统配置] ->Cloud -> [Add a new cloud]
- Kubernetes 地址: https://kubernetes.default(或者https://192.168.0.121:6443)
- Kubernetes 命名空间:jenkins
- 服务证书不用写(我们在安装Jenkins的时候已经指定过serviceAccount),均使用默认
- 连接测试,成功会提示:Connection test successful
- Jenkins地址:http://jenkins:8080
- Jenkins 通道 :jenkins:50000
二、配置Pod Templates
1、创建Pod Templates
Pod Templates相当于k8s集群的pod,包含两个容器分别是jnlp和tools
- 名称:jnlp-slave
- 命名空间:jenkins
- 标签列表:jnlp-slave,作为agent的label选择用
- 连接 Jenkins 的超时时间(秒) :300,设置连接jenkins超时时间
- 节点选择器:agent=true
- 工作空间卷:选择hostpath,设置/opt/jenkins_jobs/,注意需要设置chown -R 1000:1000 /opt/jenkins_jobs/权限,否则Pod没有权限
2、配置jnlp-slave容器
jenkins默认配置一个jnlp容器用于连接k8s集群创建slave构建,但是该容器并不包含常用的docker、java、kubectl等命令,我们在此基础上需要集成很多工具,能不能创建一个新的容器,让新容器来做具体的任务,我们采用权限分离的方式:
jnlp-slave容器只用来负责连接jenkins-master;针对不同的构建环境(java、python、go、nodejs),可以制作不同的容器,来执行对应的任务,针对本次k8s自动部署容器的任务,我们制作一个tools镜像来完成。
[root@k8s-node2 myblog]# docker inspect 911d6dcfc160 | grep ENTRYPOINT
"ENTRYPOINT [\"jenkins-agent\"]"
jnlp默认启动参数查看
jnlp默认镜像地址可以直接写,也可以先构建下任务看看系统默认启动的容器
3、制作tools-slave镜像
tools-slave镜像不像jnlp镜像是的系统自带,需要根据需求个性化构建,制作一个tools镜像,集成常用的工具,来完成常见的构建任务,需要注意的几点:
- 使用alpine基础镜像,自身体积比较小
- 替换国内安装源
- 为了使用docker,安装了docker
- 为了克隆代码,安装git
- 为了后续做python的测试等任务,安装python环境
- 为了在容器中调用kubectl的命令,拷贝了kubectl的二进制文件
- 为了认证kubectl,需要在容器内部生成.kube目录及config文件
# 创建个目录准备手动构建镜像
$ mkdir tools;
$ cd tools;
$ cp `which kubectl` .
$ cp ~/.kube/config .
vim Dockerfile
FROM alpine
LABEL maintainer="rui@email.com"
USER root
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
apk update && \
apk add --no-cache openrc docker git curl tar gcc g++ make \
bash shadow openjdk8 python2 python2-dev py-pip python3-dev openssl-dev libffi-dev \
libstdc++ harfbuzz nss freetype ttf-freefont && \
mkdir -p /root/.kube && \
usermod -a -G docker root
COPY config /root/.kube/
RUN rm -rf /var/cache/apk/*
#-----------------安装 kubectl--------------------#
COPY kubectl /usr/local/bin/
RUN chmod +x /usr/local/bin/kubectl
# ------------------------------------------------#
执行镜像构建并推送到仓库中,blog必须存在于harbor:
$ docker build . -t 192.168.0.121:5000/myblog/tools:v1
$ 确认harboe运行中:cd /usr/local/bin/harbor/;./install
$ docker push 192.168.0.121:5000/myblog/tools:v1
我们可以直接使用该镜像做测试:
# 启动临时镜像做测试
# 主要是确认下这个镜像是否满足我们构建需要的环境
$ docker run -v /var/run/docker.sock:/var/run/docker.sock --rm -ti 192.168.0.121:5000/myblog/tools:v1 bash
# / git clone http://xxxxxx.git
# / kubectl get no
# / python3
#/ docker
4、配置tools-slave容器
更新Jenkins中的PodTemplate,添加tools镜像,注意同时要先添加名为jnlp的container,因为我们是使用自定义的PodTemplate覆盖掉默认的模板,jnlp的container已经添加好了:
在卷栏目,添加卷,Host Path Volume,不然在容器中使用docker会提示docker服务未启动
三、配置Jenkinsfile文件
1、配置动态slave构建
之前是配置好固定jenkins_slave节点进行任务构建,现在采用动态生产k8s容器方式进行构建,构建时启动容器,构建完成销毁,需要配置两个地方
1、agent { label 'jnlp-slave'}需要配置成Pod Templates的标签
2、container('tools') {
checkout scm
}在需要slave执行的步骤指定容器名称,我们本次使用tools容器执行任务
3、slave容器push harbor无权限,可以把用户密码配到jenkins的secret,或者利用rbac 思路也不错
sh 'docker login -u admin -p Harbor12345 192.168.0.121:5000'
pipeline {
agent { label 'jnlp-slave'}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
disableConcurrentBuilds()
timeout(time: 20, unit: 'MINUTES')
gitLabConnection('gitlab')
}
environment {
IMAGE_REPO = "192.168.0.121:5000/myblog/myblog"
DINGTALK_CREDS = credentials('dingTalk')
TAB_STR = "\n \n "
}
stages {
stage(' 配置环境变量:') {
steps {
script{
sh "git log --oneline -n 1 > gitlog.file"
env.GIT_LOG = readFile("gitlog.file").trim()
}
sh 'printenv'
}
}
stage('检测GIT分支:') {
steps {
container('tools') {
checkout scm
}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS = env.STAGE_NAME + "OK!" + env.TAB_STR
}
}
}
stage('Docker构建镜像:') {
steps {
container('tools') {
retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
script{
env.BUILD_TASKS += env.STAGE_NAME + "OK!" + env.TAB_STR
}
}
}
stage('Docker推送镜像:') {
steps {
container('tools') {
sh 'docker login -u admin -p Harbor12345 192.168.0.121:5000'
retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
}
env.BUILD_TASKS += env.STAGE_NAME + "OK!" + env.TAB_STR
}
}
}
stage('K8s集群部署容器:') {
steps {
container('tools') {
sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' deploy/*"
timeout(time: 1, unit: 'MINUTES') {
sh "kubectl apply -f deploy/"
}
}
updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
}
}
}
}
post {
success {
echo 'Congratulations!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"myblog",
"text": "^v^ 构建成功 ^v^ \n**项目名称**:rui \n**Git log**: ${GIT_LOG} \n**构建分支**: ${BRANCH_NAME} \n**构建地址**:${RUN_DISPLAY_URL} \n**构建任务**:${BUILD_TASKS}"
}
}'
"""
}
failure {
echo 'Oh no!'
sh """
curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title":"myblog",
"text": "-_-# 构建失败 -_-# \n**项目名称**:rui \n**Git log**: ${GIT_LOG} \n**构建分支**: ${BRANCH_NAME} \n**构建地址**:${RUN_DISPLAY_URL} \n**构建任务**:${BUILD_TASKS}"
}
}'
"""
}
always {
echo 'I will always say Hello again!'
}
}
}
四、开始整活
通过Jenkinsfile配置kubernetes创建动态容器slave,实现demo项目自动发布kubenetes环境
git提交后,jenkins收到任务,开始构建,此时会多一个jnlp-slave-xxxx名字的pod,这个pod包括两个container,首先通过jnlp容器连接至jenkins-master,然后通过tools容器进行一系列构建操作,构建完成后pod自动销毁,jenkins把构建结果发送给钉钉。
[root@k8s-master harbor]# kubectl get po -n jenkins
NAME READY STATUS RESTARTS AGE
gitlab-84d466bb4f-8ds6f 1/1 Running 4 2d5h
jenkins-master-6b4c77dcc-6p6kt 1/1 Running 3 2d6h
jnlp-slave-jjd1b 2/2 Running 0 109s
postgres-74cc98f9d-8m8nv 1/1 Running 5 2d5h
redis-66b4464f88-758vt 1/1 Running 5 2d5h
[root@k8s-master harbor]# kubectl -n jenkins get po
NAME READY STATUS RESTARTS AGE
gitlab-84d466bb4f-8ds6f 1/1 Running 4 2d6h
jenkins-master-6b4c77dcc-6p6kt 1/1 Running 3 2d6h
postgres-74cc98f9d-8m8nv 1/1 Running 5 2d6h
redis-66b4464f88-758vt 1/1 Running 5 2d6h
您在 /var/spool/mail/root 中有新邮件