zoukankan      html  css  js  c++  java
  • 基于docker swarm的搭建高可用web集群

    项目描述

    实现一个高可用的负载均衡的web服务器集群,底层采用swarm管理的docker集群来提供web服务,大量使用容器来完成web服务的扩展性、高可用性。

    拓扑结构

    项目环境

    环境配置 参数
    Docker Docker version 1.13.1, build 64e9980/1.13.1
    OS CentOS Linux release 7.8.2003 (Core) (7台)
    nginx(负载均衡器) nginx/1.16.1
    Keepalived Keepalived v1.3.5 (03/19,2017)
    nginx nginx/1.19.0
    load-balancer-1 ens33: 192.168.0.121
    load-balancer-2 ens33: 192.168.0.122
    swarm-manager 192.168.0.101
    swarm-2 192.168.0.102
    swarm-3 192.168.0.103
    swarm-4 192.168.0.104
    nfs server 192.168.0.105

    项目步骤

    1. 规划设计整个集群的架构,前端使用nginx做负载均衡,采用keepalived实现高可用,后端使用swarm来实现负载均衡和高可用;
    2. 后端采用swarm来管理整个docker集群,每个docker宿主机需要启动10个容器,总共启动40个容器来提供web服务;
    3. 制作自己的nginx容器的镜像,定制nginx.conf的内容,编译安装nginx,指定参数(安装路径、https、状态统计等配置);
    4. 使用nfs服务为所有的docker节点提供相同的web数据,实现数据一致性。在所有的docker宿主机上创建使用nfs服务器的数据卷,然后所有的docker nginx容器使用此数据卷,实现所有的容器使用相同的数据卷;
    5. 排错和故障解决,整理项目文档。

    具体操作

    准备工作

    1. 修改主机名,便于区分。

      # 临时修改
      hostname xxx
      
      # 永久修改
      hostnamectl set-hostname xxx
      
    2. 配置静态ip

      systemctl stop NetworkManager
      systemctl disable NetworkManager
      
      vim /etc/sysconfig/network-script/ifcfg-ens33
      
      service network restart
      
    3. 关闭防火墙和selinux

       service firewalld stop
       systemctl disable firewalld.service
       setenforce 0
       sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
      

    配置负载均衡

    1. 下载安装nginx

      yum install epel-release -y
      yum install nginx -y
      
      # 启动服务
      nginx
      # 设置nginx开机自启
      echo 'nginx' >> /etc/rc.d/rc.local
      chmod +x /etc/rc.d/rc.local
      
    2. 修改nginx配置定义负载均衡器

      # 定义负载均衡器
          upstream mylb1{
              server 192.168.0.131;
              server 192.168.0.132;
              server 192.168.0.133;
              server 192.168.0.134;
          }
      
          server {
              listen       80 default_server;
              listen       [::]:80 default_server;
              server_name  _;
              root         /usr/share/nginx/html;
      		
      		...
      
      		# 添加负载均衡的使用
              location / {
                      proxy_pass http://mylb1;
              }
              
              ...
          }
      

    keepalived实现高可用

    1. 在两台做负载均衡的机器上安装keepalived

      yum install keepalived -y
      
      # 启动服务
      service keepalived start
      # 设置开机自启
      systemctl enable keepalived
      
    2. 修改配置文件/etc/keepalived/keepalived.conf启用VRRP协议

      virtual_server及后面全部删掉

      global_defs {
      	...
      	# 将下面这行注释掉。
      	vrrp_strict
      	...
      }
      
      vrrp_instance VI_1 {
      	state MASTER
      	interface ens33
      	virtual_router_id 51
      	priority 99
      	advert_int 1
      	authentication {
      		auth_type PASS
      		auth_pass 1111
      	}
      	virtual_ipaddress {
      		192.168.0.136
      	}
      }
      

      另一台也如上修改配置,稍有不同的是state MASTER修改为BACKUPpriority修改为101(比MASTER小就行)

    3. 刷新服务

      service keepalived restart
      

    搭建swarm集群

    1. 在四台docker节点上安装docker

      yum install docker -y
      
      # 启动服务
      service docker start
      # 设置开机自启
      systemctl enable docker
      
    2. 在四台docker节点上配置/etc/hosts文件,修改ip和域名的记录,内容如下。

      127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
      ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
      192.168.0.101 swarm-manager
      192.168.0.102 swarm-2
      192.168.0.103 swarm-3
      192.168.0.104 swarm-4
      
    3. 在swarm-manager上创建swarm集群,然后添加节点

      [root@swarm-manager ~]# docker swarm init --advertise-addr 192.168.0.101
      Swarm initialized: current node (czi8ny7odir7hiu84r25f0h92) is now a manager.
      
      To add a worker to this swarm, run the following command:
      
          docker swarm join 
          --token SWMTKN-1-1a7esyutfqeeuub4ztfmzf74uv55zsvhe47xi3tgnz7w2esl1y-d3vtqw592lypiexfgk0527s9h 
          192.168.0.101:2377
      
      To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
      
      [root@swarm-manager ~]# 
      

      输入命令后的输出显示当前节点已经加入swarm集群,成为swarm集群的一个manager,并提供了添加worker节点的方式。

      在其余几台待用作worker节点的机器上执行添加节点命令。

      [root@swarm-2 ~]# docker swarm join 
      >     --token SWMTKN-1-1a7esyutfqeeuub4ztfmzf74uv55zsvhe47xi3tgnz7w2esl1y-d3vtqw592lypiexfgk0527s9h 
      >     192.168.0.101:2377
      This node joined a swarm as a worker.
      [root@swarm-2 ~]# 
      
      [root@swarm-3 ~]# docker swarm join 
      >     --token SWMTKN-1-1a7esyutfqeeuub4ztfmzf74uv55zsvhe47xi3tgnz7w2esl1y-d3vtqw592lypiexfgk0527s9h 
      >     192.168.0.101:2377
      This node joined a swarm as a worker.
      [root@swarm-3 ~]# 
      
      [root@swarm-4 ~]# docker swarm join 
      >     --token SWMTKN-1-1a7esyutfqeeuub4ztfmzf74uv55zsvhe47xi3tgnz7w2esl1y-d3vtqw592lypiexfgk0527s9h 
      >     192.168.0.101:2377
      Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.
      [root@swarm-4 ~]# 
      

      几条命令

      • docker info 显示 docker 系统信息,可以查看集群信息

      • docker swarm leave -f 退出集群,-f 强制

      • docker node ls 在manager节点上查看集群中的机器及状态(我只是临时修改主机名,所以这里显示的还是默认主机名)

        [root@swarm-manager ~]# docker node ls
        ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
        6knoty95gqux8lzd6qb3bd423    swarm-4   Ready   Active        
        czi8ny7odir7hiu84r25f0h92 *  swarm-manager   Ready   Active        Leader
        gzuczyy7vf91kq9an9tfn34r0    swarm-3   Ready   Active        
        ogsujfhe8erbfpka3rl3qdmlb    swarm-2   Ready   Active        
        [root@swarm-manager ~]# 
        

      这时候一个swarm集群已经搭建起来了,自动的创建了一个Overlay网络,多个容器之间通过Overlay网络进行通信。

      [root@swarm-manager ~]# docker network ls
      NETWORK ID          NAME                DRIVER              SCOPE
      719f75aee18c        bridge              bridge              local
      ef1f2df1c727        docker_gwbridge     bridge              local
      ff329dbafde9        host                host                local
      jrbmwuddnbzi        ingress             overlay             swarm
      fa67605df455        none                null                local
      [root@swarm-manager ~]# 
      

      可以自定义一个Overlay网络。

      [root@swarm-manager ~]# docker network create -d overlay nginx_net
      wg2edv8o98jg848br9er063vo
      [root@swarm-manager ~]# 
      
    4. 验证swarm集群——部署服务

      # 创建了一个具有20个副本(--replicas 20 )的nginx服务,使用镜像nginx。
      # 这个命令执行后会自动下载容器镜像。
      [root@swarm-manager ~]# docker service create --replicas 20 --network nginx_net --name mynginx -p 80:80 nginx
      

    搭建nfs服务

    nfs用于实现不同机器之间的文件共享。

    1. 配置NFS-SERVER

      [root@nfs-server ~]# yum install nfs-utils -y
      
      # 启动nfs服务
      [root@nfs-server ~]# service nfs-server start
      Redirecting to /bin/systemctl start nfs-server.service
      # 设置开机自启
      [root@nfs-server ~]# systemctl enable nfs-server
      
      # /etc/exports是nfs默认的配置文件
      # rw:可读写
      # ro: 只读
      [root@nfs-server ~]# vim /etc/exports
      /web 192.168.0.0(rw,all_squash,sync)
      
      # 创建/web目录并设置权限
      [root@nfs-server ~]# mkdir /web
      [root@nfs-server ~]# chmod 777 /web
      
      # 导出目录
      [root@nfs-server ~]# exportfs -rv
      exporting 192.168.0.0:/web
      [root@nfs-server ~]# 
      

      rw:可读写
      ro: 只读
      no_root_squash:对root用户不压制,如果客户端以root用户写入,在服务端都映射为服务端的root用户
      root_squash: nfs服务:默认情况使用的是相反参数root_squash,
      如果客户端是用户root操作,会被压制成nobody用户
      all_squash: 不管客户端的使用nfs的用户是谁,都会压制成nobody用户
      insecure: 允许从客户端过来的非授权访问
      sync: 数据同步写入到内存和硬盘
      async: 数据先写入内存,不直接写入到硬盘
      anonuid: 指定uid的值,此uid必须存在于/etc/passwd中 --》 anonymous
      anongid:指定gid的值

      -r: Reexport all directories: 重新导出所有目录
      -v: verbose,输出详情

    2. 配置docker node。创建数据卷,在所有的docker worker节点上创建一样名字的数据卷执行nfs服务器的相同共享目录

      # 下载安装nfs并设置开机自启
      yum install nfs-utils -y
      systemctl enable nfs-server
      
      mkdir /con_web
      chmod 777 /con_web
      # 将docker node上的/con_web目录挂载到nfs服务器的/web上
      mount 192.168.0.105:/web  /con_web/
      
      # 创建数据卷
      docker volume create --driver local --opt type=nfs --opt o=addr=192.168.0.105,rw --opt device=:/web  mynginx
      
      # 验证
      docker volume inspect mynginx
      
    3. 定制nginx镜像,修改网页根目录,指定到/app目录

      mkdir mynginx
      cd mynginx
      
      vim Dockerfile
      

      Dockerfile文件内容如下:

      FROM docker.io/sglim2/centos7
      
      MAINTAINER Charramma
      
      WORKDIR /
      COPY nginx-1.19.0.tar.gz  /
      
      RUN yum install zlib zlib-devel openssl openssl-devel pcre pcre-devel gcc gcc-c++ autoconf automake make  -y 
          && tar xf nginx-1.19.0.tar.gz 
          && cd nginx-1.19.0 
          &&  ./configure  --prefix=/usr/local/nginx   --with-threads  --with-file-aio  --with-http_ssl_module  --with-http_stub_status_module  --with-stream  
          &&make -j 2 ; make install  
          && sed -i '44 c root /app ;' /usr/local/nginx/conf/nginx.conf
      
      ENV PATH /usr/local/nginx/sbin:$PATH
      EXPOSE 80
      STOPSIGNAL  SIGTERM
      ENTRYPOINT ["nginx"]
      
      CMD ["-g","daemon off;"]
      

      下载nginx包

      curl -O http://nginx.org/download/nginx-1.19.0.tar.gz
      

      生成镜像

      docker build -t my_nginx_app .
      

      导出镜像

      docker save -o my_nginx_app.tar my_nginx_app
      

      导入到其他节点上

      docker load -i my_nginx_app.tar
      
    4. 在manager节点上启动服务

      [root@swarm-manager ~]# docker service create --name ngs-my-nginx  --publish 80:80   --mount type=volume,source=mynginx,destination=/app  --replicas 40 my_nginx_app
      

    遇到的问题

    • 生成镜像时,运行到编译安装一步时,报错。

      [Warning] IPv4 forwarding is disabled. Networking will not work.
      

      解决方法:

      echo 'net.ipv4.ip_forward=1' >> /usr/lib/sysctl.d/00-system.conf
      
    • 网络问题,在生成镜像时,依赖下载不下来。

  • 相关阅读:
    Flask 路由映射对于双斜线的处理 //a//b
    python中的导入如何使用,以及.和..相对导入的使用
    tornado 启动WSGI应用(Flask)使用多线程将同步代码变成异步
    flask的请求处理流程和异常处理流程
    pyengine介绍及使用
    __import__
    如何为自己的pip包打造可以执行的系统命令
    JS进阶之原型
    JS基础之对象
    CSS之深入探究Position
  • 原文地址:https://www.cnblogs.com/CharrammaBlog/p/13629159.html
Copyright © 2011-2022 走看看