Jenkins with Docker

作者: 啊冬啊冬 | 来源:发表于2018-08-28 16:07 被阅读0次

    在容器化广泛运用的时代,Docker镜像作为新的构建产物有着众多的优点。我们希望CI/CD能够直接输出Docker镜像,使我们流水线的部署更加的方便快捷。

    同时,CI/CD作为基础设施,我们也希望能够快速的部署到我们的各个环境中,因此容器化的Jenkins也成为我们的选择之一。

    Jenkins

    Jenkins是一个持续集成的工具,并且拥有大量实用的插件(Maven、Gradle、Git),可以对不同风格的软件进行持续集成的管理。

    jenkins-new

    使用Jenkins发布博客镜像

    要发布一个博客镜像需要进行以下步骤

    • 拉取源码:from github
    • 编译:hexo g
      • 需要npm环境
      • 需要hexo-cli
      • 需要依赖包:npm install
    • 打包镜像
      • 将编译出的html打包到nginx里面
    • 运行/发布镜像

    使用Jenkins编译Hexo博客

    • 安装并启动Jenkins
    $ docker run -d \
    -v /Users/Shared/jenkins_home:/var/jenkins_home \
    -p 8080:8080 -p 50000:50000 \
    --name jenkins jenkins/jenkins
    
    • 配置项目

      • Git插件:拉取指定项目
      • Nodejs插件:自动安装nodejs和npm,可以在shell直接使用
    • 触发构建

      • 手动
      • 定时启动cron
    jenkins-console

    打包镜像

    现在我们已经有了一个前端工程的构建产物-public,我们需要直接构建出Docker镜像。

    • 添加Dockerfile
      FROM nginx:stable-alpine
      COPY public /usr/share/nginx/html
      EXPOSE 80
      CMD ["nginx","-g","daemon off;"]
      
    • 执行docker build生成镜像

    Docker Outside of Docker

    Build镜像要求我们在Jenkins主机(容器)上可以使用Docker:

    • 在安装Jenkins的容器中再安装一个Docker,即Docker In Docker
      • 所执行的docker是在Jenkins容器中安装的,所以依赖的镜像等都需要重新拉取到DID中
      • 最外面的Docker只能管理Jenkins,而里面的容器只能由Jenkins容器来管理
    • 将主机上的docker工具引入到Jenkins容器中,使其编译创建兄弟容器而不是父子
      • 最外面的Docker可以统一管理所有镜像

    Docker进行通信控制的主要程序是/var/run/docker.sock,因此只要将这个sock导入到容器中即可;如果需要更多的控制,可以将/var/docker也共享到容器中。

    # 启动一个新容器,将主机的docker环境挂载进去
    $ docker run \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v $(which docker):/bin/docker 
    --name docker-manager -it ubuntu
    # 容器内启动其他容器(兄弟容器)
    root@fd83341d1e5b:/# docker run busybox echo "Hello"
    Hello
    

    安装内嵌Docker的Jenkins

    $ docker run -d \
    -v /Users/Shared/jenkins_home:/var/jenkins_home \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v $(which docker):/usr/bin/docker \
    -p 8080:8080 -p 50000:50000 \
    --name jenkins jenkins/jenkins
    

    本机创建一个工作目录/Users/Shared/jenkins_home,需要提供访问权限
    绑定jenkinsdocker的相关目录到镜像中

    jenkins-failed

    为什么会失败

    • 容器默认使用root用户执行操作
      $ docker run -it --rm ubuntu whoami
      root
      $ docker run -it --rm ubuntu whoami
      uid=0(root) gid=0(root) groups=0(root)
      
      • Dockerfile:USER 可以切换工作用户
      FROM ubuntu
      RUN whoami & id
      RUN groupadd -r jenkins && useradd -r -g jenkins jenkins
      USER jenkins
      RUN whoami & id
      CMD whoami
      
      $ docker build -t users/jenkins -f Dockerfile-jenkins .
      Sending build context to Docker daemon  2.048kB
      Step 1/6 : FROM ubuntu
       ---> 74f8760a2a8b
      Step 2/6 : RUN whoami & id
       ---> Running in 7767256e7526
      root
      uid=0(root) gid=0(root) groups=0(root)
      doRemoving intermediate container 7767256e7526
       ---> 9574d455d2b3
      Step 3/6 : RUN groupadd -r jenkins && useradd -r -g jenkins jenkins
       ---> Running in a54e12e8a424
      dRemoving intermediate container a54e12e8a424
       ---> eade256f4b1e
      Step 4/6 : USER jenkins
       ---> Running in 00e7bffa42cf
      Removing intermediate container 00e7bffa42cf
       ---> c1acfe462d20
      Step 5/6 : RUN whoami & id
       ---> Running in b7dac9067b80
      jenkins
      uid=999(jenkins) gid=999(jenkins) groups=999(jenkins)
      Removing intermediate container b7dac9067b80
       ---> d27cc6c129a8
      Step 6/6 : CMD whoami
       ---> Running in 9f4a70001504
      Removing intermediate container 9f4a70001504
       ---> 71deff170f16
      Successfully built 71deff170f16
      Successfully tagged users/jenkins:latest
      
      • --user可以指定容器用户
      $ docker run -it --rm users/jenkins
        jenkins
      $ docker run -it --rm --user root users/jenkins
        root
      

    容器内的root用户和主机用户是一致的(部分权限被限制)
    (可以开启namespace进行分隔)
    jenkins镜像使用内建的jenkins用户进行操作,而这个用户是没有操作docker的权限的

    为容器用户添加权限

    FROM jenkins/jenkins
    USER root
    # Mac上访问sock需要root(0)
    RUN useradd -G root jenkins
    # Linux上访问sock通常是docker(999)用户(通过脚本安装)
    # RUN useradd -G docker jenkins
    USER jenkins
    
    jenkins-success

    使用Vagrant搭建Linux虚拟机

    因为MacOS上的Docker是运行在一个Linux虚拟机中的,会造成用户、权限、文件的混乱,因此我们使用一台Linux虚拟机作为Docker4Jenkins的宿主机。

    • 使用vagrant初始化虚拟机
    $ vagrant init
    # 修改 Vagrantfile,配置镜像、网络
    $ vagrant up
    $ vagrant ssh
    
    • 安装Docker
    vagrant@vagrant-ubuntu-trusty-64:~$ curl -fsSL https://get.docker.com -o get-docker.sh
    vagrant@vagrant-ubuntu-trusty-64:~$ sudo sh get-docker.sh
    

    相关文章

      网友评论

        本文标题:Jenkins with Docker

        本文链接:https://www.haomeiwen.com/subject/yxkqwftx.html