首页 新闻 会员 周边 捐助

docker swarm优雅关闭容器问题非常的棘手请教

0
悬赏园豆:60 [待解决问题]

兄弟们晚上好:

现在我这边使用docker swarm 遇到了一个非常棘手的问题,
我们使用docker swarm 搭建集群跑的java容器。

在做滚动更新的时候。总是有请求进来,结果nginx那边报了一堆502。因为我们每台机器上面都跑了一个nginx然后在通过nginx的upstream来转发给本地机器的容器进程的。

upstream web {
    server localhost:18081;
    keepalive 300;

理论上docker swarm 集群在做滚动更新的时候。会先把集群内部的负载均衡里面摘掉既然废弃的容器进程,切断流量。然后停止这个容器,进而拉起一个容器。接着通过健康检测判断这个容器是否启动完毕。启动完毕之后,就会把这个容器进程加入到负载均衡里面的。这么下来就完成了滚动更新,毕竟集群会先在负载均衡摘掉流量的,所以不可能还有有流量打入这个即将废弃的容器进程了。可是现在我们每次发布更新总会伴着1000多条502的记录。

通过docker file 生成镜像的,而健康检测也是写到了docker file 里面的。
健康检测设置如下:
HEALTHCHECK --interval=20s --timeout=10s --retries=10 CMD wget --quiet --tries=1 --spider http://localhost:$service_port/healthCheck || exit 1

我们尝试过优雅关闭,设置过了--stop-signal 为30s 甚至60s 发现还是一样,发布过程中会出现502,现在两个方向。不确定这些502是由于流量打到了旧容器而导致的,还是流量打到新容器而导致的,新容器这个是怀疑我们的健康检测设置不合理,也就是容器进程还没有能够对外提供服务,健康检测却通过了,认为这个新容器进程是启动完毕了,加入了负载均衡有部分流量打到了新容器进程去。

k8s 巧巧很好的处理了这个问题,比如他们配置了preStop等这种策略。能够完美解决这个问题,但是docker swarm 目前,不敢相信会有这种问题。毕竟按照docker swarm 的滚动发布流程,是不可能有这种问题的。它是先摘除流量的。现在非常的头疼,不知道从何下手了。而一时之间我们也不能断然的上k8s集群。毕竟体量也很少,暂时不考虑。各位在使用docker swarm的时候是否遇见过这样的问题。请教,万分感谢,提前祝大家新年快乐~~

补充一下:我们的nginx 部署的网络是host模式,而应用是专门创建了一个overlay网络在里面跑的
NETWORK ID NAME DRIVER SCOPE
wqpezy5g2pjl bobo-network overlay swarm (这是我们后端应用跑的网络命名空间)
b4f0b8c4ef4d bridge bridge local
59347c5dfa7a docker_gwbridge bridge local
4079bbadea8b host host local
2cw5xft9mtyj ingress overlay swarm
cadc70451b26 none null local
efmpcxfd7yv1 portainer-agent_portainer_agent overlay swarm

SeagullUp的主页 SeagullUp | 初学一级 | 园豆:148
提问于:2023-01-11 22:53
< >
分享
所有回答(1)
0

从 upstream 的配置看,nginx 的部署有问题,nginx 应该通过 service name 访问 upstream

nginx 应该作为一个 service 与应用容器部署在同一网络

version: '3.4'
services:
  public:
    image: proxy_public:${IMAGE_VERSION}
    ports:
      - 80:80
    deploy:
      mode: global
      update_config:
        order: start-first
      placement:
        constraints: [node.role == worker]    
    networks:
      public:  

networks:
  public:
    external: true

nginx 配置 proxy_public.conf

map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}

server {
  listen 80 default_server;
  access_log  off;
  return 200 'Hello, World! - nginx\n';
}

server {
  listen 80;
  server_name ~^(staging-)?(?<app>[^.]+)\.cnblogs\.com$;
  access_log  off;

  location / {
     resolver 127.0.0.11;
     proxy_set_header Host $host;
     proxy_pass http://${app}_web;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection $connection_upgrade;
  }
}

nginx proxy_public 镜像的 dockerfile

FROM nginx
COPY nginx.conf /etc/nginx
COPY proxy_public.conf /etc/nginx/conf.d

HEALTHCHECK --interval=5s --timeout=20s \
    CMD curl -fs -o /dev/null localhost || exit 1

我们的生产环境在使用 k8s 之前用的是 docker swarm,staging 环境还在使用 docker swarm,没有遇到你所说的问题。

另外,即使体量小,生产环境还是建议使用 k8s。

dudu | 园豆:29737 (高人七级) | 2023-01-12 07:45

好的,我尝试一下调整nginx

支持(0) 反对(0) SeagullUp | 园豆:148 (初学一级) | 2023-01-12 09:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册