Docker-Consul容器服务更新与发现

发布于:2024-05-08 ⋅ 阅读:(25) ⋅ 点赞:(0)

前言

Docker Compose 则进一步简化了多个容器应用的编排与管理。另一方面,Consul 作为一款先进的服务发现工具,为分布式和微服务架构提供了可靠的服务注册与发现机制。本文将探讨 Docker Compose 和 Consul 在容器化环境中的协同作用,以及它们如何共同帮助开发人员更高效地构建、部署和管理其应用程序。

Docker Compose相关介绍请参考:

Docker-Compose单机多容器应用编排与管理-CSDN博客

目录

一、概述

1. 服务注册与发现

2. 什么是 consul

3. 服务架构

3.1 传统架构

3.2 consul 架构

4. 关键特性

二、Consul 部署

1. 容器服务更新与发现拓扑图

2. 部署信息

3. consul 服务器

3.1 建立 consul 服务

3.2 查看集群信息

3.3 通过 http api 获取集群信息

4. registrator 服务器

4.1 安装 Gliderlabs/Registrato

4.2 测试服务发现功能是否正常

4.3 验证 http 和 nginx 服务是否注册到 consul 

5. consul-template 

5.1 准备 template nginx 模板文件

5.2 安装配置 nginx 服务

5.3 配置并启动 template

5.4 访问 template-nginx

5.5 增加一个 nginx 容器节点

6. consul 多节点

6.1 安装 docker 

6.2 拷贝 consul 相关服务文件,启动 consul 服务

6.3 查看集群信息


一、概述

1. 服务注册与发现

① 服务注册:在Docker中运行的应用程序可以通过Consul客户端向Consul服务注册自己的信息,包括服务名称、IP地址、端口号等。这样,Consul就会维护一个服务目录,记录着所有可用的服务实例及其位置信息。

② 服务发现:其他Docker容器或应用程序可以通过Consul客户端查询Consul服务注册中心,动态地发现和连接到需要的服务。Consul根据服务名称、标签、健康状态等条件来选择合适的服务实例,实现服务间的通信和协作。

2. 什么是 consul

Consul 是一种开源的服务发现和配置管理工具,由 HashiCorp 开发。它提供了一系列功能,包括服务注册、服务发现、健康检查、KV存储等,旨在简化构建和管理分布式系统的过程。

① 服务注册与发现:Consul 允许服务实例向 Consul 注册其信息,包括服务名称、网络位置(IP地址和端口号)、健康状态等。其他服务或客户端可以通过 Consul 查询服务注册中心,动态地发现和连接到需要的服务,从而实现服务间的通信。

② 健康检查:Consul 可以定期对服务实例进行健康检查,以确保服务的可用性。如果一个服务实例不健康,Consul 会将其标记为不可用,同时通知其他服务实例进行相应的调整,保证系统的稳定性。

③ KV 存储:Consul 提供了一个分布式的键值存储系统,允许用户存储和检索配置信息、应用程序状态等。这个功能对于动态配置和共享状态在分布式系统中是非常有用的。

④ 多数据中心支持:Consul 支持多数据中心部署,可以轻松地在不同地理位置的数据中心中管理和发现服务,提高系统的可用性和容错性。

3. 服务架构

3.1 传统架构

在 upstream 块中,需要指定后端服务器的 IP 地址和端口号,即 ip:port;在proxy_pass指令中,需要指定转发请求的目标;

当需要添加新的后端服务器时,需要修改代理端配置文件,且需要重启服务才可以生效,有一定的局限性。

3.2 consul 架构

后端服务 A-N 可以把当前自己的网络位置注册到服务发现模块,服务发现就以 K-V 的方式记录下来,K 一般是服务名,V 就是 ip:port。服务发现模块定时的进行健康检查,轮询查看这些后端服务能不能访问的了。前端在调用后端服务 A-N 的时候,会先询问服务发现模块后端服务的网络位置,然后再调用它们的服务。 

