Руководство пользователя Podman

Docker

Оригинальная ссылка:Руководство пользователя Podman

Podmanэто былоCRI-Oчасть проекта, которая позже была выделена в отдельный проект под названиемlibpod. Опыт Podman иDockerТочно так же разница в том, что у Podman нет демона. При использовании интерфейса командной строки Docker ранее интерфейс командной строки Docker сообщал Docker Engine «Я хочу запустить контейнер» через gRPC API, а затем Docker Engine проходил через среду выполнения контейнера OCI (по умолчаниюrunc), чтобы запустить контейнер. Это означает, что процесс контейнера не может быть дочерним процессом Docker CLI, но дочерним процессом Docker Engine.

Podman относительно прост и груб, не использует Daemon, а напрямую передает среду выполнения OCI (по умолчанию такжеrunc) для запуска контейнера, поэтому процесс контейнера является дочерним процессом podman. Это больше похоже на линуксfork/execмодель, в то время как Docker используетC/S(клиент-серверная) модель. По сравнению с моделью C/S,fork/execМодели имеют множество преимуществ, таких как:

  • Системные администраторы могут знать, кто запустил процесс контейнера.

  • при использованииcgroupСделайте некоторые ограничения на podman, тогда все созданные контейнеры будут ограничены.

  • SD_NOTIFY: если вы поместите команду podman вsystemdВ юнит-файле процесс-контейнер может возвращать через podman уведомление о том, что сервис готов к приему задач.

  • активация сокета: можно подключитьsocketПерешел из systemd в podman и в процессы-контейнеры для их использования.

Без дальнейших церемоний, давайте перейдем непосредственно к боевой сессии.Эта статья научит вас использовать podman для развертывания статического блога и добавления контейнера, в котором находится блог, в режим sidecar.Envoyв сетке.

1. Архитектура схемы

Мой сценарий развертывания включает два уровня Envoy:

  • Во-первых, будет внешний прокси-сервер, работающий только с контейнером. Задача внешнего прокси-сервера состоит в том, чтобы предоставить посетителю запись для пересылки запроса на доступ извне в конкретную внутреннюю службу.

  • Во-вторых, статическая страница блога обслуживается nginx при запускеEnvoyконтейнер, который используется совместно с nginxnetwork nemspace.

  • Все Envoy образуют сетку, а затем обмениваются информацией о маршрутизации между собой.

Я написал статью раньшеDockerРазверните статический блог Hugo и настройтеHTTPSСтатья о сертификате, в этой статье используется та же схема, просто замените докер на podman, конкретная ссылкаВключите проверку TLS для Envoy.

2. Разверните прокси-сервер Hugo и Sidecar

Мой блог представляет собой статическую страницу, сгенерированную Hugo, и ее можно разместить вnginx, другие инструменты статического веб-сайта аналогичны (например, hexo и т. д.), вы можете сделать это. Теперь то, что я хочу сделать, этоПусть контейнер nginx и контейнер envoy используют одно и то же сетевое пространство имен и в то же время позволяют внешнему прокси-серверу выполнять обнаружение службы через доменное имя.. Раньше использовать docker было очень просто, и это делалось напрямую с помощью docker-compose, но с podman было сложнее, и его нельзя было использовать.docker-compose, обнаружение службы, кажется, испорчено.

Наконец нашел проект на Github под названиемpodman-compose, я думал, что он был сохранен, я попробовал его и обнаружил, что он все еще не работает Когда podman-compose создал контейнер, поляnetwork_mode: "service:hugo"Преобразовано в аргументы интерфейса командной строки podman.--network service:hugo(Действительно безмозглый), что приводит к сбою создания контейнера, сообщение об ошибкеCNI network "service:hugo" not found. Измените значение поля наnetwork_mode: "container:hugo_hugo_1"Его можно запустить успешно, но возникает другая проблема: практика podman-compose есть у каждогоserviceСоздаватьpod(Название модуля — это имя каталога, в котором находится docker-compose.yml), а затем добавьте в этот модуль контейнер. Я не могу всегда втиснуть внешний прокси и внутренний сервис в один и тот же модуль? Вы можете создать только два каталога для внешнего прокси и Hugo, а затем создать docker-compose.yml соответственно. Эта проблема решена, и снова возникает следующая проблема: podman-compose не поддерживает обнаружение службы через имя службы.links(На самом деле это добавление параметра--add-host), но ссылки действуют только в рамках одного и того же модуля. Я разделил его на два модуля. Что я могу сделать, единственный способ сейчас - вручную запустить командную строку.

