Jenkins Docker 插件和 Jenkins Docker Slaves 之间的混淆

Jenkins Docker 插件和 Jenkins Docker Slaves 之间的混淆

因此,当我看到 Jenkins Docker 插件将 Docker 镜像“推送”到我的 Docker 主机金属时,我感到很惊喜,但这也令人困惑,因为我的构建是在 Docker 主机金属上运行的 Docker Slave 容器中进行的。甚至我的 Jenkins 主服务器也在 Docker 容器中运行,而不是直接在金属上运行……

继这一热门Jenkins 主/从指南我到达了 Jenkins 构建工作的阶段临时 Docker 容器

这意味着当我使用 Jenkins 构建我的一些源代码软件组件/服务时,构建将在 Jenkins 从属服务器中启动,而该从属服务器恰好是由 Jenkins Docker 插件启动的 Docker 容器。

Jenkins 的工作空间位于这个从属容器中,安装了 Docker Plugin 的 Jenkins 主服务器将在构建完成后处理这个从属容器。请参阅我制作的一张图来帮助解释:

在此处输入图片描述

理解此图之后,请注意以下几点:

  • 目前,Jenkins Master 和 Jenkins Slave 正在同一个 Docker Host Metal 上运行,因为我才刚刚开始运行这个系统
  • 我正在使用 Docker 插件和 SSH Slaves 插件来完成此设置

因此,在这个 Docker Slave 中,我的软件组件/服务构建工件被创建,例如,它可以是 .dll 或 .war。不过,我的构建工件恰好是 Docker 镜像。明确地说,我正在正在运行的 Docker 容器(Jenkins Slave)中构建 Docker 镜像。

我的困惑始于我期望我必须明确运行 cmd 才能将我的软件组件 Docker 镜像构建工件推送到 Docker 注册表。否则,当 Jenkins 构建作业完成时,Docker 插件将关闭 Docker 容器从属,处理 (rm) 从属容器,然后我将丢失该从属容器内的构建工件。

实际发生的情况是,以及为什么我感到惊喜,至少在我启动和运行 devops 的短期内,构建工件 Docker 镜像出现在 Docker 主机金属上docker image ls

我很惊讶 Docker 插件会达到这种假设/帮助的水平...我知道 Docker 插件允许您配置 Docker 注册表,并且您可以添加构建步骤来构建/发布到 Docker Cloud,我假设云被视为图像的注册表,或许也是运行这些图像的地方:

在此处输入图片描述

特别有趣的是,我没有使用 Docker 插件进行任何构建步骤,我只是使用 Docker 插件来配置用于构建 Jenkins 项目的从属容器:

在此处输入图片描述

我唯一的构建步骤是执行一个 Shell 脚本,是的,这个脚本最终会构建一个 Docker 镜像,但是 Docker 插件不知道这一点:

在此处输入图片描述

Docker 插件启动了 Docker 从属容器,我配置了 Docker 插件并告诉它 Docker 主机(在我的环境中是我的金属),云是 Docker 插件所称的 Docker 主机,以及在该 Docker 主机/云上使用的 Docker 从属映像:

在此处输入图片描述 我是否只是误解了 Jenkins 构建工作空间在 Docker 从属容器内部的隔离程度?

Docker 插件是否默认使用我为在 Jenkins Docker 从属容器内运行的所有 docker 命令设置的唯一 Docker Cloud(我的 Docker 主机金属)?(顺便说一下,从属容器上安装了 Docker-CE)

我的Jenkins 主服务器Dockerfile:

#reference
#https://engineering.riotgames.com/news/putting-jenkins-docker-container

FROM jenkins:2.60.1
MAINTAINER Brian Ogden

USER root

#Timezone
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Prep Jenkins Directories
RUN mkdir /var/log/jenkins
RUN mkdir /var/cache/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins
RUN chown -R jenkins:jenkins /var/cache/jenkins

# Copy in local config filesfiles
COPY plugins.sh /usr/local/bin/plugins.sh
RUN chmod +x /usr/local/bin/plugins.sh

# Install default plugins
# Set list of plugins to download / update in plugins.txt like this
# pluginID:version
# credentials:1.18
# maven-plugin:2.7.1
# ...
# NOTE : Just set pluginID to download latest version of plugin.
# NOTE : All plugins need to be listed as there is no transitive dependency resolution.
COPY plugins.txt /tmp/plugins.txt
RUN /usr/local/bin/plugins.sh /tmp/plugins.txt

USER jenkins

#give Jenkins a nice 8 GB memory pool and room to handle garbage collection
#ENV JAVA_OPTS="-Xmx8192m"
#give Jenkins a nice base pool of handlers and a cap
#ENV JENKINS_OPTS="--handlerCountStartup=100 --handlerCountMax=300"

ENV JENKINS_OPTS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war"

我将 docker-compose 和 Docker 卷与我的 Jenkins Master 以及我的 docker-compose.yml 结合使用:

version: '2'
services:
  data:
    build: data
    image: tsl.devops.jenkins.data.image
    container_name: tsl.devops.jenkins.data.container
  master:
    build: master
    image: tsl.devops.jenkins.master.image
    container_name: tsl.devops.jenkins.master.container
    volumes_from:
      - data
    ports:
      - "50000:50000"
    #network_mode: "host"
  nginx:
    build: nginx
    image: tsl.devops.jenkins.nginx.image
    container_name: tsl.devops.jenkins.nginx.container
    ports:
      - "80:80"
    links:
      - master:jenkins-master
  slavebasic:
    build:
      context: ./slaves
      dockerfile: basic/Dockerfile
    image: tsl.devops.jenkins.slave.basic.image
    container_name: tsl.devops.jenkins.slave.basic.container
  slavedotnetcore:
    build:
      context: ./slaves
      dockerfile: dotnetcore/Dockerfile
    image: tsl.devops.jenkins.slave.dotnetcore.image
    container_name: tsl.devops.jenkins.slave.dotnetcore.container

我的Jenkins 主卷/驱动器 Dockerfile:

#reference
#https://engineering.riotgames.com/news/docker-jenkins-data-persists
FROM centos:7
MAINTAINER Brian Ogden

#create the Jenkins user in this container
RUN useradd -d "/var/jenkins_home" -u 1000 -m -s /bin/bash jenkins
#NOTE: we set the UID here to the same one the Cloudbees Jenkins image uses 
#so we can match UIDs across containers, which is essential if you want 
#to preserve file permissions between the containers. We also use the same home directory and bash settings.

#Jenkins log directory
RUN mkdir -p /var/log/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins

#Docker volume magic
VOLUME ["/var/log/jenkins", "/var/jenkins_home"]
USER jenkins

#just a little output reminder of the container's purpose
CMD ["echo", "Data container for Jenkins"]

我的奴隶Dockerfile:

FROM centos:7
MAINTAINER Brian Ogden

#the USER will be root by default just explicitly 
#expressing it for better documentation
USER root

# Install Essentials
RUN yum update -y && \
         yum clean all

#############################################
# Jenkins Slave setup
#############################################
RUN yum install -y \
    git \
    wget \
    openssh-server \
    java-1.8.0-openjdk \
    sudo \
    make && \
    yum clean all

# gen dummy keys, centos doesn't autogen them like ubuntu does
RUN /usr/bin/ssh-keygen -A

# Set SSH Configuration to allow remote logins without /proc write access
RUN sed -ri 's/^session\s+required\s+pam_loginuid.so$/session optional pam_loginuid.so/' /etc/pam.d/sshd

# Create Jenkins User
RUN useradd jenkins -m -s /bin/bash

# Add public key for Jenkins login
RUN mkdir /home/jenkins/.ssh
COPY /files/id_rsa.pub /home/jenkins/.ssh/authorized_keys

#setup permissions for the new folders and files
RUN chown -R jenkins /home/jenkins
RUN chgrp -R jenkins /home/jenkins
RUN chmod 600 /home/jenkins/.ssh/authorized_keys
RUN chmod 700 /home/jenkins/.ssh