4. 关键特性

  • 服务注册与发现:consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也可以一样注册;
  • 健康检查:健康检测使consul可以快速的告警在集群中的操作。和服务发现的集成,可以防止服务转发到故障的服务上面;
  • Key/Value存储:一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。
  • 多数据中心:无需复杂的配置,即可支持任意数量的区域。

二、Consul 部署

1. 容器服务更新与发现拓扑图

Consul Template

  • Consul Template守护进程是Consul Template工具的一部分,用于监视Consul中的键值存储(KV)中的变化,并根据这些变化来更新本地的配置文件。它可以在后台运行,并定期检查Consul中的数据,以确保生成的配置文件与最新的配置信息保持同步;
  • 是一个配置文件模板,可以获取注册中心所有的服务发现,然后将服务发现的名称:端口号转发给 Nginx,并且更新 nginx.conf 文件。

Consul Server

  • 作为注册中心,Consul Server 负责维护服务目录,记录当前可用的服务实例及其位置信息;
  • 负责执行健康检查来确保服务的可用性,定期检查服务实例的健康状态,如果某个服务实例出现故障或不可用,Consul会将其标记为不健康,并从服务目录中移除;同时服务实例新增或者恢复,Consul会将其加入到服务目录中;
  • 提供了KV存储,用于存储配置信息、应用程序状态等。这个分布式键值存储可以用于共享配置、动态更新应用程序参数等场景;
  • 支持事件处理机制,可以发布和订阅各种事件,例如服务状态变更、健康检查结果等。

Consul Agent

  • 是一个轻量级的代理程序,用于运行在每个部署了服务的节点上。它负责与Consul集群通信,并执行各种任务,包括服务注册、健康检查、服务发现和处理来自其他节点的RPC请求等。 

Registrator

  • 是一个服务注册器,它是一个独立的进程,运行在容器编排环境中;它的主要作用是监视运行中的服务实例,并将它们注册到服务发现系统中,例如Consul或etcd。通过这种注册,其他服务可以发现并与这些服务进行通信,而无需事先知道它们的位置或IP地址。

2. 部署信息

服务节点 ip 安装运行服务 docker版本
consul 服务器 192.168.190.107 运行consul服务、nginx服务、consul-template守护进程 26.0.2
registrator 服务器 192.168.190.108 运行registrator容器、运行nginx容器 20.10.17
consul 服务器 192.168.190.106 运行consul服务 26.0.2

3. consul 服务器

3.1 建立 consul 服务

① 二进制包直接安装

[root@consul ~]# mkdir /opt/consul
[root@consul ~]# cd /opt/consul/
[root@consul consul]# ls
consul_0.9.2_linux_amd64.zip       # 准备二进制包
[root@consul consul]# unzip consul_0.9.2_linux_amd64.zip
[root@consul consul]# mv consul /usr/local/bin/

② 设置代理,后台启动 consul 服务端

[root@consul consul]#  consul agent \
> -server \
> -bootstrap \
> -ui \
> -data-dir=/var/lib/consul-data \
> -bind=192.168.190.107 \
> -client=0.0.0.0 \
> -node=consul-server01 &> /var/log/consul.log &
[1] 7694

③ 启动 consul 后默认会监听5个端口

[root@consul consul]# netstat -natp | grep consul
tcp        0      0 192.168.190.107:8300    0.0.0.0:*               LISTEN      37870/consul        
tcp        0      0 192.168.190.107:8301    0.0.0.0:*               LISTEN      37870/consul        
tcp        0      0 192.168.190.107:8302    0.0.0.0:*               LISTEN      37870/consul        
tcp6       0      0 :::8500                 :::*                    LISTEN      37870/consul        
tcp6       0      0 :::8600                 :::*                    LISTEN      37870/consul  
# 8300:replication、leader farwarding的端口
# 8301:lan cossip的端口
# 8302:wan gossip的端口
# 8500:web ui界面的端口
# 8600:使用dns协议查看节点信息的端口

3.2 查看集群信息

① 查看members状态

[root@consul consul]# consul members
Node             Address               Status  Type    Build  Protocol  DC
consul-server01  192.168.190.107:8301  alive   server  0.9.2  2         dc1

