kong组件_手把手教你搭建一个微服务架构:docker+consul+kong

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第1张图片

高能提醒,全文约3700字,系统搭建有难度,建议收藏后食用

写在前面

​ 微服务架构是一种云原生架构方法,在近年来逐渐为开发者所熟知。与其他架构相比,它具有以下几个显著的优点:

  1. 具有可扩展性:与单体应用相比,微服务架构在扩展新功能时无需对之前实现的功能做过多的调整,而只需增加新的微服务节点并关联已有的微服务节点即可。
  2. 技术栈灵活:容器技术使得团队可以为不同的组件使用不同的技术栈。
  3. 容错能力强:系统出现故障时,微服务应用只需对有问题的部分进行修正即可,而单体应用则会导致整个服务不可用。

废话不多说,开始搭建一个微服务架构吧!

搭建目标

  • 对服务使用者:请求相同的域名和不同的路径来区分不同主机上的服务,如:
用户服务: http:// ip :port/user/...
商品服务: http:// ip :port/goods/...
  • 对服务开发者:只需在给定的主机(容器)中完成开发即可
  • 对运维工程师:搭建本系统。系统架构图如下,各组件说明见下文:

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第2张图片

配置说明

搭建系统采用4台Vmware虚拟的Ubuntu Server18.04主机,均为1核+2G内存:

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第3张图片

docker相关知识

  1. Docker Network

Docker Network是一种虚拟网络,能够分离容器与真实外界网络的通信,有助于保护系统安全。Docker Network分类众多,本文使用的是Overlay网络,它是多个Docker主机之间的分布式网络,通常用于多主机通信,同一个Overlay网络中的所有节点都是可以相互通信的,却不能对外通信,如果需要的话应该让节点主动开放对外的端口

2. Docker Swarm

Docker Swarm是Docker内置的一种容器编排工具,它最实用的功能就是一条指令开启多个容器。在Swarm中,节点有ManagerNode两种角色,其中Manager负责容器调度,Node负责听从Manager指挥开启/关闭容器。

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第4张图片

3. Docker Registry

Docker Registry是Docker的一款开源项目,用于搭建一个私有的镜像服务器,配合Swarm能够方便各主机之间镜像的分发,同时也能保密系统内的代码。

consul与Registrator相关知识

  1. consul服务注册与发现

在单体应用中,应用间的调用通常都是硬编码在代码或配置文件中,而随着应用架构转向微服务,各服务的地址和端口都是动态变化的,因此我们需要一个统一的中心化组件来保存各应用实例的信息,称之为服务注册。同时,该中心化组件还应能够查询到各实例的信息,称之为服务发现。本文采用consul实现服务注册和服务发现,应用在启动时需要向consul发送HTTP请求进行服务注册,而调用服务方则需要在调用前通过DNS查询服务信息即服务发现。

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第5张图片

2. Registrator自动化服务注册与服务注销

Registrator是一款开源的自动化服务注册与服务注销工具,使得应用无需编写额外的代码进行服务注册,在应用下线时,也能自动完成服务注销。

kong相关知识

  1. 动态路由转发

kong是一款基于nginx的API网关,与nginx不同的是,kong可以查询DNS信息动态获取服务信息并将请求分发到正在活跃的服务节点上。

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第6张图片

2. 插件机制

除了路由转发功能外,插件化机制也为kong提供了强大的生命力,用户可以在kong的配置中加入用户鉴权、流量控制、日志收集等超实用的功能。

3. konga GUI管理界面

konga是一款开源的kong GUI管理界面,能够帮助运维人员轻松配置kong网关。

Docker环境搭建

Docker安装与镜像加速

  1. 安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

2. 配置Docker镜像加速器:在阿里云搜“容器镜像”,登录后进入控制台侧栏底部有个容器镜像加速。

Docker Swarm环境搭建

  1. 192.168.10.100主机中创建一个Swarm,该节点为Swarm Manager:
