标签 容器 下的文章

CRI-O 是 Kubernetes 的开源轻量级容器运行时。它是使用 开放容器组织 Open Container Initiative (OCI)兼容运行时的 Kubernetes 容器运行时接口 Container Runtime Interface (CRI)的实现。在运行 Kubernetes 时,它是 Docker 的完美替代品。

在本指南中,我们将逐步演示如何在 Ubuntu 22.04 LTS 上安装 CRI-O。

先决条件

在开始之前,这是你需要的:

  • 具有 SSH 访问权限的 Ubuntu 22.04 实例
  • 在实例上配置的 sudo 用户
  • 快速稳定的互联网连接

有了这个,让我们开始吧。

步骤 1:更新系统并安装依赖

立即登录你的服务器实例,并按如下方式更新包列表:

$ sudo apt update

更新本地包索引后,按如下方式安装依赖项:

$ sudo apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common -y

步骤 2:添加 CRI-O 存储库

要安装 CRI-O,我们需要在 Ubuntu 上添加或启用它的仓库。但首先,你需要根据操作系统和要安装的 CRI-O 版本定义变量。

因此,定义如下变量:

$ export OS=xUbuntu_22.04
$ export CRIO_VERSION=1.24

完成后,运行以下命令集以添加 CRI-O Kubic 仓库:

$ echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /"| sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
$ echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$CRIO_VERSION/$OS/ /"|sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$CRIO_VERSION.list

此后,为 CRI-O 仓库导入 GPG 密钥:

$ curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$CRIO_VERSION/$OS/Release.key | sudo apt-key add -
$ curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | sudo apt-key add -

这会产生如下输出:

再次更新包索引,使系统与新添加的 CRI-O Kubic 仓库同步:

$ sudo apt update

步骤 3:在 Ubuntu 22.04 上安装 CRI-O

添加仓库后,使用 APT 包管理器安装 CRI-O 和运行时客户端:

$ sudo apt install cri-o cri-o-runc -y

安装后,启动并启用 CRI-O 守护程序:

$ sudo systemctl start crio
$ sudo systemctl enable crio

接下来,验证 CRI-O 服务是否正在运行:

$ sudo systemctl status crio

你应该看到以下输出,表明 CRI-O 服务正在按预期运行:

步骤 4:为 CRI-O 安装 CNI 插件

接下来,你需要安装 CNI( 容器网络接口 Container Network Interface )以及 CNI 插件。请记住,环回和桥接配置已启用并且足以使用 CRI-O 运行 容器荚 Pod

因此,要安装 CNI 插件,请运行以下命令:

$ sudo apt install containernetworking-plugins -y

安装后,编辑 CRI-O 配置文件:

$ sudo nano /etc/crio/crio.conf

取消注释 network_dirplugin_dirs 部分,并在 plugin_dirs 下添加 /usr/lib/cni/

保存更改并退出配置文件。

接下来,重启 CRIO 服务:

$ sudo systemctl restart crio

步骤 5:安装 CRI-O 工具

此外,你还需要安装 cri-tools 包,它提供了 crictl 命令行程序,用于交互和管理容器和 pod。

为此,请运行以下命令:

$ sudo apt install -y cri-tools

安装后,确认 crictl 的版本和 RunTimeVersion 如下:

$ sudo crictl --runtime-endpoint unix:///var/run/crio/crio.sock version

一定要检查 CRI-O 是否准备好使用以下命令部署容器荚:

$ sudo crictl info

crictl 命令提供自动补全功能,让你可以通过按 TAB 键自动补全命令。要启用命令补全,请运行以下命令:

$ sudo su -

# crictl completion > /etc/bash_completion.d/crictl

然后重新加载当前的 Bash 会话:

# source ~/.bashrc

要使用自动补全功能,你需要注销或启动新的终端会话。然后只需键入 crictl 命令并按 TAB 键即可查看所有选项。

$ crictl

步骤 6:使用 crictl 程序创建容器荚

至此,CRI-O 已完全安装和配置并准备好启动容器荚。在本节中,我们将在容器荚中创建一个 Apache Web 服务器并确认它是否正在处理请求。

首先,我们将使用容器荚配置文件设置一个沙箱或隔离环境,如下所示:

$ sudo nano apache_sandbox.json

然后我们将以下配置添加到文件中:

{
    "metadata": {
        "name": "apache-sandbox",
        "namespace": "default",
        "attempt": 1,
        "uid": "hdishd83djaidwnduwk28bcsb"
    },
    "linux": {
    },
    "log_directory": "/tmp"
}

保存并退出。接下来使用以下命令创建容器荚。这会打印出很长的字母数字,它是容器荚 ID。

$ sudo crictl runp apache_sandbox.json

要确认容器荚已创建,请运行命令:

$ sudo crictl pods

要检索有关创建的容器荚的更多信息,请运行以下命令:

