Jenkins Docker Plugin: Difference between revisions
(69 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | =External= | ||
* https://wiki.jenkins.io/display/JENKINS/Docker+Plugin | * https://plugins.jenkins.io/docker-commons https://wiki.jenkins.io/display/JENKINS/Docker+Commons+Plugin | ||
* https://plugins.jenkins.io/docker-plugin | * https://plugins.jenkins.io/docker-plugin https://wiki.jenkins.io/display/JENKINS/Docker+Plugin | ||
=Internal= | =Internal= | ||
* [[Jenkins_Concepts# | * [[Jenkins_Concepts#Running_Build_Agents_as_Docker_Containers|Jenkins Concepts]] | ||
=Overview= | =Overview= | ||
ID | Docker plugin (ID docker-plugin) enables Jenkins to use a Docker server to provision build agents, run a single build and then tear down the agent. Optionally, the container can be committed after build. Docker plugin depends on Docker Commons plugin (ID docker-commons). | ||
=Concepts= | =Concepts= | ||
Line 16: | Line 16: | ||
==Docker Agent== | ==Docker Agent== | ||
Jenkins | Docker plugin enables Jenkins to create dynamically and use for builds [[Jenkins_Concepts#Docker_Plugin_Agent|agents]] executing as containers within a Docker instance. Docker plugin requires that the agent containers are based on one of the following base images: | ||
===jenkins/ssh-slave=== | ===jenkins/ssh-slave=== | ||
{{External|https://hub.docker.com/r/jenkins/ssh-slave/}} | {{External|https://hub.docker.com/r/jenkins/ssh-slave/}} | ||
The image comes with [[OpenSSH Concepts#sshd|sshd]] and a JDK. The Jenkins master will use ssh to connect into the agent's sshd. A SSH key based on unique Jenkins master instance identity can be injected in container on startup, obviating the need for password. | |||
The image to be used as base is "jenkinsci/ssh-slave". | |||
:<span id='DockerPluginSSH'></span>[[Image:DockerPluginSSH.png]] | |||
===jenkins/jnlp-slave=== | ===jenkins/jnlp-slave=== | ||
{{External|https://hub.docker.com/r/jenkins/jnlp-slave/}} | |||
The image comes with JDK. Jenkins master URL has to be reachable from the agent's container. The container will be configured automatically with the agent's name and secret. No special configuration of the container is needed. | |||
===jenkins/slave=== | ===jenkins/slave=== | ||
{{External|https://hub.docker.com/r/jenkins/slave/}} | |||
An "attached" agent. | |||
=Installation= | =Installation= | ||
==Plugin Installation== | |||
Manually from the UI or: | Manually from the UI or: | ||
/usr/local/bin/install-plugins.sh docker-plugin | /usr/local/bin/install-plugins.sh docker-plugin | ||
After the plugin is installed, a new configuration category shows up: Manage Jenkins -> Configure System -> Cloud. The installation process will also pull plugin dependencies. | |||
==Jenkins Server Configuration== | |||
Jenkins -> Manage Jenkins -> Configure System -> Cloud -> Add a new cloud -> Docker | |||
====Name==== | |||
docker | |||
The name should be something suggestive that indicates what docker server is actually used (ex: "Local SWMBP1 Docker Server"). | |||
====Docker Host URI==== | |||
It is the URI to the Docker Host. May be left blank to use the default value defined by DOCKER_HOST environment variable. A typical value is unix:///var/run/docker.sock or tcp://127.0.0.1:2376. | |||
=====Using Unix-domain Sockets for Jenkins Running as a Container===== | |||
Note that if Jenkins itself runs as a Docker container on the same Docker server to be used for agent provisioning, and wants to use a [[Linux Unix Socket#Overview|Unix-doman socket]] for access, it won't have access by default to unix:///var/run/docker.sock of the Docker host. Access can be enabled by starting the Jenkins container as follows: | |||
docker run ... --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock ... <''jenkins-image''> | |||
This command maps the Docker-host level /var/run/docker.sock into the container with a [[Docker_Concepts#Bind_Mount|bind mount]], and sets appropriate permissions on the container-level /var/run/docker.sock so Jenkins can access it. Also, the Docker host-level user mapped to the Jenkins process must be added to the "docker" group, so it has access to the Unix socket. For more details see [[Docker_Linux_Installation#Non-root_Management_Access|Non-root Management Access for Docker]]. | |||
Jenkins container /var/run/docker.sock permissions: | |||
<syntaxhighlight lang='bash'> | |||
ls -al /var/run/docker.sock | |||
srw-rw---- 1 root jenkins 0 Apr 23 17:30 /var/run/docker.sock | |||
</syntaxhighlight> | |||
Docker host /var/run/docker.sock permissions. | |||
<syntaxhighlight lang='bash'> | |||
ls -al /var/run/docker.sock | |||
srw-rw---- 1 root serviceusergroup 0 Apr 19 16:38 /var/run/docker.sock | |||
</syntaxhighlight> | |||
====Server credentials==== | |||
Unix-domain socket do not require credentials, though the socket must have proper access permissions. | |||
====Advanced==== | |||
=====Docker Hostname or IP address===== | |||
'''Important''': When using <tt>unix:///var/run/docker.sock</tt> as Docker host URI, it is important to provide a value here. This value will be used by the Jenkins master process when attempting to connect to [[#jenkins.2Fssh-slave|ssdd-running Docker agents]]. The agents are deployed within the Docker server as containers, and if SSH is used as master/agent communication method, the agents will expect to be invoked into by the master via SSH, as shown in the [[#DockerPluginSSH|above diagram]], and will bind to an ephemeral port on the Docker host, which will be forwarded to 22 inside the agent container: | |||
0.0.0.0:32775->22/tcp | |||
The Docker server will make available the ephemeral port on whatever Docker host-level network interface it binds to. | |||
If the Jenkins master runs itself as a container in the Docker server, it will need to know the '''external''' IP address the Docker server is available on. This is configured as "Docker Hostname or IP address". Note that 127.0.0.1 cannot be used, because for the Jenkins master container, that means "local address of the container", not "local address of the Docker host". | |||
If the Docker host has a static IP address, simply provide it as "Docker Hostname or IP address", and the SSH connections will establish correctly. The situation is more complicated if the Docker host is a development laptop that gets its IP address via DHCP, so we cannot rely on it not to change. In this situation, there are several solutions: | |||
# Configure "Docker Hostname or IP address" with the DHCP IP address of the Docker Host. This is inconvenient, as we'll have to change Jenkins configuration every time the IP address of the host changes, but it works. | |||
# Run the Docker server by default in [[Docker_Networking_Concepts#host|host network mode]]. Not Tested. | |||
# Provision an internal network interface with a fixed address on the development host, and configure Docker server to bind on it. This way, Docker and its containers will be self-contained, with a static address. It may be necessary to make that address routable, for external connectivity reasons. Not tested. | |||
Also see [[Running_Jenkins_as_a_Docker_Container#Networking|Running Jenkins as a Docker Container]]. | |||
====Test Connection==== | |||
Useful for debugging. A successful connection to the Docker server should return something like: | |||
Version = 18.03.0-ce, API Version = 1.37 | |||
====Enabled==== | |||
Must be specifically enabled. Not by default. | |||
====Container Cap==== | |||
The maximum number of containers that this provider is allowed to run in total. Note that containers that have not been created by Jenkins are counted as well. 0 disables provisioning of containers altogether. To get unlimited containers, use a non-reachable high value. | |||
===Docker Agent Templates=== | |||
This section configures the images to be launched as agent container. | |||
=====Labels===== | |||
Each agent image is associated with a Jenkins [[#Jenkins_Concepts#Label|label]]. The image must be available in an accessible registry. | |||
Label example: "jenkins-ssh-agent-label" | |||
=====Enables===== | |||
Must explicitly enable. | |||
=====Docker Image===== | |||
The image to be used as agent. Must be available in the local registry or into an accessible registry. | |||
Example: "jenkins-ssh-agent" as built by https://github.com/NovaOrdis/playground/blob/master/jenkins/docker/jenkins-ssh-agent/Dockerfile. | |||
====Connect Method==== | |||
"Attach Docker Container", "Connect with JNLP", "Connect with SSH". Corresponds to one of the agent types ([[#jenkins.2Fslave|jenkins/slave]], [[#jenkins.2Fjnlp-slave|jenkins/jnlp-slave]] and [[#jenkins.2Fssh-slave|jenkins/ssh-slave]]) and it must be in sync with the image declared as "[[#Docker_Image|Docker Image]]" above. | |||
Tested with SSH, and it works. | |||
====Pull Strategy==== | |||
The default is "Pull all images every time" which assumes the image is available in the registry the Docker server was configured with. | |||
If the image was built locally and published in the local registry of the Docker server Jenkins runs on, and nowhere else, use "Never Pull". | |||
==Job Configuration== | |||
General -> "Restrict where this project can be run": use the [[#Labels|label defined above]]. | |||
=Configuration= | |||
The agent images need to be created and accessible to the Jenkins server. |
Latest revision as of 20:01, 1 May 2018
External
- https://plugins.jenkins.io/docker-commons https://wiki.jenkins.io/display/JENKINS/Docker+Commons+Plugin
- https://plugins.jenkins.io/docker-plugin https://wiki.jenkins.io/display/JENKINS/Docker+Plugin
Internal
Overview
Docker plugin (ID docker-plugin) enables Jenkins to use a Docker server to provision build agents, run a single build and then tear down the agent. Optionally, the container can be committed after build. Docker plugin depends on Docker Commons plugin (ID docker-commons).
Concepts
Docker Agent
Docker plugin enables Jenkins to create dynamically and use for builds agents executing as containers within a Docker instance. Docker plugin requires that the agent containers are based on one of the following base images:
jenkins/ssh-slave
The image comes with sshd and a JDK. The Jenkins master will use ssh to connect into the agent's sshd. A SSH key based on unique Jenkins master instance identity can be injected in container on startup, obviating the need for password.
The image to be used as base is "jenkinsci/ssh-slave".
jenkins/jnlp-slave
The image comes with JDK. Jenkins master URL has to be reachable from the agent's container. The container will be configured automatically with the agent's name and secret. No special configuration of the container is needed.
jenkins/slave
An "attached" agent.
Installation
Plugin Installation
Manually from the UI or:
/usr/local/bin/install-plugins.sh docker-plugin
After the plugin is installed, a new configuration category shows up: Manage Jenkins -> Configure System -> Cloud. The installation process will also pull plugin dependencies.
Jenkins Server Configuration
Jenkins -> Manage Jenkins -> Configure System -> Cloud -> Add a new cloud -> Docker
Name
docker
The name should be something suggestive that indicates what docker server is actually used (ex: "Local SWMBP1 Docker Server").
Docker Host URI
It is the URI to the Docker Host. May be left blank to use the default value defined by DOCKER_HOST environment variable. A typical value is unix:///var/run/docker.sock or tcp://127.0.0.1:2376.
Using Unix-domain Sockets for Jenkins Running as a Container
Note that if Jenkins itself runs as a Docker container on the same Docker server to be used for agent provisioning, and wants to use a Unix-doman socket for access, it won't have access by default to unix:///var/run/docker.sock of the Docker host. Access can be enabled by starting the Jenkins container as follows:
docker run ... --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock ... <jenkins-image>
This command maps the Docker-host level /var/run/docker.sock into the container with a bind mount, and sets appropriate permissions on the container-level /var/run/docker.sock so Jenkins can access it. Also, the Docker host-level user mapped to the Jenkins process must be added to the "docker" group, so it has access to the Unix socket. For more details see Non-root Management Access for Docker.
Jenkins container /var/run/docker.sock permissions:
ls -al /var/run/docker.sock
srw-rw---- 1 root jenkins 0 Apr 23 17:30 /var/run/docker.sock
Docker host /var/run/docker.sock permissions.
ls -al /var/run/docker.sock
srw-rw---- 1 root serviceusergroup 0 Apr 19 16:38 /var/run/docker.sock
Server credentials
Unix-domain socket do not require credentials, though the socket must have proper access permissions.
Advanced
Docker Hostname or IP address
Important: When using unix:///var/run/docker.sock as Docker host URI, it is important to provide a value here. This value will be used by the Jenkins master process when attempting to connect to ssdd-running Docker agents. The agents are deployed within the Docker server as containers, and if SSH is used as master/agent communication method, the agents will expect to be invoked into by the master via SSH, as shown in the above diagram, and will bind to an ephemeral port on the Docker host, which will be forwarded to 22 inside the agent container:
0.0.0.0:32775->22/tcp
The Docker server will make available the ephemeral port on whatever Docker host-level network interface it binds to.
If the Jenkins master runs itself as a container in the Docker server, it will need to know the external IP address the Docker server is available on. This is configured as "Docker Hostname or IP address". Note that 127.0.0.1 cannot be used, because for the Jenkins master container, that means "local address of the container", not "local address of the Docker host".
If the Docker host has a static IP address, simply provide it as "Docker Hostname or IP address", and the SSH connections will establish correctly. The situation is more complicated if the Docker host is a development laptop that gets its IP address via DHCP, so we cannot rely on it not to change. In this situation, there are several solutions:
- Configure "Docker Hostname or IP address" with the DHCP IP address of the Docker Host. This is inconvenient, as we'll have to change Jenkins configuration every time the IP address of the host changes, but it works.
- Run the Docker server by default in host network mode. Not Tested.
- Provision an internal network interface with a fixed address on the development host, and configure Docker server to bind on it. This way, Docker and its containers will be self-contained, with a static address. It may be necessary to make that address routable, for external connectivity reasons. Not tested.
Also see Running Jenkins as a Docker Container.
Test Connection
Useful for debugging. A successful connection to the Docker server should return something like:
Version = 18.03.0-ce, API Version = 1.37
Enabled
Must be specifically enabled. Not by default.
Container Cap
The maximum number of containers that this provider is allowed to run in total. Note that containers that have not been created by Jenkins are counted as well. 0 disables provisioning of containers altogether. To get unlimited containers, use a non-reachable high value.
Docker Agent Templates
This section configures the images to be launched as agent container.
Labels
Each agent image is associated with a Jenkins label. The image must be available in an accessible registry.
Label example: "jenkins-ssh-agent-label"
Enables
Must explicitly enable.
Docker Image
The image to be used as agent. Must be available in the local registry or into an accessible registry.
Example: "jenkins-ssh-agent" as built by https://github.com/NovaOrdis/playground/blob/master/jenkins/docker/jenkins-ssh-agent/Dockerfile.
Connect Method
"Attach Docker Container", "Connect with JNLP", "Connect with SSH". Corresponds to one of the agent types (jenkins/slave, jenkins/jnlp-slave and jenkins/ssh-slave) and it must be in sync with the image declared as "Docker Image" above.
Tested with SSH, and it works.
Pull Strategy
The default is "Pull all images every time" which assumes the image is available in the registry the Docker server was configured with.
If the image was built locally and published in the local registry of the Docker server Jenkins runs on, and nowhere else, use "Never Pull".
Job Configuration
General -> "Restrict where this project can be run": use the label defined above.
Configuration
The agent images need to be created and accessible to the Jenkins server.