微服务应用使用容器部署非常方便,但是当应用服务注册自身地址(ip:port)到服务注册中心的时候,如果注册的是容器内的 ip,别的服务是无法访问到的。
解决这个问题,可以在运行容器的时候指定网络模式为 host (--net=host) ,这样就可以跳过 Docker 的独立网络栈,直接通过本机 IP 端口就可以访问,但是这样会大量占用本地端口。
最好的场景还是后端服务都在容器网络中,仅 API 网关暴露一个端口供外部访问,但是同时还后端服务还需要能实现跨机器的网络连通。
早期 Docker 本身的容器网络本身并不支持跨机器,也就是说明如果容器部署在不同的节点(服务器)上面,只能通过暴露端口到宿主机上,再通过宿主机之间进行通信。Docker 12.0 之后的版本自带 Docker Swarm,Docker Swarm 的 Overlay 网络驱动可以实现跨主机网络通信。Kubernetes 固然好,但是同时也非常重,学习成本也很大,Swarm 在小项目中还是有用武之地的。
dokcer swarm 集群搭建
准备两台安装有 docker 的机器:
192.168.0.1
192.168.0.2
192.168.0.1 创建 master 节点
# docker swarm init
# docker swarm join \
> --token SWMTKN-1-3uu3gjkdt6xgk06wd1c9gfog8xec99ga69ilcclyzyk181n5ki-6f7frw75gvpdwsl1yvpf885lw \
> 192.168.0.1:2377
This node joined a swarm as a worker.
复制上面的 docker swarm join ...
在 192.168.0.2 上执行,即将本机加入 swarm 集群。
至此,我们已经创建了一个最基础的 swarm 的集群,执行命令查看:
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
r76ighlnw0p2r0tbd9wmoqaep server2 Ready Active
rzqbzl58hlu89xoty4cedn0er * server1 Ready Active Leader
创建 overlay 网络
先创建一个可以跨机器的 overlay 网络
docker network create -d overlay my_net
部署应用服务
部署服务注册中心 consul
在服务器 192.168.0.1 中使用 Docker 简单部署一个使用。
docker run --name consul -d -p 8500:8500/tcp consul agent -server -ui -bootstrap-expect=1 -client=0.0.0.0
部署 API 网关
采用 micro 官方的 micro api,不了解 micro 的可以看我之前的博客,或者去 micro 官方仓库查看。
docker service create --replicas 4 --publish published=8898,target=8080 --name micro-p -e MICRO_REGISTRY=consul -e MICRO_REGISTRY_ADDRESS=192.168.0.1:8500 -e MICRO_API_HANDLER=http --network=my_net microhq/micro:latest api
部署后端服务
编写一个简单的 micro web 服务
package main
import (
"log"
"github.com/gin-gonic/gin"
"github.com/micro/go-micro/web"
)
type Say struct{}
func (s *Say) Anything(c *gin.Context) {
log.Print("Received Say.Anything API request")
c.JSON(200, map[string]string{
"message": "Hi, this is the Greeter API",
})
}
func main() {
// Create service
service := web.NewService(
web.Name("go.micro.api.greeter"),
)
service.Init()
// Create RESTful handler (using Gin)
say := new(Say)
router := gin.Default()
router.GET("/greeter", say.Anything)
// Register Handler
service.Handle("/", router)
// Run server
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
Dockerfile 如下:
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY hello-gin /hello-gin
ENTRYPOINT /hello-gin
LABEL Name=hello-gin Version=0.0.1
将 Docker build 出来推到自己的 Docker 仓库上,或者直接 pull 我的镜像。
部署服务
docker service create --replicas 2 --name hello-xx -e MICRO_REGISTRY=consul -e MICRO_REGISTRY_ADDRESS=192.168.0.1:8500 --network=xuxu_net xuxu123/hello-gin:v0.1.0
测试 demo
curl --request GET --url http://192.168.0.1:8080/greeter
总结
主要简单演练了一遍 Docker Swarm 集群部署以及微服务部署的一个简单场景部署。相较于 K8S 的强大功能,Swarm 似乎显得有些多余,但是 Swarm 的简单明了在小厂中未必有没有用武之地吧。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于