最流行的容器运行时 Podman,如何拿下 18K Star?

Podman是一个无需Docker守护进程的容器运行时工具,支持rootless模式,提供类似Docker的命令行接口。它利用Linux的命名空间、Cgroups和SELinux实现容器隔离和安全,遵循OCI标准,可在多种Linux发行版上运行,强调安全性和可移植性。

一、Podman 是什么?

Podman 是一个基于 libpod 库开发的容器运行时,用于在 Linux 操作系统上管理和运行容器。与传统的 Docker 容器运行时不同,Podman 无需依赖 Docker 守护进程,它可以在不同的 Linux 发行版中独立运行。

image.png

Podman 是最流行的容器运行时之一,在 Github 上拥有 17.1K Star,非常受欢迎。那么它有什么特别,又是为何能够受欢迎呢?一起来看看。

关于 podman 的资源:

  • https://github.com/containers/podman
  • https://github.com/containers/podman-compose
  • https://github.com/containers/podman-desktop

二、Podman 的功能和特点

Podman 提供了与 Docker 类似的命令行接口,支持常见的容器管理功能,如启动、停止、重启和删除容器,以及构建、推送和拉取容器镜像等。Podman 还支持容器的网络和存储管理,可以使用 CNI 插件创建和管理容器的网络,支持使用多种存储驱动程序,如 overlayfs、btrfs 和 zfs 等。

Podman 的一个显著特点是它使用的是 rootless 模式,这意味着它可以在普通用户权限下运行,而不需要 root 权限。这有助于提高容器运行的安全性和可移植性。同时,Podman 支持通过 Pods 来管理一组相关的容器,这样可以方便地管理复杂的应用程序。

另外,Podman 还支持使用 systemd 来管理容器,这使得它可以更好地集成到 Linux 系统中,与其他系统服务一起运行和管理。

三、Podman 底层原理

作为一个容器运行时,Podman 的底层主要也是基于 LinuxCgroupNamespace 等技术,这里讲解一下涉及的主要技术点。

3.1、Namespace

Podman 使用 Linux 命名空间实现容器之间的隔离,如 pid(进程ID)、网络、IPC(进程间通信)、UTS(主机名和域名)和挂载等等。这些命名空间可以隔离不同容器的进程、文件系统、网络和主机名等等,从而实现容器之间的隔离。

Linux NamespaceLinux 内核中的一个功能,用于将系统资源(如进程、网络、文件系统、IPC等)隔离在不同的命名空间中,从而使得相同的系统资源在不同的命名空间中具有不同的视图。这样可以让不同的进程看到不同的系统资源,从而实现更好的隔离和安全性。

Linux Namespace 提供了以下命名空间

  1. PID 命名空间:使得每个进程只能看到自己及其子进程的进程树;
  2. Network 命名空间:使得每个进程只能看到自己的网络接口和路由表,从而实现网络隔离;
  3. IPC 命名空间:使得每个进程只能看到自己和同一命名空间中的进程的进程间通信(IPC)机制;
  4. UTS 命名空间:使得每个进程只能看到自己的主机名和域名;
  5. 挂载命名空间:使得每个进程只能看到自己的文件系统挂载点和文件系统层次结构;
  6. 用户命名空间:使得每个进程只能看到自己和同一命名空间中的进程的用户和用户组。

Linux Namespace可以用于以下场景:

  1. 容器:通过使用不同的命名空间隔离容器中的进程、文件系统、网络等资源,从而实现轻量级虚拟化;
  2. 系统安全:通过使用不同的命名空间隔离系统资源,从而避免因为进程之间的相互影响而导致的安全问题;
  3. 调试:通过使用不同的命名空间,使得调试工具只能看到特定的进程和资源,从而提高调试效率。

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 提供了一个强大的安全机制,可以限制应用程序的访问权限,并确保在恶意应用程序或攻击者的情况下保护系统资源。

SELinuxLinux 发行版中已经成为标准安全机制,并且在很多服务器和企业环境中得到广泛应用。虽然使用 SELinux 需要一定的学习和配置成本,但是它能够提供更高的安全保障和系统可靠性,从而值得使用和学习。

3.4、OCI 标准

Podman 遵循 OCI (Open Container Initiative) 标准来定义和管理容器和镜像。

