Kubernetesで1つのyamlファイルに複数のコマンドを設定するにはどうすればよいですか?


91

この公式ドキュメントでは、yaml構成ファイルでコマンドを実行できます。

https://kubernetes.io/docs/tasks/configure-pod-container/

apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:  # specification of the pod’s contents
  restartPolicy: Never
  containers:
  - name: hello
    image: "ubuntu:14.04"
    env:
    - name: MESSAGE
      value: "hello world"
    command: ["/bin/sh","-c"]
    args: ["/bin/echo \"${MESSAGE}\""]

複数のコマンドを実行したい場合、どうすればよいですか?

回答:


144
command: ["/bin/sh","-c"]
args: ["command one; command two && command three"]

説明:command ["/bin/sh", "-c"]「シェルを実行し、次の命令を実行する」と言います。その後、引数はコマンドとしてシェルに渡されます。シェルスクリプトでは、セミコロンでコマンドを区切り&&、最初のコマンドが成功した場合は条件付きで次のコマンドを実行します。上記の例では、常ににcommand one続いて実行されcommand two、成功したcommand three場合にのみ実行されcommand twoます。

別の方法:多くの場合、実行するコマンドのいくつかは、実行する最終コマンドを設定している可能性があります。この場合、独自のDockerfileを構築するのがよいでしょう。特にRUNディレクティブを見てください。


1
はい、非常に有効です。ただし、commandDockerfileをオーバーライドするため、拡張する適切なユースケースもあると思いますEntrypoint;)
Michael Hausenblas

1
コンテナのライフサイクルでこれを行う方法について何か考えはありますか?引数はありません
aclokay 2018

1
@aclokay引数を追加のコマンド文字列として指定できます。コンテナ内のコマンドと引数の分離は、引数のオーバーライドを簡単にするためです。それらは機能的に同等です。
Tim Allclair 2018

ここで-cは何をしますか?
Abdul

1
@Abdulは、対話型シェルを起動したり、ファイルからスクリプトを読み込んだりするのではなく、引数として提供されたスクリプトを実行することを意味します。
Tim Allclair

69

私の好みは、引数を複数行にすることです。これが最も簡単で読みやすいです。また、画像に影響を与えずにスクリプトを変更できます。ポッドを再起動するだけです。たとえば、mysqlダンプの場合、コンテナの仕様は次のようになります。

containers:
  - name: mysqldump
    image: mysql
    command: ["/bin/sh", "-c"]
    args:
      - echo starting;
        ls -la /backups;
        mysqldump --host=... -r /backups/file.sql db_name;
        ls -la /backups;
        echo done;
    volumeMounts:
      - ...

これが機能する理由は、yamlが実際に「-」の後のすべての行を1つに連結し、shが1つの長い文字列「echo starting; ls ...; echo done;」を実行するためです。


いいですが、kubectlで編集をリクエストすると、再び1行になります。:)
sekrett 2018

@sekrettおおお!:(
aclokay

1
これはかなりうまくいきました-キーは各行のセミコロンです。これは、コマンドが多く、上記のソリューションで複数行になる場合に特に良いソリューションです。git diffを簡単に
kellyfj

これは私が探していたものです。このソリューションでは、環境変数を引数として使用するとうまく機能します。
Jingpengウー

+1美しいプラス複数行のコマンドは完全に機能します:command: ['/bin/bash', '-c'] args: - exec &> /path/to/redirected/program.output;`python / program.py`` --key1 = val1` `--key2 = val2`` --key3 = val3`
nelsonspbr

44

ボリュームとConfigMapを使用する場合は、ConfigMapデータをスクリプトとしてマウントし、そのスクリプトを実行できます。

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  entrypoint.sh: |-
    #!/bin/bash
    echo "Do this"

    echo "Do that"
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: "ubuntu:14.04"
    command:
    - /bin/entrypoint.sh
    volumeMounts:
    - name: configmap-volume
      mountPath: /bin/entrypoint.sh
      readOnly: true
      subPath: entrypoint.sh
  volumes:
  - name: configmap-volume
    configMap:
      defaultMode: 0700
      name: my-configmap

これにより、ポッド仕様が少し整理され、より複雑なスクリプトが可能になります。

$ kubectl logs my-pod
Do this
Do that

1
とてもすばらしいですが、スクリプトをインラインにする方が簡単だと思います。複数行の構文を使用するだけです。これを別の答えで示します。
オリバー

二重引用符を渡す必要がある場合はどうでしょうか。たとえば、次のコマンドを想像してください:printf '%s @%s \ n' "$(echo 'user')" "$(echo 'host')"
L3K0V

15

すべてのコマンドを1つのコマンドに連結することを避けたい場合、;または&&ヒアドキュメントを使用して真の複数行スクリプトを取得することもできます。

command: 
 - sh
 - "-c"
 - |
   /bin/bash <<'EOF'

   # Normal script content possible here
   echo "Hello world"
   ls -l
   exit 123

   EOF

これは既存のbashスクリプトを実行するのに便利ですが、ヒアドキュメントを設定するために内部シェルインスタンスと外部シェルインスタンスの両方を必要とするという欠点があります。


2

私見最良のオプションは、YAMLのネイティブ使用することですブロックスカラーを。特にこの場合、折りたたみスタイルのブロックです。

呼び出すsh -cことで、引数をコマンドとしてコンテナに渡すことができますが、それらを改行でエレガントに区切る場合は、折りたたみスタイルブロックを使用して、YAMLが改行を空白に変換し、コマンドを効果的に連結できるようにします。

完全に機能する例:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  containers:
  - name: busy
    image: busybox:1.28
    command: ["/bin/sh", "-c"]
    args:
    - >
      command_1 &&
      command_2 &&
      ... 
      command_n

0

ここでは、kubernetesを使用して1つのYAMLファイルで複数のコマンドと引数を渡す方法を示します。

# Write your commands here
command: ["/bin/sh", "-c"]
# Write your multiple arguments in args
args: ["/usr/local/bin/php /var/www/test.php & /usr/local/bin/php /var/www/vendor/api.php"]

yamlファイルからの完全なコンテナーブロック:

    containers:
      - name: widc-cron # container name
        image: widc-cron # custom docker image
        imagePullPolicy: IfNotPresent # advisable to keep
        # write your command here
        command: ["/bin/sh", "-c"]
        # You can declare multiple arguments here, like this example
        args: ["/usr/local/bin/php /var/www/tools/test.php & /usr/local/bin/php /var/www/vendor/api.php"]
        volumeMounts: # to mount files from config-map generator
          - mountPath: /var/www/session/constants.inc.php
            subPath: constants.inc.php
            name: widc-constants

0

別の可能なオプションをもたらすために、ボリュームとしてポッドに提示されるときにシークレットを使用できます。

秘密の例:

apiVersion: v1
kind: Secret 
metadata:
  name: secret-script
type: Opaque
data:
  script_text: <<your script in b64>>

Yaml抽出物:

....
containers:
    - name: container-name
      image: image-name
      command: ["/bin/bash", "/your_script.sh"]
      volumeMounts:
        - name: vsecret-script
          mountPath: /your_script.sh
          subPath: script_text
....
  volumes:
    - name: vsecret-script
      secret:
        secretName: secret-script

私は多くの人がこれは秘密を使用しなければならないものではないと主張するでしょうが、それはオプションです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.