Иногда требуется запустить docker в lxc, например, для установки Docker Swarm, или для установки Kubernetos. LXC позволяет запускать Docker внутри контейнера. Рекомендуется использовать хост машину Ubuntu 18.04.
Перейдите по ссылке, если вас интересует обычная настройка Docker Swarm .
Перейдите по ссылке, если вас интересует настройка Docker Swarm в LXC .
Прежде чем начать:
- выполните базовую настройку Ubuntu
- обновите ядро системы до версии 5.3
- установите LXC на Ubuntu по инструкции
На хост машине добавьте драйвера br_netfilter в автозагрузку:
_x000D_echo overlay >> /etc/modules-load.d/docker.conf_x000D_echo br_netfilter >> /etc/modules-load.d/docker.conf Для того, чтобы запустить Docker в LXC нужно выполнить следующие действия:
- запустить контейнер в privileged mode
- включить мод lxc nested containers
Запуск контейнера в privileged mode
Privileged mode — это привелигированный режим, запуск контейнера от рута.
Перед установкой контейнера, нужно закоментировать строки в файле /etc/lxc/default.conf . Комментировать строки, нужно только при установке контейнера, который вы хотите, чтобы он работал в привелигированном режиме.
_x000D_#lxc.idmap = u 0 100000 65536_x000D_#lxc.idmap = g 0 100000 65536 Это позволит установить контейнер под рутом.
Выполните команду установки контейнера для Centos 7:
_x000D_lxc-create -t download -n docker0 -- --dist centos --release 7 --arch amd64 Для Ubuntu 20.04
_x000D_lxc-create -t download -n docker0 -- --dist ubuntu --release focal --arch amd64 Для Ubuntu 22.04:
_x000D_lxc-create -t download -n test-ubuntu -- --dist ubuntu --release bionic --arch amd64 Для Ubuntu 24.04:
_x000D_lxc-create -t download -n test-ubuntu -- --dist ubuntu --release noble --arch amd64 Затем нужно обязательно раскоментировать эти строки обратно в файле /etc/lxc/default.conf
_x000D_lxc.idmap = u 0 100000 65536_x000D_lxc.idmap = g 0 100000 65536 Настройка сети
Рекомендуется для LXC использовать сеть 172.30.0.1/24. Более подробный список указан в списке сетей .
В файле /etc/default/lxc-net пропишите
_x000D_USE_LXC_BRIDGE="true"_x000D_LXC_BRIDGE="lxcbr0"_x000D_LXC_ADDR="172.30.0.1"_x000D_LXC_NETMASK="255.255.255.0"_x000D_LXC_NETWORK="172.30.0.0/24"_x000D_LXC_DHCP_RANGE="172.30.0.2,172.30.0.254"_x000D_LXC_DHCP_MAX="253"_x000D_LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf_x000D_#LXC_DOMAIN="lxc" Создайте файл /etc/lxc/dnsmasq.conf и пропишите в нем:
_x000D_port=53_x000D_listen-address=172.30.0.1_x000D_resolv-file=/etc/resolv.conf_x000D_domain-needed_x000D_no-dhcp-interface=_x000D_interface=lxcbr0_x000D_except-interface=eth*_x000D_except-interface=enp*_x000D_except-interface=wlan*_x000D_except-interface=wlp*_x000D_except-interface=virbr0_x000D_except-interface=fan-* Настройка конфига LXC контейнера
Nested контейнер — это возможность запустить контейнер в контейнере (вложенные контейнеры). Чтобы включить данную опцию, нужно внести изменения в конфиг LXC контейнера.
Опция включается в файле конфига контейнера /var/lib/lxc/<название контейнера>/config
Раскоментируйте строчку:
_x000D_#lxc.include = /usr/share/lxc/config/nesting.conf Пропишите параметры сети:
_x000D_lxc.net.0.ipv4.address = 172.30.0.20/24_x000D_lxc.net.0.ipv4.gateway = 172.30.0.1 Также вам понадобится прописать параметры для монтирования файловой системы cgroup и отключения AppArmor в контейнере
_x000D_lxc.mount.auto = cgroup-full:rw_x000D_lxc.apparmor.profile = unconfined_x000D_lxc.cgroup.devices.allow = a_x000D_lxc.cap.drop = Для Ubuntu в файле /var/lib/lxc/<название контейнера>/rootfs/etc/netplan/10-lxc.yaml укажите:
_x000D_network:_x000D_ version: 2_x000D_ ethernets:_x000D_ eth0:_x000D_ dhcp4: no_x000D_ dhcp6: no_x000D_ addresses: [172.30.0.20/24]_x000D_ gateway4: 172.30.0.1_x000D_ nameservers:_x000D_ addresses: [172.30.0.1]_x000D_ Настройка доступа к видеокарте
Для доступа к видеокарте nvidia в конфиге контейнера укажите строки:
_x000D_# GPU_x000D_lxc.cgroup.devices.allow = c 195:* rwm_x000D_lxc.cgroup.devices.allow = c 243:* rwm_x000D_lxc.cgroup.devices.allow = c 510:* rwm_x000D_lxc.cgroup2.devices.allow = c 195:* rwm_x000D_lxc.cgroup2.devices.allow = c 243:* rwm_x000D_lxc.cgroup2.devices.allow = c 510:* rwm_x000D_lxc.mount.entry = /dev/nvidia0 dev/nvidia0 none bind,optional,create=file_x000D_lxc.mount.entry = /dev/nvidiactl dev/nvidiactl none bind,optional,create=file_x000D_lxc.mount.entry = /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file_x000D_lxc.mount.entry = /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file_x000D_lxc.mount.entry = /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file_x000D_ Настройка ssh сервера
1) Вместо /home/user укажите вашу домашнюю папку.
_x000D_mkdir /var/lib/lxc/<название контейнера>/rootfs/home/ubuntu/.ssh_x000D_cat /home/user/.ssh/id_rsa.pub >> /var/lib/lxc/<название контейнера>/rootfs/home/ubuntu/.ssh/authorized_keys_x000D_chmod 700 /var/lib/lxc/<название контейнера>/rootfs/home/ubuntu/.ssh_x000D_chmod 600 /var/lib/lxc/<название контейнера>/rootfs/home/ubuntu/.ssh/authorized_keys_x000D_chown -R 1000:1000 /var/lib/lxc/<название контейнера>/rootfs/home/ubuntu/.ssh 2) Запустите контейнер и подключитесь к нему:
_x000D_lxc-start <название контейнера>_x000D_lxc-attach <название контейнера> 3) Разрешите пинг
_x000D_sudo setcap cap_net_raw+ep /bin/ping 4) Установите ssh сервер:
_x000D_apt-get update_x000D_apt-get install openssh-server 5) Подключитесь к контейнеру через ssh
Откройте терминал под текущим пользователем (не рут) и подключитесь к системе:
_x000D_ssh ubuntu@172.30.0.20 Если сертификат установлен верно, то должно подключиться без пароля.
Настройка контейнера Ubuntu 24.04
1) Установите программы:
_x000D_apt update_x000D_apt install aptitude mc nano htop iftop bwm-ng iperf iperf3 iotop tmux screen net-tools rsync jq 2) Настройка DNS
Выполните
_x000D_rm /etc/resolv.conf_x000D_nano /etc/resolv.conf Укажите следующие настройки
_x000D_nameserver 127.0.0.53_x000D_options edns0 trust-ad_x000D_ndots:1_x000D_search . 3) Отключите apparmor в LXC контейнере
_x000D_systemctl stop apparmor_x000D_systemctl disable apparmor 4) Установите локаль. Раскоментируйте строки в файле /etc/locale.gen
_x000D_en_US.UTF-8 UTF-8_x000D_ru_RU.UTF-8 UTF-8 Пропишите локаль на уровне системы:
nano /etc/profile.d/0.locale.sh
_x000D_export LANG="en_US.UTF-8"_x000D_export LANGUAGE="en_US:en"_x000D_export LC_CTYPE="en_US.UTF-8"_x000D_export LC_NUMERIC="en_US.UTF-8"_x000D_export LC_TIME="en_US.UTF-8"_x000D_export LC_COLLATE="en_US.UTF-8"_x000D_export LC_MONETARY="en_US.UTF-8"_x000D_export LC_MESSAGES="en_US.UTF-8"_x000D_export LC_PAPER="en_US.UTF-8"_x000D_export LC_NAME="en_US.UTF-8"_x000D_export LC_ADDRESS="en_US.UTF-8"_x000D_export LC_TELEPHONE="en_US.UTF-8"_x000D_export LC_MEASUREMENT="en_US.UTF-8"_x000D_export LC_IDENTIFICATION="en_US.UTF-8"_x000D_ Пересоздайте локаль:
_x000D_locale-gen 5) Установите ssh сервер:
_x000D_aptitude install openssh-server 6) Ограничьте размер логов systemd
Пропишите в /etc/systemd/journald.conf строчку:
_x000D_SystemMaxUse=1G Это строчка ограничивает максимальный размер логов в 1 гигабайт.
Перезагрузите конфигурацию systemd:
_x000D_systemctl daemon-reload 7) Сделайте sudo su -l без ввода пароля
Добавьте группу wheel
_x000D_groupadd -r wheel_x000D_usermod -a -G wheel ubuntu Создайте файл /etc/sudoers.d/wheel
_x000D_%wheel ALL=(ALL:ALL) NOPASSWD: ALL Все пользователи, которые находятся в группе wheel будут иметь возможность выполнять команды рут без пароля
8) Установите iptables
_x000D_aptitude install iptables-persistent Обязательно включите NAT, если вы хотите использовать Docker или LXC
_x000D_echo 1 > /proc/sys/net/ipv4/ip_forward_x000D_echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ip_forward.conf При работе с iptables будьте осторожны.
Одно неверное движение и доступ к серверу может быть заблокирован!!!
Пример конфига /etc/iptables/rules.v4
_x000D_*filter_x000D_:INPUT ACCEPT [19:913]_x000D_:FORWARD ACCEPT [0:0]_x000D_:OUTPUT ACCEPT [39:3584]_x000D_:ALLOW-INPUT - [0:0]_x000D_:f2b-sshd - [0:0]_x000D__x000D_-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT_x000D_-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT_x000D_-A INPUT -p icmp -j ACCEPT_x000D_-A INPUT -i lo -j ACCEPT_x000D__x000D_# Fail2Ban SSH_x000D_#-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd_x000D__x000D_# Разрешаем входящие соединения ssh_x000D_-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT_x000D__x000D_# Перейти к цепочке ALLOW-INPUT_x000D_-A INPUT -j ALLOW-INPUT_x000D__x000D_# Запрещаем остальные входящие соединения_x000D_-A INPUT -j REJECT_x000D_-A FORWARD -j REJECT_x000D__x000D_# Раскомментируйте, если нужно запретить все исходящие соединения _x000D_#-A OUTPUT -j REJECT_x000D__x000D_# Разрешить http_x000D_-A ALLOW-INPUT -p tcp -m tcp --dport 80 -j ACCEPT_x000D_-A ALLOW-INPUT -p tcp -m tcp --dport 443 -j ACCEPT_x000D_-A ALLOW-INPUT -j RETURN_x000D__x000D_# Fail2ban_x000D_-A f2b-sshd -j RETURN_x000D__x000D_COMMIT Скопируйте этот же конфиг в /etc/iptables/rules.v6
_x000D_cp /etc/iptables/rules.v4 /etc/iptables/rules.v6 9) Перезагрузите контейнер:
_x000D_init 6 Установка Docker на Centos 7
Запустите контейнер и войдите в него:
_x000D_lxc-start <название контейнера>_x000D_lxc-attach <название контейнера> Установите docker и включите автозапуск:
_x000D_yum install -y yum-utils_x000D_yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo_x000D_yum install -y docker-ce docker-ce-cli containerd.io_x000D__x000D_systemctl enable docker_x000D_systemctl start docker Установка Docker на Ubuntu 24.04
Установите Docker
_x000D_sudo aptitude install docker.io Альтернативный способ
_x000D_curl -sSL https://get.docker.com | sh_x000D_systemctl enable docker_x000D_systemctl start docker Настройка Docker
Для хранения логов рекомендуется journald. В файле /etc/docker/daemon.json пропишите:
_x000D_{_x000D_ "log-driver": "json-file",_x000D_ "log-opts": {_x000D_ "max-size": "10m",_x000D_ "max-file": "1"_x000D_ }_x000D_} Можно также добавить строчки
_x000D_"max-concurrent-uploads": 1,_x000D_"max-concurrent-downloads": 1, Они позволяют ограничить количество потоков на загрузку докер образов. По умолчанию 3 потока.
Перезапустите докер
_x000D_service docker restart Проверьте запущен ли докер:
_x000D_docker ps Если выдает ошибку, значит проблема в файле /etc/docker/daemon.json . Пересоздайте его. Возможно в нем скопировались невидимые символы.
Добавьте в группу docker пользователя ubuntu чтобы он мог управлять docker
_x000D_usermod -a -G docker ubuntu В крон через команду sudo crontab -e пропишите команду, которая будет автоматически очищать контейнеры
_x000D_0 */2 * * * docker system prune --filter "until=24h" -f -a > /dev/null_x000D_0 */2 * * * docker image prune --filter "until=168h" -f > /dev/null_x000D_ После установки, скачайте тестовый контейнер и убедитесь что он работает:
_x000D_docker pull alpine_x000D_docker run -it -d --name test alpine /bin/sh Выполните команду docker ps , должно вам выдать:
_x000D_root@docker0:/# docker ps_x000D_CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES_x000D_93f0d96197e0 alpine "/bin/sh" 28 seconds ago Up 25 seconds test Проверьте работу контейнера:
_x000D_root@docker0:/# docker exec -it test ping google.com_x000D_PING google.com (64.233.164.101): 56 data bytes_x000D_64 bytes from 64.233.164.101: seq=0 ttl=42 time=222.140 ms_x000D_64 bytes from 64.233.164.101: seq=1 ttl=42 time=140.911 ms_x000D_^C_x000D_--- google.com ping statistics ---_x000D_2 packets transmitted, 2 packets received, 0% packet loss_x000D_round-trip min/avg/max = 140.911/181.525/222.140 ms_x000D__x000D_root@docker0:/# docker exec -it test ifconfig_x000D_eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02_x000D_ inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0_x000D_ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1_x000D_ RX packets:34 errors:0 dropped:0 overruns:0 frame:0_x000D_ TX packets:33 errors:0 dropped:0 overruns:0 carrier:0_x000D_ collisions:0 txqueuelen:0_x000D_ RX bytes:3728 (3.6 KiB) TX bytes:3293 (3.2 KiB)_x000D__x000D_lo Link encap:Local Loopback_x000D_ inet addr:127.0.0.1 Mask:255.0.0.0_x000D_ UP LOOPBACK RUNNING MTU:65536 Metric:1_x000D_ RX packets:0 errors:0 dropped:0 overruns:0 frame:0_x000D_ TX packets:0 errors:0 dropped:0 overruns:0 carrier:0_x000D_ collisions:0 txqueuelen:1000_x000D_ RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) Возникаемые ошибки
Если возникают ошибки:
_x000D_docker: Error response from daemon: Could not check if _x000D_docker-default AppArmor profile was loaded: open _x000D_/sys/kernel/security/apparmor/profiles: permission denied. _x000D_failed to register layer: Error processing tar file(exit status 1): _x000D_remount /, flags: 0x84000: permission denied _x000D_docker: Error response from daemon: OCI runtime create failed: _x000D_container_linux.go:345: starting container process caused _x000D_"process_linux.go:430: container init caused "process_linux.go:396: _x000D_setting cgroup config for procHooks process caused \""_x000D_failed to write c 10:200 rwm to devices.allow: write /sys/fs/cgroup/devices/docker/27822e65d0ccd42267cd420309f1de3ea2ddfc353d18d9ab9d362b0549b43ed0/devices.allow: _x000D_operation not permitted\"""""": unknown._x000D_ То это скорее всего связано с AppArmor. Сделайте tail -n 20 /var/log/syslog. Если в логе присутсвуют следующие строки:
_x000D_Jul 16 23:49:04 alfabook kernel: _x000D_[45843.968279] audit: type=1400 audit(1563299344.593:66): _x000D_apparmor=""DENIED"" operation=""mount"" info=""failed flags match"" _x000D_error=-13 profile=""lxc-container-default-cgns"" name=""/"" _x000D_pid=5274 comm=""exe"" flags=""rw