kubernetes - Pod 无法在 kubernetes 中分配大页面

标签 kubernetes

我在 kubernetes 中运行了一个 pod,在主机中分配了大页面,在 pod 中定义了大页面。 kubernetes worker 位于 VM 中。 VM(主机)分配了大页面。但是 pod 无法分配大页面。应用程序在尝试写入第一个大页分配时获得 SIGBUS。

pod 定义包括大页面:

    securityContext:
      allowPrivilegeEscalation: true
      privileged: true
      runAsUser: 0
      capabilities:
        add: ["SYS_ADMIN", "IPC_LOCK"]
    resources:
      requests:
        intel.com/intel_sriov_netdevice : 2
        memory: 2Gi
        hugepages-2Mi: 4Gi
      limits:
        intel.com/intel_sriov_netdevice : 2
        memory: 2Gi
        hugepages-2Mi: 4Gi
    volumeMounts:
    - mountPath: /sys
      name: sysfs
    - mountPath: /dev/hugepages
      name: hugepage
      readOnly: false
  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages
  - name: sysfs
    hostPath:
      path: /sys


托管 Pod 的 VM 分配了大页面:
cat /proc/meminfo | grep -i hug
AnonHugePages:         0 kB
HugePages_Total:    4096
HugePages_Free:     4096
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

以下代码在托管 pod 的 VM 中运行良好,我可以看到在/dev/hugepages 中创建了大页面文件,并且在进程运行时 HugePages_Free 计数器减少。

#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define LENGTH (2UL*1024*1024)
#define FILE_NAME "/dev/hugepages/hugepagefile"
static void write_bytes(char *addr)
{
        unsigned long i;

        for (i = 0; i < LENGTH; i++)
                *(addr + i) = (char)i;
}
int main ()
{
   void *addr;
   int i;
   char buf[32];
   int fd;

   for (i = 0 ; i < 16 ; i++ ) {
           sprintf(buf, "%s_%d", FILE_NAME, i);
           fd = open(buf, O_CREAT | O_RDWR, 0755);
           addr = mmap((void *)(0x0UL), LENGTH, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_HUGETLB , fd, 0);

           printf("address returned %p \n", addr);

           if (addr == MAP_FAILED) {
                   perror("mmap ");
           } else {
                write_bytes(addr);
                //munmap(addr, LENGTH);
                //unlink(FILE_NAME);
           }
           close(fd);
   }
   while (1){}
   return 0;
}


但是如果我在 pod 中运行相同的代码,我会在尝试写入分配的第一个大页面时得到一个 SIGBUS。

VM 上的结果(托管 Pod)
root@k8s-1:~# cat /proc/meminfo | grep -i hug
AnonHugePages:         0 kB
HugePages_Total:    4096
HugePages_Free:     4096
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
root@k8s-1:~# ./mmap  &
[1] 19428
root@k8s-1:~# address returned 0x7ffff7800000
address returned 0x7ffff7600000
address returned 0x7ffff7400000
address returned 0x7ffff7200000
address returned 0x7ffff7000000
address returned 0x7ffff6e00000
address returned 0x7ffff6c00000
address returned 0x7ffff6a00000
address returned 0x7ffff6800000
address returned 0x7ffff6600000
address returned 0x7ffff6400000
address returned 0x7ffff6200000
address returned 0x7ffff6000000
address returned 0x7ffff5e00000
address returned 0x7ffff5c00000
address returned 0x7ffff5a00000

root@k8s-1:~# cat /proc/meminfo | grep -i hug
AnonHugePages:         0 kB
HugePages_Total:    4096
HugePages_Free:     4080
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

pod 中的结果:
Program received signal SIGBUS, Bus error.
0x00005555555547cb in write_bytes ()
(gdb) where
#0  0x00005555555547cb in write_bytes ()
#1  0x00005555555548a6 in main ()

最佳答案

这是a known problem在 K8s 中。
罪魁祸首是 kubelet 不会在节点状态更新时更新/sys/fs/cgroup/hugetlb/kubepods/hugetlb.2MB.limit_in_bytes,默认情况下每 5 分钟更新一次。然而,在主机上启用大页面后,它会正确更新节点的资源。这创造了在根 cgroup 中使用错误配置限制的节点上使用大页面调度工作负载的可能性。
前段时间发了this patch到 K8s,但它从未被接受。如果它仍然适用,您可以尝试将其应用于您的 K8s 构建。如果不是,如果其他人重新调整它并再次提交,我将不胜感激。我花了太多时间试图进入并切换到另一个项目。

关于kubernetes - Pod 无法在 kubernetes 中分配大页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57233360/

相关文章:

kubernetes - 群集自动缩放器不会在Daemonset部署上触发放大

kubernetes - kubernetes 中的节点/代理子资源是什么?

Kubernetes CRD 版本控制

logging - 使用客户端 api 获取 kubelet 日志

kubernetes - 绕过命令初始化容器

elasticsearch - Kubernetes-将Pod关联性规则应用于实时部署

kubernetes - 在 GKE 中使用具有多个静态 IP 地址的 Cloud NAT 时,是否可以为 Pod 分配特定的出站 IP 地址?

kubernetes:使用 valueFrom 在环境变量中使用 runAsUser 的值?

kubernetes - 无法从 couchdb pod kubernetes 挂载特定目录

linux - Kubernetes 上的 Nginx (99 : Cannot assign requested address)