Bagaimana saya bisa menjaga kontainer tetap berjalan di Kubernetes?

124

Sekarang saya mencoba menjalankan container sederhana dengan shell (/ bin / bash) di cluster Kubernetes.

Saya pikir ada cara untuk menjaga kontainer tetap berjalan di kontainer Docker dengan menggunakan pseudo-ttydan melepaskan opsi ( -tdopsi pada docker runperintah).

Sebagai contoh,

$ sudo docker run -td ubuntu:latest

Apakah ada opsi seperti ini di Kubernetes?

Saya sudah mencoba menjalankan container dengan menggunakan kubectl run-containerperintah seperti:

kubectl run-container test_container ubuntu:latest --replicas=1

Tetapi kontainer keluar selama beberapa detik (seperti meluncurkan dengan docker runperintah tanpa opsi yang saya sebutkan di atas). Dan ReplicationController meluncurkannya lagi berulang kali.

Apakah ada cara agar container tetap berjalan di Kubernetes seperti -tdopsi di docker runperintah?

springwell
sumber
Menggunakan gambar ini (seperti yang disarankan oleh dokumen Kubernetes ) cukup berguna:kubectl run curl --image=radial/busyboxplus:curl -i --tty
Matheus Santana
Pertanyaan ini telah disebutkan di video ini: Kubernetes dengan cara yang sangat sulit di Datadog dengan judul slide "Pemujaan kargo . Dari wikipedia: Istilah programmer kultus kargo mungkin berlaku ketika programmer komputer yang tidak terampil atau pemula (atau seorang yang tidak berpengalaman dengan masalah tersebut) di tangan) menyalin beberapa kode program dari satu tempat ke tempat lain dengan sedikit atau tanpa pemahaman tentang cara kerjanya atau apakah itu diperlukan dalam posisi barunya.
tgogos

Jawaban:

49

Sebuah kontainer keluar saat proses utamanya keluar. Melakukan sesuatu seperti:

docker run -itd debian

terus terang saja, menahan wadah terbuka adalah retasan yang hanya boleh digunakan untuk uji dan contoh cepat. Jika Anda hanya ingin wadah untuk pengujian selama beberapa menit, saya akan melakukan:

docker run -d debian sleep 300

Yang memiliki keuntungan bahwa container akan keluar secara otomatis jika Anda lupa. Alternatifnya, Anda bisa meletakkan sesuatu seperti ini dalam satu whilelingkaran agar tetap berjalan selamanya, atau jalankan aplikasi seperti top. Semua ini semestinya mudah dilakukan di Kubernetes.

Pertanyaan sebenarnya adalah mengapa Anda ingin melakukan ini? Penampung Anda harus menyediakan layanan, yang prosesnya akan membuat penampung tetap berjalan di latar belakang.

Adrian Mouat
sumber
Terima kasih atas jawaban Anda. Sekarang saya mencoba memahami perilaku container, dengan lusinan container yang berjalan pada waktu yang sama. Loop tanpa akhir dan menggunakan perintah berat lainnya, mencegah saya untuk mengetahui apa perilaku container. Itulah alasan mengapa saya membutuhkan wadah sederhana seperti hanya menjalankan / bin / bash.
springwell
Untuk saat ini, saya akan mencoba menjalankan cattanpa argumen dan topdan sleepdengan argumen dalam jumlah besar.
springwell
30
sleep infinitybekerja dalam banyak kasus (bukan busybox)
rwilson04
1
Ada banyak alasan untuk melakukan ini. Misalnya, Anda mungkin menerapkan pod Anda dengan rilis helm dan konfigurasi yang diinjeksi, yang akan membuat pembuatan ulang lingkungan serupa menjengkelkan dan tidak praktis. Namun memiliki container dengan konfigurasi tersebut jika pod lain mengalami error / dihapus bisa sangat berguna.
Richard Løvehjerte
Karena layanan saya terdiri dari banyak proses.
Константин Ван
135

Container dimaksudkan untuk dijalankan hingga selesai. Anda perlu memberi penampung Anda tugas yang tidak akan pernah selesai. Sesuatu seperti ini seharusnya bekerja:

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  containers:
  - name: ubuntu
    image: ubuntu:latest
    # Just spin & wait forever
    command: [ "/bin/bash", "-c", "--" ]
    args: [ "while true; do sleep 30; done;" ]
