Kubernetes를 사용하여 하나의 yaml 파일에 여러 명령을 설정하는 방법은 무엇입니까?


94

이 공식 문서에서는 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}\""]

둘 이상의 명령을 실행하려면 어떻게해야합니까?

답변:


148
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

1
@aclokay 인수를 추가 명령 문자열로 지정할 수 있습니다. 컨테이너에서 명령과 인수를 구분하는 것은 인수를 더 쉽게 재정의하기위한 것입니다. 기능적으로 동일합니다.
— Tim Allclair

-c는 여기서 무엇을합니까?
— Abdul

1
@Abdul은 대화 형 셸을 시작하거나 파일에서 스크립트를로드하는 대신 인수로 제공된 스크립트를 실행하는 것을 의미합니다.
— Tim Allclair

76

내가 선호하는 것은 args를 여러 줄로 만드는 것입니다. 이것은 가장 간단하고 읽기 쉽습니다. 또한 이미지에 영향을주지 않고 스크립트를 변경할 수 있으며 포드를 다시 시작하기 만하면됩니다. 예를 들어 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이 실제로 "-"뒤의 모든 행을 하나로 연결하고 sh는 하나의 긴 문자열 "echo starting; ls ...; echo done;"을 실행하기 때문입니다.


좋지만 kubectl로 편집을 요청하면 다시 한 줄로 표시됩니다. :)
— sekrett

@sekrett 오 안돼! :(
— aclokay 2010 년

1
이것은 아주 잘 작동했습니다. 핵심은 각 줄의 세미콜론입니다. 이것은 명령이 많고 위의 솔루션으로 여러 줄이 될 때 특히 좋은 솔루션입니다. git diff a breeze
— kellyfj

이것이 제가 찾던 것입니다. 이 솔루션에서 환경 변수를 인수로 사용하면 잘 작동합니다.
— Jingpeng Wu

+1 아름답고 여러 줄 명령이 완벽하게 작동합니다 : command: ['/bin/bash', '-c'] args: - exec &> /path/to/redirected/program.output;`python / program.py``
— key1

46

볼륨 및 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

당신이 하나의 명령으로 모든 명령을 연결하지 않도록하려는 경우 ;또는 &&당신은 또한 히어 닥을 사용하여 진정한 멀티 줄 스크립트를 얻을 수 있습니다 :

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

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

   EOF

이것은 기존 bash 스크립트를 실행하는 데 편리하지만 heredoc을 설정하기 위해 내부 및 외부 쉘 인스턴스가 모두 필요하다는 단점이 있습니다.


3

IMHO는 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

1

질문이 여전히 활성화되어 있는지 확실하지 않지만 위의 답변에서 해결책을 찾지 못했기 때문에 작성하기로 결정했습니다.

다음 접근 방식을 사용합니다.

readinessProbe:
  exec:
    command:
    - sh
    - -c
    - |
      command1
      command2 && command3

내 예제가 readinessProbe, livenessProbe 등과 관련되어 있다는 것을 알고 있지만 동일한 경우가 컨테이너 명령에 해당한다고 생각합니다. 이것은 Bash에서 작성하는 표준 스크립트를 반영하므로 유연성을 제공합니다.


0

다음은 kubernetes를 사용하여 하나의 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

많은 사람들이 이것이 비밀이 사용되어야하는 것이 아니라 선택 사항이라고 주장 할 것이라는 것을 알고 있습니다.


0

여기 내 성공적인 달리기

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: busybox
  name: busybox
spec:
  containers:
  - command:
    - /bin/sh
    - -c
    - |
      echo "running below scripts"
      i=0; 
      while true; 
      do 
        echo "$i: $(date)"; 
        i=$((i+1)); 
        sleep 1; 
      done
    name: busybox
    image: busybox
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.