Làm thế nào để phát hiện xem docker chạy thành công theo chương trình?


82

Tôi đang viết một tập lệnh bash rất đơn giản để nhanh chóng kiểm tra xem vùng chứa của tôi vẫn xây dựng và khởi động chính xác và ứng dụng bên trong có phản hồi các yêu cầu hay không.

Đôi khi docker run không thành công, ví dụ như vì cổng tôi đang cố gắng liên kết vùng chứa đã được cấp phát. Nhưng khi điều này xảy ra docker run, mã thoát vẫn là 0 nên tôi không thể sử dụng mã thoát. Làm cách nào để kiểm tra theo chương trình xem vùng chứa đã khởi động đúng cách chưa?

Các giải pháp tôi đang xem xét là:

  • phân tích cú pháp đầu ra cho các lỗi
  • docker ps để xem liệu vùng chứa có đang chạy không

nhưng cả hai đều có vẻ hơi quá mức cần thiết và xấu xí. Tôi đang thiếu một cách tốt hơn để kiểm tra xem có docker runthành công không?


1
Tôi không chắc vấn đề ở đây là gì. Nếu quy trình được đề cập hoạt động theo cách thông thường thì bạn chỉ cần kiểm tra mã thoát. Nếu nó phát ra mã thoát là 0 ngay cả đối với những trường hợp không thành công, hãy thử tìm xem đó có phải là lỗi hay không. Nếu chương trình trả về mã thoát là 0 trong mọi trường hợp, thì bạn có thể không còn lựa chọn nào khác ngoài việc phân tích cú pháp đầu ra.
devnull

Như @devnull đã nói, nếu bạn không thể tin tưởng rằng nó docker runsẽ trả về mã trả về khác 0 khi bị lỗi như bạn chỉ ra thì tất cả những gì bạn có thể làm là phân tích cú pháp đầu ra (có thể phức tạp hoặc dễ hỏng) hoặc sử dụng lệnh khác (tức là psđề xuất của bạn ) để kiểm tra kết quả của lệnh đầu tiên. Bạn có thể muốn xem xét việc gửi một vé với docker để xem liệu họ có thể sửa mã trả lại từ đó runhay không.
Etan Reisner

Đảm bảo rằng bạn có phiên bản mới nhất.
ooga

Đó có phải là mã tùy chỉnh đang được chạy trong vùng chứa của bạn không? nếu vậy, bạn có thể xuất một cổng trong Dockerfile của mình, khi chương trình của bạn ở trạng thái chạy ổn định, hãy gửi thông báo "OK" trên cổng đó. Mã khách hàng của bạn chờ thông báo "OK".
rexposadas

3
Bạn có thể cung cấp một ví dụ về cách bạn đang chạy docker và phiên bản nào không? Một thử nghiệm chương trình mã thoát Docker nhanh chóng trở thành 1 đối với tôidocker run -d -p 9010:9010 busybox true ; echo $?
Abel Muiño

Câu trả lời:


116

Theo đề xuất của Abel Muiño trong nhận xét, điều này có thể đã được sửa trong các phiên bản Docker gần đây hơn (tôi hiện đang chạy 0.9.1).

Tuy nhiên, nếu bạn tạm thời bị mắc kẹt giống như tôi với phiên bản cũ hơn, tôi đã tìm thấy một giải pháp phù hợp để kiểm tra xem vùng chứa đã bắt đầu bằng cách sử dụng docker inspect .

docker inspecttrả về một đối tượng JSON với nhiều thông tin về vùng chứa và cụ thể là liệu vùng chứa hiện đang chạy hay không. Các -flá cờ cho phép bạn dễ dàng trích xuất các bit cần thiết:

docker inspect -f {{.State.Running}} $CONTAINER_ID

hoặc là

docker inspect -f "{{.State.Running}}" $CONTAINER_ID

sẽ trở lại truehoặcfalse .