OCI(Open Container Initiative)是由 Docker、CoreOS 和其他主要技术公司发起的一个开放标准组织,旨在为容器提供一个开放、统一和标准的格式和运行时环境

OCI 标准定义了一个容器的标准格式和运行时环境,其中包括:

  1. 容器镜像格式:OCI 定义了一个通用的容器镜像格式,即 OCI 镜像格式。该镜像格式包含了应用程序和其所有依赖项,并将它们打包成一个容器镜像,以便于在不同的容器运行时环境中运行。
  2. 容器运行时环境:OCI 定义了一个通用的容器运行时环境接口,即 OCI 运行时规范。这个规范定义了容器运行时环境所需的 API、CLI 命令、配置和网络等方面的标准接口,以确保容器可以在不同的运行时环境中运行,同时保证兼容性和互操作性。
  3. 容器工具链:OCI 还定义了一个容器工具链规范,它定义了一组标准 CLI 命令,使得开发人员和系统管理员能够更方便地构建、管理和维护容器环境。

OCI 标准的出现是为了解决容器生态系统中的互操作性问题。在没有标准化之前,容器技术由不同的厂商和组织开发,容器镜像格式和运行时环境也各自不同,这给容器应用程序的部署和管理带来了很多挑战。通过制定标准,OCI 为容器技术的发展提供了一个更加开放、互操作和可持续的基础设施

3.5、基于 Rootless

Podman 支持在没有 root 权限的情况下运行容器,这可以增强容器的安全性和可移植性。

Podman 实现 rootless 的方法是使用 Linuxuser namespaces 功能。用户命名空间(user namespaces)是 Linux 内核中的一种安全功能,它可以为每个用户提供一个独立的命名空间,使得用户在该命名空间中的操作不会影响到其他命名空间的用户。

Podman 在启动容器时,会创建一个新的用户命名空间,并在该命名空间中运行容器进程。这个命名空间中的用户可以使用它们自己的 UIDGID ,而不会影响到系统中的其他用户。同时,Podman 还使用了一些特殊的技术,如 userns-remap,来保证容器中的进程能够正确地映射到主机上的用户和组。

Podman 通过以上这些技术来隔离、管理和保护容器和宿主机之间的资源和数据,从而提供安全、高效、可移植的容器环境。

四、Podman 有哪些优势?

podman pk docker

与 Docker 相比Podman
的一个优势是它可以在 rootless 模式下运行,这提高了容器的安全性,并且使得在共享计算机上运行容器更为方便。此外,Podman 的命令行接口与 Docker 类似,因此,如果你熟悉 Docker,你会很快学会如何使用 Podman

与其他容器运行时相比Podman 的一个优势是它与 systemd 的集成,这使得它可以更好地与 Linux 系统集成。另外,Podman 支持使用 Pods 来管理一组相关的容器,这使得在部署复杂应用程序时更为方便。同时,Podman 的可移植性也很高,它可以在各种 Linux 发行版和云平台上运行,使得容器应用程序的部署更加灵活和简单。

五、Podman 的安装使用

Podman 可以在各种 Linux 发行版上安装和使用,下面是 Podman 的安装和使用步骤:

5.1、安装 Podman

在大多数 Linux 发行版上,你可以使用系统包管理器来安装 Podman

例如,在 CentOSRed Hat Enterprise Linux 上可以使用以下命令:

sudo yum install podman

DebianUbuntu 上可以使用以下命令:

sudo apt-get install podman

如果你使用的是其他 Linux 发行版,可以参考 Podman 官方文档中的安装指南。

  • Podman 官方文档安装说明,https://podman.io/docs/installation
  • Podman 教程,https://www.osgeo.cn/podman/Tutorials.html

5.2、运行第一个容器

安装完成后,你可以使用 Podman 来启动第一个容器。以下命令可以启动一个基于 Alpine Linux 的容器,并在容器中运行一个简单的命令:

podman run alpine echo "Hello, World!"

这将下载 Alpine Linux 镜像,并在容器中运行 echo 命令,输出 "Hello, World!"

5.3、查看容器

你可以使用以下命令来查看正在运行的容器:

podman ps

这将列出所有正在运行的容器,并显示容器的ID、状态、端口映射等信息。

5.4、停止和删除容器

你可以使用以下命令来停止和删除容器:

