我尝试在 Google Container Engine 的集群节点上安装 ElasticSearch(最新),但 ElasticSearch 需要变量:
vm.max_map_count
>= 262144.
如果我 ssh 到每个节点并手动运行:
sysctl -w vm.max_map_count=262144
一切顺利,但是任何新节点都不会具有指定的配置。
所以我的问题是:
有没有办法在启动时在每个节点上加载系统配置? Deamon Set 不是好的解决方案,因为在 docker 容器内,系统变量是只读的。
我正在使用带有
gci
节点图像的新创建的集群。
我在查看这个存储库时找到了另一个解决方案。
依赖于init容器的使用,好处是只有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
您应该能够使用 DaemonSet 来模拟启动脚本的行为。如果脚本需要在节点上执行根级操作,您可以将 DaemonSet pod 配置为在特权模式下运行。
有关如何执行此操作的示例,请参阅https://github.com/kubernetes/contrib/tree/master/startup-script
正如 Robert 指出的那样,DaemonSet 可以作为启动脚本运行。不幸的是,GKE 只会让你运行一个将 restartPolicy 设置为 Always 的 DaemonSet。
所以为了防止k8s在运行
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
为此找到了 Essy 解决方案 查看opensearch pod Scheduled nodes, Provide a label to node 部署在 pod 下方。
apiVersion: v1
kind: Pod
metadata:
name: os-pod
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: os-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
nodeSelector:
disktype: ssd # node label
initContainers:
- name: init-sysctl
image: busybox
command:
- sysctl
- -w
- vm.max_map_count=262144
imagePullPolicy: IfNotPresent
securityContext:
privileged: true