Lưu ý rằng bạn có thể muốn sleep 1(hoặc hơn thế nữa) giữa việc khởi động vùng chứa và kiểm tra xem nó có hoạt động hay không. Nếu có điều gì đó không ổn với thiết lập của bạn, có thể nó sẽ xuất hiện ở dạng 'đang chạy' trong một thời gian rất ngắn trước khi thực sự thoát ra.


11
Tại sao không sử dụng docker inspect -f {{.State.Running}} <container-id>và sử dụng jqthay thế? Chỉ băn khoăn.
Dharmit,

2
Bởi vì tôi đã không nhận ra thanh tra cho phép bạn làm điều này trực tiếp! Cảm ơn @DharmitShah, đó là một gợi ý tuyệt vời, tôi sẽ cập nhật câu trả lời của mình.
Jules Olléon

2
Để loại bỏ thông báo lỗi nếu không có vùng chứa như vậy, hãy chuyển hướng stderr với 2> /dev/null.
thSoft

Nếu tôi đang gán nó cho một var, tôi sẽ gặp lỗi khi sử dụng 2> /dev/nullvì nó không đánh giá được bất cứ thứ gì. Làm cách nào để đặt nó thành mặc định falsenếu vùng chứa không tồn tại?
Jake Sankey

1
Tuy nhiên, điều này không phù hợp với các vùng chứa liên tục khởi động lại do chính sách khởi động lại ... Tức là nếu vùng chứa được cung cấp chính sách khởi động lại là trừ khi-dừng / luôn luôn, .State.Running sẽ luôn trả về true .... Chỉ là một cái gì đó để mệt mỏi của!
geekscrap

22

Để tránh phân tích cú pháp bất kỳ thứ gì, bạn có thể sử dụng docker top , trả về 1 nếu vùng chứa không chạy:

id=$(docker run mycontainer)
if ! docker top $id &>/dev/null
then
    echo "Container crashed unexpectedly..."
    return 1
fi

10

Chúng tôi có thể sử dụng docker exec $id true 2>/dev/null || echo not running .

Lệnh này không ghi vào stdout, như "docker top". Nó ghi vào stderr khi vùng chứa không chạy, thông báo tương tự như "docker top".


2

Áp dụng các đề xuất đã nói ở trên cho một tập lệnh.

1 - Tạo một script keepMyDockerUp.sh :

vi keepMyDockerUp.sh


#!/bin/bash
Container_ID=INSERT_YOUR_CONTAINER_ID HERE
result=$( docker inspect -f {{.State.Running}} $Container_ID)
echo "result is" $result
if [ $result = "true" ]
then
echo "docker is already running"
else
systemctl restart docker
docker start $Container_ID
fi

2 - Sau đó, chỉ cần thêm nó vào cron, do đó, tập lệnh của bạn sẽ xác minh xem vùng chứa Docker của bạn đôi khi có hoạt động hay không:

crontab -e

Chuyển đến dòng cuối cùng và thêm tệp script của bạn. Ví dụ:

* * * * * /root/keepMyDockerUp.sh

3 - Lưu crontab và không bao giờ lo lắng về việc vùng chứa Docker của bạn bị sập nữa.

Hy vọng nó giúp...

;-)


1

Tôi đã phải sử dụng:

$ docker inspect -f {{.State.Health.Status}} xxx

(vùng chứa ở trạng thái đang chạy nhưng dịch vụ bên trong vùng chứa chưa khởi động hoàn toàn.

Một phần của đầu ra kiểm tra:

"State": {
    "Status": "running",
    "Running": true,
    "Paused": false,
    "Restarting": false,
    "OOMKilled": false,
    "Dead": false,
    "Pid": 1618,
    "ExitCode": 0,
    "Error": "",
    "StartedAt": "2019-03-08T10:39:24.061732398Z",
    "FinishedAt": "0001-01-01T00:00:00Z",
    "Health": {
        "Status": "starting",
        "FailingStreak": 0,
        "Log": []

Điều này sẽ không cho biết nếu chạy thành công. Bởi vì một vùng chứa có thể chạy và sau đó bị lỗi.
Vino
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.