五十一、Docker Compose-服務(wù)依賴和健康檢查

一、docker compose 服務(wù)依賴

使用depends_on關(guān)鍵字

version: "3.8"

services:
  flask:
    build:
      context: ./flask
      dockerfile: Dockerfile
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
      - REDIS_PASS=${REDIS_PASSWORD}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 40s
    depends_on:
      - redis-server
    networks:
      - backend
      - frontend

  redis-server:
    image: redis:latest
    command: redis-server --requirepass ${REDIS_PASSWORD}
    networks:
      - backend

  nginx:
    image: nginx:stable-alpine
    ports:
      - 8000:80
    depends_on:
      flask:
        condition: service_healthy
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./var/log/nginx:/var/log/nginx
    networks:
      - frontend

networks:
  backend:
  frontend:

二、docker compose 健康檢查

Dockerfile healthcheck https://docs.docker.com/engine/reference/builder/#healthcheck

docker compose https://docs.docker.com/compose/compose-file/compose-file-v3/#healthcheck

健康檢查是容器運(yùn)行狀態(tài)的高級(jí)檢查,主要是檢查容器所運(yùn)行的進(jìn)程是否能正常的對(duì)外提供“服務(wù)”,比如一個(gè)數(shù)據(jù)庫(kù)容器,我們不光 需要這個(gè)容器是up的狀態(tài),我們還要求這個(gè)容器的數(shù)據(jù)庫(kù)進(jìn)程能夠正常對(duì)外提供服務(wù),這就是所謂的健康檢查。

容器的健康檢查

容器本身有一個(gè)健康檢查的功能,但是需要在Dockerfile里定義,或者在執(zhí)行docker container run 的時(shí)候,通過下面的一些參數(shù)指定

--health-cmd string              Command to run to check health
--health-interval duration       Time between running the check
                                (ms|s|m|h) (default 0s)
--health-retries int             Consecutive failures needed to
                                report unhealthy
--health-start-period duration   Start period for the container to
                                initialize before starting
                                health-retries countdown
                                (ms|s|m|h) (default 0s)
--health-timeout duration        Maximum time to allow one check to

示例源碼

我們以下面的這個(gè)flask容器為例,相關(guān)的代碼如下

PS C:\Users\Peng Xiao\code-demo\compose-env\flask> dir

    目錄: C:\Users\Peng Xiao\code-demo\compose-env\flask

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2021/7/13     15:52            448 app.py
-a----         2021/7/14      0:32            471 Dockerfile

PS C:\Users\Peng Xiao\code-demo\compose-env\flask> more .\app.py
from flask import Flask
from redis import StrictRedis
import os
import socket

app = Flask(__name__)
redis = StrictRedis(host=os.environ.get('REDIS_HOST', '127.0.0.1'),
                    port=6379, password=os.environ.get('REDIS_PASS'))

@app.route('/')
def hello():
    redis.incr('hits')
    return f"Hello Container World! I have been seen {redis.get('hits').decode('utf-8')} times and my hostname is {socket.gethostname()}.\n"

PS C:\Users\Peng Xiao\code-demo\compose-env\flask> more .\Dockerfile
FROM python:3.9.5-slim

RUN pip install flask redis && \
    apt-get update && \
    apt-get install -y curl && \
    groupadd -r flask && useradd -r -g flask flask && \
    mkdir /src && \
    chown -R flask:flask /src

USER flask

COPY app.py /src/app.py

WORKDIR /src

ENV FLASK_APP=app.py REDIS_HOST=redis

EXPOSE 5000

HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:5000/ || exit 1

CMD ["flask", "run", "-h", "0.0.0.0"]

上面Dockerfili里的HEALTHCHECK 就是定義了一個(gè)健康檢查。 會(huì)每隔30秒檢查一次,如果失敗就會(huì)退出,退出代碼是1

構(gòu)建鏡像和創(chuàng)建容器

構(gòu)建鏡像,創(chuàng)建一個(gè)bridge網(wǎng)絡(luò),然后啟動(dòng)容器連到bridge網(wǎng)絡(luò)

$ docker image build -t flask-demo .
$ docker network create mybridge
$ docker container run -d --network mybridge --env REDIS_PASS=abc123 flask-demo

查看容器狀態(tài)

$ docker container ls
CONTAINER ID   IMAGE        COMMAND                  CREATED       STATUS                            PORTS      NAMES
059c12486019   flask-demo   "flask run -h 0.0.0.0"   4 hours ago   Up 8 seconds (health: starting)   5000/tcp   dazzling_tereshkova

也可以通過docker container inspect 059 查看詳情, 其中有有關(guān)health的

"Health": {
"Status": "starting",
"FailingStreak": 1,
"Log": [
    {
        "Start": "2021-07-14T19:04:46.4054004Z",
        "End": "2021-07-14T19:04:49.4055393Z",
        "ExitCode": -1,
        "Output": "Health check exceeded timeout (3s)"
    }
]
}

經(jīng)過3次檢查,一直是不通的,然后health的狀態(tài)會(huì)從starting變?yōu)?unhealthy

docker container ls
CONTAINER ID   IMAGE        COMMAND                  CREATED       STATUS                     PORTS      NAMES
059c12486019   flask-demo   "flask run -h 0.0.0.0"   4 hours ago   Up 2 minutes (unhealthy)   5000/tcp   dazzling_tereshkova

啟動(dòng)redis服務(wù)器

啟動(dòng)redis,連到mybridge上,name=redis, 注意密碼

$ docker container run -d --network mybridge --name redis redis:latest redis-server --requirepass abc123

經(jīng)過幾秒鐘,我們的flask 變成了healthy

$ docker container ls
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                   PORTS      NAMES
bc4e826ee938   redis:latest   "docker-entrypoint.s…"   18 seconds ago   Up 16 seconds            6379/tcp   redis
059c12486019   flask-demo     "flask run -h 0.0.0.0"   4 hours ago      Up 6 minutes (healthy)   5000/tcp   dazzling_tereshkova

docker-compose 健康檢查

示例代碼下載(flask healthcheck) 本節(jié)源碼

示例代碼下載(flask + redis healthcheck) 本節(jié)源碼

一個(gè)healthcheck不錯(cuò)的例子 https://gist.github.com/phuysmans/4f67a7fa1b0c6809a86f014694ac6c3a

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容