Инструменты пользователя

Инструменты сайта


how-to:docker

Docker

Установка

Установить:

sudo apt install gnupg

Добавить репозиторий:

curl -s -L https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
echo "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update

Установить:

sudo apt install docker-ce

https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository

docker-credential-helpers

Для использования менеджера паролей установить (pass):

sudo apt install golang-docker-credential-helpers

или из официального репозитория

VER=$(curl -s https://api.github.com/repos/docker/docker-credential-helpers/releases/latest | jq -r .tag_name)
wget https://github.com/docker/docker-credential-helpers/releases/download/$VER/docker-credential-pass-$VER-amd64.tar.gz -P /tmp
sudo tar zxf /tmp/docker-credential-pass-$VER-amd64.tar.gz -C /usr/bin
sudo chmod +x /usr/bin/docker-credential-pass

/etc/default/docker

Для того чтобы docker при запуске считывал параметры из /etc/default/docker создаём директорию /etc/systemd/system/docker.service.d и файл default.conf в ней:

sudo mkdir -p /etc/systemd/system/docker.service.d
echo [Service] | sudo tee /etc/systemd/system/docker.service.d/default.conf
echo EnvironmentFile=-/etc/default/docker | sudo tee -a /etc/systemd/system/docker.service.d/default.conf
echo ExecStart= | sudo tee -a /etc/systemd/system/docker.service.d/default.conf
echo 'ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd://' | sudo tee -a /etc/systemd/system/docker.service.d/default.conf
sudo systemctl daemon-reload

DNS

Добавить /etc/docker/daemon.json:

{
    "dns": ["192.168.2.1", "1.1.1.1", "8.8.8.8"]
}

Одной командой (daemon.json перезапишется):

echo '{ "dns": ["192.168.2.1"] }' | sudo tee /etc/docker/daemon.json

Перезапустить docker

Лог

Ограничить общий объём логов в 1024mb

/etc/docker/daemon.json

/etc/docker/daemon.json

{
    "log-opts": {
        "max-size": "1024m"
    }
}
JQEMTY=$([ "$(jq length /etc/docker/daemon.json 2>/dev/null)" == "" ] && echo "--null-input"); jq . /etc/docker/daemon.json 2>/dev/null | jq ${JQEMTY} '."log-opts" |= . + {"max-size" : "1024m"}' | sudo tee /etc/docker/daemon.json ; unset JQEMTY
dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker.service


Разрешения

Чтобы разрешить пользователю работать в docker, необходимо его добавить в группу docker (на примере пользователя lioncub):

sudo adduser $LOGNAME docker

Проверить группы пользователя:

id -nG

Необходимо перезайти в систему, либо выполнить:

su - ${USER}

Команды

Вызов команды docker по d:

echo "alias d='docker'" >> ~/.bash_aliases
echo "alias dc='docker compose'" >> ~/.bash_aliases
Set-Alias -Name d -Value docker
Set-Alias -Name dc -Value docker compose

docker:

  • build - создать образ из Dockerfile
  • commit - сохранить изменённый образ
  • images - список загруженных образов
  • pull - загрузка образа
  • run - запуск образа
    • --restart - автозапуск контейнеров
      --restart no - Не запускать автоматически контейнер после его остановки. Значение по умолчанию.
      --restart on-failure[:кол-во-попыток] - Перезапускать если контейнер остановился с ошибкой. Возможно ограничить количество попыток запуска.
      --restart always - Всегда перезапускать контейнер независимо от состояния выхода.
      --restart unless-stopped - Всегда перезапускать контейнер независимо от состояния выхода, пока не будет остановлен явно.
  • rmi - удалить один или несколько образов
  • search - поиск образов
  • stats - отобразить online статистику использования ресурсов контейнера
  • update - обновить конфигурацию контейнера

Размер:

docker container ls -s               #размер контейнеров
docker image ls                      #размер образов
docker image history my_image:my_tag #размеры промежуточных образов

Inspect:

docker inspect -f "{{ .HostConfig.RestartPolicy }}" <container>  #текущее значение RestartPolicy
docker inspect -f "{{ .RestartCount }}" <container>              #количество перезапусков
docker inspect -f "{{ .State.StartedAt }}"  <container>          #время запуска

Save image:

docker save imagename | gzip > image-imagename.tgz

Save image powershell

Save image powershell

docker save imagename -o imagename.tar
& 'C:\Program Files\7-Zip\7z.exe' a imagename.tgz imagename.tar


Load image:

docker load < imagename.tgz
#или
docker load -i imagename.tgz

Получить образ по ssh:

ssh ${REMOTEHOST} docker save ${IMAGENAME} | docker load

Filter

Показать ID контейнера по имени образа:

docker ps -q -f ancestor=iamgename:tag

Показать ID контейнера по имени контейнера:

docker ps -q -f name=containername

Proxy

Docker демон использует переменные: HTTP_PROXY, HTTPS_PROXY, и NO_PROXY (Вариант 1,2)

Вариант 1 (через параметры из /etc/default/docker)

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

  1. Подключаем /etc/default/docker
  2. Добавляем переменные:
    PROXY=d2proxy.domain.loc:3128
    echo HTTP_PROXY=http://$PROXY/ | sudo tee -a /etc/default/docker
    echo HTTPS_PROXY=http://$PROXY/ | sudo tee -a /etc/default/docker
    echo NO_PROXY=localhost,127.0.0.1,.domain.loc | sudo tee -a /etc/default/docker
  3. Перегружаем docker:
    sudo service docker reload

Вариант 2 (напрямую через systemd)

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

Cоздаём директорию /etc/systemd/system/docker.service.d и файл proxy.conf в ней:

PROXY=d2proxy.domain.loc:3128
sudo mkdir -p /etc/systemd/system/docker.service.d
echo [Service] | sudo tee /etc/systemd/system/docker.service.d/proxy.conf
echo Environment=\"HTTP_PROXY=http://$PROXY/\" | sudo tee -a /etc/systemd/system/docker.service.d/proxy.conf
echo Environment=\"HTTPS_PROXY=http://$PROXY/\" | sudo tee -a /etc/systemd/system/docker.service.d/proxy.conf
echo Environment=\"NO_PROXY=localhost,127.0.0.1,.domain.loc\" | sudo tee -a /etc/systemd/system/docker.service.d/proxy.conf

Применяем изменения и перегружаем docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

Проверяем переменные:

systemctl show --property=Environment docker


https://docs.docker.com/config/daemon/systemd/#httphttps-proxy

Вариант 3 (через config.json):

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

Cоздаём файл ~/.docker/config.json или /etc/docker/config.json в ней:

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://d2proxy.domain.loc:3128",
     "httpsProxy": "http://d2proxy.domain.loc:3128",
     "ftpProxy": "http://d2proxy.domain.loc:3128",
     "noProxy": ".domain.loc"
   }
 }
}


