Kubernetes ile bir yaml dosyasında birden fazla komut nasıl ayarlanır?


96

Bu resmi belgede, bir yaml yapılandırma dosyasında command çalıştırabilir:

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}\""]

Birden fazla komut çalıştırmak istersem nasıl yapılır?

Yanıtlar:


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

Açıklama:command ["/bin/sh", "-c"] "bir kabuk çalıştırın ve aşağıdaki yönergeleri uygulayın" diyor. Daha sonra argümanlar komut olarak kabuğa aktarılır. Kabuk komut dosyası oluşturmada, bir noktalı virgül komutları ayırır &&ve ilk başarılı olursa aşağıdaki komutu koşullu olarak çalıştırır. Yukarıdaki örnekte, her zaman command oneardından gelir command twove yalnızca başarılı command threeolursa çalışır command two.

Alternatif: Çoğu durumda, çalıştırmak istediğiniz komutlardan bazıları muhtemelen çalıştırmak için son komutu ayarlıyor. Bu durumda, kendi Dockerfile'ınızı oluşturmak en iyi yoldur. Özellikle RUN direktifine bakın .


1
Evet, çok geçerli, ancak commandDockerfile'ı geçersiz kıldığı için genişletilebilecek iyi kullanım durumlarının da olduğunu düşünüyorum Entrypoint;)
Michael Hausenblas

1
Bunun kapsayıcı yaşam döngüsü ile nasıl yapılacağına dair bir fikriniz var mı?
Değiştirgeleri

1
@aclokay argümanları ek komut dizeleri olarak belirtebilirsiniz. Kaptaki komut ve bağımsız değişkenler arasındaki ayrım, yalnızca argümanların geçersiz kılınmasını kolaylaştırmak içindir. İşlevsel olarak eşdeğerdirler.
Tim Allclair

-c burada ne yapar?
Abdul

1
@Abdul, etkileşimli bir kabuk başlatmak veya betiği bir dosyadan yüklemek yerine, argüman olarak sağlanan betiği çalıştırmak anlamına gelir.
Tim Allclair

77

Tercihim argümanları çok satırlı yapmak, bu en basit ve okunması en kolay olanı. Ayrıca, komut dosyası görüntüyü etkilemeden değiştirilebilir, sadece bölmeyi yeniden başlatmanız gerekir. Örneğin, bir mysql dökümü için, kapsayıcı özelliği şuna benzer bir şey olabilir:

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

Bunun işe yaramasının nedeni, yaml'nin aslında "-" 'den sonraki tüm satırları bir araya getirmesi ve sh'nin tek bir uzun dizge çalıştırmasıdır.


Güzel, ancak kubectl ile bir düzenleme isteğinde bulunduğunuzda, yine tek satırda olacak. :)
sekrett

@sekrett oh hayır! :(
aclokay

1
Bu oldukça iyi çalıştı - anahtar her satırdaki noktalı virgüldür. Bu, komutların çok olduğu ve yukarıdaki çözümle çok satırlı olacağı durumlarda özellikle iyi bir çözümdür. Git diff a meltem yapar
kellyfj

Aradığım buydu. Bu çözümle birlikte ortam değişkenini argüman olarak kullanmak güzel çalışıyor.
Jingpeng Wu

+1 Güzel, artı çok satırlı komutlar mükemmel çalışıyor: command: ['/bin/bash', '-c'] args: - exec &> /path/to/redirected/program.output;`python / program.py` --key1 = val1` --key2 = val2`` --key3 = val3`
nelsonspbr

46

Bir Birim ve ConfigMap kullanmak istiyorsanız, ConfigMap verilerini bir komut dosyası olarak bağlayabilir ve ardından bu komut dosyasını çalıştırabilirsiniz:

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

Bu, kapsül spesifikasyonunuzu biraz temizler ve daha karmaşık komut dosyası oluşturmaya izin verir.

$ kubectl logs my-pod
Do this
Do that

1
Çok güzel, ancak betiğin satır içi olması daha kolay, sadece çok satırlı sözdizimi kullanın. Bunu ayrı bir cevapta gösteriyorum.
Oliver

Çift tırnak geçmem gerektiğinde ne olacak? Örneğin şu komutu hayal edin: printf '% s @% s \ n' "$ (echo 'user')" "$ (echo 'host')"
L3K0V

16

Tüm komutları tek bir komutta birleştirmekten kaçınmak istiyorsanız ;veya &&bir yorumlu metin kullanarak gerçek çok satırlı komut dosyalarını da elde edebilirsiniz:

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

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

   EOF

Bu, mevcut bash betiklerini çalıştırmak için kullanışlıdır, ancak heredoc'u kurmak için hem iç hem de dış kabuk örneği gerektirmenin dezavantajı vardır.


4

IMHO en iyi seçenek, YAML'nin yerel blok skalerlerini kullanmaktır . Özellikle bu durumda, katlanmış stil bloğu.

Çağırarak sh -c, argümanları konteynırınıza komut olarak iletebilirsiniz, ancak bunları yeni satırlarla zarif bir şekilde ayırmak istiyorsanız, katlanmış stil bloğunu kullanmak istersiniz , böylece YAML, yeni satırları beyaz boşluklara dönüştürerek komutları etkin bir şekilde birleştirir.

Tam bir çalışma örneği:

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

Sorunun hala aktif olup olmadığından emin değilim ama yukarıdaki cevaplarda çözümü bulamadığım için yazmaya karar verdim.

Aşağıdaki yaklaşımı kullanıyorum:

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

Örneğimin readyinessProbe, livenessProbe, vb. İle ilgili olduğunu biliyorum ama aynı durumun konteyner komutları için olduğundan şüpheleniyorum. Bu, Bash'de standart bir komut dosyası yazımını yansıttığı için esneklik sağlar.


0

Kubernetes ile tek bir YAML dosyasında birden çok komut ve argümanı nasıl geçirebileceğiniz aşağıda açıklanmıştır:

# 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 dosyasından dolu konteyner bloğu:

    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

Olası başka bir seçeneği getirmek için, sırlar bölmeye ciltler olarak sunulurken kullanılabilir:

Gizli örnek:

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

Yaml özü:

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

Birçoğunun sırların bunun için kullanılması gerektiğini savunmayacağını biliyorum, ama bu bir seçenek.


0

İşte benim başarılı koşum

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.