Поэтому я приятно удивлен в некоторых отношениях, увидев, что плагин Jenkins Docker «проталкивает» образы Docker на мой хост Docker, но это тоже сбивает с толку, потому что мои сборки выполняются в Docker Slave Containers, которые работают на хосте Docker. Даже мой мастер Jenkins работает в контейнере Docker, а не непосредственно на металле ...
После этого популярного Дженкинс ведущий / ведомый гид Я подошел к тому моменту, когда у меня работали сборки Дженкинса. эфемерные контейнеры Docker.
Это означает, что когда я делаю Jenkins сборку некоторого моего программного компонента / службы с исходным кодом, сборка запускается на ведомом устройстве Jenkins, которое оказывается контейнером Docker, созданным с помощью подключаемого модуля Jenkins Docker.
Рабочее пространство Jenkins находится в этом подчиненном контейнере, главный сервер Jenkins с установленным плагином Docker избавится от этого подчиненного контейнера после завершения сборки. См. Схему, которую я сделал, чтобы объяснить:
Некоторые важные моменты, которые нужно предпринять после того, как вы усвоите эту диаграмму:
Итак, в этом Docker Slave создается мой артефакт сборки программного компонента / службы, например, это может быть .dll или .war. Однако случается так, что моим артефактом сборки будет образ Docker. Чтобы быть ясным, я создаю образ Docker внутри работающего контейнера Docker (подчиненного устройства Jenkins).
Мое замешательство начинается с того, что я ожидал, что мне придется явно запустить cmd, чтобы протолкнуть артефакт сборки образа Docker моего программного компонента в реестр Docker. В противном случае, когда задание сборки Jenkins будет завершено, плагин Docker отключит подчиненный контейнер Docker, избавится от (rm) подчиненного контейнера, и тогда я потеряю артефакт сборки внутри этого подчиненного контейнера.
Что происходит на самом деле и почему я приятно удивлен, по крайней мере, в краткосрочной перспективе, пока я начинаю работу с DevOps, так это то, что образ Docker артефакта сборки появляется на металле хоста Docker, docker image ls
.
Я удивлен, что плагин Docker перешел на этот уровень предположения / помощи ... Я знаю, что плагин Docker позволяет вам настраивать реестр Docker и что вы можете добавить этап сборки в Build / Publish to a Docker Cloud, что я предполагаю это облако рассматривается как реестр изображений и, возможно, место для их запуска:
Что особенно интересно, я не использую подключаемый модуль Docker для каких-либо шагов сборки, я просто использую подключаемый модуль Docker для настройки подчиненного контейнера для сборки Jenkins Item:
Единственный шаг сборки, который у меня есть, - это то, что я выполняю сценарий оболочки, да, этот сценарий в конечном итоге создает образ Docker, но подключаемый модуль Docker этого не знает:
Плагин Docker запускает подчиненные контейнеры Docker, я настраиваю плагин Docker и говорю ему, что Docker Host (мой металл в моей ситуации), облако - это то, что плагин Docker называет хостом Docker, а также подчиненные образы Docker для использования на этом хосте Docker / Облако:
Я просто не понимаю, насколько изолированным оказывается рабочее пространство сборки Jenkins, когда оно находится внутри ведомого контейнера Docker?
Плагин Docker просто по умолчанию использует одно-единственное Docker Cloud (мой хост Docker). У меня есть настройки для всех любых команд докеров, которые я выполняю в подчиненном контейнере Jenkins Docker? (кстати, подчиненный контейнер, на котором установлен Docker-CE)
Мой Дженкинс Мастер 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 volume с моим 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 Master/ диск 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, который создаст артефакт сборки образа Docker внутри контейнера Docker Slave Jenkins:
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"]
#############################################
Согласно конфигурации вашего подключаемого модуля Docker, вы используете 172.17.0.1
в качестве хоста Docker. Из ведомого или главного контейнера это будет демон Docker, запущенный на хосте (здесь не происходит Docker в Docker). Когда ваше ведомое устройство Jenkins создает изображение (независимо от того, работает ли ведомое устройство как контейнер или на хосте), оно использует Docker на хосте, и именно поэтому ваше изображение появляется на хосте.
Стоит отметить, что данные, скорее всего, сначала поступают в том Docker, используемый ведомым устройством (согласно Jenkins Dockefile
в https://github.com/jenkinsci/docker/blob/9f29488b77c2005bbbc5c936d47e697689f8ef6e/Dockerfile по умолчанию /var/jenkins_home
). В вашем случае это просто том из data
service (хотя в формате Compose v2 вы можете просто определить именованный том, вам не нужно создавать контейнер данных). Отсюда ваш код и Dockerfile
отправляются в контекст сборки Docker на хосте через API по адресу tcp://172.17.0.1:4243
.