Làm cách nào để giữ một vùng chứa chạy trên Kubernetes?


124

Bây giờ tôi đang cố gắng chạy một vùng chứa đơn giản với shell (/ bin / bash) trên một cụm Kubernetes.

Tôi nghĩ rằng có một cách để giữ một vùng chứa chạy trên vùng chứa Docker bằng cách sử dụng pseudo-ttyvà tách tùy chọn ( -tdtùy chọn theo docker runlệnh).

Ví dụ,

$ sudo docker run -td ubuntu:latest

Có tùy chọn như thế này trong Kubernetes không?

Tôi đã thử chạy một vùng chứa bằng cách sử dụng kubectl run-containerlệnh như:

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

Nhưng vùng chứa thoát ra trong vài giây (giống như khởi chạy bằng docker runlệnh mà không có tùy chọn tôi đã đề cập ở trên). Và ReplicationController khởi chạy lại nó nhiều lần.

Có cách nào để giữ cho một vùng chứa chạy trên Kubernetes giống như các -tdtùy chọn trong docker runlệnh không?


Sử dụng hình ảnh này (như Kubernetes tài liệu gợi ý) là khá tiện dụng:kubectl run curl --image=radial/busyboxplus:curl -i --tty
Matheus Santana

Câu hỏi này đã được đề cập trong video này: Kubernetes rất khó khăn tại Datadog với tiêu đề trang trình bày là "Vận chuyển hàng hóa . Từ wikipedia: Thuật ngữ lập trình viên sùng bái hàng hóa có thể áp dụng khi một lập trình viên máy tính chưa có kinh nghiệm hoặc mới làm quen (hoặc một người thiếu kinh nghiệm với vấn đề trong tầm tay) bản một số mã chương trình từ nơi này sang nơi khác với ít hoặc không có sự hiểu biết về cách thức hoạt động hoặc cho dù đó là cần thiết trong vị trí mới.
tgogos

Câu trả lời:


49

Một vùng chứa thoát ra khi quá trình chính của nó thoát. Làm điều gì đó như:

docker run -itd debian

để mở thùng chứa thực sự là một cách hack chỉ nên được sử dụng cho các bài kiểm tra và ví dụ nhanh. Nếu bạn chỉ muốn một vùng chứa để thử nghiệm trong vài phút, tôi sẽ làm:

docker run -d debian sleep 300

Điều này có ưu điểm là vùng chứa sẽ tự động thoát ra nếu bạn quên nó. Ngoài ra, bạn có thể đặt một cái gì đó như thế này trong một whilevòng lặp để giữ cho nó hoạt động mãi mãi hoặc chỉ chạy một ứng dụng chẳng hạn top. Tất cả những điều này sẽ dễ dàng thực hiện trong Kubernetes.

Câu hỏi thực sự là tại sao bạn muốn làm điều này? Vùng chứa của bạn phải cung cấp một dịch vụ, quá trình của nó sẽ giữ cho vùng chứa chạy ở chế độ nền.


Cảm ơn bạn vì câu trả lời. Bây giờ tôi đang cố gắng hiểu hành vi của các container, với hàng chục container chạy cùng một lúc. Vòng lặp vô tận và sử dụng lệnh nặng khác, ngăn tôi biết hành vi của vùng chứa là gì. Đó là lý do tại sao tôi cần vùng chứa đơn giản như chỉ chạy / bin / bash.
springwell

Hiện tại, tôi sẽ thử chạy catmà không có đối số topsleepvới đối số là số lớn.
springwell

30
sleep infinityhoạt động trong rất nhiều trường hợp (không phải busybox)
rwilson04

1
Có rất nhiều lý do để làm điều này. Ví dụ: bạn có thể triển khai các nhóm của mình với các bản phát hành helm và cấu hình được chèn vào, điều này sẽ làm cho việc tạo lại các môi trường tương tự trở nên khó chịu và cồng kềnh. Nhưng việc có một vùng chứa với cấu hình đó trong trường hợp các nhóm khác gặp sự cố / bị xóa có thể hữu ích vô hạn.
Richard Løvehjerte

Bởi vì dịch vụ của tôi bao gồm nhiều quy trình.
Константин Ван

135

