【Docker】Docker-Compose内置DNS负载均衡失效问题

在这里插入图片描述

Docker Compose实现负载均衡

还是对前面的例子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
    depends_on:
      - redis-server
    deploy:
      replicas: 3
    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:

主要是修改flask-demo启动3个容器。

nginx.conf文件的内容如下:

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

启动服务:

$ docker-compose up -d
Creating network "app8_backend" with the default driver
Creating network "app8_frontend" with the default driver
Creating app8_redis-server_1 ... done
Creating app8_flask-demo_1   ... done
Creating app8_flask-demo_2   ... done
Creating app8_flask-demo_3   ... done
Creating app8_nginx_1        ... done

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

访问服务:

$ curl localhost:8000
Hello Container World! I have been seen 4 times and my hostname is 448b5d70d3d8.

$ curl localhost:8000
Hello Container World! I have been seen 5 times and my hostname is 77b2a2314533.

$ curl localhost:8000
Hello Container World! I have been seen 9 times and my hostname is 4eee9c8d54f1.

从运行结果可以发现我们可以根据service的名称访问容器,Docker会使用内置的DNS服务器将service的名称解析成IP,如果service对应的容器有多个,nginx会进行负载均衡。

Docker带有一个内置的DNS服务器。默认情况下,可以通过127.0.0.11:53访问服务器。这个DNS的IP可以通过进入容器内部查看/etc/resolv.conf获得:

$ docker-compose exec nginx cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

负载均衡的实现

在上面的例子中我们将flask-demo容器的个数提高到6个:

$ docker-compose up -d --scale flask-demo=6
app8_redis-server_1 is up-to-date
Creating app8_flask-demo_4 ... done
Creating app8_flask-demo_5 ... done
Creating app8_flask-demo_6 ... done
app8_nginx_1 is up-to-date

$ docker-compose ps
       Name                      Command                  State                      Ports
----------------------------------------------------------------------------------------------------------
app8_flask-demo_1     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app8_flask-demo_2     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app8_flask-demo_3     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app8_flask-demo_4     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app8_flask-demo_5     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app8_flask-demo_6     flask run -h 0.0.0.0             Up (healthy)   5000/tcp
app8_nginx_1          /docker-entrypoint.sh ngin ...   Up             0.0.0.0:8000->80/tcp,:::8000->80/tcp
app8_redis-server_1   docker-entrypoint.sh redis ...   Up             6379/tcp

$ docker container ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS                    PORTS
 NAMES
6e1494379165   flask-demo:latest     "flask run -h 0.0.0.0"   53 seconds ago   Up 51 seconds (healthy)   5000/tcp
 app8_flask-demo_6
62733bdccdb8   flask-demo:latest     "flask run -h 0.0.0.0"   53 seconds ago   Up 51 seconds (healthy)   5000/tcp
 app8_flask-demo_5
77e74622fa4e   flask-demo:latest     "flask run -h 0.0.0.0"   53 seconds ago   Up 51 seconds (healthy)   5000/tcp
 app8_flask-demo_4
b67132189d90   nginx:stable-alpine   "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes              0.0.0.0:8000->80/tcp, :::8000->80/tcp   app8_nginx_1
448b5d70d3d8   flask-demo:latest     "flask run -h 0.0.0.0"   2 minutes ago    Up 2 minutes (healthy)    5000/tcp
 app8_flask-demo_1
4eee9c8d54f1   flask-demo:latest     "flask run -h 0.0.0.0"   2 minutes ago    Up 2 minutes (healthy)    5000/tcp
 app8_flask-demo_2
77b2a2314533   flask-demo:latest     "flask run -h 0.0.0.0"   2 minutes ago    Up 2 minutes (healthy)    5000/tcp
 app8_flask-demo_3
215beaad114a   redis:latest          "docker-entrypoint.s…"   2 minutes ago    Up 2 minutes              6379/tcp
 app8_redis-server_1

再次访问我们的服务:

$ curl localhost:8000
Hello Container World! I have been seen 28 times and my hostname is 448b5d70d3d8.

