这段时间一直在搞kuberntes的CI/CD。
最简单的方法是在kubernetes 的master上直接部署jenkins 然后继承各种插件打包,部署。非常简单。
但是,为了装逼用了docker嵌套技术也叫docker in docker 或是 D in D。
就是把jenkins部署在k8s里。jenkins master 构建时,启动pod运行代码克隆,项目构建,镜像构建等指令操作。构成完成以后删除pod。
另外一个坑比的事儿,我不想自己下载maven 、docker client 全部通过jenkins自动继承实现。
举例,就是比如说,我们有一个java的项目,我们打包这个项目。正常的我的机器上需要安装maven、git 要做docker image,需要安装docker client。我懒,不想部署这个东西。其实这些东西都可以在jenkins上继承,就是在构建jenkins自动从下载maven,git
只需要在jenkins 上安装插件以下几个插件就可以实现
Git plugin (这个一般初始化的自动就安装了)
Maven Integration plugin (需要额外手动安装)
Docker plugin (需要额外手动安装)
Kubernetes Continuous Deploy Plugin (这个是k8s部署插件)
Kubernetes plugin (要想在k8s 上实现d in d 必须安装这个啊,没有他实现不了)
1、jenkins 在 k8s 中的部署
#vi jenkins-pod.yaml
---
apiVersion: v1
kind: ReplicationController
metadata:
name: jenkins-rc
namespace: default
spec:
replicas: 1
selector:
name: jenkins-pod
template:
metadata:
labels:
name: jenkins-pod
spec:
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- containerPort: 8080
- containerPort: 50000
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-service
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 48080
- port: 50000
targetPort: 50000
nodePort: 50000
selector:
name: jenkins-pod
把上面内容复制贴到一个文件里。
kubectl craete -f jenkins-pod.yaml
ok 这样就部署完了。
然后在浏览器里 直接访问
http://k8s-node-ip1:48080
然后,初始化的密钥就用过下面的命令查看,复制黏贴上
kubectl exec -it jenkins-rc-xxxx "cat /var/jenkins_home/secrets/initialAdminPassword"
然后就安装上面几个插件。
2、配置jenkins slave节点在k8s
1.打开jenkins系统管理–>全局安全配置–>代理
tcp prot for jnlp agents 指定端口 50000
2.打开jenkins系统管理–>系统设置–>新增一个云–>Kubernetes
填几个
name: kuernetes
kubernetes URL: http://xxxx:6443 (这个是kube-apiserver地址, 也可以是8080,前提要开启8080。如果配的6443端口,就要配置下面的credentials认证,8080是不用授权认证的。有没有问题可以点test connection测试。反复调试)
jenkins url: http://k8s_node_ip1:48080(浏览器访问啥地址填啥)
kubernetes pod template 里的
name: jnlp-slave
labels: jnlp-slave
点 添加容器(add container)
name: jnlp-slave
docker image: jenkins:jnlp-slave (jenkins官方slave,也可以用其他的晚上好多,自己找)
点 添加卷(add volumes)
选 host path volume
host path: /var/run/docker.sock
mount path: /var/run/docker.sock (这是个坑啊,没有这个不能docker build。而且还在k8s-node 运行chmod 777 /var/run/docker.sock,每个节点都要运行下,因为jnlp-slave 是已jenkins 用户运行的,如果不改成这个权限 docker build的时候,会提示unix:///var/run/docker.socker没权限)
ok
3、jenkins继承工具配置。
maven、git、docker这些工具都不用自己在配置下载。jenkins自动继承。
在系统管理->全局工具配置
点maven 安装-> 新增maven
name: default
钩上自动安装
点上新增安装->选择 从apache安装
选择自己想要的版本
点docker安装 -> 新增docker
name: default
钩上自动安装
点上新增安装->选择 download from docker.com
4、测试
这时候在jenkins界面上创建一个maven项目,然后配置上一个git地址。
在general 选项里有一个 限制项目的运行节点 勾选上,然后在标签表示里添加上jnlp-slave,如果正确就会看到一个 label xxx is serviced by no nodes and 1 cloud.
保存以后。build
这个时候通过
kubectl get pods
就会有新的pods启动了。这个节点就是在运行自动下载git 命令,maven命令然后构建项目。构建完了,pods自动删除。
5、坑
1、刚才提到的在建pod模版的时候要挂载docker.sock。然后在把k8s-node上的docker.sock的权限改成777。 而且这个权限一旦上的docker服务重启,都需要重新赋的。因为docker服务的时候会删除docker.sock文件,启动的时候重新创建。
2、D in D 使用docker API build 镜像 找不到文件。
举例,jnlp-slave 里 docker API build docker 镜像。dockerfile 里面 有add xx /opt/xx
运行掉用docker api build 这个镜像的时候,是找不到这个文件的,因为这个文件是在jnlp-slave 里, 远程调用docker api 是在 那个主机里找文件。(好鸡绕!!!!!)
如果不用d in d 可以用这个方法 。
3、 jenkins 界面项目 里不能调用docker 自动下载 。只有用pipeline的时候在可以(也可能是我不会,求指教。)界面项目里可以掉 maven 自动下载。在build ,"调用顶层maven目标"
4、当jenkins用的深入一点发现low的很,pipeline才是王道。
def label = 'jnlp-slave'
podTemplate(label: label, cloud: 'kubernetes', privileged: 'true') {
node(label) {
//git clone
stage('git') {
git 'https://github.com/big-loser/springboot-test'
}
//自动安装maven build java
stage('maven') {
withMaven (
maven: 'default'
) {
sh "mvn clean install -DskipTests"
}
}
//自动安装 docker client,build dockerfile
stage('docker build') {
sh "mv target/springboot-helloworld-0.0.1-SNAPSHOT.jar docker/"
def dockerHome = tool 'default'
env.PATH = "/home/jenkins/tools/org.jenkinsci.plugins.docker.commons.tools.DockerTool/default/docker:${env.PATH}"
sh "docker build -t test-java:v${BUILD_NUMBER} docker/"
sh "docker tag test-java:v${BUILD_NUMBER} docker.io/xiaoqi8866/test-java:latest"
sh "docker login -u docker_hub_user -p docker_hub_passwd"
sh "docker push docker.io/xiaoqi8866/test-java:latest"
}
//调用Kubernetes Continuous Deploy Plugin 插件
stage('deploy') {
kubernetesDeploy(
kubeconfigId: 'e3677709-76c8-4164-a21b-8a0ec66d1ef8',
configs: 'k8s_deploy/*.yml'
)
}
}
}
好了,搞了好几天最恶心的是这些插件文档很少。除了错误莫名其妙。
参考资料:
https://blog.csdn.net/you227/article/details/81079167
https://blog.csdn.net/lusyoe/article/details/79684318
https://code-maze.com/ci-jenkins-docker/
https://zhangchenchen.github.io/2017/12/17/achieve-cicd-in-kubernetes-with-jenkins/