【Docker】Docker Compose服务依赖与健康检查

news2024/9/22 7:39:28

在这里插入图片描述

docker compose环境变量

为增加安全性,在前面的python例子中增加redis的密码校验,密码从环境变量中获取:

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"

对前面的docker-compose.yml进行修改如下:

version: "3.3"

services:
  flask-demo:
    build:
        context: .
        dockerfile: Dockerfile
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
      - REDIS_PASS=${REDIS_PASSWORD}
    networks:
      - demo-network
    ports:
      - 8080:5000

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

networks:
  demo-network:

在工程目录下新建.env文件,将环境变量配置好:

REDIS_PASS=abc

启动服务:

$ docker-compose up -d
Creating network "app3_demo-network" with the default driver
Creating app3_redis-server_1 ... done
Creating app3_flask-demo_1   ... done

参考文档:https://docs.docker.com/compose/environment-variables/

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

健康检查是容器运行状态的高级检查,主要是检查容器所运行的进程是否能正常的对外提供“服务”,比如一个数据库容器,我们不光需要这个容器是up的状态,我们还要求这个容器的数据库进程能够正常对外提供服务,这就是所谓的健康检查。

容器的健康检查

容器本身有一个健康检查的功能,但是需要在Dockerfile里定义,或者在执行docker container run的时候,通过下面的一些参数指定:

--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

下面我们对前面的flask例子增加健康检查,主要是在Dockerfile中增加HEALTHCHECK指令:

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就是定义了一个健康检查。会每隔30秒检查一次,如果失败就会退出,退出代码是1。

构建flask-demo镜像,并启动容器:

$ docker build -t flask-demo .

$ docker network create mynetwork
b3958a0cb961ddcc856c7e0458bc10489c456727f6061d1f9dc23e7e264741ae

$ docker container run --rm -d --name flask-demo --network=mynetwork --env REDIS_PASS=abc --env REDIS_HOST=redis flask-demo
e761d19949b9e3284471864101ec196807fc6145431903f4041e04daf950fa86

$ docker container ps
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS                            PORTS      NAMES
e761d19949b9   flask-demo   "flask run -h 0.0.0.0"   8 seconds ago   Up 8 seconds (health: starting)   5000/tcp   flask-demo

启动容器后查看容器状态未health: starting

因为此时没有启动redis服务,所以无法访问http://localhost:5000/,经过3次检查后发现一直是不通的,然后health的状态会从starting变为unhealthy:

$ docker container ps
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS                     PORTS      NAMES
e761d19949b9   flask-demo   "flask run -h 0.0.0.0"   2 minutes ago   Up 2 minutes (unhealthy)   5000/tcp   flask-demo

也可以通过docker container inspect查看其中有关health的详情:

"Health": {
    "Status": "unhealthy",
    "FailingStreak": 4,
    "Log": [
        {
            "Start": "2023-10-09T14:17:51.7014803+08:00",
            "End": "2023-10-09T14:17:54.7023591+08:00",
            "ExitCode": -1,
            "Output": "Health check exceeded timeout (3s)"
        },
        {
            "Start": "2023-10-09T14:18:24.7095286+08:00",
            "End": "2023-10-09T14:18:27.7099692+08:00",
            "ExitCode": -1,
            "Output": "Health check exceeded timeout (3s)"
        },
        {
            "Start": "2023-10-09T14:18:57.7264309+08:00",
            "End": "2023-10-09T14:19:00.7267289+08:00",
            "ExitCode": -1,
            "Output": "Health check exceeded timeout (3s)"
        },
        {
            "Start": "2023-10-09T14:19:30.7443718+08:00",
            "End": "2023-10-09T14:19:33.7444952+08:00",
            "ExitCode": -1,
            "Output": "Health check exceeded timeout (3s)"
        }
    ]
}

此时再启动redis服务,注意设置访问redis的密码:

$ docker container run --rm -d --network=mynetwork --name redis redis redis-server --requirepass abc
985cd32adbffd0d631a5a193c25903d704ddf08fb9a06f65a8e05af601a2ad77

$ docker container ps
CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS                   PORTS      NAMES
985cd32adbff   redis        "docker-entrypoint.s…"   About a minute ago   Up About a minute        6379/tcp   redis
e761d19949b9   flask-demo   "flask run -h 0.0.0.0"   8 minutes ago        Up 8 minutes (healthy)   5000/tcp   flask-demo

经过几秒钟,我们的flask-demo变成了healthy。

docker-compose健康检查

在上面的例子基础上删除Dockerfile中的心跳检测。

在docker-compose.yml中增加健康检查的配置:

version: "3.8"

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

  redis-server:
    image: redis:latest
    command: redis-server --requirepass ${REDIS_PASS}
    networks:
     - demo-network