$ sudo crictl inspectp --output table 05ba2f0704f22

这将打印出 ID、名称、UID、命名空间、创建日期、内部 IP 等详细信息。

步骤 7:在容器荚中创建容器

这部分中,我们将在容器荚中创建一个 Apache Web 服务器容器。因此,使用 crictl 程序从 Docker Hub 拉取 Apache Web 服务器镜像:

$ sudo crictl pull httpd

你可以如图所示验证拉取的镜像:

$ sudo crictl images

接下来,我们将为 Apache Web 服务器定义一个容器配置文件:

$ sudo nano container_apache.json

复制并粘贴以下代码:

{
  "metadata": {
      "name": "apache"
    },
  "image":{
      "image": "httpd"
    },
  "log_path":"apache.0.log",
  "linux": {
  }
}

保存并退出配置文件。

最后,要将容器连接到之前创建的沙盒容器荚,请运行以下命令:

$ sudo crictl create 05ba2f0704f22 container_apache.json apache_sandbox.json

这会向终端输出一长串字母数字 ID。请记下此 ID。

最后,使用 ID 启动 Apache Web 服务器容器,如下所示:

$ sudo crictl start 37f4d26510965452aa918f04d629f5332a1cd398d4912298c796942e22f964a7

要检查容器状态,请运行以下命令:

$ sudo crictl ps

要验证 Apache Web 服务器是否正在运行,请使用 curl 命令和容器荚的内部 ID 向 Web 服务器发送 HTTP 请求:

$ curl -I 10.85.0.2

以下输出确认 Web 服务器正在运行:

结论

这就是全部的指南。我们已经在 Ubuntu 22.04 上成功安装了 CRI-O,并继续创建容器荚和容器。欢迎你提出意见和反馈。


via: https://www.linuxtechi.com/install-crio-container-runtime-on-ubuntu/

作者:James Kiarie 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Podman Desktop 是一个开源 GUI 应用,用于在 Linux、macOS 和 Windows 上管理容器。

从历史上看,开发人员一直使用 Docker Desktop 对容器进行图形化管理。这适用于那些安装了 Docker Daemon 和 Docker CLI 的人。然而,对于那些使用无守护进程的 Podman 工具的人来说,虽然有一些 Podman 前端,如 PodsPodman desktop companionCockpit,但没有官方应用。现在不是这种情况了。有了 Podman Desktop!

本文将讨论由红帽和其他开源贡献者开发的 Podman Desktop 的特性、安装和使用。

安装

要在 Fedora Linux 上安装 Podman Desktop,请访问 podman-desktop.io,然后单击 “Download for Linux” 按钮。你将看到两个选项:Flatpak 和 zip。在这个例子中,我们使用的是 Flatpak。单击 “Flatpak” 链接后,通过双击文件在 GNOME 软件中打开它(如果你使用的是 GNOME)。你也可以通过终端安装它:

flatpak install podman-desktop-X.X.X.flatpak

在上面的命令中,将 X.X.X 替换为你下载的特定版本。如果你下载了 zip 文件,那么解压缩存档,然后启动 Podman Desktop 应用的二进制文件。你还可以通过进入 GitHub 上项目的 发布 页找到预发布版本。

特性

Podman Desktop 仍处于早期阶段。然而,它支持许多常见的容器操作,如创建容器镜像、运行容器等。此外,你可以在 “ 首选项 Preferences ” 的 “ 扩展 Extensions ” 部分下找到 Podman 扩展,你可以使用它来管理 macOS 和 Windows 上的 Podman 虚拟机。

此外,Podman Desktop 支持 Docker Desktop 扩展。你可以在 “ 首选项 Preferences ” 下的 “Docker Desktop Extensions” 安装此类扩展。应用窗口有两个窗格。左侧窄窗格显示应用的不同功能,右侧窗格是内容区域,它将根据左侧选择的内容显示相关信息。

Podman Desktop 0.0.6 在 Fedora 36 上运行

演示

为了全面了解 Podman Desktop 的功能,我们将从 Dockerfile 创建一个镜像并将其推送到注册中心,然后拉取并运行它,这一切都在 Podman Desktop 中完成。

构建镜像

第一步是通过在命令行中输入以下行来创建一个简单的 Dockerfile:

cat <<EOF>>Dockerfile
FROM docker.io/library/httpd:2.4
COPY . /var/www/html 
WORKDIR /var/www/html 

CMD ["httpd", "-D", "FOREGROUND"]
EOF

现在,点击 “ 镜像 Images ” 并按下 “ 构建镜像 Build Image ” 按钮。你将被带到一个新页面以指定 Dockerfile、构建上下文和镜像名称。在 Containerfile 路径下,单击并浏览以选择你的 Dockerfile。在镜像名称下,输入镜像的名称。如果要将镜像推送到容器注册中心,那么可以以 example.com/username/repo:tag 形式指定完全限定的镜像名称(FQIN)。在此示例中,我输入 quay.io/codezombie/demo-httpd:latest,因为我在 quay.io 上有一个名为 demo-httpd 的公共仓库。你可以按照类似的格式来指定容器注册中心(Quay、Docker Hub、GitHub Container Registry 等)的 FQIN。现在,按下 “ 构建 Build ” 按钮并等待构建完成。

