User Tools

Site Tools


технология_docker

Технология Docker

Методические идеи

  • Добавить запись в журнал передаваемых скрипту webd заголовков
  • Использовать переменную окружения, передаваемую контейнеру для включения/выключения режима отладки/записи в журнал

Установка

Ubuntu/Debian

Настройка registry-mirrors

# cat /etc/docker/daemon.json
{
  "registry-mirrors": ["https://mirror.gcr.io"]
}

Настройка загрузки образов через proxy

# systemctl edit docker.service
...
[Service]
#Environment="http_proxy=http://proxy.isp.un:3128/"
Environment="https_proxy=http://proxy.isp.un:3128/"
Environment="no_proxy=localhost,127.0.0.1,isp.un,corpX.un"
...
# systemctl daemon-reload

# service docker restart

Тестирование установки

# systemctl status docker

# docker info

# docker run hello-world

# docker events --since '10m'

Предоставление прав непривилегированным пользователям

# usermod -aG docker gitlab-runner

# su - gitlab-runner

Работа с образами и контейнерами

Обзор и удаление

# docker images

# docker ps -a #--size
# docker container ls -a
# docker container stats

# docker start -i NNNNNNNNNNN

# docker rm $(docker ps -aq)

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

# docker rmi hello-world

# docker rmi -f $(docker images -aq)

# docker system df

# docker system prune
# docker system prune -a --volumes

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

root@webinar:~# docker cp ca.crt greenlight-v3:/usr/local/share/ca-certificates/

root@webinar:~# docker exec -ti greenlight-v3 /usr/sbin/update-ca-certificates

root@webinar:~# docker exec greenlight-v3 wget -O /dev/null https://keycloak.corp13.un

root@webinar:~# docker commit greenlight-v3 bigbluebutton/greenlight:v3

Создание образа для приложения вручную

server# docker run -it --name webd --hostname webd debian bash

webd# apt update && apt install file procps nano
webd/# cat start.sh
#!/bin/sh

/etc/init.d/inetutils-inetd start

bash
  • Ctrl+D
server# docker ps -a

server# docker diff webd
  • Методически, “вспомнили”, что “забыли” сделать скрипт start.sh “выполнимым”
server# docker start webd

server# docker attach webd

root@webd:/# chmod +x start.sh
  • Методически, можно уже на этом этапе: запустить скрипт ./start.sh, отключится от контейнера без его остановки Ctrl+P, Q(still holding Ctrl), выяснить через docker inspect webd назначенный контейнеру ip, проверить через curl работу приложения и, если все работает (правда, будет сообщение, что такого файла нет), сделать docker stop webd, и commit
server# docker commit webd test/webd

gitlab-runner@server:~$ docker images

Создание образа для приложения с использованием Dockerfile

Приложение bash webd

server# mkdir -p /root/webd/ && cd /root/webd/
  или
gitlab-runner@server:~$ mkdir -p ~/webd/webd/ && cd ~/webd/webd/

server# cp /usr/local/sbin/webd .
lan:~/webd# scp server:/usr/local/sbin/webd .
или
gitlab-runner@server:~/webd/webd$ nano webd      # добавляем закомментированные строки

server# ###tar -cvzf www.tgz -C /var/ www/

server# cat start.sh
#!/bin/sh

/etc/init.d/inetutils-inetd start

touch /var/log/webd.log
#chown 10003 /var/www/
  
if [ "$MYMODE" = 'TEST' ]; then
  sleep 3
  curl localhost && exit 0 || exit 1
else
  tail -f /var/log/webd.log
fi
server# cat Dockerfile
#FROM debian
FROM debian:bullseye
#FROM debian:bookworm

RUN cp /usr/share/zoneinfo/Etc/GMT-3 /etc/localtime \
    && apt-get update \
    && apt-get install -y inetutils-inetd file curl\
    && apt-get clean \
    && echo 'www stream tcp nowait root /usr/local/sbin/webd webd' > /etc/inetd.conf

COPY start.sh /
COPY webd /usr/local/sbin/webd
### ADD www.tgz /var/

### for helm readiness/liveness Probe 
### COPY index.html /var/www/

EXPOSE 80
#ENV MYMODE=TEST

ENTRYPOINT ["/start.sh"]
# docker build -t test/webd .

# docker run --rm -e MYMODE=TEST test/webd

# docker history test/webd

Приложение python pywebd

:~/pywebd$ dpkg -l | grep python 

:~/pywebd$ cat Dockerfile
FROM python:3.11-alpine

#RUN pip install --root-user-action=ignore --upgrade pip

#RUN adduser -D myuser
#USER myuser
#WORKDIR /home/myuser

COPY requirements.txt .
#COPY --chown=myuser:myuser requirements.txt .

#ENV PATH="/home/myuser/.local/bin:${PATH}"