# Add the jenkins user to sudoers
RUN echo "jenkins  ALL=(ALL)  ALL" >> etc/sudoers
#############################################

#############################################
# Docker and Docker Compose Install
#############################################
#install required packages
RUN yum install -y \
    yum-utils \
    device-mapper-persistent-data \
    lvm2 \
    curl && \
    yum clean all

#add Docker CE stable repository
RUN yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

#Update the yum package index.
RUN yum makecache fast

#install Docker CE
RUN yum install -y docker-ce-17.06.0.ce-1.el7.centos

#install Docker Compose 1.14.0
#download Docker Compose binary from github repo
RUN curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#Apply executable permissions to the binary
RUN chmod +x /usr/local/bin/docker-compose
#############################################

#############################################
# .NET Core SDK
#############################################
RUN yum install -y \
    libunwind \
    libicu

RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821
RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin

#add Trade Service Nuget Server
RUN mkdir -p /home/jenkins/.nuget/NuGet
COPY /files/NuGet.Config /home/jenkins/.nuget/NuGet/NuGet.Config

RUN chown -R jenkins /home/jenkins/.nuget
RUN chgrp -R jenkins /home/jenkins/.nuget

RUN chmod 600 /home/jenkins/.nuget/NuGet/NuGet.Config
RUN chmod 700 /home/jenkins/.nuget/NuGet

#speed up dotnet core builds
ENV NUGET_XMLDOC_MODE skip
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE true
#############################################

# Expose SSH port and run SSHD
EXPOSE 22
#Technically, the Docker Plugin enforces this call when it starts containers by overriding the entry command. 
#I place this here because I want this build slave to run locally as it would if it was started in the build farm.
CMD ["/usr/sbin/sshd","-D"]

一个例子软件/组件Dockerfile 将在 Jenkins Slave Docker 容器内创建 Docker 镜像构建工件:

FROM centos:7
MAINTAINER Brian Ogden

#Timezone
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN yum update -y && \
         yum clean all

#############################################
# .NET Core SDK
#############################################
RUN yum install -y \
    libunwind \
    libicu

RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?linkid=848821
RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin

#speed up dotnet core builds
ENV NUGET_XMLDOC_MODE skip
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE true
#############################################

#############################################
# .NET Sevrice setup
#############################################
ARG ASPNETCORE_ENVIRONMENT

# Copy our code from the "/src/MyWebApi/bin/Debug/netcoreapp1.1/publish" folder to the "/app" folder in our container
WORKDIR /app
COPY ./src/TSL.Security.Service/bin/Debug/netcoreapp1.1/publish .

# Expose port 5000 for the Web API traffic
ENV ASPNETCORE_URLS http://+:5000
ENV ASPNETCORE_ENVIRONMENT $ASPNETCORE_ENVIRONMENT 

EXPOSE 5000

# Run the dotnet application against a DLL from within the container
# Don't forget to publish your application or this won't work
ENTRYPOINT ["dotnet", "TSL.Security.Service.dll"]
#############################################

答案1

根据您的 Docker 插件配置,您正在使用172.17.0.1Docker 主机。从从属或主容器来看,这将是在主机上运行的 Docker 守护程序(这里没有 Docker in Docker)。当您的 Jenkins 从属构建映像时(无论从属是作为容器运行还是在主机上运行),它都会使用主机上的 Docker,这就是您的映像显示在主机上的原因。

值得注意的是,数据可能首先进入从属服务器正在使用的 Docker 卷(根据DockefileJenkinshttps://github.com/jenkinsci/docker/blob/9f29488b77c2005bbbc5c936d47e697689f8ef6e/Dockerfile默认值为/var/jenkins_home。 在您的情况下,这只是来自服务的卷data(尽管在 Compose v2 格式中,您只需定义命名卷,无需创建数据容器)。 从这里,您的代码和Dockerfile通过 处的 API 发送到主机上的 Docker 构建上下文tcp://172.17.0.1:4243

相关内容