networks:
  demo-network:

构建镜像并启动:

$ docker-compose up -d --build

$ docker-compose ps
       Name                      Command                  State                        Ports
--------------------------------------------------------------------------------------------------------------
app5_flask-demo_1     flask run -h 0.0.0.0             Up (healthy)   0.0.0.0:8080->5000/tcp,:::8080->5000/tcp
app5_redis-server_1   docker-entrypoint.sh redis ...   Up             6379/tcp

可以通过修改docker-compose.yml文件中密码来测试容器状态为Up (unhealthy)的情况。

docker compose服务依赖

如果服务之间的启动有依赖顺序,可以使用depends_on来配置。

version: "3.8"

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

  redis-server:
    image: redis:latest
    command: redis-server --requirepass ${REDIS_PASS}
    networks:
     - demo-network

networks:
  demo-network:

上面的例子配置了flask-demo依赖redis-server,在启动的时候会先启动redis-server,然后在启动flask-demo

$ docker-compose up -d
Creating network "app6_demo-network" with the default driver
Creating app6_redis-server_1 ... done
Creating app6_flask-demo_1   ... done

服务依赖与健康检查的结合

这里再引入nginx来更好的演示服务依赖与健康检查的结合。

version: "3.8"

services:
  flask-demo:
    build:
        context: .
        dockerfile: Dockerfile
    image: flask-demo:latest
    environment:
      - REDIS_HOST=redis-server
      - REDIS_PASS=${REDIS_PASS}
    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_PASS}
    networks:
      - backend
  nginx:
    image: nginx:stable-alpine
    ports:
      - 8000:80
    depends_on:
      flask-demo:
        condition: service_healthy
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./log/nginx:/var/log/nginx
    networks:
      - frontend

networks:
  backend:
  frontend:

nginx.conf文件的内容如下:

server {
  listen  80 default_server;
  location / {
    proxy_pass http://flask-demo:5000;
  }
}

启动服务,可以发现nginxflask-demo启动后并健康检查通过后才启动。

$ docker-compose up -d
Creating network "app7_backend" with the default driver
Creating network "app7_frontend" with the default driver
Creating app7_redis-server_1 ... done
Creating app7_flask-demo_1   ... done
Creating app7_nginx_1        ... done

$ docker-compose ps
       Name                      Command                  State                      Ports
----------------------------------------------------------------------------------------------------------
app7_flask-demo_1     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app7_nginx_1          /docker-entrypoint.sh ngin ...   Up             0.0.0.0:8000->80/tcp,:::8000->80/tcp
app7_redis-server_1   docker-entrypoint.sh redis ...   Up             6379/tcp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1132246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业在数字化转型时如何通过SD-WAN保证业务连续性

企业数字化建设离不开高品质的网络,随着信息化系统和应用的部署,传统网络线路逐渐暴露出不同的问题,包括: 线路资源利用率低易造成浪费 关键业务流量被抢占,缺乏保障 网络不可视,无法实时查看线路情况 故…

利用已存在的conda环境

一、已存在的环境 二、在Pycharm中使用这些环境

Linux 基于sysfs的GPIO读写操作

https://bbs.huaweicloud.com/blogs/297252 前言 最近接触到Linux系统中的GPIO开发,这里做个小总结,也分享一下;本文会介绍GPIO的读写,介绍基本原理,以及不同读写方式的性能。 一、GPIO sysfs interface 基本原理 …

Android 备案公钥、签名 MD5获取方法

公钥和 MD5 值可以通过安卓开发工具、Keytool、Jadx-GUI 等多种工具获取,本文以 jadx-gui 为例。 1 windows 下载 jadx-gui 工具 下载 jadx-gui 工具 在这里选择一个下载 下载后 解压文件 双击运行程序,然后选择 release apk安装包 2 Mac 打开终端&a…

基于springboot实现企业客户信息反馈平台管理系统项目【项目源码+论文说明】

基于springboot实现企业客户信息反馈平台管理系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把企业客户信息反馈管理与现在网络相结合,利用java技术建设企业客户信息反馈平台,实现企业客户信息反馈的信息化。则对于进一步提高企业客户信息反…

1024程序员节优惠来啦 | 芒果YOLO专栏《全年首次优惠全场8.8折活动来啦》,一年一次,优惠券数量有限,先到先得!

芒果YOLO改进专栏 订阅即可享受 优惠券直接减免,芒果专栏全场优惠!! 1024程序员 全年优惠活动 来啦!!!! 芒果专栏全场优惠8.8折!! 文章目录 活动时间🔥&…

全面解析优化企业Microsoft 365网络的加速方案

您的员工是否有因为Microsoft 365频繁掉线、卡顿、无法登录而向IT部门抱怨过? 很多时候企业会以为是自身网络带宽不足才导致访问失败,但是在采取增加带宽的方案后,办公文档协同打开仍旧很慢,文件分享依旧需要等待较长的时间&…

