Podman-compose-to-kube: различия между версиями
Kaf (обсуждение | вклад) |
Kaf (обсуждение | вклад) |
||
Строка 267: | Строка 267: | ||
* подкаталог <code>PersistentVolumeClaim</code> описания kubernet-запроса на монтируемые тома | * подкаталог <code>PersistentVolumeClaim</code> описания kubernet-запроса на монтируемые тома | ||
* подкаталог <code>PersistentVolume</code> описания томов для данного разворачивания. | * подкаталог <code>PersistentVolume</code> описания томов для данного разворачивания. | ||
'''Файл описания Pod-контейнера counter.yml''' | |||
Файл описания Pod-контейнера <code>counter.yml</code> выглядит следующим образом: | Файл описания Pod-контейнера <code>counter.yml</code> выглядит следующим образом: | ||
<pre> | <pre> | ||
# Created with podman-compose-to-kube 1.0.0-alt1 | |||
apiVersion: v1 | apiVersion: v1 | ||
kind: Pod | kind: Pod | ||
Строка 316: | Строка 319: | ||
- web | - web | ||
</pre> | </pre> | ||
Файл описывает в <code>namespace: default</code> в POD'е с именем <code><counter/code> два контейнера: <code>counterredis1</code>, <code>counterweb1</code>. | Файл описывает в <code>namespace: default</code> в POD'е с именем <code><counter</code> два контейнера: <code>counterredis1</code>, <code>counterweb1</code>. | ||
Контейнер <code>counterredis1</code> принимает запросы по порту <code>6379</code> и монтирует каталог <code>/data</code> на том, получаемый по запросу (<code>PersisnentVolumeClaim</code>) с именем (<code>claimName</code>) <code>counter-redis</code>. | Контейнер <code>counterredis1</code> принимает запросы по порту <code>6379</code> и монтирует каталог <code>/data</code> на том, получаемый по запросу (<code>PersisnentVolumeClaim</code>) с именем (<code>claimName</code>) <code>counter-redis</code>. | ||
Строка 324: | Строка 327: | ||
Так как в разворачивании типа <code>POD</code> оба контейнера стартуют в одном <code>POD</code>'е с локальным адресом <code>127.0.0.1</code>, к YML-файлу добавляется описание <code>hostAliases</code>, привязывающий короткие DNS-имена <code>web</code>, <code>redis</code> к локальному адресу <code>127.0.0.1</code>. Таким образом контейнер <code>redis</code> доступен из контейнера <code>web</code> под именем <code>redis</code> через локальный интерфейс <code>lo</code> <code>POD</code>'а. | Так как в разворачивании типа <code>POD</code> оба контейнера стартуют в одном <code>POD</code>'е с локальным адресом <code>127.0.0.1</code>, к YML-файлу добавляется описание <code>hostAliases</code>, привязывающий короткие DNS-имена <code>web</code>, <code>redis</code> к локальному адресу <code>127.0.0.1</code>. Таким образом контейнер <code>redis</code> доступен из контейнера <code>web</code> под именем <code>redis</code> через локальный интерфейс <code>lo</code> <code>POD</code>'а. | ||
'''Подкаталог описания kubernet-сервиса <code>Service</code>''' | |||
Так как в рамках разворачивания запускается всего один <code>POD</code> подкаталог описания kubernet-сервиса <code>Service</code> содержит всего один файл <code>counter.yml</code>: | |||
<pre> | |||
# Created with podman-compose-to-kube 1.0.0-alt1 | |||
apiVersion: v1 | |||
kind: Service | |||
metadata: | |||
creationTimestamp: '2024-01-27T11:05:26Z' | |||
labels: | |||
app: counter | |||
name: counter | |||
namespace: default | |||
spec: | |||
ports: | |||
- name: '6379' | |||
nodePort: 32717 | |||
port: 6379 | |||
targetPort: 6379 | |||
- name: '8080' | |||
nodePort: 31703 | |||
port: 8080 | |||
targetPort: 8080 | |||
selector: | |||
app: counter | |||
type: NodePort | |||
</pre> | |||
Файл описывает для <code>POD</code>'а с именем <code>counter</code> в <code>namespace: default</code> два порта для внешнего доступа: | |||
* <code>6379</code> - с node-портом для внешнего доступа <code>32717</code>; | |||
* <code>8080</code> - с node-портом для внешнего доступа <code>31703</code>. | |||
Если внешний доступ к контейнеру <code>counterredis1</code> не требуется описание порта <code>6379</code> можно удалить. | |||
'''Подкаталог <code>PersistentVolumeClaim</code> описания kubernet-запроса на монтируемые тома''' | |||
docker-compose YML файл содержит описание только одного внешнего тома для сервиса <code>redis</code>. Данное описание генерирует запрос на выделение тома, содержащееся в файле <code>counter-redis.yml</code>: | |||
<pre> | |||
# Created with podman-compose-to-kube 1.0.6-alt1 | |||
apiVersion: v1 | |||
kind: PersistentVolumeClaim | |||
metadata: | |||
annotations: | |||
volume.podman.io/driver: local | |||
creationTimestamp: '2024-01-27T11:05:27Z' | |||
name: counter-redis | |||
namespace: default | |||
spec: | |||
accessModes: | |||
- ReadWriteOnce | |||
resources: | |||
requests: | |||
storage: 1Gi | |||
storageClassName: manual | |||
</pre> | |||
Файл для запроса <code>counter-redis</code> в <code>namespace: default</code> запрашивает том объемом <code>1Gi</code>. | |||
'''Подкаталог <code>PersistentVolume</code> описания томов для данного разворачивания''' | |||
<code></code> | <code></code> |
Версия от 16:43, 27 января 2024
podman-compose-to-kube как средство миграция docker-compose решений в kubernetes
Одной из основных проблем миграции docker-compose
(docker swarm
) решений в kubernetes
является генерация kubernetes-манифестов
из YAML-файлов описания стека сервисов
.
Существует достаточно бедный набор инструментов, решающий данную проблему.
Данный документ описывает решение данной проблемы путем использования команд
podman-compose,
podman-compose-to-kube.
В качестве примера разворачивания стека будет использоваться docker-compose
стек hello-python проекта podman-compose
.
Будут рассмотрены вопросы разворачивания миграции как rootfull
так и rootless-решений
.
Установка ПО, создание пользователей, разворачивание kubernetes
Для разворачивания docker-compose
стеков необходимо установить пакеты podman-compose
, podman-compose-to-kube
.
rootfull-окружение
Разворачивание решений в roofull
окружении производится под пользователем root
.
В создании других пользователей необходимости нет.
Разворачивание roofull-kubernetes
описано в документе Kubernetes.
rootless-решение
Разворачивание rooless-kubernetes
описано в документе Rootless kubernetes.
В процессе его разворачивания создается пользователь u7s-admin
. Вы можете разворачивать rootless podman-compose стек либо в рамках этого пользователя либо создать пользователя, имеющий право загружать образы с внешний репозиториев. В защищенных платформах c10f.
это пользователи, входящие в группу podman_dev
.
Пользователь u7s-admin
входит в эту группу.
Разворачивание docker-compose стека в podman-compose
Загрузка описания стека сервисов hello-python
Скопируйте содержимое каталога hello-python.
Если у Вас установлен git это можно сделать командами:
# git clone -n --depth=1 --filter=tree:0 https://github.com/containers/podman-compose.git # cd podman-compose/ # git sparse-checkout set --no-cone examples/hello-python # git checkout
После выполнения команд в каталоге podman-compose/examples/hello-python
развернется содержание указанного выше каталога.
Разворачивание стека сервисов
Описание стека сервисов
Перейдите в каталог podman-compose/examples/hello-python
.
В каталогн присутсвует файл docker-compose.yml
описание стека сервисов:
--- version: '3' volumes: redis: services: redis: read_only: true image: docker.io/redis:alpine command: ["redis-server", "--appendonly", "yes", "--notify-keyspace-events", "Ex"] volumes: - redis:/data web: read_only: true build: context: . image: hello-py-aioweb ports: - 8080:8080 environment: REDIS_HOST: redis
В сервисе redis
запускается контейнер с томом redis
и портом для внешнего доступа 6379
.
В сервисе web
собирается образ hello-py-aioweb
, получающий имя localhost/hello-py-aioweb
и на его основе запускается контейнер, обеспечивающий прием HTTP-запросов по порту 8080
.
Образ localhost/hello-py-aioweb
собирается на основе Dockerfile
:
FROM python:3.9-alpine WORKDIR /usr/src/app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [ "python", "-m", "app.web" ] EXPOSE 8080
При запуске контейнера запускается python-скрипт app/web.py
, HTTP-принимающий запросы, формирующий счетчик запросов в redis-базе и возвращающий текст с номером запроса.
Запуск стека сервисов
Перед запуском стека сервисов необходимо уточнить файл docker-compose.yml
:
version: '3' volumes: redis: redis1: services: redis: read_only: true image: docker.io/redis:alpine command: ["redis-server", "--appendonly", "yes", "--notify-keyspace-events", "Ex"] volumes: - redis:/data ports: - 6379 web: read_only: true build: context: . image: hello-py-aioweb ports: - 8080:8080 environment: REDIS_HOST: redis REDIS_PORT: 6379
В файл внесены два изменения:
- В сервис
redis
добавлено описание порта6379
. - В сервис
web
добавлено описание переменнойREDIS_PORT: 6379
.
Оба эти изменения необходимы при разворачивании kubernet-сервисов в режиме Deployment
.
Первое изменения связано с тем, что если описание порта отсутствует, то при генерации из за отсутствия информации не сгенерируется YML-файл описания kubernet-сервиса
и redis-контейнер
будет недоступен из контейнера web
.
Второе изменение связано с тем, что в режиме Deployment
в сконтейнер web
экпортируется переменная REDIS_PORT
в формате http://<ip>:<port>
. Приложение App/web.py
обрабатывает это значение в формате <port>
.
Для запуска стека сервисов наберите команду:
podman-compose --in-pod counter -p counter up -d
При использовании podman-compose
версии >= 1.0.7
параметр --in-pod
необязателен.
Параметр -p
задает имя проекта - суффикс имени POD
'а (pod_counter
) и префикс имен контейнеров и томов.
Если параметр -p
отсутствует в качестве имени проекта принимается имя текущего каталога (в нашем случае hello-python
).
В процессе работы podman-compose
выводит список запускаемых команд:
... podman volume inspect counter_redis || podman volume create counter_redis ... podman pod create --name=pod_counter --infra=false --share= ... podman run --name=counter_redis_1 -d --pod=pod_counter --read-only --label ... ... podman run --name=counter_web_1 -d --pod=pod_counter --read-only --label ... ...
После запуска POD'а и контейнеров состояние можно посмотреть командами. - список запущенных POD'ов:
podman pod ls
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS d37ba3addeb3 pod_counter Running 9 minutes ago 2
- Логи контейнеров POD'а:
podman pod logs pod_counter
b5bdc8d1977f 1:C 18 Jan 2024 11:04:20.309 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo ... b5bdc8d1977f 1:M 18 Jan 2024 11:04:20.312 * Ready to accept connections tcp
- Список запущенных контейнеров:
podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ... b5bdc8d1977f docker.io/library/redis:alpine redis-server --ap... 27 minutes ago Up 27 minutes counter_redis_1 49f6f5141b24 localhost/hello-py-aioweb:latest python -m App.web 27 minutes ago Up 27 minutes 0.0.0.0:8080->8080/tcp counter_web_1 ...
- Логи контейнера базы данных redis
podman logs counter_redis_1
1:C 18 Jan 2024 11:04:20.309 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo ... 1:M 18 Jan 2024 11:04:20.312 * Ready to accept connections tcp
- Логи контейнера WEB-интерфейса web:
podman log counter_web_1
Проверка работы стека сервисов
Для проверки работы стека последовательно пошлите запросы командой curl на порт 8080:
# curl localhost:8080/ counter=1 # curl localhost:8080/ counter=2 # curl localhost:8080/ counter=3 ...
Экспорт запущенного POD'а в kubernetes-манифесты и их запуск
Разворачивание в виде kubernetes POD
Генерация манифестов
Генерация манифестов для POD-разворачивания производится командой:
podman-compose-to-kube --debug=1 pod_counter docker-compose.yaml
Generate a POD manifest based on the specified POD Generate a list of scalar yml elements ending with name(Name) Generate a jq request to replace symbols _ with symbols - in selected elements Generate list of services in docker-compose file Add descriptions of the environment variables to the container web Removing the deployment directory manifests/default/counter/Pod Generate common POD YML file Generate PersistentVolumeClaims and PersistentVolumes: manifests/default/counter/Pod/PersistentVolumeClaim/counter-redis.yml manifests/default/counter/Pod/PersistentVolume/default-counter-redis.yml /mnt/PersistentVolumes/default/counter-redis Generate a deploy file manifests/default/counter/Pod/counter.yml of the Pod type:
Если в выводе шагов генерации нет необходимости флаг --debug=1
можно опустить.
Первый параметр pod_counter
указывает имя поднятого podman-POD
'а. Второй docker-compose.yaml
- имя YAML-файла из которого поднят контейнер.
После вызова команды в текущем каталоге создастся подкаталог manifests
следующей структуры:
manifests/ └── default └── counter └── Pod ├── counter.yml ├── PersistentVolume │ └── default-counter-redis.yml ├── PersistentVolumeClaim │ └── counter-redis.yml └── Service └── counter.yml
На первом уровне создастся каталог default
имя которого задает kubernetes-namespace
в котором будет запускаться POD
.
В подкаталоге default
создается подкаталог counter
имя которого берется из имени генерируемого POD
'а отбрасыванием префикса pod_
.
В подкаталоге counter
создается подкаталог по имени разворачивания - Pod
.
В каталоге типа разворачивания Pod
генерируются:
- файл описания Pod-контейнера
counter.yml
; - подкаталог описания kubernet-сервиса
Service
- подкаталог
PersistentVolumeClaim
описания kubernet-запроса на монтируемые тома - подкаталог
PersistentVolume
описания томов для данного разворачивания.
Файл описания Pod-контейнера counter.yml
Файл описания Pod-контейнера counter.yml
выглядит следующим образом:
# Created with podman-compose-to-kube 1.0.0-alt1 apiVersion: v1 kind: Pod metadata: creationTimestamp: '2024-01-27T11:05:26Z' labels: app: counter name: counter namespace: default spec: containers: - args: - redis-server - --appendonly - 'yes' - --notify-keyspace-events - Ex image: docker.io/library/redis:alpine name: counterredis1 ports: - containerPort: 6379 securityContext: readOnlyRootFilesystem: true volumeMounts: - mountPath: /data name: counter-redis-pvc - env: - name: REDIS_HOST value: redis - name: REDIS_PORT value: '6379' image: localhost/hello-py-aioweb:latest name: counterweb1 ports: - containerPort: 8080 securityContext: readOnlyRootFilesystem: true volumes: - name: counter-redis-pvc persistentVolumeClaim: claimName: counter-redis hostAliases: - ip: 127.0.0.1 hostnames: - redis - web
Файл описывает в namespace: default
в POD'е с именем <counter
два контейнера: counterredis1
, counterweb1
.
Контейнер counterredis1
принимает запросы по порту 6379
и монтирует каталог /data
на том, получаемый по запросу (PersisnentVolumeClaim
) с именем (claimName
) counter-redis
.
Контейнер counterweb1
принимает запросы по порту 8080
. В его среду экспортируются две переменные: REDIS_HOST
и REDIS_PORT
.
Так как в разворачивании типа POD
оба контейнера стартуют в одном POD
'е с локальным адресом 127.0.0.1
, к YML-файлу добавляется описание hostAliases
, привязывающий короткие DNS-имена web
, redis
к локальному адресу 127.0.0.1
. Таким образом контейнер redis
доступен из контейнера web
под именем redis
через локальный интерфейс lo
POD
'а.
Подкаталог описания kubernet-сервиса Service
Так как в рамках разворачивания запускается всего один POD
подкаталог описания kubernet-сервиса Service
содержит всего один файл counter.yml
:
# Created with podman-compose-to-kube 1.0.0-alt1 apiVersion: v1 kind: Service metadata: creationTimestamp: '2024-01-27T11:05:26Z' labels: app: counter name: counter namespace: default spec: ports: - name: '6379' nodePort: 32717 port: 6379 targetPort: 6379 - name: '8080' nodePort: 31703 port: 8080 targetPort: 8080 selector: app: counter type: NodePort
Файл описывает для POD
'а с именем counter
в namespace: default
два порта для внешнего доступа:
6379
- с node-портом для внешнего доступа32717
;8080
- с node-портом для внешнего доступа31703
.
Если внешний доступ к контейнеру counterredis1
не требуется описание порта 6379
можно удалить.
Подкаталог PersistentVolumeClaim
описания kubernet-запроса на монтируемые тома
docker-compose YML файл содержит описание только одного внешнего тома для сервиса redis
. Данное описание генерирует запрос на выделение тома, содержащееся в файле counter-redis.yml
:
# Created with podman-compose-to-kube 1.0.6-alt1 apiVersion: v1 kind: PersistentVolumeClaim metadata: annotations: volume.podman.io/driver: local creationTimestamp: '2024-01-27T11:05:27Z' name: counter-redis namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: manual
Файл для запроса counter-redis
в namespace: default
запрашивает том объемом 1Gi
.
Подкаталог PersistentVolume
описания томов для данного разворачивания
Запуск манифестов
Разворачивание в виде kubernetes Deployment
Генерация манифестов
Запуск манифестов
Особенности запуска в rootless окружении
Копирование локальных образов в rootless окружении
В rootless-окружении образы, созданные podman-compose
хранятся в каталоге /var/lib/u7s-admin/.local/share/containers/storage/
. Образы же для kubernetes хранятся в другом каталоге /var/lib/u7s-admin/.local/share/usernetes/containers/storage/
. Для образов, загружаемых с регистраторов это несущественно, так как они подгружаются при запуске POD
'а. Образы же, созданные локально, как в нашем случае образ localhost/hello-py-aioweb
необходимо перенести в container-storage
для kubernetes-образов командой skopeo
:
# skopeo copy \ containers-storage:[/var/lib/u7s-admin/.local/share/containers/storage/]localhost/hello-py-aioweb \ containers-storage:[/var/lib/u7s-admin/.local/share/usernetes/containers/storage/]localhost/hello-py-aioweb
и изменить собственника перенесенного образа с root
на u7s-admin
:
# chown -R u7s-admin:u7s-admin /var/lib/u7s-admin/.local/