有没有办法为 helm post-install hook 启用 shareProcessNamespace?
Is there a way to enable shareProcessNamespace for helm post-install hook?
我是 运行 一个使用 shareProcessNamespace: true
.
的 3 个容器(telegraf、fluentd 和一个内部代理)的 pod
我编写了一个 python 脚本来从中央控制器 API 端点获取 telegraf 和 fluentd 的初始配置。由于这是一次性操作,我打算使用 helm post-install hook.
apiVersion: batch/v1
kind: Job
metadata:
name: agent-postinstall
annotations:
"helm.sh/hook-weight": "3"
"helm.sh/hook": "post-install"
spec:
template:
spec:
containers:
- name: agent-postinstall
image: "{{ .Values.image.agent.repository }}:{{ .Values.image.agent.tag | default .Chart.AppVersion }}"
imagePullPolicy: IfNotPresent
command: ['python3', 'getBaseCfg.py']
volumeMounts:
- name: config-agent-volume
mountPath: /etc/config
volumes:
- name: config-agent-volume
configMap:
name: agent-cm
restartPolicy: Never
backoffLimit: 1
python 脚本需要在获取配置之前检查 telegraf/fluentd/agent 个进程是否启动。我打算等待(超时)直到 pgrep <telegraf/fluentd/agent>
returns true 然后触发 APIs。有没有办法为 post-install 挂钩启用 shareProcessNamespace
?谢谢。
PS:目前,代理会调用 python 脚本及其自己的启动脚本。它有效,但它很笨拙。我想将其移出代理容器。
shareProcessNamespace
这个标志最重要的部分是它只在一个 pod 中工作,一个 pod 中的所有容器将相互共享进程。
在描述的方法中应该使用 job
。作业会创建一个单独的 pod
,因此它不会以这种方式工作。容器应该是“主”pod 的一部分,所有其他容器都可以访问该 pod 的 运行ning 进程。
More details about process sharing.
可能的解决方法
可以直接使用 kubectl
命令从容器中获取进程。
下面是如何使用 pgrep
命令检查进程状态的示例。 pgrepContainer
容器需要已安装 pgrep
命令。
job.yaml:
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-postinstall-hook"
annotations: "helm.sh/hook": post-install
spec:
template:
spec:
serviceAccountName: config-user # service account with appropriate permissions is required using this approach
volumes:
- name: check-script
configMap:
name: check-script
restartPolicy: Never
containers:
- name: post-install-job
image: "bitnami/kubectl" # using this image with kubectl so we can connect to the cluster
command: ["bash", "/mnt/script/checkScript.sh"]
volumeMounts:
- name: check-script
mountPath: /mnt/script
和 configmap.yaml
其中包含脚本和逻辑,它们检查循环中的三个进程,每 10 秒迭代 60 次:
apiVersion: v1
kind: ConfigMap
metadata:
name: check-script
data:
checkScript.sh: |
#!/bin/bash
podName=test
pgrepContainer=app-1
process1=sleep
process2=pause
process3=postgres
attempts=0
until [ $attempts -eq 60 ]; do
kubectl exec ${podName} -c ${pgrepContainer} -- pgrep ${process1} 1>/dev/null 2>&1 \
&& kubectl exec ${podName} -c ${pgrepContainer} -- pgrep ${process2} 1>/dev/null 2>&1 \
&& kubectl exec ${podName} -c ${pgrepContainer} -- pgrep ${process3} 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
break
fi
attempts=$((attempts + 1))
sleep 10
echo "Waiting for all containers to be ready...$[ ${attempts}*10 ] s"
done
if [ $attempts -eq 60 ]; then
echo "ERROR: Timeout"
exit 1
fi
echo "All containers are ready !"
echo "Configuring telegraf and fluentd services"
最终结果如下:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
test 2/2 Running 0 20m
test-postinstall-hook-dgrc9 0/1 Completed 0 20m
$ kubectl logs test-postinstall-hook-dgrc9
Waiting for all containers to be ready...10 s
All containers are ready !
Configuring telegraf and fluentd services
以上是另一种方法,您可以使用它的逻辑作为实现最终目标的基础。
开始后
另外postStart hook可以考虑用在一些逻辑会被定位的地方。创建容器后它将 运行。由于主应用程序需要时间来启动并且已经有逻辑在等待它,所以这不是问题:
there is no guarantee that the hook will execute before the container ENTRYPOINT
我是 运行 一个使用 shareProcessNamespace: true
.
我编写了一个 python 脚本来从中央控制器 API 端点获取 telegraf 和 fluentd 的初始配置。由于这是一次性操作,我打算使用 helm post-install hook.
apiVersion: batch/v1
kind: Job
metadata:
name: agent-postinstall
annotations:
"helm.sh/hook-weight": "3"
"helm.sh/hook": "post-install"
spec:
template:
spec:
containers:
- name: agent-postinstall
image: "{{ .Values.image.agent.repository }}:{{ .Values.image.agent.tag | default .Chart.AppVersion }}"
imagePullPolicy: IfNotPresent
command: ['python3', 'getBaseCfg.py']
volumeMounts:
- name: config-agent-volume
mountPath: /etc/config
volumes:
- name: config-agent-volume
configMap:
name: agent-cm
restartPolicy: Never
backoffLimit: 1
python 脚本需要在获取配置之前检查 telegraf/fluentd/agent 个进程是否启动。我打算等待(超时)直到 pgrep <telegraf/fluentd/agent>
returns true 然后触发 APIs。有没有办法为 post-install 挂钩启用 shareProcessNamespace
?谢谢。
PS:目前,代理会调用 python 脚本及其自己的启动脚本。它有效,但它很笨拙。我想将其移出代理容器。
shareProcessNamespace
这个标志最重要的部分是它只在一个 pod 中工作,一个 pod 中的所有容器将相互共享进程。
在描述的方法中应该使用 job
。作业会创建一个单独的 pod
,因此它不会以这种方式工作。容器应该是“主”pod 的一部分,所有其他容器都可以访问该 pod 的 运行ning 进程。
More details about process sharing.
可能的解决方法
可以直接使用 kubectl
命令从容器中获取进程。
下面是如何使用 pgrep
命令检查进程状态的示例。 pgrepContainer
容器需要已安装 pgrep
命令。
job.yaml:
apiVersion: batch/v1
kind: Job
metadata:
name: "{{ .Release.Name }}-postinstall-hook"
annotations: "helm.sh/hook": post-install
spec:
template:
spec:
serviceAccountName: config-user # service account with appropriate permissions is required using this approach
volumes:
- name: check-script
configMap:
name: check-script
restartPolicy: Never
containers:
- name: post-install-job
image: "bitnami/kubectl" # using this image with kubectl so we can connect to the cluster
command: ["bash", "/mnt/script/checkScript.sh"]
volumeMounts:
- name: check-script
mountPath: /mnt/script
和 configmap.yaml
其中包含脚本和逻辑,它们检查循环中的三个进程,每 10 秒迭代 60 次:
apiVersion: v1
kind: ConfigMap
metadata:
name: check-script
data:
checkScript.sh: |
#!/bin/bash
podName=test
pgrepContainer=app-1
process1=sleep
process2=pause
process3=postgres
attempts=0
until [ $attempts -eq 60 ]; do
kubectl exec ${podName} -c ${pgrepContainer} -- pgrep ${process1} 1>/dev/null 2>&1 \
&& kubectl exec ${podName} -c ${pgrepContainer} -- pgrep ${process2} 1>/dev/null 2>&1 \
&& kubectl exec ${podName} -c ${pgrepContainer} -- pgrep ${process3} 1>/dev/null 2>&1
if [ $? -eq 0 ]; then
break
fi
attempts=$((attempts + 1))
sleep 10
echo "Waiting for all containers to be ready...$[ ${attempts}*10 ] s"
done
if [ $attempts -eq 60 ]; then
echo "ERROR: Timeout"
exit 1
fi
echo "All containers are ready !"
echo "Configuring telegraf and fluentd services"
最终结果如下:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
test 2/2 Running 0 20m
test-postinstall-hook-dgrc9 0/1 Completed 0 20m
$ kubectl logs test-postinstall-hook-dgrc9
Waiting for all containers to be ready...10 s
All containers are ready !
Configuring telegraf and fluentd services
以上是另一种方法,您可以使用它的逻辑作为实现最终目标的基础。
开始后
另外postStart hook可以考虑用在一些逻辑会被定位的地方。创建容器后它将 运行。由于主应用程序需要时间来启动并且已经有逻辑在等待它,所以这不是问题:
there is no guarantee that the hook will execute before the container ENTRYPOINT