$ docker swarm init --advertise-addr 192.168.10.100
Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join 
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c 
    192.168.10.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Note:指令运行后的输出包含其他主机加入该Swarm的指令

2. 在192.168.10.101192.168.10.102192.168.10.103执行命令加入Swarm:

$ docker swarm join 
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c 
    192.168.10.100:2377

3. 在Swarm Manager中查看Swarm节点情况

docker node ls 

Docker Overlay Network搭建

  1. 192.168.10.100创建一个Overlay网络,网络名称为micro
docker network create -d overlay --attachable micro

2. 容器连接Overlay网络

在容器创建时加上--network=<网络名称>,如:

docker run -d --network=micro redis

Docker Registry搭建

  1. 192.168.10.101启动registry私有镜像服务器
docker run -d -p 5000:5000 registry 

2. 上传本地镜像到registry私有镜像服务器

docker image tag <本地镜像名称> 192.168.10.101:5000/<本地镜像名称>
docker push 192.168.10.101:5000/<本地镜像名称>
Note: docker image tag命令为本地镜像创建一个别名,当执行 docker push命令时,docker将自动读取该别名前的ip+port,并 将镜像上传到ip+port对应的镜像服务器中

3. 让我们来试着上传一个镜像吧

docker pull alpine
docker image tag alpine 192.168.10.101:5000/alpine-test
docker push 192.168.10.101:5000/alpine-test
Note:执行上述命令若出现 http: server gave HTTP response to HTTPS client这种错误信息,则在 /etc/docker/daemon.json中追加(若该文件不存在则创建一个同名文件): "insecure-registries" : [":5000"]
并使用 systemctl restart docker重启docker,强烈建议只在测试环境中使用该方法,生产环境中请使用CA证书,详情请见 https:// docs.docker.com/registr y/deploying/#run-an-externally-accessible-registry

4. 拉取registry私有镜像服务器中的镜像

docker pull 192.168.10.101:5000/<镜像名称> 

consul集群搭建

Docker启动分布式consul

  1. 192.168.10.100启动第一个consul实例
$ docker run -d -p 8500:8500 -p 8600:8600 -p 8600:8600/udp -p 8300:8300 -p 8301:8301 -p 8301:8301/udp -p 8302:8302 -p 8302:8302/udp consul agent -server -bootstrap -ui -client=0.0.0.0 -advertise=192.168.10.100

2. 在192.168.10.101192.168.10.102启动另外两个consul实例

(192.168.10.101)$ docker run -d -p 8500:8500 -p 8600:8600 -p 8600:8600/udp -p 8300:8300 -p 8301:8301 -p 8301:8301/udp -p 8302:8302 -p 8302:8302/udp consul agent -server -join=192.168.10.100 -client=0.0.0.0 -advertise=192.168.10.101
(192.168.10.102)$ docker run -d -p 8500:8500 -p 8600:8600 -p 8600:8600/udp -p 8300:8300 -p 8301:8301 -p 8301:8301/udp -p 8302:8302 -p 8302:8302/udp consul agent -server -join=192.168.10.100 -client=0.0.0.0 -advertise=192.168.10.102

3. 在浏览器中打开http://192.168.10.100:8500,进入如下页面,则consul集群搭建成功

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第7张图片

Docker Swarm启动Registrator

  1. 拉取gliderlabs/registrator镜像
docker pull gliderlabs/registrator

2. 在Swarm Manager上为所有Swarm主机上启动Registrator

docker service create --name=registrator --mount type=bind,src=/var/run/docker.sock,dst=/tmp/docker.sock --mode global --network=micro gliderlabs/registrator -deregister="always" -internal consul://192.168.10.100:8500
Note:以下是命令中相关参数的说明 --name设定该服务的名称是registrator --mount设定每个容器挂载主机的目录,这是Registrator启动所要求的 --mode设定global表示每个Swarm主机都要启动一个Registrator实例 --network设定该服务内所有实例都属于 micro这个Overlay网络 -deregister设定"always"表示服务下线时自动执行服务注销 -internal设定Registrator可以自动注册网络内部的实例,方便网络内实例互相调用 consul://192.168.10.100:8500指明了Consul的服务地址,写consul集群中其他实例的地址也可以