Выше я упомянул новый термин, называемыйpod, потратьте 30 секунд, чтобы дать вам краткое введение, если выKubernetesЕсли вы активный пользователь , вам должно быть знакомо это слово, но оно означает стручок podman. Значение остается тем же. Сначала создайте его.pauseКонтейнеры, а затем создайте бизнес-контейнеры, которые совместно используются бизнес-контейнерами.pauseРазличные пространства имен Linux для контейнеров, поэтому контейнеры в одном модуле могут легко взаимодействовать друг с другом через локальный хост. Мало того, podman также может экспортировать модули как декларативные определения ресурсов Kubernetes, например:

Сначала создайте pod:

$ podman pod create --name hugo

Просмотр подов:

$ podman pod ls

POD ID         NAME   STATUS    CREATED         # OF CONTAINERS   INFRA ID
88226423c4d2   hugo   Running   2 minutes ago   2                 7e030ef2e7ca

Запустите контейнер Hugo в этом модуле:

$ podman run -d --pod hugo nginx:alpine

Посмотреть контейнеры:

$ podman ps

CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS            PORTS  NAMES
3c91cab1e99d  docker.io/library/nginx:alpine  nginx -g daemon o...  3 minutes ago  Up 3 minutes ago         reverent_kirch

Просмотреть все контейнеры, включая контейнеры паузы:

$ podman ps -a

CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS            PORTS  NAMES
3c91cab1e99d  docker.io/library/nginx:alpine  nginx -g daemon o...  4 minutes ago  Up 4 minutes ago         reverent_kirch
7e030ef2e7ca  k8s.gcr.io/pause:3.1                                  6 minutes ago  Up 6 minutes ago         88226423c4d2-infra

Просмотрите все контейнеры, в том числе приостановленные, и отобразите идентификатор пода, которому принадлежит контейнер:

$ podman ps -ap

CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS            PORTS  NAMES               POD
3c91cab1e99d  docker.io/library/nginx:alpine  nginx -g daemon o...  4 minutes ago  Up 4 minutes ago         reverent_kirch      88226423c4d2
7e030ef2e7ca  k8s.gcr.io/pause:3.1                                  6 minutes ago  Up 6 minutes ago         88226423c4d2-infra  88226423c4d2

Просмотрите использование ресурсов процессами в модуле:

$ podman pod top hugo

USER    PID   PPID   %CPU    ELAPSED           TTY   TIME   COMMAND
root    1     0      0.000   8m5.045493912s    ?     0s     nginx: master process nginx -g daemon off;
nginx   6     1      0.000   8m5.045600833s    ?     0s     nginx: worker process
nginx   7     1      0.000   8m5.045638877s    ?     0s     nginx: worker process
0       1     0      0.000   9m41.051039367s   ?     0s     /pause

Экспортируйте модуль как декларативный манифест развертывания:

$ podman generate kube hugo > hugo.yaml

Просмотрите содержимое манифеста развертывания:

$ cat hugo.yaml

# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-1.0.2-dev
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: 2019-10-17T04:17:40Z
  labels:
    app: hugo
  name: hugo
spec:
  containers:
  - command:
    - nginx
    - -g
    - daemon off;
    env:
    - name: PATH
      value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: HOSTNAME
    - name: container
      value: podman
    - name: NGINX_VERSION
      value: 1.17.4
    - name: NJS_VERSION
      value: 0.3.5
    - name: PKG_RELEASE
      value: "1"
    image: docker.io/library/nginx:alpine
    name: reverentkirch
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
    workingDir: /
status: {}

Как, есть знакомый вкус? Это определение пода, совместимое с Kubernetes, вы можете напрямую передатьkubectl apply -f hugo.yamlРазверните его в кластере Kubernetes или напрямую через podman, примерно так:

Первые удаления стручков ранее созданные:

$ podman pod rm -f hugo

Затем создайте модуль через манифест развертывания:

$ podman play kube hugo.yaml