② 查看集群状态

[root@consul consul]# consul operator raft list-peers # 获取Consul集群中Raft协议的节点列表
Node             ID                    Address               State   Voter  RaftProtocol
consul-server01  192.168.190.107:8300  192.168.190.107:8300  leader  true   2
[root@consul consul]# consul info | grep leader
	leader = true
	leader_addr = 192.168.190.107:8300

3.3 通过 http api 获取集群信息

[root@consul consul]# curl 127.0.0.1:8500/v1/status/peers
["192.168.190.107:8300"]
# 查看集群server成员
[root@consul consul]# curl 127.0.0.1:8500/v1/status/leader
"192.168.190.107:8300"
# 集群 server-leader
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/services
{"consul":[]}
# 注册的所有服务
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/nginx
# 查看 nginx 服务信息
[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/nodes
[{"ID":"f17caaee-ff27-b4e8-c592-afcdad3a2e47","Node":"consul-server01","Address":"192.168.190.107","Datacenter":"dc1","TaggedAddresses":{"lan":"192.168.190.107","wan":"192.168.190.107"},"Meta":{},"CreateIndex":5,"ModifyIndex":6}]
# 集群节点详细信息

4. registrator 服务器

4.1 安装 Gliderlabs/Registrato

Gliderlabs/Registrator 可检查容器运行状态自动注册,还可注销 docker 容器的服务到服务配置中心。目前支持 Consul、Etcd 和 SkyDNS2。运行一个 Registrator 容器,开启自动发现服务:

[root@registrator ~]# docker run -d \  # 运行Docker容器并将其设置为后台运行
> --name=registrator \                 # 指定名称为"registrator"
> --net=host \                         # 使用主机网络模式
> -v /var/run/docker.sock:/tmp/docker.sock \
# 将主机的Docker守护进程的Unix套接字映射到容器内的/tmp/docker.sock,这样Registrator容器就可以与 Docker守护进程通信
> --restart=always \               # 容器遇到错误或意外退出时自动重启
> gliderlabs/registrator:latest \  # 使用镜像gliderlabs/registrator来运行容器,:latest表示使用最新版本的镜像
> --ip=192.168.190.108 \           # 设置Registrator容器的IP地址为192.168.10.13
> consul://192.168.190.107:8500      # 192.168.190.107:8500是Consul的地址和端口

4.2 测试服务发现功能是否正常

[root@registrator ~]# docker run -itd -p:1080:80 --name nginx-01 -h nginx1 nginx
[root@registrator ~]# docker run -itd -p:1081:80 --name nginx-02 -h nginx2 nginx
[root@registrator ~]# docker run -itd -p:1082:80 --name apache-01 -h apache1 httpd
[root@registrator ~]# docker ps -a
CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                                   NAMES
3004e92d23e4   httpd                           "httpd-foreground"       8 seconds ago    Up 7 seconds    0.0.0.0:1082->80/tcp, :::1082->80/tcp   apache-01
108612e81495   nginx                           "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes    0.0.0.0:1081->80/tcp, :::1081->80/tcp   nginx-02
dfbfe87308ed   nginx                           "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes    0.0.0.0:1080->80/tcp, :::1080->80/tcp   nginx-01
53166bf2c442   gliderlabs/registrator:latest   "/bin/registrator --…"   23 minutes ago   Up 23 minutes                                           registrator
# 一个发现服务,两个容器服务

4.3 验证 http 和 nginx 服务是否注册到 consul 

[root@consul consul]# curl 127.0.0.1:8500/v1/catalog/services 
{"consul":[],"httpd":[],"nginx":[]}

5. consul-template 

Consul-Template是基于Consul的自动替换配置文件的应用。Consul-Template是一个守护进程,用于实时查询Consul集群信息,并更新文件系统上任意数量的指定模板,生成配置文件。更新完成以后,可以选择运行 shell 命令执行更新操作,重新加载 Nginx。

Consul-Template可以查询Consul中的服务目录、Key、Key-values 等。这种强大的抽象功能和查询语言模板可以使 Consul-Template 特别适合动态的创建配置文件。例如:创建Apache/Nginx Proxy Balancers 、 Haproxy Backends等。

5.1 准备 template nginx 模板文件

在consul服务器上操作:

[root@consul consul]# vim /opt/consul/nginx.ctmpl
upstream http_backend {
  {{range service "nginx"}}
   server {{.Address}}:{{.Port}};
   {{end}}
}
# 定义nginx upstream一个模板

server {
    listen 8000;
    server_name localhost 192.168.190.107;
    access_log /var/log/nginx/kgc.com-access.log;                                                       
    index index.html index.php;
    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Client-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://http_backend;
    }
}
# 定义一个server,监听8000端口,反向代理到upstream