https://docs.docker.com/network/proxy/

Управление по сети

  1. Подключаем /​etc/​default/​docker
  2. Добавляем переменные:
    echo DOCKER_OPTS=\"-H tcp://0.0.0.0:2375\" | sudo tee -a /etc/default/docker
  3. Перегружаем docker:
    sudo service docker restart

iptables

Запуск правил iptables после запуска docker

/etc/systemd/system/iptables.service

/etc/systemd/system/iptables.service

[Unit]
Description=iptables firewall service for ipsec & docker
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
ExecStart=/etc/ipsec.d/iptables.up
RemainAfterExit=true
ExecStop=/etc/ipsec.d/iptables.down
StandardOutput=journal

[Install]
WantedBy=multi-user.target
sudo systemctl enable iptables
sudo systemctl start iptables

ipsec

GUI

Примеры

Переместить рабочие данные docker в /data/var_lib_docker:

sudo systemctl stop docker.socket
sudo systemctl stop docker
sudo mv /var/lib/docker /data/var_lib_docker
sudo ln -s /data/var_lib_docker /var/lib/docker
sudo systemctl start docker

Показать размеры образов, контейнеров

docker system df

Показать IP контейнеров

docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' $(docker ps -aq)

https://stackoverflow.com/questions/17157721/how-to-get-a-docker-containers-ip-address-from-the-host

