-
bind mount
-
volume
-
tmpfs (не рассматриваем) (оперативка)
-
Volume не зависят от хоста
-
Volume более безопасный вариант (нельзя монтировать любые файлы)
-
Volume находятся в специальном месте (удобно)
-
Volumes привязывают только директории
Volume больше про сохранение данных, а bind mount больше про присоединение файлов.
Путь до волюма в системе: /var/lib/docker/volumes/<volume name>.
Иногда волюмы могут создаваться автоматически неявно с уникальным идетификатором.
Например при поднятии yandex/clickhouse-server создаются наявно волюмы. Послу удаления контейнеров эти аолюмы останутся в системе.
Почему создаются анонимные волюмы?
Анонимные волюмы создаются когда в Dockerfile встречается команда VOLUME. В случае с clickhouse это строчка VOLUME [var/lib/clickhouse...].
FROM node:17
COPY script.js /app/script.js
VOLUME [/app/]
CMD ["node", "/app/script.js"]docker build -t node-volume .
docker compose up -d --rm node-volumeМожно скоприровать файлы с хоста внутрь контейнера. И обратною
docker cp <host_path> <container>:<path>
docker cp ./todo_result/ tg-bot:/app/todo_result/
docker cp <container>:<path> <host_path>
docker cp tg-bot:/app/todo_result/todolist.csv todo_result/todolist.csvdocker volume ls # вывести список волюмов
docker voluem create <volume name> # создание волюма
docker volum rm <volume name> # удаление волюма
docker volume prune --force # удаление неиспользуемых анонимных волюмов
docker volume prune -a --force # удаление всех неиспользуеых волюмовПо умолчанию в конейнере суперпользовтель. Поэтому из конетйнера можно получить доступ к файлам, которые доступны руту.
Поэтому лучше монтировать отдельные файлы, а не каталоги, даже если несколько раз приходится писать -v.
И не надо монтировать корень /.
Ещё можно потерять взаимодуйствие с логами, если их создвет контейнер, анпример clickhouse, а у текущего пользовтеля нету прав.
Поэтому можно монтировать в режиме чтения
docker run -v <host_path>:<cont_path>:ro imageили использовать директиву USER в Dockerfile, или указывать пользователя при запуске контейнера:
id -U # узнаём ид пользователя
docker run --user=1000 image-
none - полная изоляция контейнера от внешней среды и от хоста
-
host - контейнер сидит в сети хоста
-
bridge - сети куда все контейнеры попадают по-умолчанию 172.17.0.0/16
-
overlay
-
ipvlan
-
macvlan
-
network plugins
-
docker network ls- список сетей
docker run --rm --name temp -d -p 8000:8000 --network=none image - использовать сеть none
docker run --net=none image - можно использовать короткое имя net
Даже если будет прокинут порт с сетью none то достучаться до приложеняи через него будет нельзя и порт не будет показан в результатах вывода команды docker ps.
А из контейнера можно выйти в другую сеть? Нет нельзя. У контейнера как будто выключен интернет. Но loopback он же localhost 127.0.0.1 будет работать.
При запуске в контейнера в режиме сети хочта можно не пробрасывать порты.
docker run --net=host imageДо приложения можно будет достучаться, т.к. все его открытые порты станут доступны на хостовом компьютере.
Сюда попадают все контейнера по умолчанию.
Можно просмотреть низкоуровневую информацию об объектах докера через docker inspect:
docker inspect bridge
# или
docker network inspect bridgetcpdump -i <интерфейс> [<протокол>]
# слушаем пинги
sudp tcpdump -i eth0 icmpМожно прокидывать порты при запуске контейнера с параметром -p.
Также можно прокидывать не только порты, но и связку интерфейса с портом
docker run -p <host port>:<container port> image
# или с сокетом
docker run -p <host interface>:<host port>:<container port> imageВ таком случае можно поднять два разных контейнера с разными привязанными сокетами. Т.е. один будет напрмер работать на интерфейсе1:8000, другой на интерфейсе2:8000.
Можно контйенер при его запуске
docker run --net network_name image
# или
docker run --network network_name imageИли подключить уже после запуска
docker netwotk connect network_name containerФайл конфигурации nginx
user www-data;
worker_processes 2;
events {
worker_connections 2048;
}
http {
map $uri $base {
~/(?<file>[^/]*)$ $file;
}
server {
listen 80;
server_name docker.karpovdns.net www.docker.karpovdns.net;
location /api {
proxy_pass http://backend:8000/api;
}
location / {
root /nginx/static;
try_files /$base /index.html ~404;
}
}
include /etc/nginx/sites-enabled/*.conf;
include mime.types;
}FROM ... AS <name>
FROM ..
COPY --from=<name> ... ...FROM node:17 as build
WORKDIR /app/
COPY ./todo-list/package.json .
RUN npm i
COPY ./todo-list/ .
RUN npm run build
# stage 2
FROM nginx:alpine
COPY --from=build /app/dist/index.html /nginx/static/index.html
COPY --from=build /app/dist/static/css /nginx/static/
COPY --from=build /app/dist/static/js /nginx/static/Чтобы остановиться на определенном этапе (стейдже) в мультистейдж Dockerfile при сборке, используйте флаг --target в команде docker build, указывая имя нужного стейджа как значение, например: docker build --target <имя_стейджа> -t <имя_образа> ., что позволит получить промежуточный образ с артефактами до финальной стадии, как объясняет статья о Dockerfile от Cloud.ru.
import yaml
with open("yaml_file.yaml") as f:
templates = yaml.safe_load(f)
print(tempaltes)Пустое значение
#yaml_file.yaml
name:
# { 'name': None }name: Piter
age: 32
# {'name': 'Piter', 'age': 32}Ключ-значение
name: Piter Olga
# {'name': 'Piter Olga' }name:
Piter
Olga
# {'name': 'Piter Olga'}Многострочная запись
name: |
Piter
Olga
{'name': 'Piter\nOlga\n'}name: >
Piter
Olga
{'name': 'Piter Olga\n'}Список
name:
- Piter
- Olga
# {'name': ['Piter', 'Olga']}Список объектов
name:
- Piter: 32
- Olga: 28
# {'name': [{'Piter': 32}, {'Olga': 28}]}name:
- Piter: 32
Olga: 28
- Oleg: 33
Julia: 31
# {'name': [{'Piter': 32, 'Olga': 28}, {'Max': 33, 'Maya': 31}]}&- якорь*- ссылка на якорь<<: *- слияние ключей по ссылке(<<) и ссылка на якорь
Ссылка на списки.
x-eukaryotes:
organelles:
&eu-organelles
- nucleus
- mitochondria
- endoplasmic reticulum
- Golgi apparatus
- ribosomes
- cytoskeleton
human-cells:
cell-wall: absent
organelles: *eu-organelles
examples:
- Macrophage
- Hepatocyte
yeasts:
cell-wall: present
organelles: *eu-organelles
examples:
- Saccharomyces cerevisiae
- Komagataella phaffiiА можно преедать ссылку не на список, а на ключ.
x-eukaryotes:
&eu-organelles
organelles:
- nucleus
- mitochondria
- endoplasmic reticulum
- Golgi apparatus
- ribosomes
- cytoskeleton
human-cells:
cell-wall: absent
<<: *eu-organelles
examples:
- Macrophage
- Hepatocyte
yeasts:
cell-wall: present
<<: *eu-organelles
examples:
- Saccharomyces cerevisiae
- Komagataella phaffiijunior:
&junior
position: junior
salary: 50000
team:
backend:
- Peter:
<<: *junior
- Olga:
<<: *juniorМожно делать ссылки на структуры данных, чтобы их не повторять.
x-airflow-common:
&airflow-common
environment:
&airflow-common-env
AIRFLOW__CORE__EXECUTOR: CeleryExecutor
AIRFLOW__CORE__FERNET_KEY: ''
depends_on:
&airflow-common-depends-on
redis:
condition: service_healthy
postgres:
condition: service_healthy
services:
airflow-scheduler:
<<: *airflow-common
depends_on:
<<: *airflow-common-depends-on
airflow-worker:
<<: *airflow-common
environment:
<<: *airflowcommon-envETL: - extract - transform - load
Airflow - планировщик для работы с ETL процессами. Например есть пайплайн для работы с юзерами и каждый вечер нам надо его запускать.
name: todo
services:
db:
image: postgres:18
vol-
restart- -
restart_policy -
replicas- количество контейнеров, которые нужно поднятьservices: db: deploy: replicas: 3
-
depends_on -
healthcheckhealthcheck: test: ["CMD", "curl", "--fail", "localhost:8000/test"]
Варианты для доставки пет-проектов:
- scp
- rsync
Более удобный вариант для загрузки пет проекта:
- docker push
- docker pull
- docker run
Для деплоя на прод еть спец програмы, например Ansible - system configurtion manager. Программа для удаленного управления конфигурации. Описывается структура в виде кода.
- docker push
- docker pull
- ansible playbook
Для Ansible в самом простом случае используются два файла:
inventory- место где описываются сервера - на какие сервера надо сходить ansible.playbook.yaml- описывает какие задачи надо выполнить на серверах
ansible-playbook -i ./inventory playbook.yamlАнсибл также позволяет хранить секреты.
Предположим нам надо хранить и использовать секреты в cicd, но зранить их в открытом виде в credentials.yaml нельзя:
#credentials.yaml
Tokens:
token_1: 123
token_2: 234
token_3: 345У Ansible есть ansible-vault:
ansible-vault encrypt credentials.yamlДалее этот файл шифруется заданным паролем и позже его можно будет расшифровать в пайплайне.
ansible-vault decrypt credentials.yamlили вывести в терминал
ansible-vault view credentials.yamlСущности K8S:
- Namespaces
- Pod - минимальная еденица к8с
- ReplicaSet - абстракция для работы некоторого числа подов
- Deployment - абстракция для более гибкого поведения подов (обновление, откаты) rolling, recreate. Позволяет указать масштабирование.
- Services
- ConfigMaps
- Ingress
- Secrets
- Job
- CronJob
- Persistent Volumes
- ...
miniлube - легкая локальная версия к8с с 1 нодой.
sudo minicube start --vm-driver=none
sudo minikube status# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: frontend
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: kcoursedocker/frontend-demo:v1kubectl - утилита для общения с мастер нодой к8с через cli
список нод
kubectl get nodes
kubectl get podes
# deployments
kubectl get deploy
# replica set
kubectl get rs
# namespaces
kubectl get ns
# запуск
kubectl apply -f deploy.yaml
# удалить все
kubectl delete -f deploy.yaml
# удалить поду
kubetl delete pod <pod name>
# удалить deployment - имя можно взять из метадаты deployment.yaml
kubectl delete deploy <deploy_name>При удалении поды, к8с может автоматически поднять поду в раска конфигурации, если указано дердать некоторое количество под. За это отвечает абстракция реплика-сет.
Strategy - отвечает за обновления. Для применения обновления достаточно поменять конфигурационный файл и применить команду kubectl apply -f deployment.yaml.
Откат до предыдущей версии выполняется также одной командой.
kubectl rollout undo -f deployment.yaml