推送镜像

构建完成后,就该推送镜像了。所以,我们需要在 Podman Desktop 中配置一个注册中心。进入 “ 首选项 Preferences ” -> “ 注册中心 Registries ” 并按下 “ 添加注册中心 Add registry ” 按钮。

添加注册中心对话框

在 “ 添加注册中心 Add registry ” 对话框中,输入你的注册中心服务器地址和用户凭据,然后单击 “ 添加注册中心 Add registry ”。

现在,回到镜像列表中我的镜像,并按下上传图标将其推送到仓库。当你将鼠标悬停在设置中添加的注册中心名称开头的镜像名称上时(此演示中的 quay.io),镜像名称旁边会出现一个推送按钮。

将鼠标悬停在镜像名称上时出现的按钮

镜像通过 Podman Desktop 推送到仓库

镜像被推送后,任何有权访问镜像仓库的人都可以拉取它。由于我的镜像仓库是公开的,因此你可以轻松地将其拉入 Podman Desktop。

拉取镜像

因此,为确保一切正常,请在本地删除此镜像并将其拉入 Podman Desktop。在列表中找到镜像并按删除图标将其删除。删除镜像后,单击 “ 拉取镜像 Pull Image ” 按钮。在 “ 要拉取的镜像 Image to Pull ” 输入完全限定名称,然后按 “ 拉取镜像 Pull Image ”。

Our container image is successfully pulled

创建一个容器

作为 Podman Desktop 演示的最后一部分,让我们从镜像中启动一个容器并检查结果。转到 “ 容器 Containers ” 并按 “ 创建容器 Create Container ”。这将打开一个包含两个选项的对话框:“ 从 Containerfile/Dockerfile From Containerfile/Dockerfile ” 和 “ 从已有镜像 From existing image ”。按下 “ 从已有镜像 From existing image ”。这将进入镜像列表。在那里,选择我们要拉取的镜像。

在 Podman Desktop 中创建容器

现在,我们从列表中选择我们最近拉取的镜像,然后按它前面的 “ 运行 Play ” 按钮。在出现的对话框中,我输入 demo-web 作为容器名,输入 8000 作为端口映射,然后按下 “ 启动容器 Start Container ”。

Container configuration

容器开始运行,我们可以通过运行以下命令检查 Apache 服务器的默认页面:

curl http://localhost:8000

可以工作!

你还应该能够在容器列表中看到正在运行的容器,其状态已更改为 “ 运行中 Running ”。在那里,你会在容器前面找到可用的操作。例如,你可以单击终端图标打开 TTY 进入到容器中!

接下来是什么

Podman Desktop 还很年轻,处于 积极开发 中。 GitHub 上有一个项目 路线图,其中列出了令人兴奋的按需功能,包括:

  • Kubernetes 集成
  • 支持 Pod
  • 任务管理器
  • 卷支持
  • 支持 Docker Compose
  • Kind 支持

via: https://fedoramagazine.org/manage-containers-on-fedora-linux-with-podman-desktop/

作者:Mehdi Haghgoo 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用 Watchtower 自动更新 Docker 容器基础镜像

对开发运维人员来说,保持 Docker 容器为最新版本是重要工作之一。手动更新 Docker 容器是一项耗时的工作。这篇文章解释了 Watchtower 是什么,如何安装它,以及在 Linux 中如何 使用 Watchtower 自动更新正在运行的 Docker 容器

Watchtower 是什么?

Watchtower 是一款自由开源的应用,用来监控运行中的 Docker 容器,并且当它发现基础镜像被更改后,可以自动的更新容器。

若 Watchtower 发现一个运行中的容器需要更新,它会以发送 SIGTERM 信号的方式,优雅的结束运行中容器的运行。

它会下载新镜像,然后以最初部署时使用的方式,重启容器。所有文件会在后台自动下载,因此不需要用户的介入。

在这份指南中,我们将会明白如何在类 Unix 系统中使用 Watchtower 自动更新正在运行的 Docker 容器。

我已经在 CentOS 和 Ubuntu 中测试了这份指南,所有的 Linux 发行版中操作过程都一样。

在 Linux 中安装 Watchtower

可以通过 Docker 镜像的方式下载 Watchtower 。因此,部署它是小事一桩。在你的 Linux 中安装 Docker 镜像,然后运行 Watchtower 立即开始监控 Docker 容器。

参考下方指导在基于 PRM 和 DEB 包管理系统中安装 Docker

安装 Docker 后,你可以使用以下命令以 root 用户身份部署 Watchtower 容器:

# docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower

如果你已经安装了 Docker 桌面版,以普通用户运行 Watchtower 容器。

$ docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower

该命令会拉取最新版的 watchtower 镜像,并运行 watchtower 容器。

输出样例:

Unable to find image 'containrrr/watchtower:latest' locally
latest: Pulling from containrrr/watchtower
1045b2f97fda: Pull complete 
35a104a262d3: Pull complete 
1a0671483169: Pull complete 
Digest: sha256:bbf9794a691b59ed2ed3089fec53844f14ada249ee5e372ff0e595b73f4e9ab3
Status: Downloaded newer image for containrrr/watchtower:latest
91c104ef0e9896e8cd5ff30d9f13e728dbfad66443830ec2ac85dde6d7d37564

Run Watchtower Docker Container

使用 Watchtower 自动更新 Docker 容器

在你的系统上,Watchtower 正在和其他容器一起运行。你可以使用一下命令查看运行中的 Docker 容器列表:

$ docker ps

输出样例:

CONTAINER ID   IMAGE                       COMMAND                  CREATED          STATUS          PORTS                                         NAMES
91c104ef0e98   containrrr/watchtower       "/watchtower"            14 minutes ago   Up 14 minutes   8080/tcp                                      watchtower
f90b462b0712   bitnami/wordpress-nginx:6   "/opt/bitnami/script…"   19 minutes ago   Up 19 minutes   0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp   ostechnix-wordpress-1

正如上方输出所示,watchtower 容器正在和名为 ostechnix-wordpress-1 的容器一起运行。从现在开始,watchtower 会每隔几分钟会检查该容器。

如果 Watchtower 发现该容器的基础镜像的任何变化,它会优雅的关闭 ostechnix-wordpress-1 容器,然后使用与最初启动它时使用的相同方式,启动新的镜像。

类似的,它会自动地每隔几分钟检查所有的运行中容器,并自动更新它们。

Watchtower 如何更新多连接的容器?

在监视多连接容器时,Watchtower 十分智能。

假设我们现在运行两个容器。

$ docker ps

输出样例:

CONTAINER ID   IMAGE                       COMMAND                  CREATED          STATUS          PORTS                                         NAMES
91c104ef0e98   containrrr/watchtower       "/watchtower"            14 minutes ago   Up 14 minutes   8080/tcp                                      watchtower
f90b462b0712   bitnami/wordpress-nginx:6   "/opt/bitnami/script…"   19 minutes ago   Up 19 minutes   0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp   ostechnix-wordpress-1
a895f082438a   bitnami/mariadb:10.6        "/opt/bitnami/script…"   20 minutes ago   Up 19 minutes   3306/tcp                                      ostechnix-mariadb-1

View Running Docker Containers

正如你看到的,我们正在运行 ostechnix-wordpress-1ostechnix-mariadb-1 这两个容器。ostechnix-mariadb-1 容器链接到 ostechnix-wordpress-1 容器。

如果 Watchtower 发现 ostechnix-wordpress-1 容器有个新版本,它会先关闭与之相连接的 ostechnix-mariadb-1 容器 ,然后才会关闭 ostechnix-wordpress-1 容器。

更新 ostechnix-wordpress-1 容器后,Watchtower 会以正确的顺序,且与最初启动它们时使用的相同方式,重启这两个容器,以便应用程序正确恢复。在我们的例子中,首先启动的是 ostechnix-mariadb-1 容器,然后是 ostechnix-wordpress-1 容器,以确保连接能够继续运行。

监控特定容器

默认情况下,Watchtower 将监控在它所指向的 Docker 守护进程中运行的所有 Docker 容器。

不过,你可以像下面这样,通过指定容器名称限制 Watchtower 监视特定的 Docker 容器。

$ docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower ostechnix-wordpress-1

在上方的例子中,watchtower 会忽略其他容器,只监视名为 ostechnix-wordpress-1 的容器更新情况。

如果你不指定任何参数,Watchtower 会照常监视所有运行中的 Docker 容器。

发送提示

或许你想收到容器更新的通知。你可以通过电子邮件、Slack 、MSTeams 以及 Gotify 发送通知。

下面这个例子展示了如何通过电子邮件发送通知。假设你已经设置了 SMTP 服务器。

docker run -d \
  --name watchtower \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e WATCHTOWER_NOTIFICATIONS=email \
  -e [email protected] \
  -e [email protected] \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 \
  -e [email protected] \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=app_password \
  -e WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2 \
  containrrr/watchtower

参考下方 Watchtower Github 仓库和 Watchtower 官方主页获取更多信息:

资料


via: https://ostechnix.com/automatically-update-running-docker-containers/

作者:sk 选题:lkxed 译者:Donkey 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

通过这篇新的可下载指南开始探索容器技术的要领。

