这两天都在集中应付流水线的打通,所以没有更新
现在终于把我们项目的流水线搭的7788了,补上最近的运维笔记
上一期我们已经完成了gitlab触发jenkins的部署,然后我们来构建jenkins流水线
在新建任务里,选择流水线类型,然后就是部署脚本的编写
我说下我们现在流水线干的事情:
1. docker打包
2. 推送新的镜像包到harbor
3. 执行kubectl rollout restart 完成k8s集群服务的重启
然后我们就可以在流水线一栏里完成脚本的编写
当然你也可以把jenkinsfile放在git根目录下,然后通过scm类型来执行
这是我的pipeline脚本
pipeline {
agent any
environment {
DOCKER_REGISTRY = "harbor.address.com"
DOCKER_REPOSITORY = "projects/testProjects"
}
stages {
stage('Checkout') {
steps {
// 使用 Jenkins 凭据拉取代码
script {
checkout([
$class: 'GitSCM',
branches: [[name: "*/dev"]],
doGenerateSubmoduleConfigurations: false,
extensions: [],
userRemoteConfigs: [[
url: 'http://10.3.2.12/mygroup/myProject.git',
credentialsId: 'gitlab-user-jenkins' // 凭据 ID
]]
])
}
}
}
stage('Build Docker Image') {
steps {
script {
def imageTag = "v${env.BUILD_NUMBER}"
env.IMAGE_NAME = "${DOCKER_REGISTRY}/${DOCKER_REPOSITORY}:${imageTag}"
sh "DOCKER_BUILDKIT=0 docker build -t ${env.IMAGE_NAME} ."
}
}
}
stage('Docker Login and Push') {
steps {
script {
withCredentials([usernamePassword(
credentialsId: 'harbor-credentials',
usernameVariable: 'DOCKER_USERNAME',
passwordVariable: 'DOCKER_PASSWORD'
)]) {
sh "docker login ${DOCKER_REGISTRY} -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}"
sh "docker push ${env.IMAGE_NAME}"
}
}
}
}
stage('Restart Kubernetes Deployment') {
steps {
sh """
docker run --rm --user root \
-v ~/.kube:/root/.kube \
-e KUBECONFIG=/root/.kube/config \
bitnami/kubectl:latest rollout restart deployment/myproject -n
myproject """
}
}
}
post {
success {
echo "Pipeline executed successfully!"
}
failure {
echo "Pipeline failed. Check the logs for more details!"
}
}
}
要执行这个脚本有几个条件:
1.安装pipeline插件,在系统管理->插件管理里面完成
2.因为我的流水线在测试环境,且我使用了统一的tag版本,所以我是直接执行了rollout restart
如果你需要每次使用不同的版本,可以执行kubectl set image来更换镜像重启
3.gitlab-user-jenkins凭据,id可以自定义,可以根据当然使用的是ssh协议还是http协议来完成凭据填写
如果是ssh协议则写上相关的public-key
如果是http协议则使用账号密码类型
4.harbor-credentials 凭据,用于访问harbor,使用账号密码类型
5. 重要要说说的是重启k8s这点,其实大部分时候,当我们写到脚本这步的时候已经完成了大部分配置,如果你的jenkins是通过systemctl部署的,就少了很多烦恼
因为直接在宿主机上安装kubectl就可以完成容器的重启了
但是如果你跟我一样,也是通过docker容器部署,又不太清楚-v映射,就会发现这时候要再使用稳定的kubectl会比较麻烦,我先后尝试了多个办法
a. 使用kubenetes cli plugin
但其实这个插件底层也是调度系统的kubectl,因此如果docker镜像并没有这个命令行,是用不了的
b.使用kubenetes plugin
这个插件更加强大,主要通过在集群中创建容器的形式执行流水线
但其实我并没有搞清楚,像我这种情况,要执行集群的kubectl rollout restart要怎么做
c.有一种一劳永逸的方式,就是在jenkins镜像的基础上,手动打包一个镜像
在目录下完成kubectl环境变量的配置,然后使用新打包的镜像启动
这种方式是一劳永逸的,但因为我已经有不少的数据了,这种方式也不适合我
d.我最后实践的方案是,在jenkins容器中执行一个docker run命令,启动一个有kubectl环境的容器
并做容器-v映射,将需要的kubeconfig路径映射到容器里
然后通过--rm 在这个一次性容器里完成集群服务的重启,这也是实践可行的方案
但是这个方案有一个点要注意,它依赖于jenkins容器的一个映射:
/var/run/docker.sock:/var/run/docker.sock
通过这个映射,让容器访问宿主机的docker守护进程完成操作,使得容器内外使用一个docker
也许你会有疑问,我在jenkins里面执行docker run -v,那挂载的是容器内的目录还是宿主机的目录呢,实测结果,最后挂载的是宿主机目录
因此我们只要把需要的config文件存放在挂载目录,就可以直接挂载到在jenkins容器内的执行docker run的这个容器中
更正确的说法应该是,这时候无论是虚拟机还是docker容器,执行的都是虚拟机上的docker环境了
到这里,我们就完成了一条兼顾打包+推送+部署的流水线了
PS: 可能有些小伙伴会发现,在这个脚本里,每次都是去gitlab拉取代码的
所以如果你没有gitlab推送代码后自动触发打包的需求,其实之前配置的webhook完全是可以删除的