Difference between revisions of "Docker"
Line 2: | Line 2: | ||
= Installation = | = Installation = | ||
General procedure: | |||
# Make sure you don't have docker already installed from your packet manager | |||
# The /var/lib/docker may be | |||
To install the latest version of Docker with curl: | To install the latest version of Docker with curl: | ||
<source lang="bash"> | <source lang="bash"> | ||
curl -sSL https://get.docker.com/ | sh | curl -sSL https://get.docker.com/ | sh | ||
</source> | </source> | ||
CentOS install: | CentOS install: | ||
<source lang="bash"> | <source lang="bash"> | ||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo | sudo yum install -y yum-utils device-mapper-persistent-data lvm2 #utils | ||
sudo yum clean all | sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #docker-ee.repo for EE edition | ||
sudo yum install -y --setopt=obsoletes=0 docker-ce-17.03.1.ce-1.el7.centos | # --enable docker-ce-{edge|test} #for beta releases | ||
sudo yum update | |||
sudo systemctl start docker | sudo yum clean all #not sure why this command is here | ||
yum-config-manager --disable jenkins #disable source to prevent accidental update | sudo yum install docker-ce | ||
#old: sudo yum install -y --setopt=obsoletes=0 docker-ce-17.03.1.ce-1.el7.centos docker-ce-selinux-17.03.1.ce-1.el7.centos | |||
sudo systemctl enable docker && sudo systemctl start docker && sudo systemctl status docker | |||
yum-config-manager --disable jenkins #disable source to prevent accidental update ?jenkins? | |||
</source> | </source> | ||
Revision as of 11:03, 7 January 2019
Containers taking a world J
Installation
General procedure:
- Make sure you don't have docker already installed from your packet manager
- The /var/lib/docker may be
To install the latest version of Docker with curl:
curl -sSL https://get.docker.com/ | sh
CentOS install:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 #utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #docker-ee.repo for EE edition # --enable docker-ce-{edge|test} #for beta releases sudo yum update sudo yum clean all #not sure why this command is here sudo yum install docker-ce #old: sudo yum install -y --setopt=obsoletes=0 docker-ce-17.03.1.ce-1.el7.centos docker-ce-selinux-17.03.1.ce-1.el7.centos sudo systemctl enable docker && sudo systemctl start docker && sudo systemctl status docker yum-config-manager --disable jenkins #disable source to prevent accidental update ?jenkins?
Ubuntu 16.04+ install:
# Optional, clear out config files sudo rm /etc/systemd/system/docker.service.d/docker.conf sudo rm /etc/systemd/system/docker.service sudo rm /etc/default/docker #environment file #New docker package is called now 'docker-ce' sudo apt-get remove docker docker-engine docker.io docker-ce #start fresh sudo apt-get install apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo apt-key fingerprint 0EBFCD88 #verify #add the repository sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt-get update sudo apt-cache madison docker-ce #display available versions sudo apt-get install docker-ce=<VERSION> sudo apt-get install docker-ce=18.06.0~ce~3-0~ubuntu
Example of how to run Jenkins docker image
Add your user to docker group to be able to run docker commands without need of sudo
sudo usermod -aG docker yourusername
HTTP proxy
Configure docker if you run behind a proxy server. In this example CNTLM proxy runs on the host machine listening on localhost:3128. This example overrides the default docker.service file by adding configuration to the Docker systemd service file.
First, create a systemd drop-in directory for the docker service:
sudo mkdir /etc/systemd/system/docker.service.d sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=http://proxy.example.com:80/" Environment="HTTP_PROXY=http://172.31.1.1:3128/" #overrides previous entry Environment="HTTPS_PROXY=http://172.31.1.1:3128/" # If you have internal Docker registries that you need to contact without proxying you can specify them via the NO_PROXY environment variable Environment="NO_PROXY=localhost,127.0.0.1,10.6.96.172,proxy.example.com:80"
Flush changes:
$ sudo systemctl daemon-reload
Verify that the configuration has been loaded:
$ systemctl show --property=Environment docker Environment=HTTP_PROXY=http://proxy.example.com:80/
Restart Docker:
$ sudo systemctl restart docker
Docker run and basic options
docker run -it --name="mycentos" centos:latest /bin/bash # -i interactive mode \command to execute # -t bind to the current terminal # -d disconnect mode, daemon mode, detached mode, running the task in the background # --name="name_your_container" # -p flag shows which ports we are using
Docker inspect
Shows current configuration state of a docker container.
docker inspect <container_name> | grep IPAddress "SecondaryIPAddresses": null, "IPAddress": "172.17.0.3", "IPAddress": "172.17.0.3",
Attach to a docker process
If you are running eg. /bin/bash as a command you can get attached to this running docker process
docker attach mycentos
Mount directory in container
We can mount host directory into docker container so the content will be available from the container
docker run -it -v /mnt/sdb1:/opt/java pio2pio/java8 # syntax: -v /path/on/host:/path/in/container
Build image
Dockerfile
Each line RUN creates a container so if possible, we should join lines so it ends up with less layers.
$ wget jkd1.8.0_111.tar.gz $ cat Dockerfile <<- EOF #'<<-' heredoc with '-' minus ignores <tab> indent # Defines our base image FROM ubuntu:latest # eg. ubuntu:16.04 MAINTAINER user1 <user1@gmail.com> # Define environment variables with syntax ENV space EnvironmetVariable space Value ENV SHARE /usr/local/share ENV JAVA_HOME $SHARE/java # Copy files into the image root folder ADD jkd1.8.0_111.tar.gz / # Executes commands in a new layer E.g., it is often used for installing software packages RUN mv /jkd1.8.0_111.tar.gz $JAVA_HOME RUN apt-get update RUN apt-get upgrade -y #Add CMD, a single command that will run after the image has been created CMD ["/bin/bash"] EOF
Build
docker build -t pio2pio/java8 . # pio2pio -dockerhub username, java8 -image name, . directory where the Dockerfile docker images #list images docker push pio2pio/java8 #upload the image to DockerHub repository
Manage containers and images
Run a container
When you run a container you will create a new container from a image that has been already build/ is available then put in running state
- -d detached mode, the container will continue to run after the CMD or passed on command exited
- -i interactive mode, allows you to login in /ssh to the container
sudo docker run -it pio2pio/java8 # -i run in interactive mode, because I used CMD=/bin/bash the prompt will be present straight away # --rm will delete container after run
List
ctop #top for containers docker ps -a #list containers docker image ls #list images docker images #short form of the command above docker search ubuntu #Search the Docker Hub for images, you need to docker login first NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating sys… 8206 [OK] dorowu/ubuntu-desktop-lxde-vnc Ubuntu with openssh-server and NoVNC 210 [OK] rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 167 [OK]
Stop and delete all containers
docker stop $(docker ps -aq) && docker rm $(docker ps -aq)
Delete image
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE company-repo 0.1.0 f796d7f843cc About an hour ago 888MB <none> <none> 04fbac2fdf48 3 hours ago 565MB ubuntu 16.04 7aa3602ab41e 3 weeks ago 115MB $ docker rmi company-repo:0.1.0 Untagged: company-repo:0.1.0 Deleted: sha256:e5cca6a080a5c65eacff98e1b17eeb7be02651849b431b46b074899c088bd42a .. Deleted: sha256:bc7cda232a2319578324aae620c4537938743e46081955c4dd0743a89e9e8183
Docker Volumes
docker volume ls #list volumes created by VOLUME directive in a Dockerfile sudo tree /var/lib/docker/volumes/ #list volumes on host-side
Examples
Default project
As good practice all Docker files should be source controlled. The basic self explanatory structure can looks like below, and skeleton be created with a commend below:
mkdir APROJECT && d=$_; touch $d/{build.sh,run.sh,Dockerfile,README.md,VERSION};mkdir $d/assets; touch $_/{entrypoint.sh,install.sh} └── APROJECT ├── assets │ ├── entrypoint.sh │ └── install.sh ├── build.sh ├── Dockerfile ├── README.md └── VERSION
Dockerfile
User management
RUN addgroup --gid 1001 jenkins -q RUN adduser --gid 1001 --home /tank --disabled-password --gecos '' --uid 1001 jenkins # --gid add user to group 1001 # --gecos parameter is used to set the additional information. In this case it is just empty. # --disabled-password it's like --disabled-login, but logins are still possible (for example using SSH RSA keys) but not using password authentication USER jenkins:jenkins #sets user for next RUN, CMD and ENTRYPOINT command WORKDIR /tank #changes cwd for next RUN, CMD, ENTRYPOINT, COPY and ADD
Gracefully stop / kill a container
all below are only notes
Trap ctrl_c then kill/rm container.
- --init
- --sig-proxy this only works when --tty=false but by default is true
Proxy
If you are behind corporate proxy, you should use Docker client ~/.docker/config.json
config file. It requires Docker
17.07 minimum version.
{ "proxies": { "default": { "httpProxy": "http://10.0.0.1:3128", "httpsProxy": "http://10.0.0.1:3128", "noProxy": "localhost,127.0.0.1,*.test.example.com,.example2.com" } } }
More you can find here
Insecure proxy
These can be added to different places, the order is based on latest practices and versioning
- docker-ce 18.6
{ "insecure-registries" : [ "localhost:443","10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" ] }
sudo systemctl daemon-reload sudo systemctl restart docker sudo systemctl show docker | grep Env docker info #check Insecure Registries
- Using environment file, prior version 18
$ sudo vi /etc/default/docker DOCKER_HOME='--graph=/tank/docker' DOCKER_GROUP='--group=docker' DOCKER_LOG_DRIVER='--log-driver=json-file' DOCKER_STORAGE_DRIVER='--storage-driver=btrfs' DOCKER_ICC='--icc=false' DOCKER_IPMASQ='--ip-masq=true' DOCKER_IPTABLES='--iptables=true' DOCKER_IPFORWARD='--ip-forward=true' DOCKER_ADDRESSES='--host=unix:///var/run/docker.sock' DOCKER_INSECURE_REGISTRIES='--insecure-registry 10.0.0.0/8 --insecure-registry 172.16.0.0/12 --insecure-registry 192.168.0.0/16' DOCKER_OPTS="${DOCKER_HOME} ${DOCKER_GROUP} ${DOCKER_LOG_DRIVER} ${DOCKER_STORAGE_DRIVER} ${DOCKER_ICC} ${DOCKER_IPMASQ} ${DOCKER_IPTABLES} ${DOCKER_IPFORWARD} ${DOCKER_ADDRESSES} ${DOCKER_INSECURE_REGISTRIES}" $ sudo vi /etc/systemd/system/docker.service.d/docker.conf [Service] EnvironmentFile=-/etc/default/docker ExecStart=/usr/bin/dockerd $DOCKER_HOME $DOCKER_GROUP $DOCKER_LOG_DRIVER $DOCKER_STORAGE_DRIVER $DOCKER_ICC $DOCKER_IPMASQ $DOCKER_IPTABLES $DOCKER_IPFORWARD $DOCKER_ADDRESSES $DOCKER_INSECURE_REGISTRIES $ sudo vi /etc/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target docker.socket firewalld.service Wants=network-online.target Requires=docker.socket [Service] EnvironmentFile=-/etc/default/docker Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker ExecStart=/usr/bin/dockerd -H fd:// ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 # Having non-zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. LimitNPROC=infinity LimitCORE=infinity # Uncomment TasksMax if your systemd version supports it. # Only systemd 226 and above support this version. TasksMax=infinity TimeoutStartSec=0 # set delegate yes so that systemd does not reset the cgroups of docker containers Delegate=yes # kill only the docker process, not all processes in the cgroup KillMode=process # restart the docker process if it exits prematurely Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target
Run docker without sudo
Adding a user to docker group should be sufficient. However on apparmor, SELinux or a filesystem with ACL enabled additional permissions might be required in respect to access a socket file.
$ ll /var/run/docker.sock srw-rw---- 1 root docker 0 Sep 6 12:31 /var/run/docker.sock= # ACL $ sudo getfacl /var/run/docker.sock getfacl: Removing leading '/' from absolute path names # file: var/run/docker.sock # owner: root # group: docker user::rw- group::rw- other::--- # Grant ACL to jenkns user $ sudo setfacl -m user:username:rw /var/run/docker.sock $ sudo getfacl /var/run/docker.sock getfacl: Removing leading '/' from absolute path names # file: var/run/docker.sock # owner: root # group: docker user::rw- user:jenkins:rw- group::rw- mask::rw- other::---
References
References
- my-container-wont-stop-on-ctrl-c-and-other-minor-tragedies
- PID1 in container aka tinit
- understanding-volumes-docker
Theory
Difference between docker attach and docker exec
- Attach
The docker attach command allows you to attach to a running container using the container’s ID or name, either to view its ongoing output or to control it interactively. You can attach to the same contained process multiple times simultaneously, screen sharing style, or quickly view the progress of your detached process.
The command docker attach is for attaching to the existing process. So when you exit, you exit the existing process.
If we use docker attach, we can use only one instance of shell. So if we want open new terminal with new instance of container's shell, we just need run docker exec
If the docker container was started using /bin/bash command, you can access it using attach, if not then you need to execute the command to create a bash instance inside the container using exec. Attach isn't for running an extra thing in a container, it's for attaching to the running process.
To stop a container, use CTRL-c. This key sequence sends SIGKILL to the container. If --sig-proxy is true (the default),CTRL-c sends a SIGINT to the container. You can detach from a container and leave it running using the CTRL-p CTRL-q key sequence.
- exec
"docker exec" is specifically for running new things in a already started container, be it a shell or some other process. The docker exec command runs a new command in a running container.
The command started using docker exec only runs while the container’s primary process (PID 1) is running, and it is not restarted if the container is restarted.
exec command works only on already running container. If the container is currently stopped, you need to first run it. So now you can run any command in running container just knowing its ID (or name):
docker exec <container_id_or_name> echo "Hello from container!" docker run -it -d shykes/pybuilder /bin/bash
The most important here is the -d option, which stands for detached. It means that the command you initially provided to the container (/bin/bash) will be run in background and the container will not stop immediately.
References
- Ubuntu installation official website
- PROXY settings for systemd
- Docker RUN vs CMD vs ENTRYPOINT
- docker ARG vs ENV
- Docker online lintel
- portainer Monitor your containers via Web GUI