如何使用 k8s 创建多个容器并在其中运行不同的命令

时间:2021-07-06 04:09:59

标签: docker kubernetes google-kubernetes-engine

我有一个 Kubernetes Job, job.yaml :

---
apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace
---
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
  namespace: my-namespace
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: gcr.io/project-id/my-image:latest
        command: ["sh", "run-vpn-script.sh", "/to/download/this"] # need to run this multiple times
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never

我需要为不同的参数运行 command。我有 30 个参数要运行。我不确定这里的最佳解决方案是什么。我正在考虑在循环中创建容器来运行所有参数。我怎样才能做到这一点?我想同时运行 commands 或容器。

3 个答案:

答案 0 :(得分:2)

简单来说,您想要运行多个命令,以下是在一个 pod 中执行多个命令的示例格式:

command: ["/bin/bash","-c","touch /foo && echo 'here' && ls /"]

当我们将此逻辑应用于您对两种不同操作的要求时

 command: ["sh", "-c", "run-vpn-script.sh /to/download/this && run-vpn-script.sh /to/download/another"] 

答案 1 :(得分:1)

如果您想多次运行相同的命令,只需更改名称即可多次部署相同的 YAML。

您可以使用 sed 命令替换 YAML 中的值,并将这些 YAML 应用到集群以创建容器。

示例 job.yaml

---
apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace
---
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
  namespace: my-namespace
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: gcr.io/project-id/my-image:latest
        command: COMMAND # need to run this multiple times
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never

命令:

'job.yaml | sed -i "s,COMMAND,["sh", "run-vpn-script.sh", "/to/download/this"],"

所以上面的命令将替换 YAML 中的所有值,您可以将 YAML 应用到集群以创建容器。同样,您可以申请其他变量。

您可以根据需要在 YAML 中设置的命令中传递不同的参数。

您也可以使用命令来部署多个作业

kubectl create job test-job --from=cronjob/a-cronjob

https://www.mankier.com/1/kubectl-create-job

根据需要将其他参数传递到命令中。

如果你不只是想运行 POD 你也可以试试

kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>

https://jamesdefabia.github.io/docs/user-guide/kubectl/kubectl_run/

答案 2 :(得分:1)

在其他答案中提出的解决方案之外,您可以采取的一些方法如下:


Helm 示例:

简而言之,

Helm 是一个模板工具,可让您对清单(YAML 文件)进行模板化。通过这种方式,您可以拥有多个具有不同名称和不同命令的 Jobs 实例。

假设您已按照以下指南安装了 Helm

您可以创建一个示例图表,您将对其进行修改以运行您的 Jobs

  • helm create chart-name

您需要删除 chart-name/templates/ 中的所有内容并清除 chart-name/values.yaml 文件。

之后,您可以创建您将对其进行迭代的 values.yaml 文件:

jobs:
  - name: job1
    command: ['"perl",  "-Mbignum=bpi", "-wle", "print bpi(3)"']
    image: perl
  - name: job2
    command: ['"perl",  "-Mbignum=bpi", "-wle", "print bpi(20)"']
    image: perl
  • templates/job.yaml
{{- range $jobs := .Values.jobs }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ $jobs.name }}
  namespace: default # <-- FOR EXAMPLE PURPOSES ONLY!
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: {{ $jobs.image }}
        command: {{ $jobs.command }}
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never
---
{{- end }}

如果您创建了上述文件,您可以预先对将应用于集群的内容运行以下命令:

  • $ helm template .(在 chart-name 文件夹内)
---
# Source: chart-name/templates/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: job1
  namespace: default
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(3)"]
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never
---
# Source: chart-name/templates/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: job2
  namespace: default
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(20)"]
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never
<块引用>

附注 #1!

此示例将创建 X 数量的 Jobs,其中每个都将彼此分开。如果下载的文件需要持久存储,请参考数据持久化文档(例如:GKE)。

<块引用>

附注 #2!

您还可以在模板 (namespace) 中添加您的 templates/namespace.yaml 定义,以便在运行您的 Jobs 之前创建它。

您还可以通过以下方式运行图表:

  • $ helm install chart-name .(在 chart-name 文件夹内)

之后,您应该会看到 2 个 Jobs 已完成:

  • $ kubectl get pods
NAME         READY   STATUS      RESTARTS   AGE
job1-2dcw5   0/1     Completed   0          82s
job2-9cv9k   0/1     Completed   0          82s

以及他们创建的输出:

  • $ echo "one:"; kubectl logs job1-2dcw5; echo "two:"; kubectl logs job2-9cv9k
one:
3.14
two:
3.1415926535897932385

其他资源: