将容器从 Raspberry Pi OS 迁移到 Fedora Linux

本文介绍了如何将典型的容器设置从 Raspberry Pi OS 转换为 Fedora Linux 在 example Traefik 反向代理。 我们从一个已经设置好的开始 Fedora Linux 保持这一点,这是在第一次接触时了解基本差异和选项 Fedora Linux 和播客。

介绍

特拉菲克 是一个“容器原​​生”代理,因此可以巧妙地集成到基于容器的系统中。 它可以从“docker”-socket 中读取完成其工作所需的几乎所有内容。 某些配置会自动加载,而您为其余配置提供您操作的容器上的容器标签。 Traefik 然后绑定主机端口并将流量(HTTP、TCP、UDP)路由到其他容器。

波德曼 容器编排器是否开启 Fedora Linux。 它是 docker 的直接替代品。

在它的心脏 Fedora Linux 与 Raspberry Pi OS 有一些根本区别:

一个缺点是缺少 raspi-config,这会让您阅读(非常好) 树莓派的文档 并手动完成大部分配置任务。

编排选项

总而言之 Fedora Linux 为您提供了一系列操作容器的选项:

  • podman socket + docker-compose 作为 docker + docker-compose 的替代品
  • 播客+系统
  • podman 玩转类似 kubernetes 的 pod 配置文件
  • 适用于上述所有内容的无根 podman

您将使用 podman socket + docker-compose,因为它涉及的概念和技术变化最少。 这是一个很好的起点。 接下来更进一步,迁移到 systemd 单元。 podman 播放和无根方法将不得不等待另一个时间。 在本文的最后,您将获得 Fedora 具有通过 docker-compose 或 systemd 运行的 Traefik 反向代理的 Linux 系统,以及在使用 Fedora Linux。

先决条件

文章使用 Docker Compose 和 Podman 来编排容器 Fedora Linux 向您介绍运行 docker-compose 的基础知识 Fedora Linux。 一定要检查一下!

让我给你那篇文章的要点。 安装包 podman、podman-docker 和 docker-compose。 podman 包提供了运行容器的命令。 podman-docker 包提供了将 podman 伪装成旧工具和应用程序的 docker 所需的一切。 docker-compose 是熟悉的播放器,它不会知道它实际上是在与 podman 交谈。

在 Fedora 物联网和 Fedora CoreOS 运行:

sudo rpm-ostree install podman podman-docker docker-compose
sudo systemctl enable podman.socket
sudo systemctl reboot

在 Fedora 服务器(ARM)运行:

sudo dnf install podman podman-docker docker-compose
sudo systemctl enable podman.socket
sudo systemctl reboot

确保服务处于活动状态并且文件 docker.sock 存在。

sudo systemctl status podman.socket
ls -la /var/run/docker.socket

迁移到 podman + docker-compose

将 Traefik 从 Raspberry Pi 操作系统移至 Fedora Linux。 这应该包括一个 acme 文件夹、docker-compose.yml 和任何 traefik 配置文件。 在此期间,我会去喝杯咖啡。

将文件放在下面,对于 example/var/srv/traefik.

$ ls -la /var/srv/traefik
total 8
drwxr-xr-x.  3 root root   63 Sep  3 09:04 .
drwxr-xr-x. 15 root root  204 Sep  5 10:07 ..
drwx--x--x.  2 root root   23 Aug 19 17:07 acme
-rw-------.  1 root root 1813 Sep  3 09:04 docker-compose.yml
-rw-------.  1 root root 2178 Aug 26 13:21 traefik.toml

使用 chcon 命令更改要挂载到容器中的所有文件的 SELinux 类型标签。 在 Fedora Linux,SELinux 默认限制对主机系统上文件的访问以进行容器挂载。 最好的做法是尽可能将访问模式限制为证书文件和配置(可能包含机密)。

sudo chcon -Rt container_file_t /var/srv/proxy/acme /var/srv/proxy/traefik.toml
sudo chmod 0700 /var/srv/proxy/acme
sudo chmod 0600 /var/srv/proxy/docker-compose.yml /var/srv/proxy/traefik.toml

创建一个名为 proxy 的 podman 网络。 该网络为 traefik 提供服务,将所有请求路由到暴露在端口 80 和 443 上的容器。

$ sudo podman network create proxy
/etc/cni/net.d/proxy.conflist

更改 docker-compose 文件

最小的目标 Traefik 组合文件将如下所示。 它所做的只是绑定到主机上的 80 端口,实现一个基本的包罗万象的路由器,配置 docker 提供程序并在端口 8080 上公开不安全的仪表板。

version: '2'
services:
  proxy:
    image: docker.io/library/traefik:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)"
      - "traefik.http.routers.http_catchall.entrypoints=web"
      - "traefik.http.middlewares.compress.compress=true"
    security_opt:
      - label=disable
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/srv/traefik/traefik.toml:/etc/traefik/traefik.toml:ro"
      - "/var/run/docker.sock:/var/run/docker.sock"
    command:
      - "--entryPoints.web.address=:80"
      - "--providers.docker=true"
      - "--providers.docker.exposedByDefault=false"
      - "--log.level=INFO"
      - "--api.insecure=true"
    networks:
      proxy:
    restart: always

networks:
  proxy:
    external: true

Raspberry Pi OS 上的 compose 文件存在细微差别。 让我们逐步了解它们。

与 docker 相比,podman 编排器在从 Internet 拉取图像时会考虑多个注册表。 像 traefik:latest 这样的短名称是模棱两可的。 我建议您为 docker.io/library/traefik:latest 之类的图像提供全名。 否则 podman 将尝试每个注册表并使用第一个匹配项或产生交互式输入请求。 由于 docker 没有这种行为,docker-compose 完全被混淆了,只是出错了。

您必须提供 security_opt: label=disable 标志。 Traefik 等应用程序支持读取 docker.sock 以获取有关您的编排的信息。 SELinux 限制了这种访问。 要授予完全的、不安全的访问权限,可以禁用容器内的 SELinux 标签。

在 podman 容器中使用 rootfull docker.sock 会引发各种安全问题,就像使用 docker 容器一样。 稍微更安全的方法是使用受信任的 码头插座代理 容器,它允许您过滤套接字上允许的 API 方法。 当前可用的最安全的选项是使用无根用户套接字。 但是如何做到这一点的解释将不得不等待它自己的文章。

接下来通过 docker-compose 启动 traefik:

sudo docker-compose -f /var/srv/proxy/docker-compose.yml up -d

导航到端口 8080 上的 Raspberry Pi 以验证 Traefik 确实已启动并正在运行。

迁移到 systemd

podman-docker 和 docker-compose 的另一种方法是 systemd 单元。 这是编排容器的推荐方式 Fedora Linux; 如果有的话。 不过,这可能很难缠住你的头。 在 systemd 中指定容器及其依赖项比编写单个 docker-compose 文件要繁琐一些。 但是你获得了一个更原生的系统 Fedora 使用 systemd 时的 Linux。

有几种方法可以实现从 docker-compose 到 systemd 单元的迁移。 我们将专注于使用内置命令 podman generate systemd。

方便的命令 podman generate systemd 获取当前编排容器的快照并将其配置保存在 systemd 单元中,以便您可以通过 systemctl 启动和停止它们。 每个以 podman containers run 或 podman pod create 开始的容器都会按照推荐的格式转换为有效的 systemd 单元。

以这种方式创建一个或多个容器后,您会发现您可以简单地复制粘贴单元文件并更改其内容以满足您的需要。 这个过程真的没有什么特别的。 不过,我建议您不时使用 podman generate systemd。 该命令包含有关 systemd 如何工作的大量知识,并且它会定期接收更新。 更新可能会以小的方式更改单元文件格式,从而提高稳定性或修补错误。

podman 生成 systemd

要从头开始使用 podman generate systemd 命令,您必须通过手动编写 podman containers run 语句来启动容器一次。 几次之后,您也可以复制单元文件并仅更改小方面以适合您的应用程序。

假设您将上述撰写文件中的标签放入文件 /var/srv/traefik/labels 并将 traefik CLI 选项移动到 traefik.toml。 上述容器规范生成的 podman run 命令如下所示:

sudo podman run 
    --security-opt label=disable 
    --label-file /var/srv/traefik/label 
    --network proxy 
    --network-alias=traefik 
    --name traefik 
    -v "/var/srv/traefik/traefik.toml:/etc/traefik/traefik.toml:ro" 
    -v "/var/run/docker.sock:/var/run/docker.sock" 
    -p 80:80 
    -p 8080:8080 
    -d 
    docker.io/library/traefik:latest