Joel B
sumber
Tapi apakah ini praktik terbaik?
aneesh joshi
3
@aneeshjoshi Saya tidak akan mengatakan ini adalah praktik terbaik . Ini hanyalah sebuah contoh yang menyediakan sebuah pod yang akan berjalan tanpa langsung keluar. Praktik terbaiknya adalah membuat penampung Anda untuk melakukan pekerjaan yang dirancang untuknya (pekerjaan yang berjalan sampai selesai, server web yang berjalan terus-menerus, dll.). Saya memposting ini sebagai contoh karena Kubernetes pada awalnya dapat merasa frustasi ketika Anda terus membuat pod hanya untuk menghilangkannya karena perintah default segera keluar.
Joel B
@Joel Terima kasih. Saya bertanya-tanya apa cara yang "benar" untuk melakukannya.
aneesh joshi
1
terima kasih untuk ini karena saya membutuhkan wadah yang bisa hidup untuk sementara memungkinkan saya untuk memasukinya. Saya mencoba melakukan hal yang sama dengan gambar yang lebih terang daripada ubuntudan mencoba bashgambar tetapi tidak bisa membuatnya berfungsi. Ada ide bagaimana melakukan hal yang sama dengan bashgambar?
cryanbhu
1
@cryanbhu Untuk gambar yang lebih terang, Anda dapat menggunakan alpine, spesifikasi penampungnya akan terlihat seperti ini: {"name": "util", "image": "alpine", "command": [ "/bin/sh", "-c", "--" ], "args": [ "while true; do sleep 30; done;" ]}(hanya json karena yaml tidak akan memformat dalam komentar di sini.) Yang penting /bin/shbukan /bin/bash.
bschlueter
111

Anda dapat menggunakan CMD ini di Dockerfile:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

Ini akan membuat wadah Anda tetap hidup sampai disuruh berhenti. Menggunakan trap dan wait akan membuat container Anda segera bereaksi terhadap permintaan stop . Tanpa jebakan / menunggu, berhenti akan memakan waktu beberapa detik.

Untuk gambar berbasis busybox (digunakan dalam gambar berbasis alpine), sleep tidak mengetahui tentang argumen tak terhingga. Solusi ini memberi Anda respons langsung yang sama docker stopseperti dalam contoh di atas:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"
itsafire
sumber
Saya menggunakan hal yang sama pada kubernetes deployment yaml untuk tujuan debugging
sdkks
ini memberi saya "tidur: nomor tidak valid 'tak terhingga'"
arunkjn
@arunkjn Terima kasih untuk ini. Anda mungkin terjebak dengan gambar yang menggunakan busybox (seperti gambar alpine). Lihat jawaban yang diperbarui.
itsafire
24
  1. Di Dockerfile Anda, gunakan perintah ini:

    CMD ["sh", "-c", "tail -f /dev/null"]
    
  2. Bangun citra buruh pelabuhan Anda.

  3. Dorong ke cluster Anda atau serupa, hanya untuk memastikan gambar itu tersedia.
  4. kubectl run debug-container -it --image=<your-image>
    
Radu Gabriel
sumber
Kiat bagus untuk men-debug container.
kta
16

Untuk menjaga agar POD tetap berjalan, POD harus menjalankan tugas tertentu, jika tidak Kubernetes akan menganggapnya tidak diperlukan, oleh karena itu ia akan keluar. Ada banyak cara untuk membuat POD tetap berjalan.

Saya pernah menghadapi masalah serupa ketika saya membutuhkan POD hanya untuk berjalan terus menerus tanpa melakukan apapun. Berikut adalah dua cara yang berhasil bagi saya:

  1. Mengaktifkan perintah tidur saat menjalankan penampung.
  2. Menjalankan loop tak terbatas di dalam wadah.

Meskipun opsi pertama lebih mudah daripada yang kedua dan mungkin mencukupi persyaratannya, itu bukanlah opsi terbaik. Karena, ada batasan jumlah detik yang akan Anda tetapkan dalam perintah tidur. Tetapi wadah dengan loop tak terbatas yang berjalan di dalamnya tidak pernah keluar.

Namun, saya akan menjelaskan kedua cara tersebut (Mengingat Anda menjalankan container busybox):

