在容器中執行多個程序

容器的主要執行處理序是 Dockerfile 結尾處的 ENTRYPOINTCMD。最佳做法是透過每個容器僅執行一個服務來區分關注點。該服務可能會分支成多個處理序(例如,Apache 網頁伺服器會啟動多個背景工作處理序)。擁有多個處理序是可以的,但為了從 Docker 獲得最大效益,請避免讓一個容器負責您整體應用程式的多個面向。您可以透過使用者自訂網路和共用磁碟區來連接多個容器。

容器的主要處理序負責管理其啟動的所有處理序。在某些情況下,主要處理序的設計不良,無法在容器退出時妥善處理「收割」(停止)子處理序。如果您的處理序屬於此類,您可以在執行容器時使用 --init 選項。--init 旗標會將一個微小的初始化處理序 (init-process) 插入容器作為主要處理序,並在容器退出時處理所有處理序的收割工作。使用這種方式處理處理序,優於使用完整的初始化處理序(如 sysvinitsystemd)來處理容器內的處理序生命週期。

如果您需要在容器內執行多個服務,可以透過幾種不同的方式實現。

使用包裝腳本 (Wrapper script)

將所有命令放入一個包裝腳本中,並補齊測試和偵錯資訊。將此包裝腳本作為您的 CMD 執行。以下是一個簡單的範例。首先是包裝腳本

#!/bin/bash

# Start the first process
./my_first_process &

# Start the second process
./my_second_process &

# Wait for any process to exit
wait -n

# Exit with status of process that exited first
exit $?

接下來是 Dockerfile

# syntax=docker/dockerfile:1
FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh

使用 Bash 作業控制 (Job control)

如果您有一個需要先啟動並保持執行狀態的主要處理序,但臨時需要執行其他一些處理序(或許是為了與該主要處理序互動),那麼您可以使用 Bash 的作業控制功能。首先是包裝腳本

#!/bin/bash

# turn on bash's job control
set -m

# Start the primary process and put it in the background
./my_main_process &

# Start the helper process
./my_helper_process

# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns


# now we bring the primary process back into the foreground
# and leave it there
fg %1
# syntax=docker/dockerfile:1
FROM ubuntu:latest
COPY my_main_process my_main_process
COPY my_helper_process my_helper_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh

使用處理序管理器 (Process manager)

使用像 supervisord 這樣的處理序管理器。這比其他選項更複雜,因為它要求您將 supervisord 及其設定檔捆綁到您的映像檔中(或者將您的映像檔基於包含 supervisord 的映像檔),連同它所管理的不同應用程式一起。然後啟動 supervisord,它會為您管理這些處理序。

以下 Dockerfile 範例展示了這種方法。該範例假設這些檔案存在於建置內容的根目錄中

  • supervisord.conf
  • my_first_process
  • my_second_process
# syntax=docker/dockerfile:1
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]

如果您想確保這兩個處理序的 stdoutstderr 都輸出到容器日誌中,您可以在 supervisord.conf 檔案中新增以下內容

[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0

[program:app]
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.