【漏洞复现】蓝凌EIS智慧协同平台任意文件上传

目录 蓝凌智慧协同平台介绍 漏洞搜索 漏洞点 漏洞复现 nuclei poc 验证 漏洞修复 蓝凌智慧协同平台介绍 蓝凌智慧协同平台是个自动化办公OA,具有多端同步、无缝协作,提供移动端(蓝凌KK、阿里钉钉、微信企业号)、桌面端、网页端多端应…

『第四章』一见倾心:初识小雨燕(上)

在本篇博文中,您将学到如下内容: 1. 基本数据类型2. 基本操作符3. 枚举和结构4. 类和 Actor5. 属性、方法与访问控制6. 聚集总结夜月一帘幽梦,春风十里柔情。 无声交谈情意深,一见心曲绕梁成。 1. 基本数据类型 无论是 macOS 还是 iOS 上的开发,Swift 基础类型和功能都内置于…

淘宝API接口(商品信息获取,订单管理,库存管理,数据分析和优化)

淘宝API接口可以用于许多业务场景,以下是一些常见的应用场景: 商品信息获取:通过淘宝API接口可以获取商品的详细信息,包括商品标题、价格、库存、销量、评价等数据。这些信息可以用于在自己的网站或应用程序中展示商品&#xff0…

17 结构型模式-享元模式

1 享元模式介绍 2 享元模式原理 3 享元模式实现 抽象享元类可以是一个接口也可以是一个抽象类,作为所有享元类的公共父类, 主要作用是提高系统的可扩展性. //* 抽象享元类 public abstract class Flyweight {public abstract void operation(String extrinsicState); }具体享…

在外包干了2年,我悟了...

前言 简单的说下,我大学的一个同学,毕业后我自己去了自研的公司,他去了外包,快两年了我薪资、技术各个方面都有了很大的提升,他在外包干的这两年人都要废了,技术没一点提升,学不到任何东西&…

(免费领源码)JavaWeb#Springboot#MYSQL跳蚤市场网络商城 99706-计算机毕业设计项目选题推荐

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究现状 1.3 论文结构与章节安排 2 跳蚤市场网络商城系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1…

霍尔电流传感器如何应用在数据中心电量监测的-安科瑞 蒋静

摘要:数据中心供电电源质量的好坏直接影响到IT设备的安全运行,因此对数据中心直流列头柜电源进出线实行监测非常重要,而通过霍尔电流传感器可以采集主进线电流、多路支路直流电流和漏电流。 关键词:数据中心;直流列头…

商场巨变!拓世法宝AI智能商业一体机引爆智慧购物新浪潮

在如今信息爆炸的时代,大型商场的规模与复杂程度也呈现出愈发庞大的趋势。它的背后不仅是商场规模的扩大,更是商业模式的转型升级。消费者对于购物体验和服务质量的要求也日益提高。传统商场单一提供商品销售的职能已无法满足消费者多元化的需求&#xf…

公网IP怎么设置?公网ip有哪些优点和缺点?

随着互联网的普及,越来越多的人开始关注网络安全和隐私保护。其中,公网IP的设置成为了一个备受关注的话题。本文将详细介绍公网IP的设置方法以及公网IP的优点和缺点。 一、公网IP设置方法 1. 路由器设置 在家庭或企业网络中,路由器通常是最重…

MySQL——EXPLAIN用法详解

EXPLAIN是MySQL官方提供的sql分析的工具之一,可以用于模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句。EXPLAIN主要用于分析查询语句或表结构的性能瓶颈。 以下是基于MySQL5.7.19版本进行分析的,不同版本之间略有差异。 1、EXP…

SHELL脚本编程基础,bilibili王晓春老师课程个人笔记(写比较简单,仅供参考)

文章目录 一、第一天(Shell脚本编程基础)作者视频ppt部分作者视频操作编写一个hello.sh可执行文件使hello.sh可以到处运行没有执行权限的执行方式下载httpd(web服务器)curl字符界面浏览器 命令列表凌乱笔记 作业重点: …

【每日三十六记 —— BGP知识点汇总大全】(第一弹)

个人名片: 🐼作者简介:一名大三在校生,喜欢编程🎋 🐻‍❄️个人主页🥇:落. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️ 零基…

群晖NAS:套件源地址添加提示 无效位置 系统证书重置

群晖NAS:套件源地址添加提示 无效位置 网上很多案例和解决方案,没生效。通过重置延长系统证书即可 设置 - 安全性 - 证书 - 群晖证书 - 右击菜单 延长证书 延长成功后,在套件中心添加即可。 若不生效,可查看网上别人的方案&…