精华内容
下载资源
问答
  • 具体来说,对于每个容器,它保留资源隔离参数,历史资源使用情况,完整历史资源使用情况的直方图和网络统计信息。 此数据按容器和机器范围导出。 cAdvisor具有对容器的本机支持,并且应立即支持几乎所有其他类型的...
  • 该docker容器将读取每个正在运行容器的资源使用情况统计信息,然后将数据作为JSON转发给Fluentd。 为什么? 简单免费的详细只读监控和分析! 这是一个非常轻巧的容器,您可以在每台docker机器上运行。 转发到...
  • 可以通过 docker stats 命令实时流式传输容器运行时指标。该命令支持CPU,内存使用情况,内存限制和网络 IO 指标。 下面是 docker stats 命令的输出示例: $ docker stats redis1 redis2 CONTAINER CPU % MEM ...

    原文地址

    1. Docker stats

    可以通过 docker stats 命令实时流式传输容器的运行时指标。该命令支持CPU,内存使用情况,内存限制和网络 IO 指标。

    下面是 docker stats 命令的输出示例:

    $ docker stats redis1 redis2
    
    CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O
    redis1              0.07%               796 KB / 64 MB        1.21%               788 B / 648 B       3.568 MB / 512 KB
    redis2              0.07%               2.746 MB / 64 MB      4.29%               1.266 KB / 648 B    12.4 MB / 0 B

    docker stats 手册上有关于 docker stats 命令的更多信息。

    2. 控制组(Control groups)

    Linux 容器依赖于 控制组,这些组不仅跟踪进程组,还暴露有关 CPU,内存和块 I/O 使用情况的指标。也可以访问这些指标并获取网络使用指标。这与“pure” LXC 容器以及 Docker 容器有关。

    控制组通过 pseudo 文件系统暴露。在最近的发行版中,应该在 /sys/fs/cgroup 下找到这个文件系统。在该目录下,会看到多个子目录,称为 devices,freezer,blkio 等;每个子目录实际上对应于不同的 cgroup 层次结构。

    旧系统中,控制组可能会挂载到 /cgroup,没有明确的层次结构。在这种情况下,不是看到子目录,而是看到该目录中的一堆文件,并且可能有一些与现有容器相对应的目录。

    可以通过下面的命令找出你的控制组挂载的位置:

    $ grep cgroup /proc/mounts

    2.1 枚举 cgroups

    可以查看 /proc/cgroups 以查看系统已知的不同控制组子系统,它们所属的层次结构以及它们包含的组数。

    可以查看 /proc/<pid>/cgroup 以查看某个进程属于哪个控制组。控制组显示为相对于层次结构挂载位置根目录的路径。/ 表示该进程尚未分配给组,而 /lxc/pumpkin 则表示进程是名为 pumpkin 的容器的成员。

    2.2 找出指定容器的 cgroup

    对每个容器而言,每个层次结构中创建一个cgroup。采用在较旧版本的 LXC userland 工具的旧系统上,cgroup 的名称是容器的名称。使用更新版本的 LXC 工具,cgroup 是 lxc/<container_name>

    对于使用 cgroup 的 Docker 容器,容器名是容器的完整 ID 或长 ID。如果通过 docker ps 命令看到的容器为 ae836c95b4c3,长 ID 可能是类似 ae836c95b4c3c9e9179e0e91015512da89fdec91612f63cebae57df9a5444c79 这样的。可以通过 docker inspectdocker ps --no-trunc 命令查看。

    可以通过 /sys/fs/cgroup/memory/docker/<longid>/ 把所有东西放在一起同时看 Docker 容器的内存指标。

    2.3 来自 cgroups 的指标:内存,CPU,块 I/O

    对于每个子系统(内存、CPU 和块 I/O),存在一个或多个 pseudo 文件并包含统计信息。

    内存指标:MEMORY.STAT

    内存指标可在“memory” cgroup 中找到。内存控制组添加了一点开销,因为它对主机上的内存使用情况进行了非常细致的计算。因此,许多发行版默认选择不启用它。通常,要启用它,只需添加一些内核命令行参数:cgroup_enable=memory swapaccount=1

    指标在 pseudo 文件 memory.stat 中。下面是文件内容的大概示例:

    cache 11492564992
    rss 1930993664
    mapped_file 306728960
    pgpgin 406632648
    pgpgout 403355412
    swap 0
    pgfault 728281223
    pgmajfault 1724
    inactive_anon 46608384
    active_anon 1884520448
    inactive_file 7003344896
    active_file 4489052160
    unevictable 32768
    hierarchical_memory_limit 9223372036854775807
    hierarchical_memsw_limit 9223372036854775807
    total_cache 11492564992
    total_rss 1930993664
    total_mapped_file 306728960
    total_pgpgin 406632648
    total_pgpgout 403355412
    total_swap 0
    total_pgfault 728281223
    total_pgmajfault 1724
    total_inactive_anon 46608384
    total_active_anon 1884520448
    total_inactive_file 7003344896
    total_active_file 4489052160
    total_unevictable 32768

    前一半(没有 total_ 前缀)包含 cgroup 中除 sub-cgroups (子 cgroup)之外的进程的指标。后一半(有 total_ 前缀)也包含 sub-cgroups。

    一些指标是“gauges”(量表),或者可以增加或减少的值。例如,swap 是 cgroup 成员使用的交换空间量。其他一些是“counters”(计数器),或值只能增加,因为它们代表特定事件的发生。例如,pgfault 表示创建 cgroup 以来的页面错误数。

    指标描述
    cache此控制组的进程使用的内存,可以与块设备上的块精确关联。在使用“conventional”(常规)I/O(打开,读取,写入系统调用)以及映射文件(使用 mmap)读写磁盘上的文件时,此数量会增加。它也解释了 tmpfs 挂载使用的内存,但原因尚不清楚(It also accounts for the memory used by tmpfs mounts, though the reasons are unclear)。
    rss不和磁盘上的任何东西关联的内存:堆栈,匿名内存映射
    mapped_file控制组中的进程映射的内存量。它不会告诉你有多少内存被使用; 它会告诉你它是如何使用的。
    pgfault, pgmajfaultcgroup 的进程分别触发““page fault”(页面错误)和“major fault”(严重错误)的次数。当进程访问不存在或受保护的部分虚拟内存空间时,会发生页面错误。如果进程有 BUG 并尝试访问无效地址(它会发送一个 SIGSEGV 信号,通常使用 Segmentation fault 消息将其杀死),则前者可能发生。当进程从已被换出的内存区读取或者对应于映射文件时,后者可能发生:在这种情况下,内核从磁盘加载页面,并让 CPU 完成内存访问。当进程写入写时复制内存区域时,也可能发生这种情况:同样,内核会抢占进程,复制内存页面,并在进程自己的页面副本上恢复写入操作。内核实际需要从磁盘读取数据时发生“Major”故障。当它只是复制现有页面或分配空白页面时,它是一个常规(或“次要”)错误。
    swap当前 cgroup 中的进程使用的 swap 的大小。
    active_anon, inactive_anon内核已识别的分别处于活动状态和非活动状态的匿名内存大小。“匿名”内存是未链接到磁盘页面的内存。换句话说,这就是上述 rss 计数器的等价物。实际上,rss 计数器的定义是 active_anon + inactive_anon - tmpfs(其中,tmpfs 是由此控制组装载的 tmpfs 文件系统使用的内存量)。“active”和“inactive”之间有什么区别?页面最初是“active”; 内核定期扫描内存,并将某些页面标记为“inactive”。每当再次访问时,他们立即被重新标记为“active”。当内核几乎内存不足,就到了需要将部分内存换出磁盘回收内存的时刻,内核会交换“inactive”页面。
    active_file, inactive_file高速缓冲存储器,具有与上述匿名存储器相似的 active 和 inactive 状态。确切的公式是 cache = active_file + inactive_file + tmpfs。内核用于在 active 和 inactive 集之间移动内存页的规则与用于匿名内存的规则不同,但一般原则相同。当内核需要回收内存时,从该池中回收干净(=未修改)页面会更便宜,因为它可以立即回收(而匿名页面和脏/修改页面需要先写入磁盘)(When the kernel needs to reclaim memory, it is cheaper to reclaim a clean (=non modified) page from this pool, since it can be reclaimed immediately (while anonymous pages and dirty/modified pages need to be written to disk first))。
    unevictable无法回收的内存;一般来说,会统计被 mlock “锁定”的内存。通常被加密框架用来确保加密密钥和其他敏感材料永远不会换出到磁盘。
    memory_limit, memsw_limit这些并不是真正的指标,但是提醒了应用于此 cgroup 的限制。第一个表示该控制组的进程可以使用的最大物理内存量;第二个表示 RAM + swap 的最大数量。

    记录页面缓存中的内存非常复杂。如果不同控制组中的两个进程读取同一文件(最终依靠磁盘上的相同块),则相关内存将在控制组之间分配。这很好,但这也意味着当一个 cgroup 被终止时,可能会增加另一个 cgroup 的内存使用率,因为它们不再为这些内存页面分摊成本。
    原文:
    Accounting for memory in the page cache is very complex. If two processes in different control groups both read the same file (ultimately relying on the same blocks on disk), the corresponding memory charge is split between the control groups. It’s nice, but it also means that when a cgroup is terminated, it could increase the memory usage of another cgroup, because they are not splitting the cost anymore for those memory pages.

    2.4 CPU 指标:cpuacct.stat

    现在我们已经介绍了内存指标,其他一切都比较简单。CPU 指标位于 cpuacct 控制器中。

    对于每个容器,一个 pseudo 文件 cpuacct.stat 包含容器进程累积的 CPU 使用量,并分解为用户和系统时间。区别是:

    • user 时间是进程直接控制 CPU,执行进程代码的时间。
    • system 时间是内核代表进程执行系统调用的时间。

    这些时间以 1/100 秒的刻度表示,也称为“user jiffies”。每秒有 USER_HZ 个 “jiffies”,而在x86系统中,USER_HZ 为100。从历史上看,这恰好映射到调度器“ticks”每秒运作的数量,但更高频率调度和 tickless 内核已经使得“ticks”次数不相干。

    块 I/O 指标

    块 I/O 在 blkio 控制器中计算。不同的指标分散在不同的文件中。虽然可以在内核文档的 blkio-controller 文件中找到详细的详细信息,但下面是一些最相关的列表:

    指标描述
    blkio.sectors包含由 cgroup 的进程成员逐个设备读取和写入的 512 字节的扇区的个数。读取和写入被合并在一个计数器中。
    blkio.io_service_bytes指示 cgroup 读写的字节数。它在每个设备上有 4 个计数器,因为每个设备有同步和异步 I/O,读和写操作总共四种情况。
    blkio.io_servicedI/O 操作执行的此时,和操作的大小无关。在每个设备上也有 4 个计数器。
    blkio.io_queued指示当前 cgroup 队列的 I/O 操作数量。换句话说,如果 cgroup 没有 I/O 操作,则这个值是 0。但是如果没有 I/O 队列,则并不能表示 cgroup 就是空闲状态(I/O 方面)。它可以在静态设备上进行纯粹的同步读取,因此可以立即处理它们,而无需排队(It could be doing purely synchronous reads on an otherwise quiescent device, which can therefore handle them immediately, without queuing)。此外,尽管找出哪个 cgroup 正在对 I/O 子系统施加压力是有帮助的,但请记住这是相对的。即使进程组没有执行更多的 I/O,其队列大小也会因为其他设备的负载增加而增加(Even if a process group does not perform more I/O, its queue size can increase just because the device load increases because of other devices)。

    2.5 网络指标

    网络指标没有通过控制组直接暴露。对此的解释是:网络接口在网络命名空间上下文中存在。内核可能会计算出一组进程收发的包和字节数,但这些指标并没啥用。你需要每个接口的指标(因为在本地 lo 接口上发生的流量并不算真正的数量)。但是同一个 cgroup 中的进程可能属于多个网络命名空间,那些指标很难解释:多个网络名称空间表示多个 lo 接口,可能包含多个 eth0 接口等;所以这就是为什么没有简单的方法来收集控制组的网络指标。

    相反,我们可以从其他来源收集网络指标:

    IPTABLES

    IPtables(或者说,iptables 只是一个接口的 netfilter 框架,the netfilter framework for which iptables is just an interface)可以做一些严肃的统计。

    例如,可以设置规则来计算 web 服务器的出站 HTTP 流量:

    $ iptables -I OUTPUT -p tcp --sport 80

    没有 -j-g 标志,所以规则只是对匹配的数据包进行计数并到后面的规则。

    之后,可以检查计数器的值:

    $ iptables -nxvL OUTPUT

    从技术上讲,-n 不是必需的,但它阻止 iptables 进行 DNS 反向查找,在这种情况下这可能没有用处。

    计数器包括数据包和字节。如果你想为这样的容器流量设置指标,可以执行一个 for 循环,在 FORWARD 链中为每个容器 IP 地址添加两个 iptables 规则(每个方向一个)。这只会测量通过 NAT 层的流量;还需要添加通过用户级代理的流量。

    然后,需要定期检查这些计数器。如果你碰巧使用 collectd,那么有一个 很好的插件 来自动化 iptables 计数器集合。

    接口层计数器

    由于每个容器都有一个虚拟以太网接口,因此可能需要直接检查该接口的 TX 和 RX 计数器。每个容器都与主机中的虚拟以太网接口关联,其名称类似 vethKk8Zqi。找出哪个接口对应于哪个容器是非常困难的。

    但是现在,最佳做法是在容器内检查指标。要实现这个目的,可以使用 ip-netns magic 在容器的网络命名空间内的主机环境中运行一个可执行文件(you can run an executable from the host environment within the network namespace of a container using ip-netns magic)。

    ip-netns exec 命令允许你在任何对当前进程可见的网络命名空间中执行任何程序(在主机系统上的)。这意味着你的主机可以进入你的容器的网络命名空间,但是容器无法进入主机或其他容器的网络命名空间。但是容器可以和子容器交互。

    命令的完整格式是:

    $ ip netns exec <nsname> <command...>

    例如:

    $ ip netns exec mycontainer netstat -i

    ip netns 通过使用命名空间的 pseudo 伪文件找到“mycontainer”容器。每个进程属于一个网络命名空间,一个 PID 命名空间,一个 mnt 命名空间等,并且这些命名空间在 /proc/<pid>/ns/ 下实现。例如,PID 42 的网络命名空间由伪文件 /proc/42/ns/net 实现。

    当你运行 ip netns exec mycontainer ... 时,它会希望 /var/run/netns/mycontainer 成为那些伪文件之一(接受符号链接)。

    换句话说,要在容器的网络命名空间中执行命令,我们需要:

    • 找出我们想要调查的容器内的任何进程的 PID
    • 创建 /var/run/netns/<somename>/proc/<thepid>/ns/net 的符号链接
    • 执行 ip netns exec <somename> ....

    查看上面部分的枚举 cgroup 以了解如何查找要测量其网络使用情况的容器内进程所属的 cgroup。从那里,你可以检查伪文件命名的任务,其中包含 cgroup 中的所有PID(因此,在容器中)。选择任何一个 PID。
    原文:
    Review Enumerate Cgroups for how to find the cgroup of an in-container process whose network usage you want to measure. From there, you can examine the pseudo-file named tasks, which contains all the PIDs in the cgroup (and thus, in the container). Pick any one of the PIDs.

    把所有东西放在一起,如果一个容器的“短ID”保存在环境变量 $CID 中,那么你可以这样做:

    3. 高性能指标收集的建议

    每次想要更新指标时运行一个新进程都相当昂贵。如果想要以高分辨率和/或通过大量容器收集度量标准(将单个主机上的容器想成1000个),则不需要每次都分叉一个新进程。

    以下是如何从单个进程收集指标。需要使用 C 语言编写指标收集器(或任何允许执行低级别系统调用的语言)。需要使用一个特殊的系统调用 setns(),它允许当前进程进入任意的命名空间。然而,它需要一个打开的到命名空间伪文件(记住:这是 /proc/<pid>/ns/net 中的伪文件)的文件描述符。

    然而,有一个问题:你不能一直保持这个文件描述符打开。如果这样,当控制组的最后一个进程退出时,名称空间不会被销毁,并且其网络资源(如容器的虚拟接口)永远占用(或直到你关闭该文件描述符)。

    正确的做法是跟踪每个容器的第一个 PID,并且每次都重新打开命名空间伪文件。

    4. 在容器退出时收集指标

    有时候,你不关心实时指标收集,但是当一个容器退出时,你想知道它使用了多少CPU,内存等。

    Docker 使得这很困难,因为它依赖于 lxc-start,它在它自己之后仔细清理(carefully cleans up after itself)。 定期收集指标通常更容易,这就是 collectd LXC插件的工作方式。

    但是,如果你仍想在容器停止时收集统计信息,请执行以下操作:

    对于每个容器,启动一个收集进程,并通过将其 PID 写入 cgroup 的任务文件,将其移至要监控的控制组。收集进程应定期重新读取任务文件以检查它是否是控制组的最后一个进程。(如果还想按前一节中的说明收集网络统计信息,则还应该将进程移至适当的网络命名空间。)

    当容器退出时,lxc-start 尝试删除控制组。它失败了,因为控制组仍在使用中;但没关系。现在你的进程应该检测到它是该组中剩下的唯一一个。现在是收集你需要的所有指标的适当时机!

    最后,你的进程应该移回到根控制组,并删除容器控制组。要删除控制组,只需 rmdir 其目录。由于 rmdir 仍然包含文件,因此它是违反直觉的;但请记住这是一个伪文件系统,所以通常的规则不适用。清理完成后,收集过程可以安全地退出。

    展开全文
  • 将所有容器日志转发到 Librato Metrics 的最简单方法是将此存储库作为容器运行,使用: docker run \ -v /var/run/docker.sock:/var/run/docker.sock \ -e LIBRATO_EMAIL= " " \ -e LIBRATO_TOKEN= " " \ ...
  • 统计当前正在运行的docker容器 docker ps |wc -l 统计当前有多少个docker容器,包括exited,created状态的 docker ps -a |wc -l 统计当前有多少个退出的docker容器 docker ps -f status=exited | wc -l wc会...

    统计当前正在运行的docker容器

    docker ps |wc -l

    统计当前有多少个docker容器,包括exited,created状态的

    docker ps -a |wc -l

    统计当前有多少个退出的docker容器

    docker ps -f status=exited | wc -l

    wc会统计标题,所以以上数据最终要减去1。

    展开全文
  • Portainer 之查看容器资源占用统计

    千次阅读 2021-05-27 16:04:10
    点击容器菜单 找到正在运行容器,点击 stats 资源查看器,统计的资源,是从打开这个页面的那一刻开始统计
    1. 点击容器菜单
      在这里插入图片描述

    2. 找到正在运行的容器,点击 stats
      在这里插入图片描述

    3. 资源查看器,统计的资源,是从打开这个页面的那一刻开始统计
      在这里插入图片描述

    展开全文
  • 作者 | 贾之光阿里巴巴高级开发工程师 本文整理自《CNCF x Alibaba... ... 一、RuntimeClass 需求来源 容器运行时的演进过程 ...我们首先了解一下容器运行时的演进过程,整个过程大致分为三个阶段: 第一个阶段:20...

    4.7头图.png

    作者 | 贾之光  阿里巴巴高级开发工程师

    本文整理自《CNCF x Alibaba 云原生技术公开课》第 30 讲,点击直达课程页面
    关注“阿里巴巴云原生”公众号,回复关键词“入门”,即可下载从零入门 K8s 系列文章 PPT。

    一、RuntimeClass 需求来源

    容器运行时的演进过程

    我们首先了解一下容器运行时的演进过程,整个过程大致分为三个阶段:

    1.png
     

    • 第一个阶段:2014 年 6 月

    Kubernetes 正式开源,Docker 是当时唯一的、也是默认的容器运行时;

    • 第二个阶段:Kubernetes v1.3

    rkt 合入 Kubernetes 主干,成为了第二个容器运行时。

    • 第三个阶段:Kubernetes v.15

    与此同时,越来越多的容器运行时也想接入到 Kubernetes 中。如果还是按 rkt 和 Docker 一样内置支持的话,会给 Kubernetes 的代码维护和质量保障带来严重挑战。

    社区也意识到了这一点,所以在 1.5 版本时推出了 CRI,它的全称是 Container Runtime Interface。这样做的好处是:实现了运行时和 Kubernetes 的解耦,社区不必再为各种运行时做适配工作,也不用担心运行时和 Kubernetes 迭代周期不一致所带来的版本维护问题。比较典型的,比如 containerd 中的 cri-plugin 就实现了 CRI、kata-containers、gVisor 这样的容器运行时只需要对接 containerd 就可以了。

    随着越来越多的容器运行时的出现,不同的容器运行时也有不同的需求场景,于是就有了多容器运行时的需求。但是,如何来运行多容器运行时还需要解决以下几个问题:

    • 集群里有哪些可用的容器运行时?
    • 如何为 Pod 选择合适的容器运行时?
    • 如何让 Pod 调度到装有指定容器运行时的节点上?
    • 容器运行时在运行容器时会产生有一些业务运行以外的额外开销,这种「额外开销」需要怎么统计?

    RuntimeClass 的工作流程

    为了解决上述提到的问题,社区推出了 RuntimeClass。它其实在 Kubernetes v1.12 中就已被引入,不过最初是以 CRD 的形式引入的。v1.14 之后,它又作为一种内置集群资源对象 RuntimeClas 被引入进来。v1.16 又在 v1.14 的基础上扩充了 Scheduling 和 Overhead 的能力。

    2.png

    下面以 v1.16 版本为例,讲解一下 RuntimeClass 的工作流程。如上图所示,左侧是它的工作流程图,右侧是一个 YAML 文件。

    YAML 文件包含两个部分:上部分负责创建一个名字叫 runv 的 RuntimeClass 对象,下部分负责创建一个 Pod,该Pod 通过 spec.runtimeClassName 引用了 runv 这个 RuntimeClass。

    RuntimeClass 对象中比较核心的是 handler,它表示一个接收创建容器请求的程序,同时也对应一个容器运行时。比如示例中的 Pod 最终会被 runv 容器运行时创建容器;scheduling 决定 Pod 最终会被调度到哪些节点上。

    结合左图来说明一下 RuntimeClass 的工作流程:

    1. K8s-master 接收到创建 Pod 的请求;
    2. 方格部分表示三种类型的节点。每个节点上都有 Label 标识当前节点支持的容器运行时,节点内会有一个或多个 handler,每个 handler 对应一种容器运行时。比如第二个方格表示节点内有支持 runc 和 runv 两种容器运行时的 handler;第三个方格表示节点内有支持 runhcs 容器运行时的 handler;
    3. 根据 scheduling.nodeSelector, Pod 最终会调度到中间方格节点上,并最终由 runv handler 来创建 Pod。

    二、RuntimeClass 功能介绍

    RuntimeClass 的结构体定义

    3.png

    我们还是以 Kubernetes v1.16 版本中的 RuntimeClass 为例。首先介绍一下 RuntimeClass 的结构体定义。

    一个 RuntimeClass 对象代表了一个容器运行时,它的结构体中主要包含 Handler、Overhead、Scheduling 三个字段。

    • 在之前的例子中我们也提到过 Handler,它表示一个接收创建容器请求的程序,同时也对应一个容器运行时;
    • Overhead 是 v1.16 中才引入的一个新的字段,它表示 Pod 中的业务运行所需资源以外的额外开销;
    • 第三个字段Scheduling 也是在 v1.16 中被引入的,该 Scheduling 配置会被自动注入到 Pod 的 nodeSelector 中。

    RuntimeClass 资源定义例子

    4.png
    5.png

    在 Pod 中引用 RuntimeClass 的用法非常简单,只要在 runtimeClassName 字段中配置好 RuntimeClass 的名字,就可以把这个 RuntimeClass 引入进来。

    Scheduling 结构体的定义

    顾名思义,Scheduling 表示调度,但这里的调度不是说 RuntimeClass 对象本身的调度,而是会影响到引用了 RuntimeClass 的 Pod 的调度。

    6.png

    Scheduling 中包含了两个字段,NodeSelector 和 Tolerations。这两个和 Pod 本身所包含的 NodeSelector 和 Tolerations 是极为相似的。

    NodeSelector 代表的是支持该 RuntimeClass 的节点上应该有的 label 列表。一个 Pod 引用了该 RuntimeClass 后,RuntimeClass admission 会把该 label 列表与 Pod 中的 label 列表做一次合并。如果这两个 label 中有冲突的,会被 admission 拒绝。这里的冲突是指它们的 key 相同,但是 value 不相同,这种情况就会被 admission 拒绝。另外需要注意的是,RuntimeClass 并不会自动为 Node 设置 label,需要用户在使用前提前设置好。

    Tolerations 表示 RuntimeClass 的容忍列表。一个 Pod 引用该 RuntimeClass 之后,admission 也会把 toleration 列表与 Pod 中的 toleration 列表做一个合并。如果这两处的 Toleration 有相同的容忍配置,就会将其合并成一个。

    为什么引入 Pod Overhead?

    7.png

    上图左边是一个 Docker Pod,右边是一个 Kata Pod。我们知道,Docker Pod 除了传统的 container 容器之外,还有一个 pause 容器,但我们在计算它的容器开销的时候会忽略 pause 容器。对于 Kata Pod,除了 container 容器之外,kata-agent, pause, guest-kernel 这些开销都是没有被统计进来的。像这些开销,多的时候甚至能超过 100MB,这些开销我们是没法忽略的。

    这就是我们引入 Pod Overhead 的初衷。它的结构体定义如下:

    8.png

    它的定义非常简单,只有一个字段 PodFixed。它这里面也是一个映射,它的 key 是一个 ResourceName,value 是一个 Quantity。每一个 Quantity 代表的是一个资源的使用量。因此 PodFixed 就代表了各种资源的占用量,比如 CPU、内存的占用量,都可以通过 PodFixed 进行设置。

    Pod Overhead 的使用场景与限制

    Pod Overhead 的使用场景主要有三处:

    • Pod 调度

    在没有引入 Overhead 之前,只要一个节点的资源可用量大于等于 Pod 的 requests 时,这个 Pod 就可以被调度到这个节点上。引入 Overhead 之后,只有节点的资源可用量大于等于 Overhead 加上 requests 的值时才能被调度上来。

    • ResourceQuota

    它是一个 namespace 级别的资源配额。假设我们有这样一个 namespace,它的内存使用量是 1G,我们有一个 requests 等于 500 的 Pod,那么这个 namespace 之下,最多可以调度两个这样的 Pod。而如果我们为这两个 Pod 增添了 200MB 的 Overhead 之后,这个 namespace 下就最多只可调度一个这样的 Pod。

    • Kubelet Pod 驱逐

    引入 Overhead 之后,Overhead 就会被统计到节点的已使用资源中,从而增加已使用资源的占比,最终会影响到 Kubelet Pod 的驱逐。

    以上是 Pod Overhead 的使用场景。除此之外,Pod Overhead 还有一些使用限制和注意事项:

    • Pod Overhead 最终会永久注入到 Pod 内并且不可手动更改。即便是将 RuntimeClass 删除或者更新,Pod Overhead 依然存在并且有效;
    • Pod Overhead 只能由 RuntimeClass admission 自动注入(至少目前是这样的),不可手动添加或更改。如果这么做,会被拒绝;
    • HPA 和 VPA 是基于容器级别指标数据做聚合,Pod Overhead 不会对它们造成影响。

    三、多容器运行时示例

    9.png

    目前阿里云 ACK 安全沙箱容器已经支持了多容器运行时,我们以上图所示环境为例来说明一下多容器运行时是怎么工作的。

    如上图所示有两个 Pod,左侧是一个 runc 的 Pod,对应的 RuntimeClass 是 runc,右侧是一个 runv 的Pod,引用的 RuntimeClass 是 runv。对应的请求已用不同的颜色标识了出来,蓝色的代表是 runc 的,红色的代表是 runv 的。图中下半部分,其中比较核心的部分是 containerd,在 containerd 中可以配置多个容器运行时,最终上面的请求也会到达这里进行请求的转发。

    我们先来看一下 runc 的请求,它先到达 kube-apiserver,然后 kube-apiserver 请求转发给 kubelet,最终 kubelet 将请求发至 cri-plugin(它是一个实现了 CRI 的插件),cri-plugin 在 containerd 的配置文件中查询 runc 对应的 Handler,最终查到是通过 Shim API runtime v1 请求 containerd-shim,然后由它创建对应的容器。这是 runc 的流程。

    runv 的流程与 runc 的流程类似。也是先将请求到达 kube-apiserver,然后再到达 kubelet,再把请求到达 cri-plugin,cri-plugin 最终还回去匹配 containerd 的配置文件,最终会找到通过 Shim API runtime v2 去创建 containerd-shim-kata-v2,然后由它创建一个 Kata Pod。

    下面我们再看一下 containerd 的具体配置。

    10.png

    containerd 默认放在 [file:///etc/containerd/config.toml]() 这个位置下。比较核心的配置是在 plugins.cri.containerd 目录下。其中 runtimes 的配置都有相同的前缀 plugins.cri.containerd.runtimes,后面有 runc, runv 两种 RuntimeClass。这里面的 runc 和 runv 和前面 RuntimeClass 对象中 Handler 的名字是相对应的。除此之外,还有一个比较特殊的配置 plugins.cri.containerd.runtimes.default_runtime,它的意思是说,如果一个 Pod 没有指定 RuntimeClass,但是被调度到当前节点的话,那么就默认使用 runc 容器运行时。

    下面的例子是创建 runc 和 runv 这两个 RuntimeClass 对象,我们可以通过 kubectl get runtimeclass 看到当前所有可用的容器运行时。

    11.png

    下图从左至右分别是一个 runc 和 runv 的 Pod,比较核心的地方就是在 runtimeClassName 字段中分别引用了 runc 和 runv 的容器运行时。

    12.png

    最终将 Pod 创建起来之后,我们可以通过 kubectl 命令来查看各个 Pod 容器的运行状态以及 Pod 所使用的容器运行时。我们可以看到现在集群中有两个 Pod:一个是 runc-pod,另一个是 runv-pod,分别引用的是 runc 和 runv 的 RuntimeClass,并且它们的状态都是 Running。

    13.png

    四、本文总结

    本文的主要内容就到此为止了,这里为大家简单总结一下:

    • RuntimeClass 是 Kubernetes 一种内置的集群资源,主要用来解决多个容器运行时混用的问题;
    • RuntimeClass 中配置 Scheduling 可以让 Pod 自动调度到运行了指定容器运行时的节点上。但前提是需要用户提前为这些 Node 设置好 label;
    • RuntimeClass 中配置 Overhead,可以把 Pod 中业务运行所需以外的开销统计进来,让调度、ResourceQuota、Kubelet Pod 驱逐等行为更准确。

    4.7尾图.png

    活动报名链接:https://yqh.aliyun.com/live/CloudNative

    阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

     

    原文链接
    本文为云栖社区原创内容,未经允许不得转载。

    展开全文
  • Docker Compose是一个用来定义和运行多个docker容器的工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。 Compose 通过一个配置文件来管理多个Docker容器,...
  • 在Docker容器中使用运行HTTP负载测试。 负载测试脚本内置在容器中,并提供了将HTTP请求统计信息存储到磁盘的功能。 用法 编写蝗虫脚本 可以在scripts/main.py找到示例脚本。 使用import docker 。 始终在脚本顶部...
  • 提供 容器统计信息(例如,ID,​​内存使用率百分比,CPU使用率百分比,正在运行的进程等) 支持 和 资料库 显示实时温度,速度,延迟和内存统计信息 返回 演示版 返回 安装 这适用于最新的Chronos 5.1版及更高...
  • Doker容器

    2019-07-22 10:55:19
    容器是Docker 的三大核心概念之一,使应用程序运行的基础环境,下面我们就来具体讲解一下Docker容器。 一、什么是容器 所谓容器就是镜像的一个运行实例,并且带有运行时需要的可写的文件层,其中的应用程序也处于...
  • 容器是用于管理Linux容器的gnome-shell扩展,由和运行 支持的动作: 开始 停止 去掉 暂停 重新开始 顶级资源 shell-在新的Termainl中打开一个Shell 统计-在新终端中打开统计信息,实时更新 日志-在新终端中记录...
  • 描述:本人在docker容器运行Tensorflow实验,为了统计Tensorflow训练过程中容器内部的资源使用情况,查阅不少资料。发现当下网上具体介绍docker容器内部资源统计的文章很少,于是,在此暂且充当指路人留下此文为...
  • docker 中 单容器和多容器的部署

    千次阅读 2018-07-11 01:42:39
    单容器应用部署实践说明:部署一个单页面的应用 参考网址:...查看容器运行情况 5.在浏览器中输入地址和端口号,就可以看到网页 6.创建文件夹flas...
  • Docker选择容器作为核心和基础,依靠容器技术支撑的Docker迅速成为国内外各大云计算厂商以及开发者手中的至宝。在一片热火朝天之后,新的革命已经悄然来到。 1.1 云计算平台 回首历史,云计算时代蕴育出了众多...
  • 固定式压力容器试题

    2014-04-16 21:15:21
    1.以下选项中,( D )不是压力容器的使用情况记录资料。 A. 定期检验、定期自行检查的...10.使用单位必须建立《压力容器技术档案》,(每年 )应将压力容器数量和变动情况统计报表报送主管部门和当地安全监察部门。
  • 美团容器平台架构及容器技术实践

    千次阅读 2018-11-16 10:54:09
    本文根据美团基础架构部/容器研发中心技术总监欧阳坚在2018 QCon(全球软件开发大会)上的演讲内容整理而成。 背景 美团的容器集群管理平台叫做HULK。漫威动画里的HULK在发怒时会变成“绿巨人”,它的这个特性和...
  • 可选地,来自诸如mlat-client类的提供程序的MLAT数据(如果您想查看MLAT统计信息) 它在linux/amd64 、 linux/arm/v6 、 linux/arm/v7和linux/arm64上构建和运行(见下文)。 弃用通知 readsb (Mictronics) 的作者...
  • Docker与容器

    千次阅读 2016-12-26 23:01:30
    它通过将运行环境和应用程序打包到一起,来解决部署的环境依赖问题,真正做到跨平台的分发和使用。而这一点和DevOps不谋而合,通过Docker可以大大提升开发、测试和运维的效率。在这个移动互联网的时代,如果一个工具...
  • docker容器技术基础

    千次阅读 2018-10-24 15:56:48
    容器是轻量的,可同时运行数十个容器,模拟分布式系统 不必花时间在配置和安装上,无需担心系统的改动,以及依赖关系是否满足 容器与虚拟机 运行在同一主机的3个虚拟机 运行在同一主机的3个容器 区别: A....
  • Docker之容器操作

    千次阅读 多人点赞 2020-11-02 02:48:45
    1.创建容器 1. 新建容器 可以使用 docker [container] create 命令新建一个容器。 docker create -it ubuntu:latest af8f4f922dafee22c8fe6cd2aelld16e2507d61flblfa55b36e94db7ef45178 $ docker ps - a CONTAINER ...
  • 据晶少了解,国庆假期后的...据悉这是一款可以适用于 Amazon ECS的计算引擎,主要帮助企业在生产过程中运行容器、却无需部署或者管理服务器,换句话说就是专注设计和构建应用程序,而不用挂心太多基础设施的“那些事...
  • cadvisor实现容器监控

    万次阅读 2017-03-15 11:33:47
    随着docker容器云的广泛应用,大量的业务软件运行容器中,这使得对docker容器的监控越来越重要,具体监控指标总结如下: 首先是容器本身资源使用情况:cpu,内存,网络,磁盘 然后物理机的资源使用情况:cpu,...
  • kubernetes容器启动详解

    万次阅读 2017-06-10 16:57:43
    如果大家对kubernetes组件以及架构相关分析,可以看我之前的源码阅读,今天只从一个函数分析容器的启动过程,这个函数就是SyncPod,这个是创建kubelet里面最核心的一个函数了。这个方法分为五步:// 1. Compute ...
  • 如何设计一个可用的web容器

    千次阅读 2015-09-15 08:20:46
    开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探讨实现的...
  • 容器技术是最快被数据中心所广泛接受和采用的技术之一,从2013年起,据统计Docker的下载量已经快达到30亿次,容器已经彻底改变了应用部署方式,但是IT基础设施的管理却没有及时跟上。
  • Docker 容器入门

    千次阅读 2018-02-24 15:56:00
    Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和...
  • 默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的给定资源。Docker 提供了一些方法来控制容器可以使用多少内存、CPU 或块 IO,并设置 docker run 命令的运行时配置标志。本节详细介绍了何时应该设置...
  • 如何设计一个web容器

    万次阅读 多人点赞 2016-02-14 10:20:45
    开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探讨实现的...
  • 容器的企业级应用中,即便是提供单个服务往往也需要大量容器的共同参与,从而增加了程序运行的复杂性,对大规模 容器的编排管理和程序故障后的排查溯源等需求催生了进一步统筹容器的工具的需求,Kubernetes(K8s)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 81,400
精华内容 32,560
关键字:

统计容器运行情况