在电视剧 《 太空堡垒卡拉狄加 Battlestar Galactica 》中,这艘名副其实的巨型飞船其实并没有做什么。它是船员们坚定的庇护所,是战略和协调的中心联络点,也是资源管理的安全场所。而 卡布里安毒蛇号 Caprican Vipers 这种单人的独立太空船,出去对付邪恶的 赛昂人 Cylons 和其他太空中的危险。他们也从不只派一两艘毒蛇号出去。他们派了很多。这许许多多的冗余的飞船具有基本相同的能力和目的,但由于它们非常灵活和数量众多,它们总是能够处理每个星期都在威胁战星的任何问题。

如果你认为你感到这像是一个正在发展中的比喻,那么你是对的。现代的“云”大而无当,是分布在很远距离的大量基础设施的集合体。它具有强大的能力,但如果你将其视为普通计算机,就会浪费了它的大部分能力。当你想要处理来自数百万个输入源的大量数据时,把你的解决方案(无论它是采用应用、网站、数据库、服务器还是其他形式)打包起来,并发送该解决方案的微小镜像来处理数据集群,实际上是更有效的。当然,这些都是 “ 容器 container ”,它们是云的劳动力。它们是你发送来处理服务请求的小型解决方案工厂,并且由于你可以根据任何给定时间传入的请求生成所需要的数量,因此理论上它们是取之不尽的。

在家里使用容器

如果你没有大量的传入请求需要处理,你可能会想知道容器给你带来什么好处。不过,在个人电脑上使用容器确实有其用途。

容器作为虚拟环境

通过 Podman、LXC 和 Docker 等工具,你可以像以往运行虚拟机一样运行容器。不过,与虚拟机不同,容器没有因模拟固件和硬件而产生的开销。

你可以从公共仓库下载容器镜像,启动一个最小化的 Linux 环境,并将其作为命令或开发的测试场所。例如,假设你想试试你在 Slackware Linux 上构建的一个应用。首先,在仓库中搜索一个合适的镜像:

$ podman search slackware

然后选择一个镜像,作为你的容器的基础:

$ podman run -it --name slackware vbatts/slackware
sh-4.3# grep -i ^NAME\= /etc/os-release
NAME=Slackware

在工作中使用容器

当然,容器不只是个精简的虚拟机。它们可以是针对为非常具体的需求提供的特定解决方案。如果你不熟悉容器,那么新系统管理员最常见的入门仪式之一可能会有所帮助:启动你的第一个 Web 服务器,但是在容器中。

首先,获取一个镜像。你可以使用 podman search 命令来搜索你喜欢的发行版,或者直接搜索你喜欢的 httpd 服务器。当使用容器时,我倾向于信任我在裸机上使用的相同发行版。

当你你找到一个镜像作为你的容器的基础,你就可以运行你的镜像。然而,正如这个术语所暗示的,容器是封起来的,所以如果你只是启动一个容器,你将无法访问标准的 HTTP 端口。你可以使用 -p 选项将一个容器端口映射到一个标准的网络端口:

$ podman run -it -p 8080:80 docker.io/fedora/apache:latest

现在看看你本地主机上的 8080 端口:

$ curl localhost:8080
Apache

成功了。

了解更多

容器拥有比模仿虚拟机更多的潜力。你可以将它们分组在 “ pod ” 中,构建复杂应用的自动部署,启动冗余服务以满足高需求等等。如果你刚刚开始使用容器,你可以 下载我们最新的电子书 来学习该技术,甚至学习创建一个 “ pod ”,以便你可以运行 WordPress 和数据库。

下载我们最新的电子书

(LCTT 译注:容器环境中使用的 “Pod” 一词,我以前根据容器相关术语多用航海领域名词比喻来将其译做“吊舱”,但也有同学表示了不同意见。根据对 Kubernetes 文档,这个词来自对 鲸鱼荚 pod of whales 豌豆荚 pea pod 的比喻,所以我觉得采用“荚”的翻译比较合适。—— wxy)


via: https://opensource.com/article/22/5/containers-pods-101-ebook

作者:Seth Kenlon 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在本教程中,你将学习如何在一个“吊舱”中运行两个容器来托管一个 WordPress 站点。

 title=

无论你是将其作为工作的一部分、未来的工作机会或者仅仅是出于对新技术的兴趣,容器对很多人,即使是经验丰富的系统管理员,可能是非常难以应付的。那么如何真正开始使用容器呢?从容器到 Kubernetes 的成长路径是什么?另外,为什么有不止一条路径?如你所料,最好的起点就是现在。

1、了解容器

略一回忆,容器的开端可以追溯到早期 BSD 及其特殊的 chroot 监狱,但让我们直接跳到发展中期讲起。

之前,Linux 内核引入了 “ 控制组 cgroup ”,允许你能够使用 “ 命名空间 namespace ” 来“标记”进程。当你将进程分组到一个命名空间时,这些进程的行为就像在命名空间之外的东西不存在一样,这就像你把这些进程放入某种容器中。当然,这种容器是虚拟的,它位于计算机内部,它和你操作系统的其余进程使用相同的内核、内存和 CPU,但你用容器包含了这些进程。

分发的预制容器仅包含运行它所包含的应用程序必须的内容。使用容器引擎,如 Podman、Docker 或 CRI-O,你可以运行一个容器化应用程序,而无需进行传统意义上的安装。容器引擎通常是跨平台的,因此即使容器运行在 Linux 上,你也可以在其他 Linux、MacOS 或 Windows 上启动容器。

更重要的是,当需求量很大时,你可以运行同一应用程序的多个容器。

现在你知道了什么是容器,下一步是运行一个容器。

2、运行一个容器

在运行容器之前,你应该有一个想要运行它的理由。你可以编一个,这有助于你对让容器创建过程感兴趣,这样你就会受到鼓舞,真正去使用你所运行的容器。毕竟,运行容器但不使用它提供的应用程序,只能证明你没有注意到任何故障,但使用容器证明它可以工作。

我推荐从 WordPress 开始,它是一个很流行的 Web 应用程序,容易使用,所以一旦容器运行起来,你就可以测试使用它。虽然你可以轻松地配置一个 WordPress 容器,但还是有很多配置选项可以引导你发现更多运行容器的方式(例如运行数据库容器)以及容器如何通信。

我使用 Podman,它是一个友好、方便且无守护进程的容器引擎。如果你没有安装 Podman,可以改用 Docker 命令。它们都是很棒的开源容器引擎,而且它们的语法是相同的(只需输入 docker 而不是 podman)。因为 Podman 没有守护进程,所以它需要更多的配置,但为了这种运行免 root、无守护进程的容器的能力是值得的。

如果你使用 Docker,可以跳到下面的 运行 WordPress 容器 小节,否则,打开终端安装并配置 Podman:

$ sudo dnf install podman

容器会产生许多进程,通常只有 root 用户有权创建数千个进程 ID。创建一个名为 /etc/subuid 的文件,定义一个适当的起始 UID 和大量合法的 PID,这样就可以为你添加一些额外的进程 ID:

seth:200000:165536

在名为 /etc/subgid 的文件中对你的组执行相同的操作。在这个例子中,我的主要组是 staff(对你来说可能是 users,或者和你的用户名一样,这取决于你的系统)。

staff:200000:165536

最后,确认你的用户可以管理很多命名空间:

$ sysctl --all --pattern user_namespaces
user.max_user_namespaces = 28633

如果你的用户无权管理超过 28,000 个命名空间,创建 /etc/sysctl.d/userns.conf 文件来增加数量并输入:

user.max_user_namespaces=28633

运行 WordPress 容器

现在,无论你使用的是 Podman 还是 Docker,你都可以从在线容器仓库中下载 WordPress 容器并运行它。你可以使用以下 Podman 命令完成所有这些操作:

$ podman run --name mypress \
    -p 8080:80 -d wordpress

给 Podman 一会时间来找到容器、从互联网下载它,然后启动。

在收到终端返回提示符后,启动 Web 浏览器,打开 localhost:8080。WordPress 正在运行,等待你进行设置。

 title=

不过,你很快就会遇到障碍,因为 WordPress 使用数据库来存储数据,因此你需要为其提供一个数据库。

在继续之前,停止并删除 WordPress 容器:

$ podman stop mypress
$ podman rm mypress

3、在吊舱中运行容器

正如名字所暗示的那样,容器在设计上是独立的。在容器中运行的应用程序不应该与在容器外的应用程序或基础设施进行交互。因此,当一个容器需要另一个容器才能运行时,一种解决方案是将这两个容器放在一个更大的容器中,称为 “ 吊舱 pod ”。吊舱确保其容器可以共享重要的命名空间以便相互通信。

创建一个新的吊舱,为它提供一个名称,以及希望能够访问的端口:

$ podman pod create \
    --name wp_pod \
    --publish 8080:80

确认吊舱存在:

$ podman pod list
POD ID        NAME     STATUS    INFRA ID      # OF CONTAINERS
100e138a29bd  wp_pod   Created   22ace92df3ef   1

将容器添加到吊舱

现在你已经为相互依赖的容器创建了一个吊舱,你可以通过指定一个运行的吊舱来启动每个容器。

首先,启动一个数据库容器。你可以创建自己的凭据,只要在 WordPress 连接到数据库时使用相同的凭据。

$ podman run --detach \
    --pod wp_pod \
    --restart=always \
    -e MYSQL_ROOT_PASSWORD="badpassword0" \
    -e MYSQL_DATABASE="wp_db" \
    -e MYSQL_USER="tux" \
    -e MYSQL_PASSWORD="badpassword1" \
    --name=wp_db mariadb