1. Perintah Tidur

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    ports:
    - containerPort: 80
    command: ["/bin/sh", "-ec", "sleep 1000"]
  nodeSelector:
    beta.kubernetes.io/os: linux

2. Loop Tak Terbatas

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    ports:
    - containerPort: 80
    command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"]
  nodeSelector:
    beta.kubernetes.io/os: linux

Jalankan perintah berikut untuk menjalankan pod:

kubectl apply -f <pod-yaml-file-name>.yaml

Semoga membantu!

Arbaaz
sumber
Bolehkah saya bertanya, apa itu tidur? Apakah ini perintah internal untuk Ubuntu? Atau perintah buruh pelabuhan?
Faraz
@Faraz Ini adalah perintah shell linux, tidak khusus untuk buruh pelabuhan.
Arbaaz
11

Saya bisa membuat ini bekerja dengan perintah sleep infinitydi Kubernetes, yang akan membuat container tetap terbuka. Lihat jawaban ini untuk alternatif bila itu tidak berhasil.

rwilson04
sumber
Ini tidak memberikan jawaban atas pertanyaan tersebut. Untuk mengkritik atau meminta klarifikasi dari seorang penulis, tinggalkan komentar di bawah postingannya. - Dari Ulasan
Will
1
@ Akan yakin itu. sleep infinitymembuat penampung tetap terbuka, menyediakan jenis fungsionalitas yang sama dengan yang ditanyakan pertanyaan (untuk sebagian besar jenis penampung). Ini juga menyediakan tautan ke alternatif untuk kasus ketika perintah khusus itu tidak berfungsi
rwilson04
Ini dari review. Jika Anda menambahkan teks komentar di sana ke jawabannya maka itu adalah jawaban yang berkualitas :) Bendera / pujian awal saya didasarkan pada ucapan komentar Anda tidak berhasil, membuat saya berpikir ini seharusnya menjadi komentar. Menambahkan pengeditan cepat dan suara positif.
Akankah
"... sleep infinity in Kubernetes" adalah pernyataan yang tidak diketahui. Ini menyiratkan bahwa tidak ada unix dan tidak ada buruh pelabuhan di dalam gambar.
mmla
10

Perintah paling sederhana untuk manifes pod k8s menjalankan container selamanya:

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  containers:
  - name: ubuntu
    image: ubuntu:latest
    # Just sleep forever
    command: [ "sleep" ]
    args: [ "infinity" ]
Wlodek B.
sumber
5

Gunakan perintah ini di dalam Dockerfile Anda untuk menjaga container tetap berjalan di cluster K8s Anda:

  • CMD tail -f / dev / null
Omar Khaled
sumber
3

Dalam kasus saya, pod dengan initContainer gagal diinisialisasi. Berjalan docker ps -adan kemudian docker logs exited-container-id-herememberi saya pesan log yang kubectl logs podnametidak ditampilkan. Misteri terpecahkan :-)

Stefan L.
sumber
1

Ada banyak cara berbeda untuk mencapai ini, tetapi salah satu yang paling elegan adalah:

kubectl run -i --tty --image ubuntu:latest ubuntu-test --restart=Never --rm /bin/sh
Ivan Aracki
sumber
Mengapa Anda menganggapnya sebagai solusi paling elegan?
mordowiciel
1

Beberapa sen saya untuk masalah ini. Dengan asumsi itu kubectlberfungsi maka perintah terdekat yang akan setara dengan perintah buruh pelabuhan yang Anda sebutkan dalam pertanyaan Anda, akan menjadi seperti ini.

$ kubectl run ubuntu --image=ubuntu --restart=Never --command sleep infinity

Perintah di atas akan membuat satu Poddi defaultnamespace dan, itu akan mengeksekusi sleepperintah denganinfinity argumen -dengan cara ini Anda akan memiliki proses yang berjalan di latar depan menjaga kontainer tetap hidup.

Kata penutup, Anda dapat berinteraksi dengan Podmenjalankan kubectl execperintah.

$ kubectl exec ubuntu -it -- bash

Teknik ini sangat berguna untuk membuat resource Pod dan debugging ad-hoc.

Lukasz Dynowski
sumber
1
Bekerja dengan baik. Tidak perlu --restart=Never, cukup hubungikubectl run ubuntu --image=ubuntu -- sleep infinity
Noam Manos