kubernetes - 在所有 pod 中运行特定命令
问题描述
我想知道是否可以在所有现有 pod(包括不在默认命名空间中的 pod)中的特定时间运行特定命令(例如:echo "foo")。它就像一个 cronJob,但唯一的区别是我只想在一个地方指定/部署它。这甚至可能吗?
解决方案
有可能的。请找到我遵循的步骤,希望对您有所帮助。
首先,创建一个简单的脚本来读取 pod 的名称,exec
然后执行命令。
import os, sys
import logging
from datetime import datetime
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
dt = datetime.now()
ts = dt.strftime("%d-%m-%Y-%H-%M-%S-%f")
pods = os.popen("kubectl get po --all-namespaces").readlines()
for pod in pods:
ns = pod.split()[0]
po = pod.split()[1]
try:
h = os.popen("kubectl -n %s exec -i %s sh -- hostname" %(ns, po)).read()
os.popen("kubectl -n %s exec -i %s sh -- touch /tmp/foo-%s.txt" %(ns, po, ts))
logging.debug("Executed on %s" %h)
except Exception as e:
logging.error(e)
接下来,Dockerize 上面的脚本,构建和推送。
FROM python:3.8-alpine
ENV KUBECTL_VERSION=v1.18.0
WORKDIR /foo
ADD https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl .
RUN chmod +x kubectl &&\
mv kubectl /usr/local/bin
COPY foo.py .
CMD ["python", "foo.py"]
稍后我们将在 CronJob 中使用此图像。你可以看到我已经在 Dockerfile 中安装了 kubectl 来触发 kubectl 命令。但这还不够,我们应该将clusterole
和添加clusterrolebinding
到运行 CronJob 的服务帐户中。
我创建了一个 nsfoo
并将 foo 的默认服务帐户绑定到我创建的集群角色,如下所示。
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: foo
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec"]
verbs: ["get", "list", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: foo
subjects:
- kind: ServiceAccount
name: default
namespace: foo
roleRef:
kind: ClusterRole
name: foo
apiGroup: rbac.authorization.k8s.io
现在服务帐户默认值 foo 有权访问get, list, exec
集群中的所有 pod。
最后创建一个 cronjob 来运行任务。
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: foo
spec:
schedule: "15 9 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: foo
image: harik8/sof:62177831
imagePullPolicy: Always
restartPolicy: OnFailure
登录到 pod 并检查,它应该在/tmp
每个 pod 的目录中创建了带有时间戳的文件。
$ kubectl exec -it app-59666bb5bc-v6p2h sh
# ls -lah /tmp
-rw-r--r-- 1 root root 0 Jun 4 09:15 foo-04-06-2020-09-15-06-792614.txt
日志
error: cannot exec into a container in a completed pod; current phase is Failed
error: cannot exec into a container in a completed pod; current phase is Succeeded
DEBUG:root:Executed on foo-1591262100-798ng
DEBUG:root:Executed on grafana-5f6f8cbf75-jtksp
DEBUG:root:Executed on istio-egressgateway-557dcf8d8-npfnd
DEBUG:root:Executed on istio-ingressgateway-6489d9556d-2dp7j
command terminated with exit code 126
DEBUG:root:Executed on OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"hostname\": executable file not found in $PATH": unknown
DEBUG:root:Executed on istiod-774777b79-mvmqm
推荐阅读
- office-js - 如何在 Outlook 加载项中设置 PR_SECURITY_FLAGS MAPI 属性(新 Web 加载项、Office JS + 清单)
- authentication - istio 从 ext-auth 中排除服务
- javascript - 如何从两个数组中创建 json 对象
- sql - 时间戳和增加周数
- azure-cosmosdb - 使用 Entity Framework Core 3 在 CosmosDB 中存储具有 JSON 值的属性
- ajax - ASP.NET Core 3.1 Razor Pages Web App:使用 Ajax 调用后,剃刀页面表单数据被擦除的原因是什么?
- akka - 使用 Akka 流进行一对多合并
- perl - 如何从 unix shell 调用带有参数的子例程
- airflow-scheduler - 每周二 00:00:00 运行 Airflow DAG
- javascript - 加载后使用数据表