在集群节点上设置 vm.max_map_count

Set vm.max_map_count on cluster nodes

我尝试在 Google 容器引擎上的集群节点上安装 ElasticSearch(最新),但 ElasticSearch 需要变量:vm.max_map_count >= 262144。

如果我 ssh 到每个节点并手动 运行 :

sysctl -w vm.max_map_count=262144

一切顺利,但任何新节点都不会具有指定的配置。

所以我的问题是:

有没有办法在启动时在每个节点上加载系统配置? Deamon Set 不是好的解决方案,因为在 docker 容器内,系统变量是只读的。

我正在使用带有 gci 节点映像的全新创建的集群。

您应该能够使用 DaemonSet 来模拟启动脚本的行为。如果脚本需要在节点上执行根级操作,您可以在特权模式下将 DaemonSet pods 设置为 运行。

有关如何执行此操作的示例,请参阅 https://github.com/kubernetes/contrib/tree/master/startup-script

我在查看 this repository 时找到了另一个解决方案。

依赖an init container的使用,好处是只有init容器是运行权限:

annotations:
    pod.beta.kubernetes.io/init-containers: '[
      {
      "name": "sysctl",
        "image": "busybox",
        "imagePullPolicy": "IfNotPresent",
        "command": ["sysctl", "-w", "vm.max_map_count=262144"],
        "securityContext": {
          "privileged": true
        }
      }
    ]'

自 Kubernetes 1.6 以来,有一种新语法可用,它仍然适用于 1.7。从 1.8 开始需要这个新语法。初始化容器的声明移动到 spec:

  - name: init-sysctl
    image: busybox
    command:
    - sysctl
    - -w
    - vm.max_map_count=262144
    imagePullPolicy: IfNotPresent
    securityContext:
      privileged: true

正如 Robert 指出的那样,DaemonSet 可以 运行 作为启动脚本。不幸的是,GKE 只会让您 运行 一个将 restartPolicy 设置为 Always 的 DaemonSet。

因此,为了防止 k8s 在 运行ning sysctl 之后不断重启容器,它必须在设置后休眠,最好只在选定节点上 运行。这不是一个优雅的解决方案,但它至少是有弹性的。

示例

es-host-setup Dockerfile:

FROM alpine
CMD sysctl -w vm.max_map_count=262144; sleep 365d

DaemonSet 资源文件:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: es-host-setup
spec:
  template:
    metadata:
      labels:
        name: es-host-setup
    spec:
      containers:
      - name: es-host-setup
        image: es-host-setup
        securityContext:
          privileged: true
      restartPolicy: Always
      nodeSelector:
        pool: elasticsearch