Jenkins with Docker

在容器化广泛运用的时代,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
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、Docker 简介 Docker 两个主要部件:Docker: 开源的容器虚拟化平台Docker Hub: 用...
    R_X阅读 4,411评论 0 27
  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,544评论 0 120
  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,636评论 15 147
  • 曾和世界初次见面 阳光是最亮的 是金灿灿的 蓝天是最纯净的 是蔚蓝的 人是单纯的 是善良的 当我19岁爱上了一个人...
    哈利波予阅读 603评论 0 1
  • 夜深了,今天又算过去了,室友小雅的妈妈来了,小雅是一个孝顺的女孩子,在国企上班,工资虽然不高,也很忙碌,前段时间加...
    家书飞鸽阅读 533评论 0 2