Возвращаясь к предыдущему вопросу, если вы создаете модули с помощью декларативных определений, вы все равно не сможете решить проблему обнаружения службы, если не перейдете на ту, которая поддерживает статический IP.CNIПлагины и эти CNI-плагины, поддерживающие статический IP-адрес, также нуждаются в etcd в качестве базы данных.У меня очень мало ресурсов, но я не хочу добавлять etcd, поэтому я просто запущу командную строку вручную.

Сначала я должен создать контейнер Hugo и указать IP-адрес контейнера:

$ podman run -d --name hugo \
  --ip=10.88.0.10 \
  -v /opt/hugo/public:/usr/share/nginx/html \
  -v /etc/localtime:/etc/localtime \
  nginx:alpine

Создайте еще один контейнер envoy, чтобы разделить сетевое пространство имен с контейнером Hugo:

$ podman run -d --name hugo-envoy \
  -v /opt/hugo/service-envoy.yaml:/etc/envoy/envoy.yaml \
  -v /etc/localtime:/etc/localtime \
  --net=container:hugo envoyproxy/envoy-alpine:latest

Содержимое service-envoy.yaml выглядит следующим образом:

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - name: envoy.file_access_log
            config:
              path: "/dev/stdout"
          route_config:
            name: local_route
            virtual_hosts:
            - name: service
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: local_service
          http_filters:
          - name: envoy.router
            config: {}
  clusters:
  - name: local_service
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    hosts:
    - socket_address:
        address: 127.0.0.1
        port_value: 80
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8081

Пожалуйста, обратитесь к конкретному значениюВключите проверку TLS для Envoy.

В начале этой статьи упоминается, что контейнер, созданный podman, является подпроцессом podman.Это выражение может быть расплывчатым.На самом деле podman состоит из двух частей, одна из которых является интерфейсом командной строки podman, а другая является средой выполнения контейнера. среда выполнения контейнера состоит изconmonнести ответственность, в основном включая мониторинг, ведение журнала, выделение TTY и тому подобноеout-of-memoryХлопоты ситуации. То есть conmon является родительским процессом всех контейнеров.

Конмон должен делать всеsystemdВещи, которые вы не делаете или не хотите делать. Несмотря на то, что CRI-O не использует systemd напрямую для управления контейнерами, он назначает контейнеры системно-совместимым.cgroup, такие обычные инструменты systemd, какsystemctlВы можете увидеть использование ресурсов контейнера.

$ podman ps

CONTAINER ID  IMAGE                                     COMMAND               CREATED             STATUS                 PORTS  NAMES
42762bf7d37a  docker.io/envoyproxy/envoy-alpine:latest  /docker-entrypoin...  About a minute ago  Up About a minute ago         hugo-envoy
f0204fdc9524  docker.io/library/nginx:alpine            nginx -g daemon o...  2 minutes ago       Up 2 minutes ago              hugo

Учащиеся, незнакомые с контрольными группами, могут обратиться к следующей серии статей:

Студенты с нулевой базой предлагают обновиться сверху вниз по приведенному выше списку, желаю удачи!

3. Разверните внешний прокси

Это очень просто, просто создайте контейнер напрямую:

$ podman run -d --name front-envoy \
--add-host=hugo:10.88.0.10 \
-v /opt/hugo/front-envoy.yaml:/etc/envoy/envoy.yaml \
-v /etc/localtime:/etc/localtime \
-v /root/.acme.sh/yangcs.net:/root/.acme.sh/yangcs.net \
--net host envoyproxy/envoy