Các thùng chứa có nghĩa là sẽ hoàn thành. Bạn cần cung cấp cho vùng chứa của mình một nhiệm vụ sẽ không bao giờ hoàn thành. Một cái gì đó như thế này sẽ hoạt động:

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

Nhưng đây có phải là một thực hành tốt nhất?
aneesh joshi

3
@aneeshjoshi Tôi sẽ không nói đây là phương pháp hay nhất . Đây chỉ là một ví dụ cung cấp một nhóm sẽ chạy mà không cần thoát ngay lập tức. Phương pháp hay nhất là tạo các vùng chứa của bạn để thực hiện công việc mà chúng được thiết kế cho (một công việc sắp hoàn thành, một máy chủ web chạy vĩnh viễn, v.v.). Tôi đã đăng điều này làm ví dụ vì Kubernetes có thể cảm thấy bực bội ban đầu khi bạn tiếp tục tạo các nhóm chỉ để biến mất vì lệnh mặc định thoát ngay lập tức.
Joel B

@JoelB Cảm ơn. Tôi đã tự hỏi đâu là cách làm "đúng".
aneesh joshi

1
cảm ơn vì điều này vì tôi đang cần một thùng chứa có thể sống trong một thời gian cho phép tôi nhập nó. Tôi đã cố gắng làm điều tương tự với một hình ảnh nhẹ hơn ubuntuvà đã thử bashhình ảnh nhưng không thể hoạt động. Bất kỳ ý tưởng làm thế nào để làm tương tự như thế này với bashhình ảnh?
cryanbhu

1
@cryanbhu Để có hình ảnh nhẹ hơn, bạn có thể sử dụng alpine, thông số vùng chứa có thể trông giống như: {"name": "util", "image": "alpine", "command": [ "/bin/sh", "-c", "--" ], "args": [ "while true; do sleep 30; done;" ]}(chỉ json vì yaml sẽ không định dạng trong các nhận xét ở đây.) Điều quan trọng là /bin/shthay vì /bin/bash.
bschlueter

111

Bạn có thể sử dụng CMD này trong Dockerfile:

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

Điều này sẽ giữ cho thùng chứa của bạn tồn tại cho đến khi nó được yêu cầu dừng lại. Sử dụng bẫy và chờ sẽ khiến vùng chứa của bạn phản ứng ngay lập tức với yêu cầu dừng . Nếu không có bẫy / dừng chờ sẽ mất vài giây.

Đối với hình ảnh dựa trên hộp số bận (được sử dụng trong hình ảnh dựa trên núi cao) giấc ngủ không biết về đối số vô cực. Cách giải quyết này cung cấp cho bạn phản hồi ngay lập tứcdocker stop giống như trong ví dụ trên:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

Tôi đang sử dụng yaml triển khai kubernetes tương tự cho mục đích gỡ lỗi
sdkks 12/1217

này mang lại cho tôi "ngủ: số không hợp lệ 'vô cực'"
arunkjn

@arunkjn Cảm ơn vì điều này. Bạn có thể bị mắc kẹt với một hình ảnh sử dụng hộp số bận (như hình ảnh núi cao). Xem câu trả lời cập nhật.
itsafire

24
  1. Trong Dockerfile của bạn, sử dụng lệnh này:

    CMD ["sh", "-c", "tail -f /dev/null"]
    
  2. Xây dựng hình ảnh docker của bạn.

  3. Đẩy nó vào cụm của bạn hoặc tương tự, chỉ để đảm bảo rằng nó có sẵn hình ảnh.
  4. kubectl run debug-container -it --image=<your-image>
    

Mẹo hay để gỡ lỗi vùng chứa.
kta

16

Để giữ cho POD chạy POD phải thực hiện một số tác vụ nhất định, nếu không Kubernetes sẽ thấy nó không cần thiết, do đó nó thoát ra. Có nhiều cách để giữ cho POD hoạt động.

Tôi đã phải đối mặt với những vấn đề tương tự khi tôi cần một POD chỉ để chạy liên tục mà không làm gì cả. Sau đây là hai cách đã làm việc cho tôi:

  1. Kích hoạt lệnh ngủ trong khi chạy vùng chứa.
  2. Chạy một vòng lặp vô hạn bên trong vùng chứa.

