既然都已经搭建后了 K8s 集群了,那 Worker 不跑在集群里面就不太合理了。
还好,官方已经给我们提供了 Kubernetes 插件,我们直接安装就可以了!
选择你的鉴权方式
如果你的 Jenkins 自身就跑在 Worker 所在的 K8s 集群上,那么你可以直接使用 ServiceAccount 做鉴权。
如果不是的话,你可能就需要手动生成证书,使用用户账号访问了。证书的生成方法在我之前的文章中有提到。
插件的配置
安装完毕后,点击 Clouds – New Cloud,选择 Kubernetes 一步一步添加就可以了。
主要配置的要点如下:
– Kubernetes 地址:填写你的集群管理平面的地址。你可以从你的 kubectl 配置文件里面找到这个地址。
– Kubernetes 服务证书 key:这个指的是服务器的 TLS 证书(对于 K3s,是 server-ca.crt);
– Kubernetes 命名空间:要运行 pod 的所在的命名空间;
– 凭据:这里选择你的用户账号的证书,需要提前在凭据管理里面添加 X.509 证书。
剩下的都是 Jenkins Worker 相关的配置了,如果你之前配置过 Worker 的话,应该对这些配置很熟悉了。
我在这里指定了:
– 使用 Websocket 连接;
– Jenkins 地址为外部可访问的地址;
Jenkins 这边配置完毕后,你还需要为对应的用户账号/ServiceAccount添加RABC。官方仓库提供了模板,直接改一改就可以使用了。
配置并成功连上集群后,就可以配置运行实际任务的 pod 模板了。pod 模板里面可以声明多个 container,每个 container 就是一个运行环境。添加 container 的时候只需要设置名字和对应镜像就可以,其他可以保持默认。
不过,部分镜像默认会使用 root 用户运行。此时你需要在高级设置里面强行设置运行的用户的 UID 和PID,否则容易出现权限问题。
如果你在跑脚本的时候出现process apparently never started in ...
,那大概率就是权限问题,修改下 container 的权限试试 。
每个 pod 模板实际就是一个 Worker,你可以为这些 pod 指定标签,这样就能使用标签匹配到对应的模板了。
可以使用下面的 Groovy 脚本来测试你的环境是否正常:
#!groovy
pipeline {
agent {
label 'k8s' # 选择带有 k8s 标签的 pod
}
stages {
stage('Test') {
steps {
container('alpine') { # 指定使用名为 alpine 的 container
script {
sh '''
echo "hello world"
'''
}
}
}
}
}
}
参考资料:
- https://www.jenkins.io/blog/2018/09/14/kubernetes-and-secret-agents/
- https://plugins.jenkins.io/kubernetes/
buildah 构建
之前我们构建镜像的方式,是使用 docker build 命令实现的。之前也说过,在 docker 镜像中运行 docker,不可避免的会使用到 dind 的技术。
现在我们既然已经把 worker 放到 k8s 集群内了,而 k8s 的底层又是 containerd,那么我们是不是可以放弃掉 docker 来构建镜像呢?答案是肯定的。
Buildah 是一个构建 OCI 容器镜像的工具。它不需要 root 权限,也没有守护进程,特别适合单纯构建镜像使用。
Buildah 构建镜像的用法与 docker 基本一致,只需要把 docker 命令换成 buildah 命令即可:
docker build -f Dockerfile -t image:tag . # 构建镜像
docker tag image:tag registry/image:tag # 打别名,用于标识推送到哪里去
docker image push registry/image:tag # 推送镜像
buildah build -f Dockerfile -t image:tag . # 构建镜像
buildah push image:tag docker://registry/image:tag # 将本地的镜像推送到 docker 镜像仓库中
在使用 Buildah 的时候需要注意,它并不默认使用 docker.io 的镜像。也就是说,对于 jenkins/jenkins
这种镜像,它其实并不会自动认为是 docker.io/jenkins/jenkins
镜像。虽然大部分发行版可能都设置了 unqualified-search 指向了 docker.io
,但还是建议手动指定一下到底是从哪个仓库拉取。
由于 docker.io 还有另一种不带命名空间的短名称,这种实际上是指向了 library
命名空间。这种 buildah(podman)是没办法使用上面说的 unqualified search 获取到的,所以需要手动建立别名(参见 man(podman pull))放置到 /etc/containers/registries.conf.d
目录下:
unqualified-serach-registries=["docker.io"] # 短名称
[aliases]
"alpine"="docker.io/library/alpine"
最后还有个问题,如果你的机器忘了开 fuse,那你可能要参考这里在上面的命令后面添加 --driver vfs
,手动指定使用 vfs 作为驱动。
持续部署
既然已经可以持续集成了,那为什么不顺便把持续部署也给做上呢?
将应用部署在 k8s 集群上其实非常简单,只需要调用 kubectl 命令更新对应的资源就可以了。
那么问题就在于,我们要怎么运行 kubectl,以及如何给 kubectl 鉴权了。
第一个问题其实很简单,只要在上面说的 pod template 中新增一个 kubectl 的容器就可以了;第二个问题也很简单,Pod template 中只要指定了 Service Account,kubectl 就会自动使用这一个凭据去调用对应的接口了。
(同样的,Service Account 也要记得使用 RBAC 授权对应的操作才可以)
使用下面的 script 就可以测试是否能够正常调用 kubectl 了:
stage('kubectl') {
steps {
container('kubectl') {
script {
sh '''
kubectl -n prod get pods
'''
}
}
}
}
0 条评论