security.alpha.kubernetes.io/sysctls 字段只允许在 cgroup 命名空间中运行的 sysctl,以便更改设置不会影响不相关的 pod。
正如您所建议的,Kubernetes k8s 中的默认解决方案是在 kubelet 启动时添加 --experimental-allowed-unsafe-sysctls 标志,但是在 GKE 中无法添加 kubelet 标志,因为它们不可访问。
您可以通过修改其中一个节点上的 /etc/default/kubelet 文件以包含实验标志,然后尝试向其中添加 pod 来解决此问题。但是,这只能作为临时解决方法,因为这将被主服务器覆盖。即使你编辑了kubelet文件,master也会在一段时间后恢复默认配置设置。
在 GKE 中无法覆盖此行为,但有一些解决方法。您可以选择以下两种解决方案中的任何一种。请注意,您必须将 <ctl name> 替换为您想要访问的 sysctl pod。
解决办法:
1) 第一个选项是赋予容器读/写权限,然后在底部添加命令行sysctl -w [<ctl name> operation]。
pod yaml 文件如下所示:
kind: Pod
metadata:
name: sample
labels:
app: gpdb
spec:
hostname: sample
containers:
- name: gpdb
image: ubuntu
securityContext:
privileged: true
command:
- /bin/sh
- -c
- |
sysctl -w [<ctl name> operation] && sleep 5000
2) 第二个选项是创建一个手动运行 sysctl 命令的 DaemonSet。您可以通过以下方式使用 DockerFile 执行此操作:
Dockerfile sysctl-change
FROM alpine
CMD sysctl -w [<ctl name> operation] ; sleep 365d
DaemonSet 资源文件
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: sysctl-change
spec:
template:
metadata:
labels:
name: sysctl-change
spec:
containers:
- name: sysctl-change
image: sysctl-change # remember to set this correctly. It is the Docker image
securityContext:
privileged: true
restartPolicy: Always
nodeSelector: # update this appropriately to the nodes
pool: elasticsearch
在上面的示例中,确保 nodeSelector 设置为适当的值(您希望设置 sysctl 的所有节点)并且图像名称适当。
有关此问题的更多讨论,您可以查看following StackOverflow page。