Mặc dù lựa chọn đầu tiên dễ hơn lựa chọn thứ hai và có thể đáp ứng đủ yêu cầu, nhưng nó không phải là lựa chọn tốt nhất. Như, có một giới hạn về số giây bạn sẽ chỉ định trong lệnh ngủ. Nhưng một vùng chứa với vòng lặp vô hạn chạy bên trong nó không bao giờ thoát ra.

Tuy nhiên, tôi sẽ mô tả cả hai cách (Xem xét bạn đang chạy vùng chứa busybox):

1. Lệnh ngủ

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. Vòng lặp vô hạn

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

Chạy lệnh sau để chạy nhóm:

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

Hy vọng nó giúp!


Tôi xin hỏi, giấc ngủ là gì? Nó có phải là một lệnh bên trong Ubuntu không? Hoặc lệnh docker?
Faraz

@Faraz Đây là một lệnh shell linux, nó không dành riêng cho docker.
Arbaaz

11

Tôi đã có thể làm cho điều này hoạt động với lệnh sleep infinitytrong Kubernetes, lệnh này sẽ giữ cho vùng chứa luôn mở. Xem câu trả lời này để biết các lựa chọn thay thế khi điều đó không hiệu quả.


Điều này không cung cấp câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ tác giả, hãy để lại bình luận bên dưới bài đăng của họ. - Từ đánh giá
Sẽ

1
@Will Chắc chắn nó có. sleep infinitygiữ cho vùng chứa luôn mở, cung cấp cùng loại chức năng mà câu hỏi yêu cầu (đối với hầu hết các loại vùng chứa). Nó cũng cung cấp một liên kết đến lựa chọn thay thế cho trường hợp khi mà lệnh cụ thể không làm việc
rwilson04

Đây là từ đánh giá. Nếu bạn thêm văn bản nhận xét ở đó vào câu trả lời thì đó là một câu trả lời chất lượng :) Cờ / lời khen ngợi ban đầu của tôi dựa trên việc nói rằng nhận xét của bạn không thành công, khiến tôi nghĩ đây phải là một nhận xét. Đã thêm một chỉnh sửa nhanh chóng và được ủng hộ.
Will

"... ngủ vô tận ở Kubernetes" là một tuyên bố không được thông tin. Nó ngụ ý rằng không có unix và không có docker trong hình.
mmla

10

Lệnh đơn giản nhất có thể để tệp kê khai pod k8s chạy vùng chứa mãi mãi:

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

5

Sử dụng lệnh này bên trong Dockerfile của bạn để giữ cho vùng chứa chạy trong cụm K8s của bạn:

  • CMD tail -f / dev / null

3

Trong trường hợp của tôi, một nhóm có initContainer không khởi tạo được. Đang chạy docker ps -avà sau đó docker logs exited-container-id-herecho tôi một thông báo nhật ký kubectl logs podnamekhông hiển thị. Bí ẩn đã được giải quyết :-)


1

Có nhiều cách khác nhau để thực hiện điều này, nhưng một trong những cách thanh lịch nhất là:

kubectl run -i --tty --image ubuntu:latest ubuntu-test --restart=Never --rm /bin/sh

Tại sao bạn lại coi đó là giải pháp tao nhã nhất?
mordowiciel

1

Vài xu của tôi về chủ đề này. Giả sử điều đó kubectlđang hoạt động thì lệnh gần nhất sẽ tương đương với lệnh docker mà bạn đã đề cập trong câu hỏi của mình, sẽ giống như thế này.

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

Lệnh trên sẽ tạo một lệnh duy nhất Podtrong defaultkhông gian tên và nó sẽ thực thi sleeplệnh với infinityđối số - theo cách này, bạn sẽ có một quá trình chạy ở nền trước giữ cho vùng chứa tồn tại.

Sau đó, bạn có thể tương tác với Podbằng cách chạy kubectl execlệnh.

$ kubectl exec ubuntu -it -- bash

Kỹ thuật này rất hữu ích để tạo tài nguyên Pod và gỡ lỗi đặc biệt.


1
Hoạt động tuyệt vời. Không cần --restart=Never, chỉ cần gọikubectl run ubuntu --image=ubuntu -- sleep infinity
Noam Manos
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.