这将为您提供一个带有 podman 的正在运行的 traefik 容器。 确认:

sudo podman ps -a
sudo podman logs -f traefik
curl -v https://localhost:8080/

现在从中生成一个 systemd 单元并将其放在 /etc/systemd/system 目录中。 之后启用并启动它:

$ sudo podman generate systemd --new --name traefik | sudo tee /etc/systemd/system/container-traefik.service
# container-traefik.service
# autogenerated by Podman 3.3.1
# Wed Sep 15 08:58:59 CEST 2021

[Unit]
Description=Podman container-traefik.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run 
    --cidfile=%t/%n.ctr-id 
    --sdnotify=conmon 
    --cgroups=no-conmon 
    --rm 
    --replace 
    --security-opt label=disable 
    --label-file /var/srv/traefik/label 
    --network proxy 
    --network-alias=traefik 
    --name traefik 
    -v /var/srv/traefik/traefik.toml:/etc/traefik/traefik.toml:ro 
    -v /var/run/docker.sock:/var/run/docker.sock 
    -p 80:80 
    -p 8080:8080 
    -d 
    docker.io/library/traefik:latest
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target default.target

删除生成此单元文件所需的初始容器。 然后启用并启动设备并验证结果:

sudo podman rm -f traefik
sudo systemctl enable --now container-traefik.service
sudo systemctl status container-traefik.service
sudo podman ps -a
sudo podman logs -f traefik

traefik 容器现在由 podman + systemd 操作,将在启动时自动启动。 恭喜! 为了控制容器之间的启动顺序和依赖关系,您现在可以使用 systemd 工具。

豆荚在哪里?

您通过使用手动创建的网络和由 systemd 依赖项粘合在一起的容器构建了一个 podman+systemd 结构。 您可能已经想知道为什么它被称为 podman,尽管我们不使用任何与 pod 相关的东西。 特别是对于具有更复杂依赖关系的容器,例如具有多个数据库、搜索引擎和缓存的应用程序,podman 了解 pod 的概念。 Pod 本质上是一个空间,所有容器都参与其中并相互查看,就好像它们在同一主机上运行一样。 您还可以将该构造转换为 systemd 托管的构造。 现在,我将把它作为练习留给你。

如果您配置基于 pod 的设置并在其上使用 podman generate systemd,或者您是否使用网络和所有内容手动组合容器并将其转换为 systemd 单元,这完全取决于您。

概括

太好了,你做到了这一点! 到目前为止,您已经使用 podman.sock 设置了一个基于 docker-compose 的简单 traefik 安装。 您了解了从 Raspberry Pi OS 过渡到 Fedora Linux 涉及到普通的容器编排。 在第一次成功之后,您更进一步,使用 podman generate systemd 从头开始​​将 docker-compose 文件迁移到 systemd 单元中。

Systemd 在启动时通过 podman 创建 traefik 容器并管理其依赖项。 Traefik 通过 podman.socket 接收其配置,作为 docker 的替代品,并通过手动创建的 podman 网络代理与其他容器通信。

下一步是什么? 您可能想看看如何使用 rootless podman 操作容器堆栈。 也许还有无根的 podman.socket + docker-compose? 这绝对是可能的。

故障排除

首次迁移到 Fedora (IoT) 来自像 Raspberry Pi OS 这样的基于 debian 的系统,您最终可能会陷入几个陷阱。 让我们确保你有尊严地离开那里。

应用程序配置文件的权限被拒绝:

这很可能是 SELinux 问题。 通过 ls -laZ 检查相关文件的标签是否为 container_file_t。 如果不是,请使用 chcon -Rt container_file_t 进行更改。

/var/run/docker.sock 上的权限被拒绝:

再一次,这可能与 SELinux 有关。 确保使用 –security-opt label=disable 启动容器,或者套接字具有标签 container_file_t。 不幸的是,每次重新创建套接字时,它的标签都会被重置。

Docker-compose 错误:

podman 和 docker-compose 之间可能会发生一些怪癖。 docker-compose 不知道 podman 的一些功能。 这可能会导致意外或误导性错误消息。 在调试模式下运行 docker-compose 并使用 journalctl -xe 检查日志。

可能的错误是:

  • 容器状态不一致:先尝试使用docker-compose down
  • 模糊的图像名称:确保使用完整的图像名称,包括它们的注册表

资源