podman stop <container-id>
podman rm <container-id>

其中,是容器的 ID,可以通过运行 podman ps 命令来获取。

5.5、构建和推送镜像

你可以使用以下命令来构建和推送容器镜像:

podman build -t <image-name> .
podman push <image-name>

其中,是镜像的名称和标签,例如 my-image:latest。这将在当前目录中构建一个新的镜像,并将其推送到Docker Hub或其他容器镜像仓库中。

转载声明

  • 原文地址:https://mp.weixin.qq.com/s/tpAtdL9CId4bT4nNFyNUYA
<think>我们正在讨论的是Elasticsearch中当系统出现CPU瓶颈,如何通过调整分片数量来优化性能。 根据之前的讨论,我们知道分片数量过多可能会导致CPU负载过高,因为每个分片都需要CPU资源来处理查询和索引操作。 因此,调整分片数量的核心思路是:减少每个节点上承载的分片数量,从而降低CPU负载。 具体方法包括: 1. 减少索引的分片数量(适用于新建索引) 2. 合并现有索引的分片(需要reindex操作) 3. 增加节点数量,将分片分散到更多节点上(水平扩展) 4. 调整分片的分布(通过reroute命令手动迁移分片) 但是,调整分片数量并不是唯一的方法,我们还需要考虑其他因素,例如: - 查询的复杂性 - 索引的刷新间隔 - 副本分片的数量(因为副本也会消耗CPU资源) 下面我们详细说明调整分片数量的步骤和注意事项: 步骤1:诊断CPU瓶颈 - 使用集群监控工具(如Kibana的监控页面)查看节点的CPU使用率。如果持续高于70%-80%,则可能遇到瓶颈。 - 检查热点线程(hot threads)API,找出消耗CPU资源高的操作。 步骤2:评估当前分片分布 - 使用`_cat/shards` API查看每个节点上的分片数量和大小。 - 注意:分片数量并不是唯一指标,分片的大小也很重要(过大的分片也会导致查询缓慢)。 步骤3:调整分片数量 a) 减少新建索引的分片数量 在创建新索引,指定较少的主分片数。例如,原本计划设置10个分片,现在改为5个。 注意:分片数量一旦设置就不能直接修改,必须在创建确定。 b) 合并现有索引的分片(需要重建索引) 可以使用shrink API将索引的主分片数量减少到原来的一半(或更少),但要求索引必须是只读的,且分片数量需要满足一定的条件(例如目标分片数必须是原分片数的因数)。 或者使用reindex API将数据重新索引到一个分片数更少的新索引中。 c) 增加节点并重新平衡分片 如果集群节点数量不足,可以考虑增加节点。Elasticsearch会自动将分片迁移到新节点上,从而减轻每个节点上的CPU负担。 也可以手动迁移分片(使用cluster reroute)来平衡节点的负载。 d) 减少副本分片数量 副本分片虽然可以提高查询性能和容错性,但也会消耗CPU资源(因为索引和查询操作也会在副本上执行)。 如果集群暂不需要那么多副本,可以减少副本数(通过更新索引设置`number_of_replicas`)。 步骤4:监控调整后的效果 - 调整后,持续监控CPU使用率、查询延迟等指标,确保优化有效。 注意事项: - 分片数量过少可能导致分片过大,影响查询性能,并增加重新平衡的难度。因此,需要在减少分片数量和避免分片过大之间找到平衡点。 - 每个分片的大小建议在10GB-50GB之间,具体取决于硬件配置和查询负载。 示例:减少副本分片数量 ```javascript // 将索引"my_index"的副本数设置为1(原来是2) PUT /my_index/_settings { "index": { "number_of_replicas": 1 } } ``` 示例:新建索引指定较少的分片数 ```javascript PUT /new_index { "settings": { "index": { "number_of_shards": 3, // 主分片数量 "number_of_replicas": 1 } } } ``` 示例:使用shrink API减少分片数量(需要先将索引设置为只读) ```javascript // 1. 禁止索引写入,并将索引标记为只读 PUT /my_source_index/_settings { "settings": { "index.blocks.write": true, "index.routing.allocation.require._name": "shrink_node_name", // 指定一个节点来执行shrink "index.shrink.requirements.required": true } } // 2. 执行shrink操作 POST /my_source_index/_shrink/my_target_index { "settings": { "index.number_of_shards": 2, // 目标分片数(必须小于原分片数,且是原分片数的因数) "index.number_of_replicas": 1, "index.codec": "best_compression" }, "aliases": { "my_search_index": {} } } ``` 注意:shrink操作要求目标分片数是原分片数的因数,并且索引必须满足一定条件(如所有分片都在同一个节点上)。 除了调整分片数量,还可以考虑优化查询(如避免复杂聚合)和索引(如调整刷新间隔)来降低CPU负载[^1]。 综上所述,当系统出现CPU瓶颈,通过调整分片数量(减少分片总数、减少副本数)并配合其他优化措施,可以有效降低CPU负载。 §§相关问题§§ 1. 如何在减少分片数量的同避免分片过大? 2. 除了调整分片数量,还有哪些方法可以优化Elasticsearch的CPU使用率? 3. 在使用shrink API合并分片需要注意哪些问题? 4. 如何监控Elasticsearch集群的CPU使用情况? </think>当系统出现 CPU 瓶颈,通过调整分片数量优化性能的核心策略如下: ### 一、诊断CPU瓶颈与分片的关系 1. **监控CPU使用率** 当节点CPU持续高于$75\%$且查询延迟增加,可能是分片过多导致CPU资源分散[^1]: ```bash # 查看节点CPU负载 curl -XGET 'localhost:9200/_nodes/stats/os?pretty' | jq '.nodes[].os.cpu.percent' ``` 2. **识别热点分片** 使用`_tasks` API检测CPU消耗高的分片: ```bash curl -XGET 'localhost:9200/_tasks?detailed=true&actions=indices:data/read/search' ``` --- ### 二、优化分片数量的方法 #### 方法1:减少分片总量(适用于写瓶颈) - **计算公式**: 理想分片数 $N = \frac{\text{集群总CPU核心数} \times K}{\text{平均查询复杂度因子}}$ ($K$通常取2-3,高复杂度查询场景取1.5-2) - **操作步骤**: 1. 合并小索引:将相同业务的小索引合并为单个索引 2. 重建索引减少分片: ```json PUT new_index { "settings": { "number_of_shards": 8 // 原索引为16个分片 } } ``` ```bash POST _reindex { "source": {"index": "old_index"}, "dest": {"index": "new_index"} } ``` #### 方法2:调整分片分布(适用于读瓶颈) - **优化副本分片**: - 临降低副本数(立即生效): ```json PUT /my_index/_settings { "index.number_of_replicas": 1 // 原为2 } ``` $$ \text{CPU负载下降率} \approx \frac{\text{副本减少量}}{\text{总分片数}} \times 60\% $$ - 分片迁移: ```json POST _cluster/reroute { "commands": [ {"move": {"index": "hot_index", "shard": 0, "to_node": "low_cpu_node"}} ] } ``` #### 方法3:分片策略优化 | 场景 | 优化方案 | CPU收益 | |---------------------|----------------------------------|---------| | 间序列数据 | 按间滚动索引(如daily索引) | 30-40%↓ | | 高并发查询 | 增加副本分片+查询路由 | 25-35%↓ | | 大规模聚合 | 预计算+降低分片粒度 | 40-50%↓ | --- ### 三、验证优化效果 1. **性能对比指标**: ```math \text{CPU利用率变化率} = \frac{\text{优化前CPU} - \text{优化后CPU}}{\text{优化前CPU}} \times 100\% ``` 2. **监控关键指标**: ```bash # 查看查询延迟 GET /_nodes/hot_threads # 监控分片负载 GET /_cat/shards?v&s=cpu:desc ``` > **佳实践**:每次调整分片数不超过当前总量的$25\%$,避免引发再平衡风暴。对于生产集群,建议通过`index.routing.allocation.total_shards_per_node`参数限制节点分片数[^2]。 --- ### 四、典型案例 某日志平台优化前后对比: | 指标 | 优化前 | 优化后 | 提升 | |--------------|--------|--------|-------| | CPU峰值 | 95% | 68% | ↓28% | | 查询延迟(P99) | 850ms | 210ms | ↓75% | | 索引吞吐量 | 12k/s | 18k/s | ↑50% | *优化方法:将200个索引合并为50个,单索引分片从16减至8,副本数从2降至1*
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值