目标

在UK8S里部署一个三副本ZooKeeper集群,向集群中的dubbo客户端提供注册服务。同时在K8s里部署一个demoService,三个Provider实例,再通过测试consumer对provider进行测试。为了展示结果方便,再额外部署一个DubboAdmin用于展示相应的部署成果。( 福利预告: 三个月的UK8S集群免费用)

ff21180f26db3e7018c12c2ff1435c09.png

操作步骤

Zookeeper部署

ZooKeeper的部署其实是比较坑爹的。我选择的方法是使用DockerHub的DockerHub官方的 ZooKeeper 镜象作为基础来进行安装。(这句话本身就很绕,对不对?意思是这镜像是Docker Hub做的,而不是Zookeeper做的。)在K8S的官方教程里,其实也有一段是讲使用StatefulSet来部署ZooKeeper的,但这个镜象在墙外,而且相关的脚本是进行二次封装的,并不是ZooKeeper本身提供的。因此,我选择了DockerHub的镜象。但这是我一整天痛苦部署、改代码、改配置、调整部署的开始。

其实我一开始是秉承了一贯的迁移上K8S的套路的,先把Docker镜象先在虚拟机跑一下,然后把配置文件的位置和内容找出来,再通过K8S的 ConfigMap来注入配置文件。万万没想到,在ZooKeeper这个镜象里有点失灵了。

那么,原因何在呢?

在UK8S上使用Zookeeper时,一开始总也无法成功的启动。后来仔细的查了一下Docker Hub ZooKeeper镜像的源代码和Zookeeper的说明,其实关键的点(KEN)有以下几点:

  1. 创建POD和容器启动时,每次都按环境变量会重新生成/conf/zoo.cfg文件。即配置实际是上传入容器的环境变量决定的,而不是由配置文件。

  2.  启动文件会检查/data/myid文件是否存在,如果不存在,则从环境变量的ZOO_MY_ID环境变量生成myid文件。如果我们在K8S里使用PVC的话,StatefulSet删除重创的话,PVC是不会重创的,也就是说/data目录一直在。所以如果我们要改变myid文件的话,必须想办法删除相关的内容 。如果在创建过程中出现错误,则应该删除相应的PVC。

  3.  /data/myid文件是一个非常非常非常重要的文件,这个文件只有一行,而且只有一个1-255的数字。Zookeeper会拿这个ID和zoo.cfg的中server对比,找到本服务器对的IP地址等信息。如果不匹配的话,就会产生错误 。

  4.  在2、3项交叉出错时,其实很难定位问题所在。最后还是要去研究相应的官方镜象的docker源以及加入的shell文件内容。同时还要结合K8S里的相关的概念才能真正分析,定位问题。

最后我的解决方案就比较粗暴,方案如下:

1. 在镜象中增加脚本 并改写了官方镜象中生成/data/myid的代码。由于K8S里使用StatefulSet部署,主机名的命名规则是{StatefulSetName}-Index, 其中Index 是0开始的序号。但Zookeeper要求server id为1-255之间的数字,我这里直接截取了主机名的Index部分,然后加1后存入/data/myid 文件

2. 在StatefulSet Yaml文件中用环境变量设置集群信息

Stroage Class 准备

在上面的配置里,zookeeper是把数据存到了/data和/datalog下,必须把/data目录放到PVC上才行。UK8S提供了原生的存贮支持,我们使用相应的storage class实现就好。所以要增加相应的 StorageClass以及相应的 PVC。UK8Ss可以直接使用UDisk作为存贮。如果大家是用自建K8S或者其他云厂商的K8S,也要对应修改StorageClass。
kind: StorageClassapiVersion: storage.k8s.io/v1metadata:  name: zk-storage-class  namespace: zkprovisioner: udisk.csi.ucloud.cnparameters:  type: "ssd"  fsType: "ext4"  udataArkMode: "no"reclaimPolicy: RetainvolumeBindingMode: WaitForFirstConsumer

Zookeeper StatefulSet

请在公众号后台留言后获取。

Dubboer Provider

ZooKeeper完成后,再部署其他的DubboProvider/DubboAdmin/Dubbo Consumer就基本上没有什么坑了。只需要注意相应的配置文件内容别写错就好。

然后我们把Dubbo 官方提供的provider和consumer的demo版本打成Docker镜像,放到k8s里。

注:master可能会失败,可以用 dubbo-2.7.4.1的tag进行编译,通过

这样我们有一个jar包可以运行了,但是这个demo指定了zookeeper服务器为本地,且dubbo的配置文件也已经打进了jar包里。

我们来看一下代码,实际非常的简单,为了适配K8S,我们从指定的位置读取配置文件,例如 我这里改成了 dubbo-provider.xml。这样我们可以很方便的通过ConfigMap来配置Dubbo了。