接下来,在同一个吊舱中启动 WordPress 容器:

$ podman run --detach \
    --restart=always --pod=wp_pod \
    -e WORDPRESS_DB_NAME="wp_db" \
    -e WORDPRESS_DB_USER="tux" \
    -e WORDPRESS_DB_PASSWORD="badpassword1" \
    -e WORDPRESS_DB_HOST="127.0.0.1" \
    --name mypress wordpress

现在启动你最喜欢的网络浏览器并打开 localhost:8080

这一次,设置会正常进行。WordPress 会连接到数据库,因为你在启动容器时传递了这些环境变量。

 title=

创建用户账户后,你可以登录查看 WordPress 仪表板。

 title=

下一步

你已经创建了两个容器,并在一个吊舱中运行了它们。你现在已经了解了如何在自己的服务器上运行容器及服务。如果你想迁移到云,容器非常适合你。使用像 Kubernetes 和 OpenShift 这样的工具,你可以自动化启动 集群上的容器和吊舱。如果你正在考虑采取下一步行动,阅读 Kevin Casey 的 3 个开始使用 Kubernetes 的方法,并尝试他提到的 Minikube 教程。


via: https://opensource.com/article/22/2/start-running-containers

作者:Seth Kenlon 选题:lujun9972 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

黑掉你的系统,了解为什么配置 SELinux 作为你的第一道容器防线是很重要的。

 title=

当有些事情在你的 Linux 环境中不能正常工作时,最简单的方法就是禁用 安全增强型 Linux Security-Enhanced Linux SELinux)。而当它突然可以工作了,你就会忘记了禁用这件事 —— 这是一个常见的陷阱,意味着你已经失去了一个非常强大的安全工具。

随着容器、微服务和分布式架构的兴起,威胁也在上升。这是由于一个老的、众所周知的问题:速度。容器的优势在于它们能让你快速行动,做更多的事情,并迅速改变。这意味着容器的采用已经飞速发展,但它所提供的速度也意味着你会遇到更多的问题和漏洞。当你越来越快地做更多的事情时,这自然会发生。

如何减轻威胁

正如孙子所说,“不战而屈人之兵”。当涉及到容器的基本防御时,这句话真的很有共鸣。为了避免问题(战斗),确保你的容器主机是安全的,你可以使用 SELinux 作为你的第一道防线。

SELinux 是一个开源项目,于 2000 年发布,2003 年集成到 Linux 内核中。根据 红帽公司的解释,“SELinux 是 Linux 系统 的一个安全架构,允许管理员对谁可以访问系统有更多的控制。它最初是由美国国家安全局(NSA)开发的,是使用 Linux 安全模块(LSM)对 Linux 内核 的一系列补丁。”

开始吧

当你想到容器时,首先想到的可能是 Docker。Docker 在 2013 年出现后掀起了一场容器采用革命。它是容器爆炸性流行的主要原因之一,但如上所述,大量采用增加了用户对安全风险的脆弱性。

在你用 SELinux 保护你的 Docker 容器之前,你需要设置一些东西。

前置条件

  • 安装并配置了 CentOS 8/RHEL 8。
  • 安装并配置好 Docker CE
  • 创建两个账户:root 和 非 root 用户(下面的例子中是 mcalizo)。

如果你需要在你的 RHEL 8/CentOS 8 服务器上设置 Docker,你可以按照这些 说明。如果你运行的是 RHEL 8,你需要在开始之前删除预装的 Podman 和 runc 包。

首先,确保 SELinux 被启用:

[mcalizo@Rhel82 ~]$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      31
[mcalizo@Rhel82 ~]$

然后,验证你的操作系统版本和 Docker 正在运行。以 root 身份登录并运行:

