使用Virtual Box桥接网络,部分需要登录才能访问外网的需要配置双网卡
桥接网卡配置:
vi /etc/sysconfig/network-scripts/ifcfg-enp0s8
BOOTPROTO=static # 自动获取ip
ONBOOT="yes"
IPADDR=192.168.2.111
GATEWAY=192.168.2.1
NETMASK=255.255.255.0
网络常用命令
service network restart --重启网卡
ip addr --查看ip
hostnamectl set-hostname node1 --设置机器名称
systemctl stop firewalld //临时关闭关闭防火墙
systemctl disable firewalld //禁止开机启动关闭防火墙
安装docker
yum -y update --更新
yum install -y yum-utils device-mapper-persistent-data lvm2 --安装需要的软件包
设置源
//官方镜像
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
//阿里镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum list docker-ce --showduplicates | sort -r --查看版本
yum install -y docker-ce --这里默认安装的是最新稳定版,你也可以指定版本号安装
systemctl start docker --启动
systemctl enable docker --加入自启
docker login --username=canyanol@qq.com registry.cn-hangzhou.aliyuncs.com 登录远程仓库
docker swarm 集群
node1:管理节点
node2:计算节点
node3:计算节点
node1 执行
docker swarm init --advertise-addr 192.168.2.151
node2 ,node3加入
docker swarm join --token XXXXXX
docker service
-- docker service update命令 https://www.yiibai.com/docker/service_update.html
docker service create --replicas 2 --network jdt --name queue -p 80:80 registry.cn-hangzhou.aliyuncs.com/my-work/work:jdt-queue-v3-115 --创建一个服务
docker service ls:查看所有的service基本信息
docker service ps [SERVICE_ID]:查看具体某个service的信息
docker service rm queue --删除服务
docker service update --replicas=3 queue 更新服务
docker service update --image registry.cn-hangzhou.aliyuncs.com/my-work/work:jdt-queue-v3-114 queue 更新镜像版本
docker service scale queue=3 缩放单个服务
docker service ps queue 查看服务
docker node ls 查看计算节点
docker node update --availability drain node2 更新节点 上线/下线
docker service update \
--image nginx:2.0 \
--update-parallelism 2 \
--update-delay 20s my-nginx
# 滚动更新 将镜像更新为2.0 每次更新两个副本 每20s更新一次
使用图形化工具portainer 管理docker
docker run -d -p 9000:9000 --name=portainer -v "/var/run/docker.sock:/var/run/docker.sock"
-v /host/data:/data portainer/portainer
timescaledb:latest Stack
version: '3.6'
services:
timescaledb14:
image: timescale/timescaledb:latest-pg14
environment:
- POSTGRES_PASSWORD=123456
volumes:
- /data/postgresql:/var/lib/postgresql/data
deploy:
replicas: 1
restart_policy:
condition: any
resources:
limits:
cpus: "0.2"
memory: 512M
update_config:
parallelism: 1 # 每次更新1个副本
delay: 5s # 每次更新间隔
monitor: 10s # 单次更新多长时间后没有结束则判定更新失败
max_failure_ratio: 0.1 # 更新时能容忍的最大失败率
order: start-first # 更新顺序为新任务启动优先
placement:
constraints: [node.role == manager] #运行在 管理角色机器上 该hostname为指定容器在哪个主机启动 - node.hostname == node1
ports:
- 5432:5432
networks:
- mynet
networks:
mynet:
external: true
queue 的部署指令
version: '3.6'
services:
webserver: # webserver 服务
image: nginx:1.23.3
ports:
- 80:80
- 443:443
networks:
- mynet
volumes:
- /data/nginx/conf.d:/etc/nginx/conf.d
- /data/nginx/nginx.conf:/etc/nginx/nginx.conf
deploy:
replicas: 1
placement:
constraints: [node.role == manager] #运行在 管理角色机器上 该hostname为指定容器在哪个主机启动 - node.hostname == node1
restart_policy:
condition: any
update_config:
parallelism: 1 # 每次更新1个副本
delay: 5s # 每次更新间隔
monitor: 10s # 单次更新多长时间后没有结束则判定更新失败
max_failure_ratio: 0.1 # 更新时能容忍的最大失败率
order: start-first # 更新顺序为新任务启动优先
webapi: # webapi 服务
image: registry.cn-hangzhou.aliyuncs.com/canyanol/queue:3.120
ports:
- 8111:80
networks:
- mynet
# depends_on:
# - redis6
# - mysql5
deploy:
replicas: 2
restart_policy:
condition: any
resources:
limits:
cpus: "0.5"
memory: 512M
update_config:
parallelism: 1 # 每次更新1个副本
delay: 3s # 每次更新间隔
monitor: 20s # 单次更新多长时间后没有结束则判定更新失败
max_failure_ratio: 0.1 # 更新时能容忍的最大失败率
order: start-first # 更新顺序为新任务启动优先
placement:
constraints: [node.role == worker] #运行在 管理角色机器上 该hostname为指定容器在哪个主机启动 - node.hostname == node1
redis6:
image: redis:6.0.6
restart: always
ports:
- 6379:6379
networks:
- mynet
privileged: true
command: redis-server /etc/redis/redis.conf --appendonly yes
volumes:
- /data/redis/data:/data
- /data/redis/conf/redis.conf:/etc/redis/redis.conf
deploy:
placement:
constraints: [node.role == manager]
mysql5:
restart: always
image: mysql:5.7.22
container_name: mysql
ports:
- 3306:3306
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123456
deploy:
replicas: 1
restart_policy:
condition: any
placement:
constraints: [node.role == manager]
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
--sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
volumes:
- /data/mysql/conf:/etc/mysql
- /data/mysql/logs:/var/log/mysql
- /data/mysql/data:/var/lib/mysql
networks:
- mynet
networks:
mynet:
external: true
queue_service.yaml
traefik+ jaeger+mysql5+redis+helloworld+webapi
traefik 实现反向代理, 负载均衡,限流,熔断 ,健康检查。jaegertracing实现分布式追踪
version: '3.6'
services:
traefik: # 反向代理服务
image: traefik:2.9.6
ports:
- "80:80"
- "8080:8080" # traefik dashboard
command:
- --api.insecure=true # set to 'false' on production
- --api.dashboard=true # see https://docs.traefik.io/v2.0/operations/dashboard/#secure-mode for how to secure the dashboard
- --api.debug=true # enable additional endpoints for debugging and profiling
- --log.level=DEBUG # debug while we get it working, for more levels/info see https://docs.traefik.io/observability/logs/
- --providers.docker=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=proxy
- --entryPoints.web.address=:80
# 日志追踪 jaeger
- --tracing.jaeger.collector.endpoint=http://jaegertracing:14268/api/traces?format=jaeger.thrift
#- --entryPoints.elderServer.address=:7122
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- mynet
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`traefik.xxx.com`)"
- "traefik.http.routers.api.service=api@internal" # Let the dashboard access the traefik api
placement:
constraints: [node.role == manager] #运行在 管理角色机器上 该hostname为指定容器在哪个主机启动 - node.hostname == node1
webapi: # webapi 服务
image: registry.cn-hangzhou.aliyuncs.com/canyanol/queue:3.120
networks:
- mynet
deploy:
labels:
# 对外暴露容器服务
- "traefik.enable=true"
# 对外访问的路由地址,路由规则请参考官网
# https://docs.traefik.io/routing/routers/ Host(`www.a.com`)
- "traefik.http.routers.webapi.rule=Host(`b.a.com`)"
# 对外暴露的入口点
- "traefik.http.routers.webapi.entrypoints=web"
# 容器内的入口点,treafik无法获知你的服务的访问入口点
# 所以你必须以此告诉Traefik
# Traefik同时会在此对横向拓展的容器建立负载均衡
# 更多见https://docs.traefik.io/routing/services/
# 负载均衡 https://doc.traefik.io/traefik/routing/services/#load-balancing
- "traefik.http.services.webapi.loadbalancer.server.port=80"
# 启用粘性会话后,将在初始响应上设置标头,让客户端知道哪个服务器处理第一个响应。 在后续请求中,为了保持会话与同一服务器处于活动状态,客户端应发送具有设置值的 cookie
#- "traefik.http.services.webapi.loadbalancer.sticky.cookie={}"
#- "traefik.http.services.webapi.loadbalancer.sticky.cookie.name=loadbalancer"
#- "traefik.http.services.webapi.loadbalancer.sticky.cookie.secure=true"
#- "traefik.http.services.webapi.loadbalancer.sticky.cookie.httpOnly=true"
# 健康检查 https://doc.traefik.io/traefik/routing/services/#health-check
- "traefik.http.services.webapi.loadbalancer.healthCheck.path=/api/services/app/Session/GetCurrentLoginInformations"
- "traefik.http.services.webapi.loadbalancer.healthCheck.interval=5s"
- "traefik.http.services.webapi.loadbalancer.healthCheck.timeout=3s"
# 限流 https://doc.traefik.io/traefik/middlewares/http/ratelimit/
#average 是给定源允许的最大速率,默认情况下以每秒请求数为单位
- "traefik.http.middlewares.webapi-ratelimit.ratelimit.average=100"
# burst 是在同一任意短时间内允许通过的最大请求数。
- "traefik.http.middlewares.webapi-ratelimit.ratelimit.burst=50"
# 熔断 断路器可防止系统将请求堆叠到不正常的服务,从而导致级联故障 https://doc.traefik.io/traefik/middlewares/http/circuitbreaker/
# 当 30% 的请求返回 5XX 状态代码或网络错误比率达到 10% 时,触发断路器
- "traefik.http.middlewares.webapi-latency-check.circuitbreaker.expression=ResponseCodeRatio(500, 600, 0, 600) > 0.30 || NetworkErrorRatio() > 0.10"
# 添加到中间件
- "traefik.http.routers.webapi.middlewares=webapi-ratelimit,webapi-latency-check"
replicas: 2 # 2个实例
restart_policy: # 重启策略
condition: any
resources: # 资源配置
limits:
cpus: "0.5"
memory: 512M
update_config: # 更新配置
parallelism: 1 # 每次更新1个副本
delay: 3s # 每次更新间隔
monitor: 20s # 单次更新多长时间后没有结束则判定更新失败
max_failure_ratio: 0.1 # 更新时能容忍的最大失败率
order: start-first # 更新顺序为新任务启动优先
placement:
constraints: [node.role == worker] #运行在 管理角色机器上 该hostname为指定容器在哪个主机启动 - node.hostname == node1
helloworld:
image: tutum/hello-world:latest
networks:
# 与traefik同一个网络
- mynet
deploy:
labels:
# 对外暴露容器服务
- "traefik.enable=true"
# 对外访问的路由地址,路由规则请参考官网
# https://docs.traefik.io/routing/routers/
- "traefik.http.routers.helloworld.rule=Host(`a.a.com`)"
# 对外暴露的入口点
- "traefik.http.routers.helloworld.entrypoints=web"
# 容器内的入口点,treafik无法获知你的服务的访问入口点
# 所以你必须以此告诉Traefik
# Traefik同时会在此对横向拓展的容器建立负载均衡
# 更多见https://docs.traefik.io/routing/services/
- "traefik.http.services.helloworld.loadbalancer.server.port=80"
redis6: # redis 服务
image: redis:6.0.6
restart: always
ports:
- 6379:6379
networks:
- mynet
command: redis-server /etc/redis/redis.conf --appendonly yes
volumes:
- /data/redis/data:/data
- /data/redis/conf/redis.conf:/etc/redis/redis.conf
deploy:
placement:
constraints: [node.role == manager]
mysql5: # mysql 数据库服务
image: mysql:5.7.22
ports:
- 3306:3306
networks:
- mynet
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123456
deploy:
replicas: 1
restart_policy:
condition: any
placement:
constraints: [node.role == manager]
volumes:
- /data/mysql/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
- /data/mysql/logs:/var/log/mysql
- /data/mysql/data:/var/lib/mysql
jaegertracing: # 分布式追踪 https://zhuanlan.zhihu.com/p/524695029
image: jaegertracing/all-in-one:1.33
ports:
- 14268:14268 # 接收日志
- 14269:14269
- 16686:16686 # web ui
- 14250:14250
- 9411:9411
networks:
- mynet
environment:
COLLECTOR_ZIPKIN_HOST_PORT: 9411
deploy:
replicas: 1
restart_policy:
condition: any
placement:
constraints: [node.role == manager]
networks:
mynet:
external: true