techiall / Blog

🍋 [My Blog] See discussions
https://github.com/techiall/Blog/discussions
MIT License
8 stars 1 forks source link

docker-compose 水平扩容 #68

Open techiall opened 4 years ago

techiall commented 4 years ago

某天心血来潮,docker-compose --help 想看下 docker-compose 有哪些自己没发现好玩的命令。

然后就发现了 docker-compose scale,使用方式如下

➜  knowledge git:(master) docker-compose scale --help
Set number of containers to run for a service.

Numbers are specified in the form `service=num` as arguments.
For example:

    $ docker-compose scale web=2 worker=3

This command is deprecated. Use the up command with the `--scale` flag
instead.

Usage: scale [options] [SERVICE=NUM...]

Options:
  -t, --timeout TIMEOUT      Specify a shutdown timeout in seconds.
                             (default: 10)

简单总结一下也就是制定容器运行的个数,比如有一个 web 服务,你可以指定运行个数,比如 5 个。

docker-compose scale 也有一些小坑

在 docker-compose service 中,不能指定 name,不然扩容的时候会报错,说容器名字已存在。

service 映射 port 也不能指定,不然会报端口号被占用。

要解决这个问题可以使用 nginx,反向代理转发。

下面以我 Github 某个项目的 docker-compose 举例

服务 作用
nginx 网关,反向代理 web
web 前后端服务
mysql 数据存储
redis session 缓存
elastic 搜索引擎

Nginx 指定映射端口 8080,反向代理 web。

docker-compose scale 扩容 web

当然了也可以扩容 mysql / redis / elasticsearch(需要配置

version: '3.7'
services:
  nginx:
    image: nginx:latest
    volumes:
      - ./deploy/nginx/knowledge.conf:/etc/nginx/conf.d/knowledge.conf
    depends_on:
      - web
    ports:
      - "8080:8080"
    networks:
      - knowledge
  web:
    image: techial.top/knowledge:latest
    networks:
      - knowledge
    depends_on:
      - mysql
      - redis
      - elastic
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./deploy/resources/application.yml:/app/resources/application.yml:ro
      - ./deploy/resources/application-elastic.yml:/app/resources/application-elastic.yml:ro
      - ./deploy/resources/ehcache.xml:/app/resources/ehcache.xml:ro
      - ./deploy/resources/logback.xml:/app/resources/logback.xml:ro
      - /root/knowledge-storage:/knowledge/storage
    healthcheck:
      test: "curl -f http://localhost:8080/api/user/me || exit 1"
      retries: 3
      interval: 30s
      timeout: 30s
    restart: always

  mysql:
    image: mysql:8.0
    ports:
      - 3306:3306
    networks:
      - knowledge
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./deploy/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    restart: always

  redis:
    image: redis:alpine
    networks:
      - knowledge
    ports:
      - 6379:6379
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - redis_data:/data

  elastic:
    image: elasticsearch:latest
    ports:
      - 9200:9200
    networks:
      - knowledge
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - elastic_data:/usr/share/elasticsearch/data
    environment:
      - 'ES_JAVA_OPTS=-Xms1024m -Xmx1024m'
      - 'discovery.type=single-node'

networks:
  knowledge:
    external: true

volumes:
  elastic_data:
    external: true
  redis_data:
    external: true
  mysql_data:
    external: true

启动多个个 web 服务

➜  knowledge git:(master) docker-compose scale web=3
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Starting knowledge_web_1 ... done
Creating knowledge_web_2 ... done
Creating knowledge_web_3 ... done

这里提示命令已经过时,那我们换一个命令

➜  knowledge git:(master) docker-compose up -d --scale web=3
Creating knowledge_mysql_1   ... done
Creating knowledge_elastic_1 ... done
Creating knowledge_redis_1   ... done
Creating knowledge_web_1     ... done
Creating knowledge_web_2     ... done
Creating knowledge_web_3     ... done
Creating knowledge_nginx_1   ... done

这样子的就创建了 web 服务,nginx 容器配置一个 proxy_pass 即可。

请求会通过 nginx 转发到不同的 web。

server {
    client_max_body_size 1G;
    listen 8080;

    location / {
        proxy_pass http://web:8080;
        proxy_redirect     off;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}

docker-compose.yml 配置来源于 https://github.com/techial1042/knowledge

ming2281 commented 2 years ago

web不会报这种错误吗 service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash

techiall commented 2 years ago

web不会报这种错误吗 service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash

web 不设置映射端口到宿主主机, 是不会有问题的, 通过 nginx 反代 web

ming2281 commented 2 years ago

web不会报这种错误吗 service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash

web 不设置映射端口到宿主主机, 是不会有问题的, 通过 nginx 反代 web

懂了

web 不能 映射端口出来 ====> 另外mysql/redis/es也不能暴露端口 (安全问题) nginx 作为对外的统一网关