Docker之自定义jenkins镜像,支持multijob project插件,完美支持微服务项目的CI

背景

  • 随着互联网时代的到来,单体架构的抗压能力已经力不从心了,各项目已经向分布式方向发展。可是这会带来一个问题: 部署很麻烦。若集群数量非常大,手动部署的话会疯的。于是各种CI流行了起来,比如GitlabRunner, jenkins等等。虽说搭建这两个东西都非常简单,但作为一台CI服务器的话,我们还需要安装项目的各种环境,比如部署的是java maven项目的话,还需要安装maven、jdk环境等等。于是,本人为了工作的方便,基于centos镜像构建了一个jenkins镜像,此镜像内嵌java、maven、git、docker环境,并安装了jenkins的许多插件,如github、multijob project等等,并且内嵌了light-blue的样式,总而言之,它能基本满足分布式系统的CI。

一、产品实例(内嵌multijob project案例)

在这里插入图片描述
在这里插入图片描述

二、产品实例(无任何案例)

在这里插入图片描述

三、安装的插件

在这里插入图片描述

四、该jenkins镜像具有什么特性

  • 包含multijob、Extended Choice Parameter插件
  • 拥有微服务流程构建case实例,参考如下实例,达到举一反三的目的
       微服务流程构建case:
       在微服务架构中,我们的模块都是以服务的方式存在的,所以可能会存在互相依赖的情况,
       并且所有服务都依赖的模块叫做common模块。假设我们现在要单独部署“用户服务”, 因为
       在部署“用户服务”时, 肯定会执行“mvn clean package”命令,而此命令在添加需要依赖的jar
       包时是会从本地仓库去找的,所以我们要先把common模块install至本地仓库。这样,
       “用户服务”打包时才能依赖上最新的common模块
    
  • 内部安装了git, jdk, maven ssh等软件,支持日常工作部署需要。若jenkins需要将项目虚拟化(docker), 后续可以为镜像中安装docker环境。

五、如何运行jenkins镜像

  1. clone项目至本地
    git clone https://github.com/AvengerEug/jenkins-java-backend -b jobs
    
  2. 将工作目录下的jobs.tar.gz解压到/root下(此时root目录下会多出一个jobs的文件夹)
    cd jenkins-java-backend
    tar -zxvf jobs.tar.gz -c /root
    
  3. 拉取jenkins镜像
    docker pull registry.cn-hangzhou.aliyuncs.com/avengereug/jenkins:v2
    
  4. 启动镜像 (若需要将本地的maven仓库挂载可以添加参数: -v 宿主机maven仓库repository目录:/root/.m2/repository), 启动镜像是以host的网络模式启动的,若不需要可将--network host删除
    docker run --name jenkins -it -d -v /root/jobs:/root/.jenkins/jobs --network host registry.cn-hangzhou.aliyuncs.com/avengereug/jenkins:v2
    
  5. 浏览器访问jenkins
      http://ip:8050 
    
  6. 使用root/root用户名和密码登录
  7. 点击start-dynamic-proxy-adapter
  8. 点击左侧build with parameters, 分支名改成: jenkins-for-dynamic-proxy
  9. 点击构建
  • 注意事项:

  • 当再次重新走CI流程时,名为local-dynamic-proxy-adapter的job会报错,原因是端口被占用。此时可以在此job的配置的shell脚本的第一行添加如下脚本再重新run即可:

    	ps -ef | grep dynamic-proxy-adapter | grep -v grep | awk '{print $2}' | xargs kill -9
    
  • 若jenkins需要在本机上部署项目,则启动容器时需要指定network类型为host,这样的话,容器中暴露出来的端口和宿主机的端口一致了,容器不需要再额外暴露了, 若不想使用此网络模式,run命令时可忽略--network host参数

  • CI执行的过程中,maven会下载依赖,过程可能会久一点,有条件的朋友可以将本地maven仓库的路径挂载至容器