Показать точки монтирования контейнеров

docker inspect -f '{{ .Name }} - {{ range .Mounts }}{{ .Source }}:{{ .Destination }} {{ end }}' $(docker ps -aq)

https://stackoverflow.com/questions/30133664/how-do-you-list-volumes-in-docker-containers

Показать переменные контейнера

docker inspect --format='{{ join .Config.Env "\n" }} ${CONTAINERID}'

Показать путь до лог файла контейнера

docker inspect --format='{{.LogPath}}' container_name_or_id

https://stackoverflow.com/questions/41091634/how-to-clean-docker-container-logs

Показать Exposed порты в образе

docker inspect --format='{{.Config.ExposedPorts}}' ${IMAGENAME}

Интерактивный доступ

Запустить контейнер и получить интерактивный доступ:

docker run -it ubuntu

Запуск командной строки в контейнере (пример: tcagent1) и получить интерактивный доступ:

docker exec -i -t tcagent1 cmd

Запустить и удалить контейнер после выхода:

docker run --rm -it -e http_proxy="http://proxy.domain.com:3128" --name alpine-test alpine

Копирование файла в контейнер:

cat /tmp/acme.json | docker exec -i traefik_traefik.1.4q6h6pdj4283ydeech5tlt8ja sh -c "cat > /acme/acme.json"

Копирование файла между серверами по ssh в контейнер с промежуточного:

ssh server1 docker exec traefik_traefik.1.y1j17dqx7gx2plj5rbcaef3cz cat /acme/acme.json | ssh server2 docker exec -i traefik_traefik.1.4q6h6pdj4283ydeech5tlt8ja 'sh -c "cat > /acme/acme.json"'

Удаление

Удалить неиспользуемые кэши сборок, контейнеры, тома, сети, образы:

docker <system|builder|container|image|volume|network> prune

Удалить все неиспользуемые контейнеры, тома, сети, образы и кэш сборок:

docker system prune -a --volumes

https://docs.docker.com/config/pruning/
https://docs.docker.com/engine/reference/commandline/system_prune/

Запустить и удалить контейнер после остановки:

docker run --rm имя_контейнера

Другой способ

Другой способ

Удалить все остановленные контейнеры:

docker rm $(docker ps -a -f status=exited -q)

Удалить все образы:

docker rmi $(docker images -a -q)

Удалить недействительные образы (не имеют никакого отношения к образам с метками):

docker rmi $(docker images -f dangling=true -q)

Удалить неиспользуемые тома:

docker volume rm $(docker volume ls -qf dangling=true)

https://www.8host.com/blog/udalenie-obrazov-kontejnerov-i-tomov-docker/


Пример очистки старых образов в crontab:

0 0 * * 6 docker system prune --filter "until=72h" -f
1 0 * * 6 docker volume rm $(docker volume ls -q --filter dangling=true)

или:

0 0 * * * docker rm $(docker ps -a -f status=exited -q); docker rmi $(docker images -f dangling=true -q)
0 0 * * 1 docker volume rm $(docker volume ls -q --filter dangling=true)

С помощью bash

по тэгу и имени

по тэгу и имени

TAG=0
REPO=registry/services-standalone
IMAGES=(service1 service2 standalone1 standalone2)
for image in ${IMAGES[@]}; do docker rmi $REPO/$image:$TAG; done


по имени

по имени