Kong服务网关搭建与管理

Docker启动Kong

  1. 192.168.10.103启动Kong依赖的数据库postgres
docker run -d --name kong-database 
               --network=micro 
               -p 5432:5432 
               -e "POSTGRES_USER=kong" 
               -e "POSTGRES_DB=kong" 
               -e "POSTGRES_PASSWORD=kong" 
               postgres:9.6

2. 在192.168.10.103查询postgres在Overlay网络中的地址

$ docker container inspect kong-database

...
"Networks": {
  "micro": {
    "IPAMConfig": {
      "IPv4Address": "10.0.2.174"  <-- 这个就是postgres在micro网络中的ip
  },
...

3. 在192.168.10.103初始化Kong的数据库

docker run --rm 
     --network=micro 
     -e "KONG_DATABASE=postgres" 
     -e "KONG_PG_HOST=kong-database" 
     -e "KONG_PG_USER=kong" 
     -e "KONG_PG_PASSWORD=kong" 
     -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" 
     kong:latest kong migrations bootstrap

4. 在192.168.10.103启动Kong

docker run -d --name kong
     --network=micro 
     -e "KONG_DATABASE=postgres" 
     -e "KONG_PG_HOST=10.0.2.174" 
     -e "KONG_PG_USER=kong" 
     -e "KONG_PG_PASSWORD=kong" 
     -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" 
     -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" 
     -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" 
     -e "KONG_PROXY_ERROR_LOG=/dev/stderr" 
     -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" 
     -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" 
     -e "KONG_DNS_RESOLVER=192.168.10.100:8600,192.168.10.101:8600,192.168.10.102:8600" 
     -e "KONG_DNS_ORDER=SRV,LAST,A,CNAME" 
     -p 8000:8000 
     -p 8443:8443 
     -p 8001:8001 
     -p 8444:8444 
     kong:latest
Note:以下是命令中需要配置的参数说明 KONG_PG_HOST是上一步中查询到的 postgres在Overlay网络中的地址 KONG_DNS_RESOLVER是DNS解析地址列表,本文中开启了三个consul服务,其DNS解析端口默认是8600

5. 测试一下Kong是否启动,若如下命令输出一大堆信息则表示启动成功

curl -i http://192.168.10.103:8001/

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第8张图片

Docker启动Konga

  1. 192.168.10.103启动Konga
docker run -d -p 1337:1337 --network micro pantsel/konga

2. 打开浏览器,进入Konga管理界面:http://192.168.10.103:1337

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第9张图片

至此,微服务基本架构就搭建完毕啦!

微服务部署示例

alpine-base服务镜像制作

alpine是一种超精简的Linux版本(镜像不到10MB),如果对内存要求比较苛刻的话就可以考虑用这款linux哦

  1. 制作一个可以连接ssh,开放端口是8000的web应用镜像,首先新建一个目录,并使用vim写一个Dockerfile:
# 指定创建的基础镜像
FROM alpine:latest

# 作者描述信息
MAINTAINER alpine_sshd_service

# 替换阿里云更新源、安装ssh、修改配置文件、生成key、同步时间、设置账号密码为root和admin
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories   
	&& apk update
    && apk add --no-cache openssh tzdata 
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
    && sed -i "s/#PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config 
    && ssh-keygen -t dsa -P "" -f /etc/ssh/ssh_host_dsa_key 
    && ssh-keygen -t rsa -P "" -f /etc/ssh/ssh_host_rsa_key  
    && ssh-keygen -t ecdsa -P "" -f /etc/ssh/ssh_host_ecdsa_key 
    && ssh-keygen -t ed25519 -P "" -f /etc/ssh/ssh_host_ed25519_key 
    && echo "root:admin" | chpasswd

# 开放22、8000端口
EXPOSE 22
EXPOSE 8000

# 容器启动时执行ssh启动命令
CMD ["/usr/sbin/sshd", "-D"]

2. 使用Dockerfile构建镜像

docker build -t alpine-base:v1 .

3. 运行alpine-base实例

docker run -d -P --name=base-srv --network=micro  alpine-base:v1
Note:这里使用 -P参数是将容器的开放端口随机映射到30000以上,这是为了不占用主机其他应用程序的端口,使用 docker container ls可以查看到容器的映射端口,这里的映射结果是 0.0.0.0:32771->22/tcp, 0.0.0.0:32770->8000/tcp

4. ssh连接容器实例
这里我们使用XShell连接容器,新建连接,填写IP、端口、账号密码等信息

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第10张图片

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第11张图片


开启连接进入容器

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第12张图片

5. 编写服务代码

本文使用Python的Tornado框架编写一个简单的web服务,在访问/index路径时返回"index"字符串

首先安装一下Python解释器和Tornado框架

apk add python3    
apk add py3-pip    
pip3 install tornado

编写main.py文件

import tornado.ioloop
import tornado.web
import tornado.log

class IndexHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write("index")

def make_app():
    return tornado.web.Application(
        handlers=[
            (r"/index", IndexHandler),
        ],
    )

if __name__ == "__main__":
    app = make_app()
    app.listen(8000)
    tornado.log.enable_pretty_logging()
    tornado.ioloop.IOLoop.current().start()

6. 生成首个镜像版本并上传Registor私有镜像仓库

docker commit base-srv tornado-srv:v1
docker tag tornado-srv:v1 192.168.10.101:5000/tornado-srv:v1
docker push 192.168.10.101:5000/tornado-srv:v1

Docker Swarm启动多服务实例

  1. 在制作并成功上传服务镜像后,我们可以在Swarm Manager启动服务集群
docker service create --name=tornado-srv --network=micro --replicas=3 192.168.10.101:5000/tornado-srv:v1 python3 /root/main.py
Note:以下是命令中相关参数的说明 --name设定服务名称为"tornado-srv" --network设定服务网络为“micro” --replicas设定服务有3个副本 192.168.10.101:5000/tornado-srv:v1是私有镜像名称 python3 /root/main.py是第一次启动容器实例时执行的命令,这里我们要启动web服务

2. 进入http://192.168.10.100:8500就能看到部署的实例,这里后缀指明了服务的端口,事实上这里我们只要使用8000端口就可以了,即tornado-srv-8000

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第13张图片

Kong路由配置

  1. 前文提到过通过http://192.168.10.103:1337进入Konga,事实上那是一个注册页面,填写相应信息就可以啦,接下来登录进入控制台页面,我这里的账号密码分别是“kong”和“kongkong”

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第14张图片

2. 进入konga控制台,首先需要连接Kong,需要填写Name和Kong Admin URL

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第15张图片

3. 连接成功后点击add service,填写相关信息

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第16张图片
Note:以下是信息中相关参数的说明 Name:服务的名称 Protocol:服务的协议,这里我们只有http Host:由于我们配置了DNS自动解析,因此这里我们只需要填写DNS解析域名即可,格式为 <服务在consul中的名称>.service.consul Port:服务的端口,这里设定容器的开放服务端口为8000

4. 为service添加route

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第17张图片
Note:以下是信息中相关参数的说明 Name:route的命名 Paths:route的路径,每个service可以有多个route

5. 使用Postman测试请求

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第18张图片

6. 最后,用一张图来总结这个配置过程:

kong组件_手把手教你搭建一个微服务架构:docker+consul+kong_第19张图片

参考文献

https://www.consul.io/docs

https://docs.docker.com/engine/swarm/

https://docs.docker.com/registry/

https://docs.konghq.com/getting-started-guide/2.1.x/overview/

后记

作者水平有限,若有缺失严谨性请轻喷。

在撰写本文时作者查阅了大量资料,劳动不易点个赞是支持作者的最好动力。

你可能感兴趣的:(kong组件)