RUN pip install -r requirements.txt
#RUN pip install --user -r requirements.txt

COPY . .
#COPY --chown=myuser:myuser . .

ENTRYPOINT ["python"]
CMD ["app.py"]
:~/pywebd$ time docker build -t pywebd .

:~/pywebd$ docker run -d --rm -p 8080 --name pywebd01 pywebd

Приложение golang gowebd

Dockerfile Multistage Building
student@client1:~/gowebd$ cat Dockerfile
FROM golang
#FROM golang as builder

WORKDIR /build
COPY . .
RUN test -e go.mod || go mod init gowebd

#ENV CGO_ENABLED=0
RUN go build -o /gowebd

#FROM alpine
#COPY --from=builder /gowebd /gowebd

ENTRYPOINT ["/gowebd"]
student@client1:~/gowebd$ docker images

student@client1:~/gowebd$ time docker build -t gowebd .
real    6m2.564s

student@client1:~/gowebd$ docker run -d -p 8080:80 --rm gowebd

student@client1:~/gowebd$ docker run -d --rm -p 80 --name gowebd01 gowebd
docker buildx
ubuntu:~/gowebd# apt install docker-buildx

ubuntu:~/gowebd# cat Dockerfile
...
RUN --mount=type=cache,target="/root/.cache/go-build" go build -o /gowebd
...
ubuntu:~/gowebd# time docker build -t gowebd .

Запуск в режиме демона и подключение к контейнеру

1-й пример - запуск образа сделанного “вручную”, можно запустить несколько экземпляров с -p 80 выяснить назначенные порты, настроить keepalived и провести нагрузочное тестирование

server# docker run --name webd01 --hostname webd01 -itd -v /var/www/:/var/www/ -p 8000:80 test/webd /start.sh

2-й пример - через Dockerfile задан entrypoint и expose, ключ –rm для удаления контейнера после остановки, добавить, при необходимости, -v

server# docker run --name webd01 -e MYMODE=TEST -itd --rm -P test/webd

3-й раз - запустить несколько экземпляров, указав параметры для подключения внешнего каталога /var/www/, выяснить назначенные порты, настроить keepalived, по журналам определять какой контейнер используется

Процессы контейнера и системы

server# docker top webd01

server# ps axw | grep inetd
server# ps axw | grep start.sh

server# cat /proc/<PID>/cgroup
server# systemd-cgls

cgroup-v1# cat /sys/fs/cgroup/memory/docker/NNNNNNNNNNNNNNNNNNNNNNNNNNNNN/memory.max_usage_in_bytes
cgroup-v2# cat /sys/fs/cgroup/system.slice/docker-NNNNNNNNNNNNNNNNNNNNNNNNNNNNN.scope/memory.max

server# docker stats

server# lsns | grep start.sh

Анализ параметров запущенного контейнера

server# docker inspect webd01

server# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' webd01 

server# wget -qO - http://172.17.0.2/
server$ curl --noproxy '*' http://172.17.0.2/

server# docker port webd01

server# docker logs webd01

node1# docker logs webd01 -f

server# wget -qO - http://localhost:8000/
server$ curl http://localhost:8000
server$ curl http://localhost:8000/not_exit_file

host browser -> http://server.corpX.un:8000/

server# docker attach webd01 

server# docker exec -it webd01 bash

webd01# ps ax
  или
webd01# ls /proc/
webd01# cat /proc/1/cmdline

webd01# ss -tpan
  или
webd01# cat /proc/net/tcp
webd01# cat /proc/net/tcp6

Ctrl+P, Q(still holding Ctrl)

server# docker stop webd01

server# docker inspect webd01

server# docker start webd01

host browser -> http://server.corpX.un:8000/

server# docker stop webd01 && docker rm webd01

Использование готовых образов приложений

atmoz/sftp

# docker search sftp

# chown -R 10003 /var/www

# docker run --name sftp01 -v /var/www:/home/user3/www -p 2222:22 -d atmoz/sftp user3:password3:10003

# docker exec -it sftp01 bash

Ctrl+D

# docker top sftp01

# sftp -P 2222 user3@localhost
# docker logs sftp01

# docker stop sftp01

# docker rm sftp01

docker-compose

# apt install docker-compose

# cat docker-compose.yml
version: "3"
services:
  webd:
#    image: server.corpX.un:5000/student/webd:ver1.N
    image: test/webd
#    build: webd/
    entrypoint: /start.sh
#    ports:
#      - "80"
    volumes:
      - /var/www/:/var/www/
#      - vol1:/var/www/
    deploy:
      mode: replicated
      replicas: 3

#    environment:
#      - MYMODE=TEST
#    stdin_open: true
    tty: true

  sftp:
    image: atmoz/sftp
    ports:
      - "2222:22"
    volumes:
      - /var/www/:/home/user3/www
