[英]docker keep restarting until file is created in a mounted volume
我正在嘗試創建一個可以自行重啟的腳本,一個微服務(在我的例子中是node-red
)。
這是我的碼頭工人撰寫文件:
docker-compose.yml
version: '2.1'
services:
wifi-connect:
build: ./wifi-connect
restart: always
network_mode: host
privileged: true
google-iot:
build: ./google-iot
volumes:
- 'app-data:/data'
restart: always
network_mode: host
depends_on:
- "wifi-connect"
ports:
- "8883:8883"
node-red:
build: ./node-red/node-red
volumes:
- 'app-data:/data'
restart: always
privileged: true
network_mode: host
depends_on:
- "google-iot"
volumes:
app-data:
我正在使用wait-for-it.sh來檢查之前的容器。
這是 node-red 微服務的 Dockerfile 的摘錄。
RUN chmod +x ./wait-for-it/wait-for-it.sh
# server.js will run when container starts up on the device
CMD ["bash", "/usr/src/app/start.sh", "bash", "/usr/src/app/wait-for-it/wait-for-it.sh google-iot:8883 -- echo Google IoT Service is up and running"]
我見過inotify
。
基本上,我想要的只是在安裝到node-red
容器以及/data
文件夾路徑下的app-data
卷中創建文件后重新啟動容器node-red
,例如,文件路徑為: /data/myfile.txt
。
請注意,此文件會自動生成到google-iot
微服務,但node-red
容器需要該文件,並且通常是node-red
容器啟動且/data/myfile.txt
文件不存在的情況。
聽起來您正在嘗試延遲一個容器的啟動,直到另一個容器生成了您要查找的文件,或者如果它不可用則退出。
您可以相當直接地將該邏輯寫入 shell 腳本。 例如:
#!/bin/sh
# entrypoint.sh
# Wait for the server to be available
./wait-for-it/wait-for-it.sh google-iot:8883
if [ $? -ne 0 ]; then
echo 'google-iot container did not become available' >&2
exit 1
fi
# Wait for the file to be present
seconds=30
while [ $seconds -gt 0 ]; do
if [ -f /data/myfile.txt ]; then
break
fi
sleep 1
seconds=$(($seconds-1))
done
if [ $seconds -eq 0 ]; then
echo '/data/myfile.txt was not created' >&2
exit 1
fi
# Run the command passed to us as arguments
exec "$@"
在您的 Dockerfile 中,將此腳本設為ENTRYPOINT
。 您必須在ENTRYPOINT
行中使用 JSON 數組語法。 您的CMD
可以使用任何有效的語法。 請注意,我們在入口點包裝器中運行wait-for-it
腳本,因此您無需將其包含在CMD
中。 (而且由於腳本是可執行的並且以“shebang”行#!/bin/sh
開頭,我們不需要顯式地命名解釋器來運行它。)
# Dockerfile
RUN chmod +x entrypoint.sh wait-for-it/wait-for-it.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
CMD ["/usr/src/app/start.sh"]
入口點包裝器有兩個檢查,首先是google-iot
容器最終接受端口 8883 上的 TCP 連接,其次是創建文件。 如果其中任何一種情況失敗,則腳本在運行CMD
之前exit 1
。 這將導致整個容器以該狀態碼退出( restart: on-failure
仍將重新啟動它)。
我也可能會考慮其他獲取文件的方法是否可行,例如使用curl
向另一個容器發出 HTTP 請求。 共享 Docker 卷存在幾個實際問題(特別是在所有權方面,但如果文件的舊副本仍然存在於之前的運行中),並且在 Kubernetes 等集群環境中共享文件的效果尤其糟糕。
您可以使用depends_on
的long-syntax
來解決競爭條件問題,您可以在其中指定運行狀況檢查。 這將保證您的文件在您的node-red
服務運行時存在。
node-red:
build: ./node-red/node-red
volumes:
- 'app-data:/data'
restart: always
privileged: true
network_mode: host
depends_on:
google-iot:
condition: service_healthy
然后您可以定義health-check
(請參閱此處的文檔)以查看您的文件是否存在於卷中。 您可以在google-iot
服務的服務描述中添加以下內容:
healthcheck:
test: ["CMD", "cat", "/data/myfile.txt"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
根據需要隨意調整持續時間值。
這能解決您的問題嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.