$ curl localhost:8000
Hello Container World! I have been seen 29 times and my hostname is 77b2a2314533.

$ curl localhost:8000
Hello Container World! I have been seen 30 times and my hostname is 4eee9c8d54f1.

$ curl localhost:8000
Hello Container World! I have been seen 31 times and my hostname is 448b5d70d3d8.

$ curl localhost:8000
Hello Container World! I have been seen 32 times and my hostname is 77b2a2314533.

$ curl localhost:8000
Hello Container World! I have been seen 33 times and my hostname is 4eee9c8d54f1.

连续访问6次之后发现请求并没有转发到我们新启动的3个容器中,这是为什么呢?

负载均衡失效原因分析

初步怀疑是DNS解析失效,我们进入nginx容器查看DNS在解析flask-demo时解析出哪些IP:

$ docker-compose exec nginx sh
/ # apk update
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
v3.14.10-47-g7553b19fe26 [https://dl-cdn.alpinelinux.org/alpine/v3.14/main]
v3.14.10-42-gd8ce7b89082 [https://dl-cdn.alpinelinux.org/alpine/v3.14/community]
OK: 14983 distinct packages available

/ # apk add bind-tools
(1/11) Installing fstrm (0.6.1-r0)
(2/11) Installing krb5-conf (1.0-r2)
(3/11) Installing libcom_err (1.46.2-r1)
(4/11) Installing keyutils-libs (1.6.3-r0)
(5/11) Installing libverto (0.3.2-r0)
(6/11) Installing krb5-libs (1.18.5-r0)
(7/11) Installing json-c (0.15-r1)
(8/11) Installing protobuf-c (1.3.3-r6)
(9/11) Installing libuv (1.41.0-r0)
(10/11) Installing bind-libs (9.16.39-r0)
(11/11) Installing bind-tools (9.16.39-r0)
Executing busybox-1.33.1-r6.trigger
OK: 31 MiB in 53 packages
/ # dig flask-demo

; <<>> DiG 9.16.39 <<>> flask-demo
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55582
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;flask-demo.                    IN      A

;; ANSWER SECTION:
flask-demo.             600     IN      A       192.168.96.7
flask-demo.             600     IN      A       192.168.96.2
flask-demo.             600     IN      A       192.168.96.3
flask-demo.             600     IN      A       192.168.96.4
flask-demo.             600     IN      A       192.168.96.8
flask-demo.             600     IN      A       192.168.96.6

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Tue Oct 10 08:45:53 UTC 2023
;; MSG SIZE  rcvd: 184

发现DNS解析出了6个IP,然后我们在nginx容器中访问flask-demo

/ # curl flask-demo:5000
Hello Container World! I have been seen 281 times and my hostname is 77e74622fa4e.

/ # curl flask-demo:5000
Hello Container World! I have been seen 282 times and my hostname is 4eee9c8d54f1.

/ # curl flask-demo:5000
Hello Container World! I have been seen 283 times and my hostname is 62733bdccdb8.

/ # curl flask-demo:5000
Hello Container World! I have been seen 284 times and my hostname is 448b5d70d3d8.

/ # curl flask-demo:5000
Hello Container World! I have been seen 285 times and my hostname is 6e1494379165.

/ # curl flask-demo:5000
Hello Container World! I have been seen 289 times and my hostname is 77b2a2314533.

在nginx容器内访问就能访问到6个节点,那就说明nginx容器中DNS的解析没有问题,问题出在Nginx服务上。

Nginx在启动的时候会将代理服务器域名解析的ip地址缓存起来,后续不会再更新这个缓存,除非重启。

我们可以给nginx的缓存设置一个失效事件来解决这个问题,nginx.conf配置修改如下:

server {
  listen  80 default_server;
  location / {
    resolver 127.0.0.11 valid=1s; #设置dns服务器,缓存时间改为1s
    set $backend http://web:5000
    proxy_pass $backend;
  }
}

然后再让nginx重新加载配置,再访问服务,发现已经生效了:

$ docker-compose exec nginx nginx -s reload

$ curl localhost:8000
Hello Container World! I have been seen 414 times and my hostname is 77b2a2314533.

$ curl localhost:8000
Hello Container World! I have been seen 415 times and my hostname is 448b5d70d3d8.

$ curl localhost:8000
Hello Container World! I have been seen 417 times and my hostname is 4eee9c8d54f1.

$ curl localhost:8000
Hello Container World! I have been seen 420 times and my hostname is 77e74622fa4e.

$ curl localhost:8000
Hello Container World! I have been seen 421 times and my hostname is 6e1494379165.

$ curl localhost:8000
Hello Container World! I have been seen 422 times and my hostname is 62733bdccdb8.

docker compose参考例子

  • 投票app练习:https://github.com/dockersamples/example-voting-app
  • docker-compose example:https://github.com/docker/awesome-compose

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

N-129基于springboot,vue学生宿舍管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vuevue-element-admin 服务端技术&#xff1a;springboot,mybatis…

UML中类之间的六种主要关系

UML中类之间的六种主要关系: 继承&#xff08;泛化&#xff09;&#xff08;Inheritance、Generalization&#xff09;, 实现&#xff08;Realization&#xff09;&#xff0c;关联&#xff08;Association)&#xff0c;聚合&#xff08;Aggregation&#xff09;&#xff0c;组…

JDK API Diff Report Generator-Java版本对比工具

今天查资料找到了除了EMT4J之外&#xff0c;其他可以用于Java版本迁移的工具。 这里简单的记录一下。 非Java er&#xff0c;有不同意见欢迎评论区交流。 JDK API Diff Report Generator JDK API Diff是一个用于比较不同Java版本API区别的工具。github地址在这里。 例如&am…

Android---StartActivity启动过程

在手机桌面应用中点击某一个 icon 之后&#xff0c;最终是通过 startActivity 去打开某一个 Activity 页面。我们知道&#xff0c;Android 中的一个 APP 就相当于一个进程。所以&#xff0c;startActivity 操作中还需要判断&#xff0c;目标 Activity 的进程是否已经创建。如果…

竞赛选题 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

STM32-ADC实验

目录 实验1&#xff1a;单ADC单通道中断 硬件原理图 USART配置 ADC1配置 初始化结构体的参数 ScanConvMode&#xff1a;扫描转换模式 ContinuousConvMode&#xff1a;连续转换模式 ExternalTrigConv&#xff1a;外部触发方式 测试环节 实验现象 实验2&#xff1a;单…

【疑问解决】在自动装箱中Integer赋予一个常量1,为什么会出现==判断true和flase的情况(JDK源码、内部缓冲)

问题来源自讲课时的Integer练习中 当时第一反应是false true true 因为第一段的输出为flase毋庸置疑了&#xff0c;因为已经new了两个新的堆空间&#xff0c;当然指向不同的空间了 但是第二段第三段就没有头绪了&#xff0c;自动装箱了难道不是执行同一个空间吗…

服务网络基础

服务网络基础 目录 前言 从今天开始我们将进入服务网格的学习&#xff0c;服务网格是微服务架构中的一种重要的技术&#xff0c;它可以解决微服务架构中的一些问题&#xff0c;比如服务发现、服务治理、服务监控等等&#xff0c;我们将从服务网格的基础开始&#xff0c;逐步深…

怎么突破反爬虫机制

在当今的数字化时代&#xff0c;网络爬虫已经成为了收集信息和数据的重要工具。然而&#xff0c;许多网站和平台都配备了反爬虫机制&#xff0c;以防止恶意攻击和过度访问。对于普通用户来说&#xff0c;如何突破这些反爬虫机制呢&#xff1f;本文将为你提供一些实用的技巧和建…

权限系统设计(转载)

1 为什么需要权限管理 2 权限模型 2.1 权限设计 2.2 为什么需要角色 2.3 权限模型的演进 2.4 用户划分 2.5 理想的RBAC模型 3 权限系统表设计 3.1 标准RBAC模型表设计 3.2 理想RBAC模型表设计 4 结语 1 为什么需要权限管理 日常工作中权限的问题时时刻刻伴随着我们&a…

流程引擎-自定义函数的应用

背景&#xff1a; 某些业务需求比较特殊&#xff0c;需要在表单中校验或实现一些功能&#xff0c;泛微流程表单配置时实现的方式多种多样&#xff1a;JS脚本、SQL语句、公式以及其他一些标准化拖拽功能&#xff0c;本次给大家分享一下流程表单中的公式实现的一些需求场景。泛微…

Python轮廓追踪【OpenCV形态学操作】

文章目录 概要代码运行结果 概要 一些理论知识 OpenCV形态学操作理论1 OpenCV形态学操作理论2 OpenCV轮廓操作|轮廓类似详解 代码 代码如下&#xff0c;可以直接运行 import cv2 as cv# 定义结构元素 kernel cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) # print kern…

安装虚拟机找不到虚拟网啦1(eth1)不出现

一、安装虚拟机找不到虚拟网啦1&#xff08;eth1&#xff09;不出现 1、先安装virtualbox 2、再安装vagrant 3、在windows使用ipconfig没有VirtualBoxHost-OnlyNetWork解决方法 1) 解决办法 在windows的设置中找到 网络和Internet 选项&#xff0c;选择右侧 更改适配器选项 …

selenium+python web自动化测试框架项目实战实例教程

自动化测试对程序的回归测试更方便。 由于回归测试的动作和用例是完全设计好的,测试期望的结果也是完全可以预料的,将回归测试自动运行... 可以运行更加繁琐的测试 自动化测试的一个明显好处就是可以在很短的时间内运行更多的测试。学习自动化测试最终目的是应用到实际项目中&…

Android Studio 导出 jar

AS版本&#xff1a;Android Studio Giraffe | 2022.3.1 Patch 1 1、File——New Module——Android Library 2、mylibrary——main——新建功能类 3、mylibrary——build.gradle——android {}内复制以下代码——Sync Now //Copy类型 tasks.register(makeJar, Copy) { //删…

【Java 进阶篇】Java Request 继承体系详解

在Java编程中&#xff0c;Request&#xff08;请求&#xff09;是一个常见的概念&#xff0c;特别是在Web开发中。Request通常用于获取来自客户端的信息&#xff0c;以便服务器能够根据客户端的需求提供相应的响应。在Java中&#xff0c;Request通常涉及到一系列类和接口&#…

CentOS 编译安装TinyXml2

安装 TinyXml2 Git 源码下载地址:https://github.com/leethomason/tinyxml2 步骤1&#xff1a;首先&#xff0c;你需要下载tinyxml2的源代码。你可以从Github或者源代码官方网站下载。并上传至/usr/local/source_code/ 步骤2&#xff1a;下载完成后&#xff0c;需要将源代码解…

Java IDEA feign调用上传文件MultipartFile以及实体对象亲测可行

Java IDEA feign调用上传文件MultipartFile以及实体对象亲测可行 1. 报错 java.lang.IllegalStateException: Body parameter cannot be used with form parameters2. 解决参考 1. 报错 java.lang.IllegalStateException: Body parameter cannot be used with form parameters …

1-多媒体通信概述

文章目录 媒体和多媒体媒体多媒体VarityIntergrationInteraction 多媒体通信(MMC)业务类型 MMC主要问题和关键技术主要问题关键技术 MMC发展动向重要事件趋势 标准化组织 媒体和多媒体 媒体 承载信息的载体. 感知媒体, 表示媒体, 显示媒体, 存储媒体, 传输媒体. 多媒体 Var…

【设计模式】第3节:设计模式概论

设计模式不是代码&#xff0c;而是某类问题的通用方案。设计模式的本质是提高软件的维护性、通用性和扩展性&#xff0c;并降低软件的复杂度。一共有24种设计模式&#xff0c;可以分为创建型模式、结构型模式和行为型模式三大类。设计模式中比较重要的有&#xff1a;单例模式、…