#      - vol1:/home/user3/www
    command: user3:password3:10003
#volumes:
#  vol1:
# ###docker-compose build

# docker-compose up -d

# docker-compose stop

# docker-compose start

# docker-compose down

# docker-compose rm

# docker volume rm root_vol1

# docker-compose up -d --scale webd=N

# docker ps
gitlab-runner@server:~/webd$ cat docker-compose.yml
version: "3"
services:
  webd:
    image: server.corpX.un:5000/student/webd:ver1.N
    ports:
      - "80"
    volumes:
      - /var/www/:/var/www/
    deploy:
      mode: replicated
      replicas: 3
node1,2,3# docker-compose --compatibility up -d

node1,2,3# docker-compose --compatibility down

node1,2,3# docker ps -q | xargs -l docker port | sort -n

Локальные репозитории

Копирование образов

server# docker save -o test-webd.tgz test/webd

lan# scp server:test-webd.tgz .

lan# docker load -i test-webd.tgz

Insecure Private Registry

# cat /etc/docker/daemon.json
{
  "insecure-registries" : ["server.corpX.un:5000"]
}
# service docker restart

Аутентификация в Registry

gitlab-runner@server:~$ docker login

gitlab-runner@server:~$ docker login http://server.corpX.un:5000

gitlab-runner@server:~$ less ~/.docker/config.json
{
        "auths": {
                "server.corpX.un:5000": {
                        "auth": "c3R1ZGVudDpQYSQkdzByZA=="
                }
        }
}

Использование Private Registry

gitlab-runner@server:~$ docker images

gitlab-runner@server:~$ docker tag test/webd server.corpX.un:5000/student/webd
gitlab-runner@server:~$ docker tag test/webd server.corpX.un:5000/student/webd:1.1

gitlab-runner@server:~$ docker images

gitlab-runner@server:~$ docker push server.corpX.un:5000/student/webd
gitlab-runner@server:~$ docker push server.corpX.un:5000/student/webd:1.1
...
node1_2_3# docker run --name webd01 --hostname webd01 -itd --rm -p 8000:80 server.corpX.un:5000/student/webd

node1_2_3# docker run --name webd0N --hostname webd0N -itd --rm -P -v /var/www/:/var/www/ server.corpX.un:5000/student/webd

Использование образа Docker Registry on-premise

# docker run -d -p 5000:5000 -v /root:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/wild.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/wild.key \
  --name registry --restart=always registry:2

# docker tag gowebd server.corp13.un:5000/student/gowebd

# docker push server.corp13.un:5000/student/gowebd

# curl https://server.corp13.un:5000/v2/_catalog
{"repositories":["student/gowebd"]}

# curl https://server.corp13.un:5000/v2/student/gowebd/tags/list

Дополнительная информация

Инструмент kaniko

~/gowebd# time docker run \
  -v $(pwd):/workspace --rm\
  gcr.io/kaniko-project/executor:latest \
  --skip-tls-verify --log-timestamp\
  --dockerfile=./Dockerfile \
  --context=/workspace \
  --destination=server.corp13.un:5000/student/gowebd \
  --cache=true --cache-copy-layers --cache-repo server.corp13.un:5000/dev-cache --use-new-run \
  --verbosity debug
или, интерактивно:
root@ubuntu:~/gowebd# docker run -it \
  -v $(pwd):/workspace --rm --entrypoint "/bin/sh" \
  gcr.io/kaniko-project/executor:debug 

# time /kaniko/executor --skip-tls-verify --log-timestamp \
  --dockerfile=./Dockerfile \
  --context=/workspace \
  --destination=server.corp13.un:5000/student/gowebd
тестируем результат:
# docker run --pull=always --name gowebd -itd --rm \
  -p 8000:80 server.corp13.un:5000/student/gowebd

Приложение apwebd

~/apwebd$ cat Dockerfile
FROM debian:bookworm

RUN cp /usr/share/zoneinfo/Etc/GMT-3 /etc/localtime \
    && apt-get update \
    && apt-get install -y findutils gettext-base apache2 libapache2-mod-auth-openidc \
    && apt-get clean \
    && a2enmod cgid \
    && a2enmod auth_openidc

COPY rootfs/ /

EXPOSE 80

ENTRYPOINT ["/start.sh"]
~/apwebd$ find rootfs/ -type f | xargs tail -n +1
==> rootfs/var/www/html/index.html.apwebd-template <==
<HTML>
  <HEAD>
    <META HTTP-EQUIV="Refresh" CONTENT="10;URL=/cgi-bin/apwebd/">
  </HEAD>
  <BODY text="blue">
    <H1><A HREF=/cgi-bin/apwebd/>Login to ${APWEBD_HOSTNAME}</A></H1>
    Version: 1.2
  </BODY>
</HTML>
==> rootfs/start.sh <==
#!/bin/sh

[ "$APWEBD_HOSTNAME" ] || { echo Please set env APWEBD_HOSTNAME; exit; }
[ "$KEYCLOAK_HOSTNAME" ] || { echo Please set env KEYCLOAK_HOSTNAME; exit; }
[ "$REALM_NAME" ] || { echo Please set env REALM_HOSTNAME; exit; }

find / -type f -name '*.apwebd-template' | while read -r FILE; do envsubst < "$FILE" > "${FILE%.apwebd-template}"; done

/etc/init.d/apache2 start

tail -f /var/log/apache2/error.log -f /var/log/apache2/access.log
==> rootfs/etc/apache2/conf-available/serve-cgi-bin.conf.apwebd-template <==
<IfModule mod_alias.c>
        <IfModule mod_cgi.c>
                Define ENABLE_USR_LIB_CGI_BIN
        </IfModule>

        <IfModule mod_cgid.c>
                Define ENABLE_USR_LIB_CGI_BIN
        </IfModule>

        <IfDefine ENABLE_USR_LIB_CGI_BIN>

                OIDCSSLValidateServer Off
                OIDCProviderMetadataURL https://${KEYCLOAK_HOSTNAME}/realms/${REALM_NAME}/.well-known/openid-configuration
                OIDCRedirectURI http://${APWEBD_HOSTNAME}/cgi-bin/apwebd
                OIDCClientID any-client
                OIDCCryptoPassphrase anystring

                ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
                <Directory "/usr/lib/cgi-bin">
                        AllowOverride None
                        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
#                       Require all granted
                        AuthType openid-connect
                        Require valid-user
                </Directory>
        </IfDefine>
</IfModule>
==> rootfs/usr/lib/cgi-bin/apwebd <==
#!/bin/sh

echo Content-type: text/html
echo

echo "<h1 style=\"color:blue;\">Hello ${OIDC_CLAIM_preferred_username}</h1>"

echo "<pre>"; env; echo "</pre>"
~/apwebd# chmod +x rootfs/usr/lib/cgi-bin/apwebd rootfs/start.sh

~/apwebd$ docker build -t server.corp13.un:5000/student/apwebd:ver1.2 .

~/apwebd$ docker run -e APWEBD_HOSTNAME=apwebd.corp13.un -e KEYCLOAK_HOSTNAME=keycloak.corp13.un -e REALM_NAME=corp13 -itd --rm -P server.corp13.un:5000/student/apwebd:ver1.2

~/apwebd$ docker run -e APWEBD_HOSTNAME=apwebd.corp13.un -e KEYCLOAK_HOSTNAME=keycloak.corp13.un -e REALM_NAME=corp13 -itd --entrypoint bash server.corp13.un:5000/student/apwebd:ver1.2

~/apwebd$ docker push server.corp13.un:5000/student/apwebd:ver1.2

Старая версия

Работа с образами

# docker search debian

# docker pull debian

# docker images

# docker commit debian_cont_01 debian_img_01

# docker rmi debian_img_01

Работа с контейнерами

  • ключи -i -t необходимы для возможности интерактивно (attach) подключаться к запущенному контейнеру
# docker create -i -t --name debian_cont_01 debian

# docker ps -a
# docker container ls -a

# docker update --restart=always debian_cont_01
# docker start debian_cont_01

# docker ps
# docker container ls

# docker inspect debian_cont_01

# docker top debian_cont_01

# docker attach debian_cont_01

:/# apt update

:/# apt install iputils-ping

:/# ping -c1 ya.ru
Ctrl+P, Q(still holding Ctrl)

# docker stop debian_cont_01

# docker rm debian_cont_01

# docker rm $(docker ps -aq)

Работа с сетью

Управление сетями

# docker network ls

# docker network create --subnet=192.168.200+X.0/24 corpX_dmz

# docker run -h mail.corpX.un --net corpX_dmz --ip 192.168.200+X.10 -i -t --name debian_cont_01 debian

# docker network inspect corpX_dmz

Назначение публичного ip для контейнера

Вариант 1
Вариант 2

Использование nat/dnat

  • присваиваем публичные ip адреса интерфейсу host машины и настраиваем NAT/DNAT связывающие публичные ip host машины со статическими ip контейнеров
# ip addr add 172.16.1.100+X dev eth2

# iptables -t nat -A POSTROUTING -o eth2 -s 192.168.100+X.10 -j SNAT --to-source 172.16.1.100+X
# iptables -t nat -A PREROUTING -i eth2 --destination 172.16.1.100+X -j DNAT --to-destination 192.168.100+X.10

HEARTBEAT и Docker

nodeN# cat haresources
node1.corpX.un drbddisk Filesystem::/dev/drbd0::/disk2::ext4 docker
технология_docker.txt · Last modified: 2024/11/15 11:16 by val