5.2 安装配置 nginx 服务

在 consul 节点安装: 

[root@consul consul]# yum install -y epel-release.noarch
[root@consul consul]# yum install -y nginx
[root@consul consul]# vim /etc/nginx/nginx.conf
http {
    include             vhost/*.conf;  # 添加虚拟主机目录

创建虚拟主机目录:
[root@consul consul]# cd /etc/nginx/
[root@consul nginx]# mkdir vhost
启动nginx服务:
[root@consul nginx]# systemctl start nginx.service

5.3 配置并启动 template

在 consul 节点操作: 

[root@consul opt]# ls
consul-template_0.19.3_linux_amd64.zip # 准备安装包
[root@consul opt]# unzip consul-template_0.19.3_linux_amd64.zip
[root@consul opt]# mv consul-template /usr/local/bin/

在前台启动template服务,启动后不要按ctrl+c中止consul-template进程:
consul-template --consul-addr 192.168.190.107:8500 \
--template "/opt/consul/nginx.ctmpl:/etc/nginx/vhost/fqlnginx.conf:/usr/sbin/nginx -s reload" \
--log-level=info

另外打开一个终端查看生成配置文件:
[root@consul opt]# cd /etc/nginx/vhost/
[root@consul vhost]# ls
fqlnginx.conf
[root@consul vhost]# cat fqlnginx.conf 
upstream http_backend {
  
   server 192.168.190.108:1080;
   
   server 192.168.190.108:1081;
   
}

server {
    listen 8000;
    server_name localhost 192.168.190.107;
    access_log /var/log/nginx/kgc.com-access.log;
    index index.html index.php;
    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Client-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://http_backend;
    }
}

5.4 访问 template-nginx

在 registrator 节点操作: 

[root@registrator ~]# docker ps -a
CONTAINER ID   IMAGE                           COMMAND                  CREATED        STATUS        PORTS                                   NAMES
3004e92d23e4   httpd                           "httpd-foreground"       15 hours ago   Up 15 hours   0.0.0.0:1082->80/tcp, :::1082->80/tcp   apache-01
108612e81495   nginx                           "/docker-entrypoint.…"   15 hours ago   Up 15 hours   0.0.0.0:1081->80/tcp, :::1081->80/tcp   nginx-02
dfbfe87308ed   nginx                           "/docker-entrypoint.…"   15 hours ago   Up 15 hours   0.0.0.0:1080->80/tcp, :::1080->80/tcp   nginx-01
53166bf2c442   gliderlabs/registrator:latest   "/bin/registrator --…"   15 hours ago   Up 15 hours                                           registrator

[root@registrator ~]# docker exec -it nginx-01 /bin/bash
root@nginx1:/# echo "this is web1 nginx_01" > /usr/share/nginx/html/index.html 
root@nginx1:/# exit
[root@registrator ~]# docker exec -it nginx-02 /bin/bash
root@nginx2:/# echo "this is web2 nginx_02" > /usr/share/nginx/html/index.html
root@nginx2:/# exit

访问 192.168.190.107:8000/ 查看轮询结果:

[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02

5.5 增加一个 nginx 容器节点

① 增加一个 nginx 容器节点,测试服务发现及配置更新功能

[root@registrator ~]# docker run -itd -p:1083:80 --name nginx-03 -h nginx3 nginx
# 观察template服务,会从模板更新/usr/local/nginx/conf/vhost/kgc.conf文件内容,并且重载nginx服务

② 查看 cousul 节点 template 更新的配置文件内容

[root@consul vhost]# pwd
/etc/nginx/vhost
[root@consul vhost]# ls
fqlnginx.conf
[root@consul vhost]# cat fqlnginx.conf 
upstream http_backend {
  
   server 192.168.190.108:1080;
   
   server 192.168.190.108:1081;
   
   server 192.168.190.108:1083;  # 新增了一个nginx服务
   
}
……

③ 访问 192.168.190.107:8000/ 查看轮询结果

[root@registrator ~]# docker exec -it nginx-03 /bin/bash
root@nginx3:/# echo "this is web3 nginx_03" > /usr/share/nginx/html/index.html
root@nginx3:/# exit

[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
[root@registrator ~]# curl http://192.168.190.107:8000
this is web1 nginx_01

④ 停用 nginx-01 服务,查看 template 更新的配置文件内容,以及轮询结果

[root@registrator ~]# docker stop nginx-01
nginx-01
[root@registrator ~]# docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED         STATUS         PORTS                                   NAMES
a9814459efac   nginx                           "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   0.0.0.0:1083->80/tcp, :::1083->80/tcp   nginx-03
108612e81495   nginx                           "/docker-entrypoint.…"   15 hours ago    Up 9 minutes   0.0.0.0:1081->80/tcp, :::1081->80/tcp   nginx-02
53166bf2c442   gliderlabs/registrator:latest   "/bin/registrator --…"   15 hours ago    Up 9 minutes                                           registrator

[root@consul vhost]# cat fqlnginx.conf 
upstream http_backend {
  
   server 192.168.190.108:1081;
   
   server 192.168.190.108:1083;
   
}
……

[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03
[root@registrator ~]# curl http://192.168.190.107:8000
this is web2 nginx_02
[root@registrator ~]# curl http://192.168.190.107:8000
this is web3 nginx_03

6. consul 多节点

添加一台 docker 环境的服务器 192.168.190.106/24 加入已有的群集中,实际是为了扩展 consul 集群的规模和容量,以提高系统的可用性和可靠性。

6.1 安装 docker 

安装依赖包:
yum install -y yum-utils device-mapper-persistent-data lvm2 
设置阿里云镜像源:
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
安装最新版本:
yum install -y docker-ce docker-ce-cli containerd.io  

systemctl start docker.service
systemctl enable docker.service 

6.2 拷贝 consul 相关服务文件,启动 consul 服务

192.168.190.107:
[root@consul vhost]# scp /usr/local/bin/consul 192.168.190.106:/usr/local/bin/
192.168.190.106:
[root@ha02 ~]# consul agent \
> -server \
> -ui \
> -data-dir=/var/lib/consul-data \
> -bind=192.168.190.106 \           # 指定Consul agent监听的IP地址,用于节点间通信
> -client=0.0.0.0 \
> -node=consul-server02 \           # 指定当前节点的名称为"consul-server02"
> -enable-script-checks=true  \
> -datacenter=dc1  \                # 指定Consul集群所属的数据中心名称为"dc1"
> -join 192.168.190.107 &> /var/log/consul.log &
# 加入已知的Consul节点,这里指定加入IP地址为192.168.190.107的节点
[1] 3171

6.3 查看集群信息

查看members状态:
[root@ha02 ~]# consul members
Node             Address               Status  Type    Build  Protocol  DC
consul-server01  192.168.190.107:8301  alive   server  0.9.2  2         dc1
consul-server02  192.168.190.106:8301  alive   server  0.9.2  2         dc1
查看集群状态:
[root@ha02 ~]# consul operator raft list-peers
Node             ID                    Address               State     Voter  RaftProtocol
consul-server01  192.168.190.107:8300  192.168.190.107:8300  leader    true   2
consul-server02  192.168.190.106:8300  192.168.190.106:8300  follower  true   2
# 192.168.190.106状态为follower