Podman是一个基于libpod库开发的容器运行时,用于在Linux操作系统上管理和运行容器。与传统的Docker容器运行时不同,Podman无需依赖Docker守护进程,它可以在不同的Linux发行版中独立运行。
Podman是最流行的容器运行时之一,在Github上拥有17.1K Star,非常受欢迎。那么它有什么特别,又是为何能够受欢迎呢?一起来看看。
二、Podman的功能和特点
Podman提供了与Docker类似的命令行接口,支持常见的容器管理功能,如启动、停止、重启和删除容器,以及构建、推送和拉取容器镜像等。Podman还支持容器的网络和存储管理,可以使用CNI插件创建和管理容器的网络,支持使用多种存储驱动程序,如overlayfs、btrfs和zfs等。
Podman的一个显著特点是它使用的是rootless模式,这意味着它可以在普通用户权限下运行,而不需要root权限。这有助于提高容器运行的安全性和可移植性。同时,Podman支持通过Pods来管理一组相关的容器,这样可以方便地管理复杂的应用程序。
另外,Podman还支持使用systemd来管理容器,这使得它可以更好地集成到Linux系统中,与其他系统服务一起运行和管理。
三、Podman底层原理
作为一个容器运行时,Podman的底层主要也是基于Linux的Cgroup和Namespace等技术,这里讲解一下涉及的主要技术点。
3.1、Namespace
Podman使用Linux命名空间实现容器之间的隔离,如pid(进程ID)、网络、IPC(进程间通信)、UTS(主机名和域名)和挂载等等。这些命名空间可以隔离不同容器的进程、文件系统、网络和主机名等等,从而实现容器之间的隔离。
Linux Namespace是Linux内核中的一个功能,用于将系统资源(如进程、网络、文件系统、IPC等)隔离在不同的命名空间中,从而使得相同的系统资源在不同的命名空间中具有不同的视图。这样可以让不同的进程看到不同的系统资源,从而实现更好的隔离和安全性。
Linux Namespace提供了以下命名空间:
- PID命名空间:使得每个进程只能看到自己及其子进程的进程树;
- 网络命名空间:使得每个进程只能看到自己的网络接口和路由表,从而实现网络隔离;
- IPC命名空间:使得每个进程只能看到自己和同一命名空间中的进程的进程间通信(IPC)机制;
- UTS命名空间:使得每个进程只能看到自己的主机名和域名;
- 挂载命名空间:使得每个进程只能看到自己的文件系统挂载点和文件系统层次结构;
- 用户命名空间:使得每个进程只能看到自己和同一命名空间中的进程的用户和用户组。
Linux Namespace可以用于以下场景:
- 容器:通过使用不同的命名空间隔离容器中的进程、文件系统、网络等资源,从而实现轻量级虚拟化;
- 系统安全:通过使用不同的命名空间隔离系统资源,从而避免因为进程之间的相互影响而导致的安全问题;
- 调试:通过使用不同的命名空间,使得调试工具只能看到特定的进程和资源,从而提高调试效率。
3.2、Cgroups
Podman使用Linux cgroups来限制和管理容器的资源使用情况,如CPU、内存、I/O等等。
Cgroups(control groups)是Linux内核的一个功能,用于限制、隔离和控制系统资源的使用。Cgroups允许将进程组织成一个或多个层次结构,每个层次结构都可以被分配一定数量的系统资源(如CPU、内存、磁盘I/O等),以便实现更好的系统资源管理和控制。
它可以限制CPU使用率、磁盘I/O、网络资源、进程树等,是一个非常强大的工具,可以让系统管理员更好地管理和控制系统资源的使用。在大型系统中,使用Cgroups可以有效地避免资源耗尽和进程之间的干扰,从而提高系统的稳定性和可靠性。
3.3、SELinux
Podman使用SELinux来增强容器的安全性,它可以通过对容器进程的安全上下文进行限制,保证容器不会访问到宿主机上的敏感文件和资源。
SELinux是一种强制访问控制(MAC)安全机制,用于Linux操作系统。它是由美国国家安全局(NSA)开发的,旨在增强操作系统的安全性和可靠性,提高系统的完整性和保密性。
SELinux使用安全策略来管理访问控制规则,这些规则决定哪些进程可以访问哪些资源,以及如何访问这些资源。SELinux安全策略基于标签(label)机制,它给操作系统中的每个对象(如文件、进程、套接字等)分配一个唯一的标签。这个标签用于识别该对象的所有权、访问控制以及安全上下文。
与传统的访问控制模型不同,SELinux将访问控制放在了应用程序之外,从而增强了操作系统的安全性。SELinux提供了一个强大的安全机制,可以限制应用程序的访问权限,并确保在恶意应用程序或攻击者的情况下保护系统资源。
SELinux在Linux发行版中已经成为标准安全机制,并且在很多服务器和企业环境中得到广泛应用。虽然使用SELinux需要一定的学习和配置成本,但是它能够提供更高的安全保障和系统可靠性,从而值得使用和学习。
3.4、OCI 标准
Podman遵循OCI (Open Container Initiative) 标准来定义和管理容器和镜像。
OCI(Open Container Initiative)是由Docker、CoreOS和其他主要技术公司发起的一个开放标准组织,旨在为容器提供一个开放、统一和标准的格式和运行时环境。
OCI标准定义了一个容器的标准格式和运行时环境,其中包括:
- 容器镜像格式:OCI定义了一个通用的容器镜像格式,即OCI镜像格式。该镜像格式包含了应用程序和其所有依赖项,并将它们打包成一个容器镜像,以便于在不同的容器运行时环境中运行。
- 容器运行时环境:OCI定义了一个通用的容器运行时环境接口,即OCI运行时规范。这个规范定义了容器运行时环境所需的API、CLI命令、配置和网络等方面的标准接口,以确保容器可以在不同的运行时环境中运行,同时保证兼容性和互操作性。
- 容器工具链:OCI还定义了一个容器工具链规范,它定义了一组标准CLI命令,使得开发人员和系统管理员能够更方便地构建、管理和维护容器环境。
OCI标准的出现是为了解决容器生态系统中的互操作性问题。在没有标准化之前,容器技术由不同的厂商和组织开发,容器镜像格式和运行时环境也各自不同,这给容器应用程序的部署和管理带来了很多挑战。通过制定标准,OCI为容器技术的发展提供了一个更加开放、互操作和可持续的基础设施。
3.5、基于Rootless
Podman支持在没有root权限的情况下运行容器,这可以增强容器的安全性和可移植性。
Podman实现rootless的方法是使用Linux的user namespaces功能。用户命名空间(user namespaces)是Linux内核中的一种安全功能,它可以为每个用户提供一个独立的命名空间,使得用户在该命名空间中的操作不会影响到其他命名空间的用户。
Podman在启动容器时,会创建一个新的用户命名空间,并在该命名空间中运行容器进程。这个命名空间中的用户可以使用它们自己的UID和GID,而不会影响到系统中的其他用户。同时,Podman还使用了一些特殊的技术,如userns-remap,来保证容器中的进程能够正确地映射到主机上的用户和组。
Podman通过以上这些技术来隔离、管理和保护容器和宿主机之间的资源和数据,从而提供安全、高效、可移植的容器环境。
四、Podman有哪些优势?
与Docker相比,Podman的一个优势是它可以在rootless模式下运行,这提高了容器的安全性,并且使得在共享计算机上运行容器更为方便。此外,Podman的命令行接口与Docker类似,因此,如果你熟悉Docker,你会很快学会如何使用Podman。
与其他容器运行时相比,Podman的一个优势是它与systemd的集成,这使得它可以更好地与Linux系统集成。另外,Podman支持使用Pods来管理一组相关的容器,这使得在部署复杂应用程序时更为方便。同时,Podman的可移植性也很高,它可以在各种Linux发行版和云平台上运行,使得容器应用程序的部署更加灵活和简单。
五、Podman的安装使用
Podman可以在各种Linux发行版上安装和使用,下面是Podman的安装和使用步骤:
5.1、安装Podman
在大多数Linux发行版上,你可以使用系统包管理器来安装Podman,例如,在CentOS和Red Hat Enterprise Linux上可以使用以下命令:
代码语言:javascript复制sudo yum install podman
在Debian和Ubuntu上可以使用以下命令:
代码语言:javascript复制sudo apt-get install podman
如果你使用的是其他Linux发行版,可以参考Podman官方文档中的安装指南。
5.2、运行第一个容器
安装完成后,你可以使用Podman来启动第一个容器。以下命令可以启动一个基于Alpine Linux的容器,并在容器中运行一个简单的命令:
代码语言:javascript复制podman run alpine echo "Hello, World!"
这将下载Alpine Linux镜像,并在容器中运行echo命令,输出"Hello, World!"。
5.3、查看容器
你可以使用以下命令来查看正在运行的容器:
代码语言:javascript复制podman ps
这将列出所有正在运行的容器,并显示容器的ID、状态、端口映射等信息。
5.4、停止和删除容器
你可以使用以下命令来停止和删除容器:
代码语言:javascript复制podman stop <container-id>
podman rm <container-id>
其中,是容器的ID,可以通过运行podman ps命令来获取。
5.5、构建和推送镜像
你可以使用以下命令来构建和推送容器镜像:
代码语言:javascript复制podman build -t <image-name> .
podman push <image-name>
其中,是镜像的名称和标签,例如my-image:latest。这将在当前目录中构建一个新的镜像,并将其推送到Docker Hub或其他容器镜像仓库中。