[root@rhel82 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux release 8.2 (Ootpa)
[root@rhel82 ~]#

[root@rhel82 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-10-28 19:10:14 EDT; 15s ago
     Docs: https://docs.docker.com
 Main PID: 30768 (dockerd)
    Tasks: 8
   Memory: 39.0M
   CGroup: /system.slice/docker.service
           └─30768 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.889602941-04:00" level=error msg=">
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903413613-04:00" level=warning msg>
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903427451-04:00" level=warning msg>
Oct 28 19:10:13 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:13.903538271-04:00" level=info msg="L>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.132060506-04:00" level=info msg="D>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.308943088-04:00" level=info msg="L>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.319438549-04:00" level=info msg="D>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.319570298-04:00" level=info msg="D>
Oct 28 19:10:14 rhel82.home.labs.com dockerd[30768]: time="2020-10-28T19:10:14.333419209-04:00" level=info msg="A>
Oct 28 19:10:14 rhel82.home.labs.com systemd[1]: Started Docker Application Container Engine

检查你的 Docker 版本:

[root@rhel82 ~]# docker --version
Docker version 19.03.13, build 4484c46d9d

黑掉主机

了解一个问题的最好方法之一就是去体验它。因此,我将告诉你,如果你的安全设置不当,向 Docker 主机注入恶意代码是多么容易。

为了能够在 Docker 主机上做坏事,“恶意”的非 root 用户(本教程中为 mcalizo)必须是可以实例化 Docker 容器的组的成员。

首先,确认 mcalizo 用户属于哪个组:

[root@Rhel82 ~]# groups mcalizo
mcalizo : mcalizo

输出显示,mcalizo 只属于它自己的组。这意味着 mcalizo 不能实例化 Docker 容器,如果它试图这样做,将会得到这个错误:

[mcalizo@Rhel82 ~]$ docker run -it --rm centos:latest /bin/sh
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.

要允许 mcalizo 实例化容器,将用户加入 docker 组:

[root@Rhel82 ~]# usermod -G docker -a mcalizo
[root@Rhel82 ~]# groups mcalizo
mcalizo : mcalizo docker

接下来,部署一个 fedora:latest 的容器,并登录到实例化的容器中去探索它:

[mcalizo@Rhel82 ~]$ docker run -it --rm fedora:latest /bin/sh
Unable to find image 'fedora:latest' locally
latest: Pulling from library/fedora
ee7e89337106: Pull complete
Digest: sha256:b9ec86d36fca7b1d3de39cd7c258e8d90c377d312c21a7748071ce49069b8db4
Status: Downloaded newer image for fedora:latest
sh-5.0# cat /etc/redhat-release
Fedora release 33 (Thirty Three)

当你登录到新创建的容器时,你可以看到你是以 root 身份自动登录的:

sh-5.0# whoami
root
sh-5.0#

作为 root 用户,你可以在这个容器中做任何事情,这意味着你可以利用容器主机,做很多破坏。因为你可以实例化一个容器,即使你不属于主机的 sudoers 账户,你也可以对主机做一些事情。

退出你刚刚创建的容器,并创建一个新的容器来演示这个漏洞:

[mcalizo@Rhel82 ~]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[root@131043f2e306 /]#

-v 选项 将 Docker 主机的 / 目录挂载到 /exploit 目录下的容器:

[root@131043f2e306 /]#ls exploit/
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

因为它已被挂载,你可以在 Docker 主机上做任何事情。例如,你可以删除文件、编辑特定的配置来破害系统,甚至安装木马程序或其他恶意软件来窃取重要信息。

为什么会发生这种情况?

你可能想知道,既然 SELinux 处于强制模式,为什么会出现这种情况?深入挖掘 SELinux,看看哪里出了问题。

验证 SELinux 是否有一个 Docker 上下文

[mcalizo@Rhel82 ~]$ ps -eZ | grep docker
system_u:system_r:container_runtime_t:s0 30768 ? 00:00:04 dockerd
[mcalizo@Rhel82 ~]$

正如预期的那样,它确实有。这意味着 SELinux 管理着 Docker 守护进程。检查 Docker 守护进程,看看 SELinux 是否默认启用:

[mcalizo@Rhel82 ~]$ docker info | grep Security -A3
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.18.0-193.el8.x86_64

Docker 守护进程中的 SELinux 在默认情况下是 不启用 的。 这就是问题所在!要解决这个问题,按 文档 说明,通过更新或创建文件 /etc/docker/daemon.json 来启用 SELinux 来控制和管理 Docker(你必须有 root 权限才能这样做):

[root@Rhel82 ~]# cat /etc/docker/daemon.json
{
  "selinux-enabled": true
}
[root@Rhel82 ~]#
[root@Rhel82 ~]# systemctl restart docker

在创建或更新该文件并重启 Docker 后,你应该看到 Docker 守护进程中启用了 SELinux 支持:

[root@Rhel82 ~]# systemctl restart docker
[mcalizo@Rhel82 root]$ docker info | grep Security -A3
 Security Options:
  seccomp
   Profile: default
  selinux
[mcalizo@Rhel82 root]$

虽然仍然可以在你的 Docker 容器上挂载 Docker 主机中的特定文件系统,但不再允许更新或访问该文件:

[mcalizo@Rhel82 root]$ docker run -it --rm -v /:/exploit fedora:latest /bin/bash
[root@ecb5836da1f6 /]# touch /exploit/etc/shadow.sh
touch: cannot touch '/exploit/etc/shadow.sh': Permission denied
[root@ecb5836da1f6 /]#

了解更多

你在容器世界中的第一道防线取决于你对容器主机的操作系统的设置有多强。有许多方法可以实现 Linux 的安全性,包括市场上可供选择的方案,以增强你的安全态势。

SELinux 是一个额外的安全层,默认情况下内置于 Linux 发行版 中。为了借助它保护你的系统不被破坏,请确保 SELinux 保持开启状态。

如果你想了解更多,请参阅:


via: https://opensource.com/article/20/11/selinux-containers

作者:Mike Calizo 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出