docker rmi $(docker images | grep services-standalone | awk '{print $3}'


Сохранить сделанные изменения в запущенном контейнере

После сделанных изменений, выходим:

exit

Ключ -m позволяет задать комментарий коммита. Ключ -a позволяет указать автора коммита:

docker commit -m "What did you do to the image" -a "Author Name" container-id repository/new_image_name

Пример:

docker commit -m "add repo" -a "lioncub" d17f0027df77 domain/ubuntu_start

https://www.digitalocean.com/community/tutorials/docker-ubuntu-16-04-ru

Список соединений

Пример для кол-ва соединений TCP контейнера traefik на порт 443

Пример для кол-ва соединений TCP контейнера traefik на порт 443

TRAEFIKPID=$(docker container inspect -f "{{.State.Pid}}" $(docker ps -q -f name=traefik))
sudo nsenter -t $TRAEFIKPID -n ss -nt dst :443 | wc -l


Запуск приложений

Ansible
ASP.Net Core
Confluence
FreeRADIUS - FreeRADIUS с использованием MariaDB
GitLab
Graylog
HAProxy
MariaDB
MariaDB - MariaDB с репликацией Galera Cluster
mongoDB
nextcloud
Nginx
PHP-FPM - PHP-FPM с установленными gd, mcrypt и pear DB
Portainer
PostgreSQL
Samba - Samba Anonymous
Vault

Часовой пояс / timezone

Передать контейнеру часовой пояс хоста (на примере nginx):

docker run -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro --name nginx nginx:alpine

Монтирование NFS

Пример запуска контейнера с созданием volume:

docker run --rm --mount "src=dataset,dst=/data,volume-opt=device=:/data/dataset,\"volume-opt=o=addr=fs.domain.com,ro\",type=volume,volume-driver=local,volume-opt=type=nfs" alpine ls /data

Пример создания volume:

docker volume create --driver local --opt type=nfs --opt o=addr=fs.domain.com,ro --opt device=:/data/dataset --name dataset

Пример создания service mariadb в swarm:

docker service create -p 3306:3306 --mount type=volume,\"volume-opt=o=addr=fs.domain.com,nolock,ro\",volume-opt=device=:/data/docker/mariadb/var_lib_mysql,volume-opt=type=nfs,source=mariadb,target=/var/lib/mysql --name mariadb mariadb:10

https://docs.docker.com/engine/storage/volumes/
https://gist.github.com/ruanbekker/4a9c0d250bce9f84482f2a788ce92131
https://blog.dahanne.net/2017/11/20/docker-swarm-and-nfs-volumes/

Монтирование cifs

Создать volume с анонимным подключением:

docker volume create --driver local --opt type=cifs --opt device='//192.168.88.99/DatasetScans' --opt o='username=guest' dataset

для docker-compose:

docker-compose.yaml

docker-compose.yaml

volumes:
  dataset:
    driver: local
    driver_opts:
      type: cifs
      o: username=guest,ro
      device: "//192.168.88.99/DatasetScans"


для swarm:

docker-compose.yaml

docker-compose.yaml

volumes:
  dataset:
    driver: local
    driver_opts:
      type: cifs
      o: addr=192.168.88.99,username=guest,ro
      device: "//192.168.88.99/DatasetScans"


Предоставление учётных данных

https://stackoverflow.com/questions/22651647/docker-and-securing-passwords

  • .env файл в docker-compose
  • secrets в swarm
  • Vault хранилище секретов
  • credstash хранилище секретов (требуется AWS)

С помощью переменных в .env файле (значение по умолчанию TAG=latest):

$ cat .env
TAG=v1.5

$ cat docker-compose.yml
services:
  web:
    image: "webapp:${TAG-latest}"

Docker Registry

Альтернативы:

Репозитроий для docker images

Запустить репозиторий:

docker run -d -p 5000:5000 --name registry registry:2

или для последующего запуска в автоматическом режиме:

docker run -d -p 5000:5000 --restart=always --name registry registry:2

Загрузка образа из хаба в репозиторий:

docker pull ubuntu
docker image tag ubuntu localhost:5000/myfirstimage
docker push localhost:5000/myfirstimage

Получить образ из репозитория:

docker pull localhost:5000/myfirstimage

Остановить репозиторий и удалить все данные:

docker container stop registry && docker container rm -v registry

https://docs.docker.com/registry/

HTTP registry

Незащищённый режим

Добавить внешний IP на который Registry будет принимать запросы:

echo '{ "insecure-registries":["172.17.0.1:5000"] }' | sudo tee -a /etc/docker/daemon.json

https://docs.docker.com/registry/insecure/

Docker in Docker

Пример запуска dind без tls и с подключением по tcp:

docker run -d --restart always \
  -e DOCKER_HOST=tcp://172.17.0.1:2375 \
  -e DOCKER_TLS_CERTDIR="" \
  -e HTTPS_PROXY=http://d2proxy.domain.loc:3128 \
  -e HTTP_PROXY=http://d2proxy.domain.loc:3128 \
  -e NO_PROXY=localhost,127.0.0.1,.domain.loc \
  -v /data/docker/dind/var_lib_docker:/var/lib/docker \
  --privileged \
  --name dind docker:dind \
  --storage-driver=overlay2 --insecure-registry=registry.git.domain.loc:5005

Пример запуска dind c tls и с подключением к сокету:

docker run -d --restart always \
  -e HTTPS_PROXY=http://d2proxy.domain.loc:3128 \
  -e HTTP_PROXY=http://d2proxy.domain.loc:3128 \
  -e NO_PROXY=localhost,127.0.0.1,.domain.loc \
  -v /data/docker/dind/certs:/certs \
  -v /data/docker/dind/var_lib_docker:/var/lib/docker \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --privileged \
  --name dind docker:dind \
  --storage-driver=overlay2 --insecure-registry=registry.git.domain.loc:5005

https://hub.docker.com/_/docker

Dockerfile

https://docs.docker.com/engine/reference/builder/

Создать образ dkbubuntu с тэгом 16.04 в локальном репозитории localhost:5000 из dkbubuntu/Dockerfile:

docker build -t localhost:5000/dkbubuntu:16.04 dkbubuntu

Установить часовой пояс в контейнере как на хосте:

 -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro

Отображение информации

 --progress plain
#или
export BUILDKIT_PROGRESS=plain
export DOCKER_BUILDKIT=0

Syntax

Добавить возможность include в Dockerfile:

Test

Test

Dockerfile.base:

FROM alpine
RUN echo "Hello World"
ENTRYPOINT ["echo", "End!"]

Dockerfile.plus:

# syntax = edrevo/dockerfile-plus
FROM alpine
INCLUDE+ Dockerfile.base
ENTRYPOINT [ "echo", "include" ]

Dockerfile.x:

# syntax = devthefuture/dockerfile-x
FROM alpine
INCLUDE Dockerfile.base
#- MultipleInstructionsDisallowed: Multiple ENTRYPOINT instructions should not be used in the same stage because only the last one will be used (line 5)
#ENTRYPOINT [ "echo", "include" ]

Собрать и запустить:

docker build -t test.plus -f Dockerfile.plus .
docker build -t test.x -f Dockerfile.x .
docker run --rm test.plus
docker run --rm test.x

Удалить:

docker rmi test.plus test.x


Docker Compose

Запустить

Исключая сервис:

docker compose up --scale serviceName=0

Используя профили - https://docs.docker.com/compose/profiles/

Docker Swarm mode

  • docker node - Управление Swarm нодами

Инициализация swarm:

docker swarm init

Показать токен для подключения worker:

docker swarm join-token worker -q

https://docs.docker.com/reference/cli/docker/swarm/init/
https://docs.docker.com/engine/swarm/ingress/

Запустить docker-compose.yaml:

docker stack deploy --compose-file docker-compose.yaml name

Запустить alpine как сервис test:

docker service create -t --name test alpine

Перезагрузка

Показать сервисы в стэке (для определения ID):

docker stack services NameStack

Перегрузить сервис по ID:

docker service update --force ID

Обновление

Обновить сервис на определённый образ из приватного реестра:

docker service update --update-failure-action rollback --with-registry-auth --image RegistryHost/Image:Tag Name_Service

Переменные

Использовать переменные из .env файла:

env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy -c docker-compose.yml Name_Stack

Docker Mirror

Debug

Лимиты dockerd:

cat /proc/$(pidof dockerd)/limits

Ошибки

WARNING! Your password will be stored unencrypted in /home/***/.docker/config.json

Ссылки

Checks / Scanners

https://github.com/goodwithtech/dockle - Container Image Linter for Security
trivy - Vulnerability Scanner for Containers and other Artifacts, Suitable for CI
https://www.zaproxy.org/docs/docker/about/ - Docker image with Zed Attack Proxy preinstalled

how-to/docker.txt · Последнее изменение: lioncub