kubernetes里部署jenkins踩坑之路(Docker in Docker)

这段时间一直在搞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/

你可能感兴趣的:(kubernetes里部署jenkins踩坑之路(Docker in Docker))