Làm thế nào để đặt nhiều lệnh trong một tệp yaml với Kubernetes?


95

Trong tài liệu chính thức này, nó có thể chạy lệnh trong tệp cấu hình 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}\""]

Nếu tôi muốn chạy nhiều hơn một lệnh thì phải làm thế nào?

Câu trả lời:


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

Giải thích: Câu command ["/bin/sh", "-c"]nói "chạy một trình bao và thực hiện các hướng dẫn sau". Các args sau đó được chuyển dưới dạng lệnh tới shell. Trong kịch bản shell, dấu chấm phẩy phân tách các lệnh và &&chạy lệnh sau có điều kiện nếu lệnh đầu tiên thành công. Trong ví dụ trên, nó luôn chạy command onetheo sau command twovà chỉ chạy command threenếu command twothành công.

Thay thế: Trong nhiều trường hợp, một số lệnh bạn muốn chạy có thể đang thiết lập lệnh cuối cùng để chạy. Trong trường hợp này, xây dựng Dockerfile của riêng bạn là cách nên làm. Nhìn vào chỉ thị RUN nói riêng.


1
Vâng, rất có giá trị, tuy nhiên, tôi nghĩ rằng cũng có những trường hợp sử dụng tốt để mở rộng commandvì nó sẽ ghi đè của Dockerfile Entrypoint;)
Michael Hausenblas

1
Bất kỳ ý tưởng về cách thực hiện điều này với vòng đời của container? Nó không có args
aclokay

1
@aclokay bạn có thể chỉ định các đối số dưới dạng chuỗi lệnh bổ sung. Việc tách biệt giữa lệnh & args trong Vùng chứa chỉ là để làm cho việc ghi đè các đối số dễ dàng hơn. Chúng tương đương về mặt chức năng.
Tim Allclair

-c làm gì ở đây?
Abdul

1
@Abdul có nghĩa là chạy tập lệnh được cung cấp dưới dạng đối số, thay vì bắt đầu một trình bao tương tác hoặc tải tập lệnh từ một tệp.
Tim Allclair

77

Sở thích của tôi là đa dòng các args, điều này đơn giản nhất và dễ đọc nhất. Ngoài ra, tập lệnh có thể được thay đổi mà không ảnh hưởng đến hình ảnh, chỉ cần khởi động lại pod. Ví dụ: đối với kết xuất mysql, thông số vùng chứa có thể là một cái gì đó như sau:

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:
      - ...

Lý do điều này hoạt động là yaml thực sự nối tất cả các dòng sau dấu "-" thành một và sh chạy một chuỗi dài "echo started; ls ...; echo done;".


Tốt, nhưng khi bạn yêu cầu chỉnh sửa với kubectl, nó sẽ lại ở một dòng. :)
sekrett

@sekrett ồ không! :(
aclokay

1
Điều này hoạt động khá tốt - chìa khóa là dấu chấm phẩy trên mỗi dòng. Đây là một giải pháp đặc biệt tốt khi các lệnh có nhiều và sẽ có nhiều dòng với giải pháp trên. Làm cho git diff một làn gió
kellyfj

Đây là những gì tôi đang tìm kiếm. sử dụng biến môi trường làm đối số với giải pháp này hoạt động tốt.
Jingpeng Wu

1 đẹp, cộng với nhiều dòng lệnh hoạt động hoàn hảo: command: ['/bin/bash', '-c'] args: - exec &> /path/to/redirected/program.output;'python / program.py`' --key1 = val1` '--key2 = val2`' --key3 = val3`
nelsonspbr

46

Nếu bạn sẵn sàng sử dụng Volume và ConfigMap, bạn có thể gắn dữ liệu ConfigMap dưới dạng tập lệnh, sau đó chạy tập lệnh đó:

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

Điều này làm sạch thông số nhóm của bạn một chút và cho phép tạo tập lệnh phức tạp hơn.

$ kubectl logs my-pod
Do this
Do that

1
Rất tuyệt, nhưng tôi nghĩ đơn giản hơn để có script nội dòng, chỉ cần sử dụng cú pháp đa dòng. Tôi chỉ ra điều này trong một câu trả lời riêng.
Oliver

Còn khi tôi cần chuyển dấu ngoặc kép. Ví dụ tưởng tượng lệnh này: printf '% s @% s \ n' "$ (echo 'sử dụng')" "$ (echo 'host')"
L3K0V

16

Nếu bạn muốn tránh nối tất cả các lệnh thành một lệnh duy nhất với ;hoặc &&bạn cũng có thể lấy các tập lệnh nhiều dòng thực sự bằng cách sử dụng heredoc:

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

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

   EOF

Điều này rất hữu ích để chạy các tập lệnh bash hiện có, nhưng có nhược điểm là yêu cầu cả phiên bản bên trong và bên ngoài để thiết lập heredoc.


3

IMHO lựa chọn tốt nhất là sử dụng vô hướng khối gốc của YAML . Cụ thể trong trường hợp này, khối kiểu gấp .

Bằng cách gọi, sh -cbạn có thể chuyển các đối số đến vùng chứa của mình dưới dạng lệnh, nhưng nếu bạn muốn tách chúng một cách trang nhã bằng các dòng mới, bạn muốn sử dụng khối kiểu gấp , để YAML biết chuyển đổi các dòng mới thành khoảng trắng, nối các lệnh một cách hiệu quả.

Một ví dụ hoạt động đầy đủ:

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

Tôi không chắc liệu câu hỏi có còn hoạt động hay không nhưng do thực tế là tôi không tìm thấy lời giải trong các câu trả lời trên nên tôi quyết định viết nó ra.

Tôi sử dụng cách tiếp cận sau:

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

Tôi biết ví dụ của mình có liên quan đến readinessProbe, livenessProbe, v.v. nhưng nghi ngờ trường hợp tương tự là đối với các lệnh vùng chứa. Điều này mang lại sự linh hoạt vì nó phản ánh cách viết script chuẩn trong Bash.


0

Đây là cách bạn có thể chuyển, nhiều lệnh và đối số trong một tệp YAML với kubernetes:

# 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"]

Toàn bộ vùng chứa chặn từ tệp 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

Chỉ để mang lại một tùy chọn khả thi khác, các bí mật có thể được sử dụng khi chúng được trình bày cho nhóm dưới dạng các tập:

Ví dụ bí mật:

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

Trích xuất 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

Tôi biết nhiều người sẽ tranh luận rằng đây không phải là bí mật phải được sử dụng để làm gì, nhưng nó là một lựa chọn.


0

Đây là lần chạy thành công của tôi

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.