This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
технология_docker [2022/06/30 09:47] val [docker-compose] |
технология_docker [2025/05/05 07:39] (current) val [docker-compose] |
||
---|---|---|---|
Line 3: | Line 3: | ||
* [[https://youtu.be/hdVNKmru3LM|youtube/Проникновение в Docker с примерами, Дмитрий Столяров, Flant]] | * [[https://youtu.be/hdVNKmru3LM|youtube/Проникновение в Docker с примерами, Дмитрий Столяров, Flant]] | ||
* [[https://www.upguard.com/articles/docker-vs-lxc|Docker vs LXC]] | * [[https://www.upguard.com/articles/docker-vs-lxc|Docker vs LXC]] | ||
- | * [[https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04-ru|Установка и использование Docker в Ubuntu 20.04]] | ||
* [[https://youtu.be/QF4ZF857m44|youtube/Артем Матяшов/Основы Docker. Большой практический выпуск]] | * [[https://youtu.be/QF4ZF857m44|youtube/Артем Матяшов/Основы Docker. Большой практический выпуск]] | ||
Line 14: | Line 13: | ||
===== Установка ===== | ===== Установка ===== | ||
- | ==== Ubuntu ==== | + | ==== Ubuntu/Debian ==== |
* [[https://docs.docker.com/engine/install/ubuntu/|Install Docker Engine on Ubuntu]] | * [[https://docs.docker.com/engine/install/ubuntu/|Install Docker Engine on Ubuntu]] | ||
+ | * [[https://docs.docker.com/engine/installation/linux/docker-ce/debian/|Get Docker CE for Debian]] | ||
<code> | <code> | ||
# apt install docker.io | # apt install docker.io | ||
</code> | </code> | ||
- | ==== Debian ==== | ||
- | * [[https://docs.docker.com/engine/installation/linux/docker-ce/debian/|Get Docker CE for Debian]] | ||
- | === Debian 10 === | + | ==== Настройка registry-mirrors ==== |
+ | |||
+ | * [[https://habr.com/ru/news/818177/|Docker hub перестал работать в России]] | ||
<code> | <code> | ||
- | # apt install ca-certificates curl gnupg lsb-release | + | # cat /etc/docker/daemon.json |
+ | </code><code> | ||
+ | { | ||
+ | "registry-mirrors": ["https://mirror.gcr.io"] | ||
+ | } | ||
+ | </code> | ||
- | # curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg | + | ==== Настройка загрузки образов через proxy ==== |
- | # echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list | + | * [[Переменные окружения]] |
- | # apt update | + | <code> |
+ | # systemctl edit docker.service | ||
+ | </code><code> | ||
+ | ... | ||
+ | [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" | ||
+ | ... | ||
+ | </code><code> | ||
+ | # systemctl daemon-reload | ||
- | # apt install docker-ce docker-ce-cli containerd.io | + | # service docker restart |
</code> | </code> | ||
==== Тестирование установки ==== | ==== Тестирование установки ==== | ||
+ | |||
<code> | <code> | ||
# systemctl status docker | # systemctl status docker | ||
# docker info | # docker info | ||
+ | </code> | ||
+ | ==== Запуск контейнеров ==== | ||
+ | * [[https://stackoverflow.com/questions/41694329/docker-run-override-entrypoint-with-shell-script-which-accepts-arguments|Docker run override entrypoint with shell script which accepts arguments]] | ||
+ | * Запуск сервиса TACACS+ в [[Сервис TACACS+#Docker]] | ||
+ | |||
+ | <code> | ||
# docker run hello-world | # docker run hello-world | ||
+ | |||
+ | # docker events --since '10m' | ||
</code> | </code> | ||
Line 51: | Line 75: | ||
<code> | <code> | ||
# usermod -aG docker gitlab-runner | # usermod -aG docker gitlab-runner | ||
+ | |||
+ | # su - gitlab-runner | ||
</code> | </code> | ||
===== Работа с образами и контейнерами ===== | ===== Работа с образами и контейнерами ===== | ||
+ | * [[https://www.baeldung.com/ops/docker-image-layers-sizes|Finding the Layers and Layer Sizes for a Docker Image]] | ||
+ | * [[https://stackoverflow.com/questions/37966973/what-is-the-difference-between-the-size-and-the-virtual-size-of-the-docker-image|What is the difference between the size and the virtual size of the docker images?]] | ||
+ | * [[https://docs.docker.com/engine/reference/commandline/system_prune/|docker system prune - Remove unused data]] | ||
* [[Сервис Grafana]] | * [[Сервис Grafana]] | ||
==== Обзор и удаление ==== | ==== Обзор и удаление ==== | ||
+ | |||
+ | * [[https://forums.docker.com/t/why-arent-base-layer-images-listed-in-docker-image-ls-a/139044/5|Why aren’t base layer images listed in `docker image ls -a`?]] | ||
<code> | <code> | ||
# docker images | # docker images | ||
- | # docker ps -a | + | # docker ps -a #--size |
# docker container ls -a | # docker container ls -a | ||
+ | # docker container stats | ||
# docker start -i NNNNNNNNNNN | # docker start -i NNNNNNNNNNN | ||
Line 73: | Line 105: | ||
# docker rmi -f $(docker images -aq) | # docker rmi -f $(docker images -aq) | ||
- | # docker system prune -a --volumes | + | # docker system df |
+ | |||
+ | # docker system prune | ||
+ | # docker system prune -a #--volumes | ||
</code> | </code> | ||
+ | ==== Копирование файлов в контейнер ==== | ||
+ | |||
+ | <code> | ||
+ | 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 | ||
+ | </code> | ||
- | ==== Создание контейнера для приложения вручную ==== | + | ==== Создание образа для приложения вручную ==== |
Line 103: | Line 149: | ||
</code> | </code> | ||
- | "Забыли" сделать скрипт start.sh "выполнимым" нажали Ctrl+D | + | * Ctrl+D |
<code> | <code> | ||
- | server# docker diff webd | + | server# docker ps -a |
+ | server# docker diff webd | ||
+ | </code> | ||
+ | * Методически, "вспомнили", что "забыли" сделать скрипт start.sh "выполнимым" | ||
+ | <code> | ||
server# docker start webd | server# docker start webd | ||
Line 115: | Line 165: | ||
</code> | </code> | ||
- | Ctrl+D | + | * Методически, можно уже на этом этапе: запустить скрипт ./start.sh, отключится от контейнера без его остановки Ctrl+P, Q(still holding Ctrl), выяснить через docker inspect webd назначенный контейнеру ip, проверить через curl работу приложения и, если все работает (правда, будет сообщение, что такого файла нет), сделать docker stop webd, и commit |
+ | |||
+ | * [[https://cpab.ru/kak-rabotajut-tegi-docker-cloudsavvy-it/|Как работают теги Docker?]] | ||
+ | |||
+ | * [[https://code.tutsplus.com/ru/tutorials/docker-from-the-ground-up-understanding-images--cms-28165|Докер с нуля: понимание слоев образов]] | ||
+ | * Пакет RSYNC - [[Пакет RSYNC#Инкрементное копирование (Incremental Backup)]] | ||
<code> | <code> | ||
server# docker commit webd test/webd | server# docker commit webd test/webd | ||
+ | |||
+ | gitlab-runner@server:~$ docker images | ||
</code> | </code> | ||
- | * [[#Запуск в режиме демона и подключение к контейнеру]] | + | * [[#Запуск в режиме демона и подключение к контейнеру]] из полученного образа |
- | ==== Создание контейнера для приложения с использованием Dockerfile ==== | + | ==== Создание образа для приложения с использованием Dockerfile ==== |
* [[Сервис TACACS+]] | * [[Сервис TACACS+]] | ||
- | * [[Средства программирования shell#Web сервер на shell]] | ||
+ | === Приложение bash webd === | ||
<code> | <code> | ||
- | server# mkdir /root/webd/ && cd /root/webd/ | + | server# mkdir -p /root/webd/ && cd /root/webd/ |
+ | или | ||
+ | gitlab-runner@server:~$ mkdir -p ~/webd/webd/ && cd ~/webd/webd/ | ||
- | server# mv /usr/local/sbin/webd . | + | server# cp /usr/local/sbin/webd . |
+ | lan:~/webd# scp server:/usr/local/sbin/webd . | ||
+ | или | ||
+ | </code> | ||
+ | * [[Средства программирования shell#Web сервер на shell]] | ||
+ | <code> | ||
+ | gitlab-runner@server:~/webd/webd$ nano webd # добавляем закомментированные строки | ||
server# ###tar -cvzf www.tgz -C /var/ www/ | server# ###tar -cvzf www.tgz -C /var/ www/ | ||
Line 140: | Line 205: | ||
/etc/init.d/inetutils-inetd start | /etc/init.d/inetutils-inetd start | ||
+ | touch /var/log/webd.log | ||
+ | #chown 10003 /var/www/ | ||
+ | | ||
if [ "$MYMODE" = 'TEST' ]; then | if [ "$MYMODE" = 'TEST' ]; then | ||
- | bash # not work in k8s | + | sleep 3 |
+ | curl localhost && exit 0 || exit 1 | ||
else | else | ||
- | tail -F /var/log/webd.log | + | tail -f /var/log/webd.log |
fi | fi | ||
</code><code> | </code><code> | ||
server# cat Dockerfile | server# cat Dockerfile | ||
</code><code> | </code><code> | ||
- | #FROM debian:buster | + | #FROM debian |
- | FROM debian:bullseye | + | #FROM debian:bullseye |
+ | FROM debian:bookworm | ||
- | RUN apt-get update && apt-get install -y inetutils-inetd file && echo 'www stream tcp nowait root /usr/local/sbin/webd webd' > /etc/inetd.conf | + | 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 start.sh / | ||
COPY webd /usr/local/sbin/webd | COPY webd /usr/local/sbin/webd | ||
- | ### ADD www.tgz /var/ #for simple test in k8s | + | ### ADD www.tgz /var/ |
+ | |||
+ | ### for helm readiness/liveness Probe | ||
+ | ### COPY index.html /var/www/ | ||
EXPOSE 80 | EXPOSE 80 | ||
Line 163: | Line 240: | ||
</code><code> | </code><code> | ||
# docker build -t test/webd . | # docker build -t test/webd . | ||
+ | |||
+ | # docker run --rm -e MYMODE=TEST test/webd | ||
# docker history test/webd | # docker history test/webd | ||
</code> | </code> | ||
- | ==== Запуск в режиме демона и подключение к контейнеру ==== | + | * [[#Запуск в режиме демона и подключение к контейнеру]] |
+ | |||
+ | === Приложение python pywebd === | ||
+ | |||
+ | * [[Язык программирования Python]] | ||
+ | |||
+ | * [[https://stackoverflow.com/questions/49955097/how-do-i-add-a-user-when-im-using-alpine-as-a-base-image|How do I add a user when I'm using Alpine as a base image?]] | ||
<code> | <code> | ||
- | 1-й раз - запуск образа сделанного "вручную" | + | :~/pywebd$ ### mkdir etc/; cp -rv /etc/pywebd/ etc/ |
+ | :~/pywebd$ ### echo '<h1>Hello from pywebd</h1>' > index.html | ||
- | server# docker run --name webd01 --hostname webd01 -itd -v /var/www/:/var/www/ -p 8000:80 test/webd /start.sh | + | :~/pywebd$ dpkg -l | grep python |
- | 2-й раз - через Dockerfile задан entrypoint и expose, ключ --rm для удаления контейнера после остановки | + | :~/pywebd$ cat Dockerfile |
+ | </code><code> | ||
+ | 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 . . | ||
+ | |||
+ | #COPY --chown=myuser:myuser app.py . | ||
+ | ### COPY --chown=myuser:myuser etc/pywebd/ /etc/pywebd/ | ||
+ | ### COPY --chown=myuser:myuser index.html /var/www/ | ||
+ | ### ADD www.tgz /var/ | ||
+ | |||
+ | ### ENV PYWEBD_PORT=4080 | ||
+ | |||
+ | ### EXPOSE 4080 | ||
+ | |||
+ | ENTRYPOINT ["python"] | ||
+ | CMD ["app.py"] | ||
+ | </code><code> | ||
+ | :~/pywebd$ time docker build -t pywebd . | ||
+ | |||
+ | :~/pywebd$ ### docker run -ti --rm --entrypoint /bin/sh pywebd | ||
+ | :~/pywebd$ ### docker run -p 4443 -d --rm pywebd | ||
+ | |||
+ | :~/pywebd$ docker run -d --rm -p 4088 -e PYWEBD_PORT=4088 -v /etc/pywebd:/etc/pywebd -v /var/www/:/var/www/ --name pywebd01 pywebd | ||
+ | </code> | ||
+ | |||
+ | * [[#Запуск в режиме демона и подключение к контейнеру]] | ||
+ | |||
+ | === Приложение golang gowebd === | ||
+ | |||
+ | == Dockerfile Multistage Building == | ||
+ | |||
+ | * [[Язык программирования Golang]] | ||
+ | * [[https://habr.com/ru/articles/647255/|Рекомендации по работе с Docker для Golang-разработчиков (Multistage Building)]] | ||
+ | * [[https://www.docker.com/blog/containerize-your-go-developer-environment-part-2/|Containerize Your Go Developer Environment – Part 2]] | ||
+ | |||
+ | <code> | ||
+ | student@client1:~/gowebd$ cat Dockerfile | ||
+ | </code><code> | ||
+ | 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 | ||
+ | |||
+ | EXPOSE 80 | ||
+ | |||
+ | ENTRYPOINT ["/gowebd"] | ||
+ | </code><code> | ||
+ | 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 | ||
+ | </code> | ||
+ | |||
+ | == docker buildx == | ||
+ | |||
+ | * [[https://doroshev.com/blog/docker-mount-type-cache/|Docker Buildkit: Правильное использование --mount=type=cache]] | ||
+ | |||
+ | <code> | ||
+ | ubuntu# apt install docker-buildx | ||
+ | или | ||
+ | docker# apt install docker-buildx-plugin | ||
+ | |||
+ | ubuntu:~/gowebd# cat Dockerfile | ||
+ | </code><code> | ||
+ | ... | ||
+ | RUN --mount=type=cache,target="/root/.cache/go-build" go build -o /gowebd | ||
+ | ... | ||
+ | </code><code> | ||
+ | ubuntu:~/gowebd# time docker build -t gowebd . | ||
+ | ... | ||
+ | real 0m6.686s | ||
+ | </code> | ||
+ | |||
+ | == Smoke test == | ||
+ | |||
+ | <code> | ||
+ | $ MY_ID=$(docker run -d --rm gowebd) | ||
+ | $ MY_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $MY_ID) | ||
+ | $ docker run --rm alpine/curl -sS $MY_IP | ||
+ | $ docker stop $MY_ID | ||
+ | </code> | ||
+ | |||
+ | * [[#Запуск в режиме демона и подключение к контейнеру]] | ||
+ | ==== Запуск в режиме демона и подключение к контейнеру ==== | ||
+ | |||
+ | 1-й пример - запуск образа сделанного "вручную", можно запустить несколько экземпляров с -p 80 выяснить назначенные порты, настроить keepalived и провести нагрузочное тестирование | ||
+ | <code> | ||
+ | server# docker run --name webd01 --hostname webd01 -itd -v /var/www/:/var/www/ -p 8000:80 test/webd /start.sh | ||
+ | </code> | ||
+ | 2-й пример - через Dockerfile задан entrypoint и expose, ключ --rm для удаления контейнера после остановки, добавить, при необходимости, -v | ||
+ | <code> | ||
server# docker run --name webd01 -e MYMODE=TEST -itd --rm -P test/webd | server# docker run --name webd01 -e MYMODE=TEST -itd --rm -P test/webd | ||
+ | </code> | ||
+ | 3-й раз - запустить несколько экземпляров, указав параметры для подключения внешнего каталога /var/www/, выяснить назначенные порты, настроить keepalived, по журналам определять какой контейнер используется | ||
+ | === Процессы контейнера и системы === | ||
+ | |||
+ | * [[Технология cgroup]] | ||
+ | * [[https://www.baeldung.com/ops/docker-memory-limit|Setting Memory And CPU Limits In Docker]] | ||
+ | * [[https://stackoverflow.com/questions/72185669/what-is-the-real-memory-available-in-docker-container|What is the real memory available in Docker container?]] | ||
+ | * [[Технология namespaces]] | ||
+ | |||
+ | |||
+ | <code> | ||
server# docker top webd01 | server# docker top webd01 | ||
server# ps axw | grep inetd | server# ps axw | grep inetd | ||
+ | server# ps axw | grep start.sh | ||
+ | |||
server# cat /proc/<PID>/cgroup | 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 | ||
+ | </code> | ||
+ | == Анализ параметров запущенного контейнера == | ||
+ | <code> | ||
server# docker inspect webd01 | server# docker inspect webd01 | ||
- | server# docker inspect webd01 -f {{.NetworkSettings.IPAddress}} | + | server# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' webd01 |
server# wget -qO - http://172.17.0.2/ | server# wget -qO - http://172.17.0.2/ | ||
+ | server$ curl --noproxy '*' http://172.17.0.2/ | ||
server# docker port webd01 | server# docker port webd01 | ||
server# docker logs webd01 | server# docker logs webd01 | ||
+ | |||
+ | node1# docker logs webd01 -f | ||
server# wget -qO - http://localhost:8000/ | 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/ | host browser -> http://server.corpX.un:8000/ | ||
+ | </code> | ||
+ | == Анализ параметров запущенного контейнера изнутри == | ||
+ | <code> | ||
server# docker attach webd01 | server# docker attach webd01 | ||
+ | |||
+ | server# docker exec -it webd01 sh | ||
webd01# ps ax | webd01# ps ax | ||
Line 203: | Line 439: | ||
webd01# cat /proc/1/cmdline | webd01# cat /proc/1/cmdline | ||
- | Ctrl+P, Q(still holding Ctrl) | + | webd01# ip a |
+ | или | ||
+ | webd01# cat /proc/net/fib_trie | ||
+ | webd01# ss -tpan | ||
+ | |||
+ | или https://www.rapidtables.com/convert/number/decimal-to-hex.html | ||
+ | |||
+ | webd01# cat /proc/net/tcp | ||
+ | webd01# cat /proc/net/tcp6 | ||
+ | |||
+ | Ctrl+P, Q(still holding Ctrl) | ||
+ | </code> | ||
+ | == Управление контейнером после запуска == | ||
+ | <code> | ||
server# docker stop webd01 | server# docker stop webd01 | ||
Line 216: | Line 465: | ||
</code> | </code> | ||
- | ==== Микросервисы ==== | + | |
+ | ==== Использование готовых образов приложений ==== | ||
* [[https://hub.docker.com/search?type=image|Explore Docker's Container Image Repository]] | * [[https://hub.docker.com/search?type=image|Explore Docker's Container Image Repository]] | ||
+ | |||
+ | === atmoz/sftp === | ||
* [[https://hub.docker.com/r/atmoz/sftp|atmoz/sftp]] | * [[https://hub.docker.com/r/atmoz/sftp|atmoz/sftp]] | ||
Line 226: | Line 478: | ||
# chown -R 10003 /var/www | # 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 run --name sftp01 -v /var/www:/home/user3/www -p 2222:22 -d --rm atmoz/sftp user3:password3:10003 |
- | # docker exec -it sftp01 bash | + | # ###docker exec -it sftp01 bash |
</code> | </code> | ||
Ctrl+D | Ctrl+D | ||
Line 236: | Line 488: | ||
# sftp -P 2222 user3@localhost | # sftp -P 2222 user3@localhost | ||
</code> | </code> | ||
- | * [[Сервис SSH#Настройка ssh клиента]] | + | * [[Сервис SSH#WinSCP]] |
<code> | <code> | ||
# docker logs sftp01 | # docker logs sftp01 | ||
Line 246: | Line 498: | ||
* [[https://habr.com/ru/company/ruvds/blog/450312/|Руководство по Docker Compose для начинающих]] | * [[https://habr.com/ru/company/ruvds/blog/450312/|Руководство по Docker Compose для начинающих]] | ||
+ | * [[https://stackoverflow.com/questions/39663096/docker-compose-creating-multiple-instances-for-the-same-image|docker-compose creating multiple instances for the same image]] | ||
+ | * [[https://docs.docker.com/compose/how-tos/lifecycle/|Using lifecycle hooks with Compose]] | ||
+ | |||
+ | * [[Инструмент GitLab#Установка через docker-compose]] GitLab | ||
+ | * Установка через [[Сервис Keycloak#docker-compose]] Keycloak | ||
<code> | <code> | ||
# apt install docker-compose | # apt install docker-compose | ||
- | |||
- | debian11# service docker start | ||
# cat docker-compose.yml | # cat docker-compose.yml | ||
Line 257: | Line 512: | ||
services: | services: | ||
webd: | webd: | ||
- | image: test/webd | + | # image: server.corpX.un:5000/student/webd:ver1.N |
- | build: webd/ | + | image: pywebd |
- | ports: | + | # build: webd/ |
- | - "8000:80" | + | # entrypoint: /start.sh |
+ | # ports: | ||
+ | # - "80" | ||
volumes: | volumes: | ||
+ | - /etc/pywebd/:/etc/pywebd/ | ||
- /var/www/:/var/www/ | - /var/www/:/var/www/ | ||
+ | # - vol1:/var/www/ | ||
+ | deploy: | ||
+ | mode: replicated | ||
+ | replicas: 3 | ||
+ | |||
# environment: | # environment: | ||
- | # - MYMODE=TEST | + | # - PYWEBD_PORT=80 |
# stdin_open: true | # stdin_open: true | ||
- | tty: true | + | # tty: true |
sftp: | sftp: | ||
image: atmoz/sftp | image: atmoz/sftp | ||
Line 273: | Line 537: | ||
volumes: | volumes: | ||
- /var/www/:/home/user3/www | - /var/www/:/home/user3/www | ||
+ | # - vol1:/home/user3/www | ||
command: user3:password3:10003 | command: user3:password3:10003 | ||
+ | #volumes: | ||
+ | # vol1: | ||
</code><code> | </code><code> | ||
- | # docker-compose build | + | # ###docker-compose build |
# docker-compose up -d | # docker-compose up -d | ||
+ | |||
+ | # docker-compose logs -f webd | ||
# docker-compose stop | # docker-compose stop | ||
Line 285: | Line 554: | ||
# docker-compose down | # docker-compose down | ||
- | # docker-compose rm #Возможно, не требуется | + | # docker-compose rm |
- | </code> | + | |
- | ===== Дополнительные материалы ===== | + | |
- | ==== Локальный репозиторий ==== | + | # docker volume inspect root_vol1 |
- | * [[https://docs.docker.com/registry/|Docker Registry]] | + | # docker volume rm root_vol1 |
- | <code> | + | # docker-compose up -d --scale webd=N |
- | gate# docker run -d -p 5000:5000 -v /root:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/gate.crt -e REGISTRY_HTTP_TLS_KEY=/certs/gate.key --name registry registry:2 | + | |
- | node1# cp ~vagrant/gate.crt /etc/docker/certs.d/gate.corp13.un\:5000/ca.crt | + | # docker ps |
+ | </code><code> | ||
+ | gitlab-runner@server:~/webd$ cat docker-compose.yml | ||
+ | </code><code> | ||
+ | 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 | ||
+ | </code><code> | ||
+ | node1,2,3# docker-compose --compatibility up -d | ||
- | node1# service docker restart | + | node1,2,3# docker-compose --compatibility down |
- | node1# docker tag val/webd:latest gate.corp13.un:5000/webd | + | node1,2,3# docker ps -q | xargs -l docker port | sort -n |
+ | </code> | ||
- | node1# docker push gate.corp13.un:5000/webd | + | ===== Локальные репозитории ===== |
- | node1# curl --insecure -X GET https://gate.corp13.un:5000/v2/_catalog | + | ==== Копирование образов ==== |
- | {"repositories":["webd"]} | + | <code> |
- | </code> | + | server# docker save -o test-webd.tgz test/webd |
- | ==== GitLab репозиторий ==== | + | lan# scp server:test-webd.tgz . |
+ | |||
+ | lan# docker load -i test-webd.tgz | ||
+ | </code> | ||
+ | ==== Insecure Private Registry ==== | ||
* [[Инструмент GitLab#GitLab Docker Registry]] | * [[Инструмент GitLab#GitLab Docker Registry]] | ||
+ | * [[https://docs.docker.com/registry/insecure/|Test an insecure registry/Deploy a plain HTTP registry]] | ||
<code> | <code> | ||
# cat /etc/docker/daemon.json | # cat /etc/docker/daemon.json | ||
</code><code> | </code><code> | ||
- | ... | ||
{ | { | ||
"insecure-registries" : ["server.corpX.un:5000"] | "insecure-registries" : ["server.corpX.un:5000"] | ||
} | } | ||
- | ... | ||
</code><code> | </code><code> | ||
# service docker restart | # service docker restart | ||
+ | </code> | ||
- | # docker login http://server.corpX.un:5000 | + | ==== Аутентификация в Registry ==== |
- | # docker tag test/webd server.corpX.un:5000/student/webd | + | <code> |
- | # docker tag test/webd server.corpX.un:5000/student/webd:wwwdir | + | gitlab-runner@server:~$ docker login |
- | # docker push server.corpX.un:5000/student/webd | + | gitlab-runner@server:~$ docker login http://server.corpX.un:5000 |
- | # docker push server.corpX.un:5000/student/webd:wwwdir | + | |
+ | gitlab-runner@server:~$ less ~/.docker/config.json | ||
+ | </code><code> | ||
+ | { | ||
+ | "auths": { | ||
+ | "server.corpX.un:5000": { | ||
+ | "auth": "c3R1ZGVudDpQYSQkdzByZA==" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | * [[https://serverfault.com/questions/703344/how-to-remove-an-image-tag-in-docker-without-removing-the-image-itself|How to remove an image tag in Docker without removing the image itself?]] | ||
+ | ==== Использование Private Registry ==== | ||
+ | |||
+ | <code> | ||
+ | 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:ver1.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:ver1.1 | ||
... | ... | ||
- | # docker run --name webd01 --hostname webd01 -itd -p 8000:80 server.corp13.un:5000/student/webd:wwwdir | + | 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 | ||
</code> | </code> | ||
+ | |||
+ | |||
+ | ==== Использование образа Docker Registry on-premise ==== | ||
+ | |||
+ | * [[https://docs.docker.com/registry/|Docker Registry]] | ||
+ | * [[https://stackoverflow.com/questions/25436742/how-to-delete-images-from-a-private-docker-registry?newreg=e655d7146b114f0f9b88b1132990f346|How to delete images from a private docker registry?]] | ||
+ | |||
+ | <code> | ||
+ | # 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 | ||
+ | </code> | ||
+ | |||
+ | ===== Дополнительная информация ===== | ||
+ | |||
+ | ==== Инструмент kaniko ==== | ||
+ | |||
+ | * [[https://habr.com/ru/companies/slurm/articles/436126/|Kubernetes: сборка образов Docker в кластере, можно использовать kaniko]] | ||
+ | |||
+ | <code> | ||
+ | ~/gowebd# time docker run \ | ||
+ | -v $(pwd):/workspace \ | ||
+ | -v ~/.docker/config.json:/kaniko/.docker/config.json \ | ||
+ | gcr.io/kaniko-project/executor:latest \ | ||
+ | --skip-tls-verify --log-timestamp \ | ||
+ | --dockerfile=./Dockerfile \ | ||
+ | --context=/workspace \ | ||
+ | --destination=server.corpX.un:5000/student/gowebd | ||
+ | </code><code> | ||
+ | или, интерактивно: | ||
+ | </code><code> | ||
+ | root@ubuntu:~/gowebd# docker run -it \ | ||
+ | -v $(pwd):/workspace --rm --entrypoint "/bin/sh" \ | ||
+ | -v ~/.docker/config.json:/kaniko/.docker/config.json \ | ||
+ | gcr.io/kaniko-project/executor:debug | ||
+ | |||
+ | # time /kaniko/executor --skip-tls-verify --log-timestamp \ | ||
+ | --dockerfile=./Dockerfile \ | ||
+ | --context=/workspace \ | ||
+ | --destination=server.corpX.un:5000/student/gowebd | ||
+ | </code><code> | ||
+ | тестируем результат: | ||
+ | </code><code> | ||
+ | # docker run --pull=always --name gowebd -itd --rm \ | ||
+ | -p 8000:80 server.corpX.un:5000/student/gowebd | ||
+ | </code> | ||
+ | ==== Приложение apwebd ==== | ||
+ | |||
+ | <code> | ||
+ | ~/apwebd$ cat Dockerfile | ||
+ | </code><code> | ||
+ | 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"] | ||
+ | </code><code> | ||
+ | ~/apwebd$ find rootfs/ -type f | xargs tail -n +1 | ||
+ | </code><code> | ||
+ | ==> rootfs/var/www/html/index.html.apwebd-template <== | ||
+ | </code><code> | ||
+ | <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> | ||
+ | </code><code> | ||
+ | ==> rootfs/start.sh <== | ||
+ | </code><code> | ||
+ | #!/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 | ||
+ | |||
+ | </code><code> | ||
+ | ==> rootfs/etc/apache2/conf-available/serve-cgi-bin.conf.apwebd-template <== | ||
+ | </code><code> | ||
+ | <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> | ||
+ | </code><code> | ||
+ | ==> rootfs/usr/lib/cgi-bin/apwebd <== | ||
+ | </code><code> | ||
+ | #!/bin/sh | ||
+ | |||
+ | echo Content-type: text/html | ||
+ | echo | ||
+ | |||
+ | echo "<h1 style=\"color:blue;\">Hello ${OIDC_CLAIM_preferred_username}</h1>" | ||
+ | |||
+ | echo "<pre>"; env; echo "</pre>" | ||
+ | </code><code> | ||
+ | ~/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 | ||
+ | </code> | ||
+ | |||
===== Старая версия ===== | ===== Старая версия ===== |