咱们一块儿回顾上一篇文章《Bees平台的微服务架构(1)docker和docker-compose》,一共经过Dockerfile构建了三个docker镜像:mysql数据库,部署angular前端页面的nginx,和springboot接口。而后使用docker-compose来作容器服务的编排,以保障不一样容器之间能够互访。为了提升开发的效率,咱们还写了一个自动部署的脚本,实际是只是经过docker-compose.yml启动和关闭容器,在本地镜像库中生成或删除镜像。前端
不能否认,docker-compose服务编排的小巧灵活性让人爱不释手,那咱们今天为何要迁移到k8s(kubernetes)上呢?由于k8s的编排能力更强,由于k8s能够作跨主机的分布式集群,由于k8s搭载rancher将更有利于微服务架构的统一管理,等等。node
本文将不讲解k8s和rancher的安装和配置,相关的安装文档和配置文档网上有不少。最近阿里云产品春节大促销,我一时没忍住又买了一台服务器,打完折扣仍是很贵。心疼归心疼,不过这样我就有两台服务器了,就顺便搭建了k8s的集群环境。mysql
分布式集群带来的复杂度就增长了。你没办法直接使用本地的镜像库地址了,我不想搭建镜像仓库,好在阿里的docker镜像仓库是免费的,就将最终版的docker镜像推送到阿里的容器仓库里面。当须要启动容器时,容器的地址就写阿里容器仓库里的地址,后文中会出现。nginx
分布式的另外一个问题就是宿主机的挂载卷,若是对上一篇文章印象深入的话,应该记得mysql数据库的数据文件和nginx代理的图片文件等,都是挂载在宿主机上的。由于docker容器的特性,若是不使用挂载卷,在重启容器以后容器内的数据都会丢失。分布式环境中,不一样主机之间是没办法互访目录的。我是经过在一台机器上搭建了nfs服务器,将单台机器上的目录开放为共享目录,具体内容下文有介绍。git
不一样服务之间免不了要相互访问,例如:springboot要访问数据库和redis,angualr要调用springboot接口。并且考虑到k8s上常常要对某个服务作多节点的集群,因此要在注册中心开放给外界访问的地址应该是集群的地址。github
咱们在docker-compose上是怎么作的呢?在docker-compose.yml 上定义多个服务service,每一个service对应于一个镜像。容器启动后,对应容器的服务名称便可以做为 hostname来使用。redis
k8s上也有相似的用法,它使用yaml文件,kind类型有不少,例如:Pod表示启动的服务是一个pod;ReplicationController则会根据Pod模板生成一批pod做为集群;Service则至关于服务的注册,可给与之对应的pod副本集群提供访问地址,等等还有不少。那这个问题Service就能解决,咱们给不一样的服务都建立一个Service,这样就也能同docker-compose同样经过服务的名称就能访问与之对应服务的pod副本集群。spring
由于业务须要,在以前的三个镜像的基础上又加了一个redis镜像。那么分布式redis、分布式mysql环境搭建就太麻烦了,若是之后有机会再单独写文章来介绍,此次我干脆就只启动单节点的mysql和redis。sql
NFS是Network File System的简写,即网络文件系统,NFS是FreeBSD支持的文件系统中的一种。NFS基于RPC(Remote Procedure Call)远程过程调用实现,其容许一个系统在网络上与它人共享目录和文件。经过使用NFS,用户和程序就能够像访问本地文件同样访问远端系统上的文件。NFS是一个很是稳定的,可移植的网络文件系统。docker
选用nfs的另外一个缘由是,nfs服务在k8s上能够直接做为存储卷使用,十分方便。
nfs是基于rpc的,安装nfs就须要确保已安装rpcbind,不过通常CentOS都默认已安装了rpcbind
##查找是否已安装nfs 和 rpcbind [mpaas@kerry1 k8s]$ rpm -qa | grep nfs [mpaas@kerry1 k8s]$ rpm -qa | grep rpcbind ##若是没安装,则经过有yum安装 [mpaas@kerry1 k8s]$ yum -y install nfs-utils [mpaas@kerry1 k8s]$ yum -y install rpcbind
安装完成后,必需要先启动rpcbind服务,再启动nfs服务
[mpaas@kerry1 k8s]$ systemctl start rpcbind [mpaas@kerry1 k8s]$ systemctl start nfs-server
设置开机启动
[mpaas@kerry1 k8s]$ systemctl enable rpcbind [mpaas@kerry1 k8s]$ systemctl enable nfs-server
经过修改 /etc/exports 文件,设置nfs的共享目录
/home/nfs/bees/mysql/data *(rw,no_root_squash,no_all_squash,sync)
如上,将 /home/nfs/bees/mysql/data做为共享目录
星号* 表明可在任意服务器上访问该共享目录,也能够指定特色的ip和端口访问
括号内是参数设置,常见的参数则有:
rw ro 该目录分享的权限是可擦写 (read-write) 或只读 (read-only),但最终能不能读写,仍是与文件系统的 rwx 及身份有关。 sync async sync 表明数据会同步写入到内存与硬盘中,async 则表明数据会先暂存于内存当中,而非直接写入硬盘! no_root_squash root_squash 客户端使用 NFS 文件系统的帐号若为 root 时,系统该如何判断这个帐号的身份?预设的状况下,客户端 root 的身份会由 root_squash 的设定压缩成 nfsnobody, 如此对服务器的系统会较有保障。但若是你想要开放客户端使用 root 身份来操做服务器的文件系统,那么这里就得要开 no_root_squash 才行! all_squash 不论登入 NFS 的使用者身份为什么, 他的身份都会被压缩成为匿名用户,一般也就是 nobody(nfsnobody) 啦! anonuid anongid anon 意指 anonymous (匿名者) 前面关于 *_squash 提到的匿名用户的 UID 设定值,一般为 nobody(nfsnobody),可是你能够自行设定这个 UID 的值!固然,这个 UID 必须要存在于你的 /etc/passwd 当中! anonuid 指的是 UID 而 anongid 则是群组的 GID 啰。
编辑完 /etc/exports 文件后,执行下列命令生效
[mpaas@kerry1 k8s]$ exportfs -r
在服务器端,可执行下列命令查看目录是否共享成功
[mpaas@kerry1 k8s]$ showmount -e localhost Export list for localhost: /home/nfs/bees/mysql/data *
也能够在另一台机器上安装nfs后执行上述命令,只须要将localhost换成目标服务器的ip地址便可。
先启动nginx来部署angualr,咱们须要建立一个RC,根据模板建立pods,暂时只建立一个pod,后续若是须要扩展再在rancher上管理。
建立bees_angular_rc.yaml,开放pod的80端口
apiVersion: v1 kind: ReplicationController metadata: name: bees-angular spec: replicas: 1 selector: app: bees-angular template: metadata: labels: app: bees-angular spec: containers: - name: bees-angular image: registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-nginx:v1.0 ports: - containerPort: 80
建立bees_angualr_svc.yaml,设置nodePort,将pod的80端口映射给宿主机的30000端口
apiVersion: v1 kind: Service metadata: name: bees-angular spec: type: NodePort ports: - port: 80 nodePort: 30000 selector: app: bees-angular
那么执行下列命令便可建立rc和service,与之对应的pod也会运行起来
##启动rc [mpaas@kerry1 k8s]$ kubectl create -f bees-angular-rc.yaml ##启动service [mpaas@kerry1 k8s]$ kubectl create -f bees-angular-svc.yaml ##查看pod是否启动成功 [mpaas@kerry1 k8s]$ kubectl get pods
建立bees_mysql_rc.yaml,开放pod的3306端口,并将nfs服务器上的共享目录 /home/nfs/bees/mysql/data 挂载到容器中
apiVersion: v1 kind: ReplicationController metadata: name: bees-mysql spec: replicas: 1 selector: app: bees-mysql template: metadata: labels: app: bees-mysql spec: containers: - name: bees-mysql image: registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-mysql:v1.0 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: 数据库密码 volumeMounts: - name: mysql-data-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-data-persistent-storage nfs: path: /home/nfs/bees/mysql/data server: nfs服务器的ip
建立bees_mysql_svc.yaml
apiVersion: v1 kind: Service metadata: name: bees-mysql spec: type: NodePort ports: - port: 3306 nodePort: 30003 selector: app: bees-mysql
bees_springboot_rc.yaml
kind: ReplicationController metadata: name: bees-springboot spec: replicas: 1 selector: app: bees-springboot template: metadata: labels: app: bees-springboot spec: containers: - name: bees-springboot image: registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-springboot:v1.0 ports: - containerPort: 8010
bees_springboot_svc.yaml
apiVersion: v1 kind: Service metadata: name: bees-springboot spec: type: NodePort ports: - port: 8010 nodePort: 30004 selector: app: bees-springboot
都是一些基础的代码使用,这里就不过多写了。
#!/bin/bash echo "nginx版本:"$1 echo "springboot版本:"$2 v_springboot_jar=`find /bees/devops/upload/ -name "*.jar"` echo "找到jar:"$v_springboot_jar v_angular_zip=`find /bees/devops/upload/ -name "dist.zip"` echo "找到dist:"$v_angular_zip docker rmi -f $(docker images|grep "paperbee-nginx" | awk '{print $3}') docker rmi -f $(docker images|grep "paperbee-springboot" | awk '{print $3}') echo "删除原镜像" cd /bees/devops/dockerfiles/springboot-k8s/ rm -f *.jar cp $v_springboot_jar ./bees-0.0.1-SNAPSHOT.jar docker build -t paperbee-springboot . echo "生成springboot镜像" cd /bees/devops/dockerfiles/angular-k8s/ rm -rf dist/ cp $v_angular_zip ./dist.zip unzip dist.zip rm -f dist.zip docker build -t paperbee-nginx . echo "生成angular镜像" docker login --username=帐号 --password=密码 registry.cn-hangzhou.aliyuncs.com echo "登陆docker容器仓库" v_nginx_image=$(docker images|grep "paperbee-nginx" | awk '{print $3}') v_springboot_image=$(docker images|grep "paperbee-springboot" | awk '{print $3}') docker tag $v_nginx_image registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-nginx:$1 docker push registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-nginx:$1 echo "推送 bees-nginx:"$1 docker tag $v_springboot_image registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-springboot:$2 docker push registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-springboot:$2 echo "推送 bees-springboot:"$2