Поскольку автоматического обнаружения службы нет, необходимо передать параметры--add-hostВручную добавьте хосты в контейнер. В конфигурационном файле envoy кластер добавляется через доменное имя, содержимое front-envoy.yaml такое:

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 80
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - name: envoy.file_access_log
            config:
              path: "/dev/stdout"
          route_config:
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/"
                redirect:
                  https_redirect: true
                  response_code: "FOUND"
          http_filters:
          - name: envoy.router
            config: {}
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 443
    filter_chains:
    - filter_chain_match:
        server_names: ["yangcs.net", "www.yangcs.net"]
      tls_context:
        common_tls_context:
          alpn_protocols: h2
          tls_params:
            tls_maximum_protocol_version: TLSv1_3
          tls_certificates:
            - certificate_chain:
                filename: "/root/.acme.sh/yangcs.net/fullchain.cer"
              private_key:
                filename: "/root/.acme.sh/yangcs.net/yangcs.net.key"
      filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "yangcs.net"
              - "www.yangcs.net"
              routes:
              - match:
                  prefix: "/admin"
                route:
                  prefix_rewrite: "/"
                  cluster: envoy-ui
              - match:
                  prefix: "/"
                route:
                  cluster: hugo
                  response_headers_to_add:
                    - header:
                        key: "Strict-Transport-Security"
                        value: "max-age=63072000; includeSubDomains; preload"
          http_filters:
          - name: envoy.router
            config: {}
  clusters:
  - name: hugo
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    http2_protocol_options: {}
    hosts:
    - socket_address:
        address: hugo
        port_value: 8080
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8001

Пожалуйста, обратитесь к конкретному значениюВключите проверку TLS для Envoy.

Теперь вы можете получить доступ к веб-сайту блога через общедоступное доменное имя.Если в будущем появятся другие приложения, вы можете обратиться к шагам, описанным в разделе 2, а затем воссоздать внешний прокси-сервер и добавить--add-hostпараметр. возьми мой сайтwww.yangcs.netНапример:

Кажется, я раскрыл что-то ужасное, так что стой здесь, не говори этого, не спрашивай.

4. Самостоятельный запуск при загрузке

Поскольку podman больше не использует демон для управления службой,--restartОт параметров отказались.Для автоматического запуска контейнера при загрузке им может управлять только systemd. Сначала создайте файл конфигурации службы systemd:

$ vim /etc/systemd/system/hugo_container.service

[Unit]
Description=Podman Hugo Service
After=network.target
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/podman start -a hugo
ExecStop=/usr/bin/podman stop -t 10 hugo
Restart=always

[Install]
WantedBy=multi-user.target
$ vim /etc/systemd/system/hugo-envoy_container.service

[Unit]
Description=Podman Hugo Sidecar Service
After=network.target
After=network-online.target
After=hugo_container.service

[Service]
Type=simple
ExecStart=/usr/bin/podman start -a hugo-envoy
ExecStop=/usr/bin/podman stop -t 10 hugo-envoy
Restart=always

[Install]
WantedBy=multi-user.target
$ vim /etc/systemd/system/front-envoy_container.service

[Unit]
Description=Podman Front Envoy Service
After=network.target
After=network-online.target
After=hugo_container.service hugo-envoy_container.service

[Service]
Type=simple
ExecStart=/usr/bin/podman start -a front-envoy
ExecStop=/usr/bin/podman stop -t 10 front-envoy
Restart=always

[Install]
WantedBy=multi-user.target

Затем остановите ранее созданный контейнер,Примечание: это остановить, а не удалить!

$ podman stop $(podman ps -aq)

Наконец, эти контейнеры запускаются через службу systemd.

$ systemctl start hugo_container
$ systemctl start hugo-envoy_container
$ systemctl start front-envoy_container

Установите автоматический запуск.

$ systemctl enable hugo_container
$ systemctl enable hugo-envoy_container
$ systemctl enable front-envoy_container

После каждого перезапуска системы systemd автоматически запускает контейнер, соответствующий этой службе.

4. Резюме

Выше перечислены все изменения по переносу блога с Docker на Podman, в целом это довольно мучительно, т.к. Podman разработан для Kubernetes, а мои требования слишком высоки, просто vps с ограниченными ресурсами, т.е. хочу пойтиKubernetes, не хочуetcd,хочу заниматься и коляской и автоматическим обслуживанием открытием,что поделать,я тоже в отчаянии,не могу винить в этом podman,чтобы это не осталось у всех в сердце«Подман не работает»впечатление, настоящим заявляю. Я ничего не хочу, я просто должен разобраться~

Публичный аккаунт WeChat

Отсканируйте QR-код ниже, чтобы подписаться на официальную учетную запись WeChat, и ответьте на официальную учетную запись ◉Добавить группу◉, чтобы присоединиться к нашей облачной коммуникационной группе и обсудить облачные технологии с Сунь Хунляном, директором Чжаном, Ян Мином и другими важными шишками.