六、如何查看jenkins的工作目录

  • 有两种方式:
  • 进入容器内部, 工作路径位于: /root/.jenkins/
  • 构建镜像时的VOLUME指令绑定了镜像内部的/root/.jenkins/路径,那究竟是宿主机的哪个目录与之挂在的呢?使用docker inspect + 容器id或容器名称命令来确认, eg: docker inspect jenkins 执行此命令后,会输出结构如下的信息:
    [
        {
            "Id": "5d955a41b56325b04e04657a16c12743abc5505a76e6fe85dbc399e5b796753e",
            "Created": "2020-03-23T14:14:41.293507324Z",
            "Path": "java",
            "Args": [
                "-jar",
                "jenkins.war",
                "--httpPort=8050"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 2430,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2020-03-23T14:14:46.480503585Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
            "Image": "sha256:fce6824dd89f87eedc5e43e356e1b78a6143d54290c65c8c587c58507ac6b5a1",
            "ResolvConfPath": "/var/lib/docker/containers/5d955a41b56325b04e04657a16c12743abc5505a76e6fe85dbc399e5b796753e/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/5d955a41b56325b04e04657a16c12743abc5505a76e6fe85dbc399e5b796753e/hostname",
            "HostsPath": "/var/lib/docker/containers/5d955a41b56325b04e04657a16c12743abc5505a76e6fe85dbc399e5b796753e/hosts",
            "LogPath": "/var/lib/docker/containers/5d955a41b56325b04e04657a16c12743abc5505a76e6fe85dbc399e5b796753e/5d955a41b56325b04e04657a16c12743abc5505a76e6fe85dbc399e5b796753e-json.log",
            "Name": "/jenkins",
            "RestartCount": 0,
            "Driver": "overlay2",
            "Platform": "linux",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "docker-default",
            "ExecIDs": null,
            "HostConfig": {
                "Binds": [
                    "/home/eug/workspace/jenkins-java-backend/jobs:/root/.jenkins/jobs"
                ],
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "json-file",
                    "Config": {}
                },
                "NetworkMode": "host",
                "PortBindings": {
                    "8050/tcp": [
                        {
                            "HostIp": "",
                            "HostPort": "8050"
                        }
                    ]
                },
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": false,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "Capabilities": null,
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "private",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": [],
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DeviceCgroupRules": null,
                "DeviceRequests": null,
                "KernelMemory": 0,
                "KernelMemoryTCP": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": null,
                "OomKillDisable": false,
                "PidsLimit": null,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0,
                "MaskedPaths": [
                    "/proc/asound",
                    "/proc/acpi",
                    "/proc/kcore",
                    "/proc/keys",
                    "/proc/latency_stats",
                    "/proc/timer_list",
                    "/proc/timer_stats",
                    "/proc/sched_debug",
                    "/proc/scsi",
                    "/sys/firmware"
                ],
                "ReadonlyPaths": [
                    "/proc/bus",
                    "/proc/fs",
                    "/proc/irq",
                    "/proc/sys",
                    "/proc/sysrq-trigger"
                ]
            },
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/ee1a97c8f344a32c01871c0eaec54d6d556141997776ffacef8758d19cf79a83-init/diff:/var/lib/docker/overlay2/b18b12027ec179983112befb6854c14be4940706591d58ecbbba12459da48c7d/diff:/var/lib/docker/overlay2/517a2ba8b65492a8924d0c918c312652cc9d51cb3305a3a0a96fcbf3b292c7c8/diff:/var/lib/docker/overlay2/187926888df517955161b17d3d8186f8819b98de05d9ca28b97732844c265b33/diff:/var/lib/docker/overlay2/634feff375df5b2c04cad0ae627c301d683e42451145b1d922527116f2bd298b/diff:/var/lib/docker/overlay2/06b35c7aac0be64296c3055059f664061963dfff8b3b6e23327909a1b644b797/diff:/var/lib/docker/overlay2/34221b4a597dfe5117cc042a638c13a3bf15a7ca3efead221522260208ac4ebc/diff:/var/lib/docker/overlay2/b9e017f2836b4e6f738d84351a24ffb24093a9d7d8b78a434919ff3e0e141287/diff:/var/lib/docker/overlay2/e8537efad3b1af2ebfe83ecf0c255152a8a2ff82e9bd54b76b478e215ffe28e5/diff:/var/lib/docker/overlay2/3bacca5cc70365acc8d2e6329dd6f0b873de0cb946a5929672d18199e57c5f4a/diff:/var/lib/docker/overlay2/66fd1ac299fb387ae0743a938452be4a6b6612bfad0a85065faf6dde0c2fb78d/diff",
                    "MergedDir": "/var/lib/docker/overlay2/ee1a97c8f344a32c01871c0eaec54d6d556141997776ffacef8758d19cf79a83/merged",
                    "UpperDir": "/var/lib/docker/overlay2/ee1a97c8f344a32c01871c0eaec54d6d556141997776ffacef8758d19cf79a83/diff",
                    "WorkDir": "/var/lib/docker/overlay2/ee1a97c8f344a32c01871c0eaec54d6d556141997776ffacef8758d19cf79a83/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/home/eug/workspace/jenkins-java-backend/jobs",
                    "Destination": "/root/.jenkins/jobs",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                },
                {
                    "Type": "volume",
                    "Name": "daf861dedd5ff437d1db318c329cc36258598c7fbec9a62111b1dd0be4252227",
                    "Source": "/var/lib/docker/volumes/daf861dedd5ff437d1db318c329cc36258598c7fbec9a62111b1dd0be4252227/_data",
                    "Destination": "/root/.jenkins",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
            "Config": {
                "Hostname": "ubuntu",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "8050/tcp": {}
                },
                "Tty": true,
                "OpenStdin": true,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk/bin:/usr/local/maven/bin",
                    "JAVA_HOME=/usr/local/jdk",
                    "MAVEN_HOME=/usr/local/maven"
                ],
                "Cmd": null,
                "Image": "registry.cn-hangzhou.aliyuncs.com/avengereug/jenkins:v2",
                "Volumes": {
                    "/root/.jenkins": {}
                },
                "WorkingDir": "/root",
                "Entrypoint": [
                    "java",
                    "-jar",
                    "jenkins.war",
                    "--httpPort=8050"
                ],
                "OnBuild": null,
                "Labels": {
                    "MAINTAINER": "avengerEug",
                    "org.label-schema.build-date": "20200114",
                    "org.label-schema.license": "GPLv2",
                    "org.label-schema.name": "CentOS Base Image",
                    "org.label-schema.schema-version": "1.0",
                    "org.label-schema.vendor": "CentOS",
                    "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00",
                    "org.opencontainers.image.licenses": "GPL-2.0-only",
                    "org.opencontainers.image.title": "CentOS Base Image",
                    "org.opencontainers.image.vendor": "CentOS"
                }
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "1c419efa93aead7739f5ff9a062c12572109badcb41cce3eb9e1187ac4075c49",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {},
                "SandboxKey": "/var/run/docker/netns/default",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "",
                "Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "",
                "IPPrefixLen": 0,
                "IPv6Gateway": "",
                "MacAddress": "",
                "Networks": {
                    "host": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "648c0afff000e653fad1a5eac5d32dffdd6e6f1808a6db0eed2c999a3978e2c2",
                        "EndpointID": "71e5f186ea3a6f7eb5ecf6e4c394fdeb48b97db5bcfb628e39a15cf474606ea4",
                        "Gateway": "",
                        "IPAddress": "",
                        "IPPrefixLen": 0,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    
    我们找到Mounts节点,如下
    "Mounts": [
            {
                "Type": "volume",
                "Name": "daf861dedd5ff437d1db318c329cc36258598c7fbec9a62111b1dd0be4252227",
                "Source": "/var/lib/docker/volumes/daf861dedd5ff437d1db318c329cc36258598c7fbec9a62111b1dd0be4252227/_data",
                "Destination": "/root/.jenkins",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
    ......
    
    由如上可知,宿主机的"/var/lib/docker/volumes/daf861dedd5ff437d1db318c329cc36258598c7fbec9a62111b1dd0be4252227/_data"目录与容器的/root/.jenkins目录相互挂载,而/root/.jenkins就是jenkins的工作目录

七、构建镜像目录及路径

  • Dockerfile
    FROM centos
    LABEL MAINTAINER=avengerEug
    ADD apache-maven-3.3.9-bin.tar.gz /usr/local/
    RUN mv /usr/local/apache-maven-3.3.9 /usr/local/maven
    
    ADD jdk-8u221-linux-x64.tar.gz  /usr/local/
    RUN mv /usr/local/jdk1.8.0_221 /usr/local/jdk
    
    ENV JAVA_HOME=/usr/local/jdk
    ENV MAVEN_HOME=/usr/local/maven
    ENV PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
    
    COPY .jenkins /root/.jenkins/
    COPY ./jenkins/jenkins.war /root/
    
    RUN yum install -y git
    
    VOLUME "/root/.jenkins"
    
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo 'Asia/Shanghai' >/etc/timezone
    
    EXPOSE 8050
    
    WORKDIR /root
    
    ENTRYPOINT ["java", "-jar", "jenkins.war", "--httpPort=8050"]
    
  • 构建镜像目录
    在这里插入图片描述
  • 构建镜像命令
    docker build -t jenkins:v2 .
    

八、项目路径

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值