import org.springframework.context.support.FileSystemXmlApplicationContext;public class Application{  public static void main(String[]args)throwsException{    //ClassPathXmlApplicationContextcontext=newClassPathXmlApplicationContext("spring/dubbo-provider.xml");    FileSystemXmlApplicationContextcontext=newFileSystemXmlApplicationContext(" conf/dubbo-provider.xml");    context.start();    System.in.read();  }}

第二步准备DockerFile,打成镜像放到并推送到Uhub上,我们直接通过命令行测试一下。这里启动成功,但是因为Docker缺省用的网络是用的Docker容器里的IP,这个IP Zookeeper是访问不到的,所以一定会失败。
找了一下网上的说明,应该是需要进行这个配置,同时要去改一下dubbo的源代码处理异常,才会用Docker宿主机的IP进行注册。(参考 :https://my.oschina.net/ditan/blog/646863)第三步,就是通过ConfigMap将相应的配置文件注入Zookeeper服务器地址。根据Dubbo 的文档,其实还有若干种不同的方式,例如直接通过命令行注入,然后在由yaml 文件配置环境变量,通过环境变量控制命令行的方式,这样可以使Dubbo的环境配置和接口配置分开。但我这里由于篇幅关系,还是直接使用的配置文件注入配置的方式。

 Yaml请在公众号后台留言后获取。

然后准备相应k8s pod Yaml文件,为了方便测试,我都用了deployment的方式来准备provider,这里,我起了三个provider这里的关键点:Dubbo 的service 是通过20880端口直接对外暴露的,和web端口无关。如果大家在Tomcat里同时又作为Dubbo的provider,那么一定是暴露不同的端口的。另外还有一个配置的qos端口,也需要一并对外暴露。

Yaml请在公众号后台留言后获取。

部署Dubbo Admin

关于Dubbo Admin项目有两个发布的版本,最新的是2019年4月的0.2.0版本,似乎也不是很新。但可以拿来先试试效果,总比没有好。

maven需要用3.2.3以上版本,CentOS用yum安装的版本又老了,手工升版本。

DockerFile 

FROM uhub.service.ucloud.cn/hello/maven:3-jdk-8-alpineWORKDIR /usr/src/appCOPY dubbo-admin-server/target/dubbo-admin-server-0.1.jar /usr/src/app#COPY application.properties /etc/appconfig/application.propertiesENV PORT 9999EXPOSE $PORTCMD [ "sh", "-c", "java -Dserver.port=9999 -jar /usr/src/app/dubbo-admin-server-0.1.jar  --spring.config.location=/etc/appconfig/application.properties" ]

配置文件老规矩,用ConfigMap

apiVersion: v1kind: ConfigMapmetadata:  name: dubbo-admin-config  namespace: zk  labels:    kubernetes.io/cluster-service: "true"    addonmanager.kubernetes.io/mode: EnsureExistsdata:  application.properties: |    admin.registry.address=zookeeper://zk-0.zk-hs.zk.svc.cluster.local:2181,zk-1.zk-hs.zk.svc.cluster.local:2181,zk-2.zk.zk-hs.svc.cluster.local:2181    admin.config-center=zookeeper://zk-0.zk-hs.zk.svc.cluster.local:2181,zk-1.zk-hs.zk.svc.cluster.local:2181,zk-2.zk-hs.zk.svc.cluster.local:2181    admin.metadata-report.address=zookeeper://zk-0.zk-hs.zk.svc.cluster.local:2181,zk-1.zk-hs.zk.svc.cluster.local:2181,zk-2.zk-hs.zk.svc.cluster.local:2181    #group    admin.registry.group=dubbo    admin.config-center.group=dubbo    admin.metadata-report.group=dubbo    admin.apollo.token=e16e5cd903fd0c97a116c873b448544b9d086de9    admin.apollo.appId=test    admin.apollo.env=dev    admin.apollo.cluster=default    admin.apollo.namespace=dubbo

POD文件

Yaml请在公众号后台留言后获取。

跑起来之后,看下各个POD的状态

60d7d54c3ec222569ee25410a74d9ec5.png

看一下界面,感觉 还是很清爽的,这里可以看到上一步部署的三个Provider

98febe1b399582a0a1544d70adf5b6ec.png

最后,我们使用consumer来看一下效果。本着一切从简的原则,我的consumer直接采用了改xml设置zookeeper,在命令行下运行的方式。(大家正式应用的时候,consumer一定是打个某个对外的服务里,这个光荣而坚巨的任务就交给好事的大家了。如果要在DubboAdmin里见到你的Consumer,需要在原代码上做点手脚,否则界面还没刷完,Consumer就已经执行完成退出了,永远也见不到。

32e705726a2879ec6cf0f2171535f993.png

最后是福利时间,点击原文,完成答题即可获得3个月的免费试用。

fb9e526ecbfcd5f4df2cd1e97401a740.png

精彩回顾

敏捷专场PPT学习笔记-PMI 2019大会PPT学习(一)

PMO专场PPT学习笔记-PMI 2019大会PPT学习(二)

行业实战一PPT学习笔记-PMI 2019大会PPT学习(三)

PMI 2019 上海项目管理大会志愿者风采

《捭阖第一》-2 同气相求,与啵啵一起学《鬼谷子》 之四

项目经理必须掌握的财务基础之三

OKR与项目计划

用GitLab Runner + K8S实现GitFlow CI/CD全流程

在K8S里用JMeter进行性能测试

怼一下GitFlow吧

IT人员画像 - PM私董会201906次公益场会后知识点回顾

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