微服务架构实战:云服务环境与Docker部署工具

2022-10-28 16:41:20 浏览数 (1)

云服务环境与Docker部署工具

完成微服务的开发之后,必须为其提供-一个合 适的分布式环境进行最终的部署和发布,才能充分发挥微服务架构的优势。这个环境首先应该是安全可靠的,并且是可以进行任意扩展的分布式环境。其次,它的基础设施应该是配备齐全的,并且稳定可靠、可扩展。这些基础设施包括数据库管理系统、文件管理系统、消息服务系统等服务,以及自动化测试和持续交付等工具。

我们开发的每-一个微服务都可以进行任意多副本的发布,能够持续保持高性能的服务状态,所以微服务应用的基础服务设施和构建环境也必须具有可持续扩展的特性。

为了给微服务提供一个可伸缩的环境,我们必须组建或租用云服务。既可以组建私有云,也可以租用公有云,或者两者兼而有之。

虚拟机与基于Docker创建的容器

在Docker出现之前,为了充分利用服务器资源,我们使用VMware等技术来构建虚拟机。

那么,虚拟机与容器之间有什么不一样呢?有人对服务器、虚拟机和Docker这三者做了-一个很形象的比喻,可以用来说明它们的区别:

◎服务器好比运输码头: 拥有场地和各种设备(服务器硬件资源)。

◎虚拟机好比码头 上的仓库:拥有独立的空间堆放各种货物或集装箱。

◎Docker 好比集装箱:是各种货物的打包。

所以,使用Docker工具创建的容器可以存在于任何服务器或虚拟机中,它比虚拟机更加灵活、小巧,在处理一个服务的启动、关闭和更新等操作时更快、更便捷。

安全可靠的云服务环境

如图12-1所示是一个基于阿里云设计的安全云服务架构的网络拓扑图。从这个图中可以看出,任何外部对服务器的访问,包括运维管理人员的访问,都必须经过阿里云云盾和防火墙。

在此基础上,我们可以构建各种集群体系,包括微服务、网关、注册中心、Nginx. 各种基础资源和各种基础设施等。

当然,我们也可以自己组建服务器,建立私有云,来搭建这些环境和基础设施。但是,从成本和便利性等综合条件考虑,建议还是选择云服务供应商提供的服务。

Docker 和docker-compose的下载与配置

Docker是一个优秀的容器引擎,通过它可以为应用系统创建一一个可移植的容器。容器运行于宿主系统上,其功能相当于一个虚拟主机。但是与虚拟主机相比,Docker 的性能更好。Docker占用资源少,构建非常灵活、方便,且可以非常快速地启动和关闭。

正因为如此,对于整个电商平台的微服务应用来说,我们都将使用Docker进行部署和发布。

在我们开发的微服务中,已经自包含了Tomcat中间件和打包后的Jar文件,可以使用如下所示的Java命令直接运行:

代码语言:javascript复制
Java -jar *.jar

由此可见,使用Docker部署微服务是非常简便的,只需使用类似于上面所示的命令就可以在Docker中运行Jar包。

另外,使用Docker部署微服务还可以利用更多的服务器资源,设置简单、操作方便。而服务的更新和运行,将更加快速和高效。

下面介绍Docker及其工具的安装,以及Docker的使用方法,以帮助读者加深对Docker 的认识和理解。

Docker 引擎的安装及使用

在Linux环境中安装Docker,可以按以下步骤进行。需要注意的是,Docker需要在Linux7.0或以上的版本中才能运行。下面的安装配置以CentOS 7.0为例。

首先,使用下列命令更新安装环境:

代码语言:javascript复制
# yum update

然后,编辑下列命令,配置Docker的安装源:

代码语言:javascript复制
# tee /etc/yum. repos .d/docker.repo <<-' EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum . dockerproject .org/ repo/main/centos/7/
gpgcheck=1
gpgkey=https://yum. dockerproject.org/gpg
EOF

最后,使用下列命令开始安装:

代码语言:javascript复制
#yum install docker-engine

安装需要一定的时间, 并且会通过网络下载一些安装文件。

安装完成后可以使用下列命令启动Docker:

代码语言:javascript复制
service docker start

使用下列命令检查版本:

代码语言:javascript复制
# docker --version

使用下列命令查看详细的版本信息:

代码语言:javascript复制
# docker version

使用”下列命令可以将Docker设置为开机启动:

代码语言:javascript复制
# systemctl enable docker

更多有关Docker的信息,读者可以到其官方网站查看。

docker-compose 的下载及配置

docker-compose是一个通 过编排脚本来使用Docker引擎的工具组件,这一工具组件使得我们不必记住那么多的命令和配置参数,即可更加方便和快速地进行应用的部署和更新。

使用下列命令可以将已经编译的docker- compose下载到本地系统中:

代码语言:javascript复制
curl -L https://github.com/ docker/compose/ releases/download/1.16.0-rc2/
docker-compose- uname -s'-'uname -m > /usr/local/bin/docker-compose

其中,“1.16.0-rc2” 为版本号,可以先从GitHub上查看docker-compose的最新版本,然后更改.上面命令中的版本号,即可下载最新的版本。

下载完成后执行下列命令,更改docker-compose的执行权限:

代码语言:javascript复制
chmod  x /usr/ local/bin/docker-compose

使用下列命令查看docker compose的版本号:

代码语言:javascript复制
docker-compose version

执行下列命令可以输出docker -compose的完整帮助信息:

代码语言:javascript复制
# docker-compose -h

对于docker-compose,我们常用的命令有build、up、ps、 start、 stop、 down 和logs等。如果要发布一个微服务,则只需使用一个up命令就足够了。

另外,还可以使用help命令查看每一-个命令的详细帮助信息。例如,可以使用下列命令查看down命令的使用说明:

代码语言:javascript复制
docker -compose help down

使用Docker方式发布微服务

在使用Docker运行一个服务时,首先必须创建这个服务的镜像,然后使用这个镜像创建容器并运行服务。在同一主机中,一个镜像可以创建多个容器副本,所以在-一个主机中,也可以为所部署的服务做有限度的扩展部署。

镜像创建 及其生成脚本

在创建镜像时,我们需要一个生成脚本, 然后将脚本文件与Jar 包- -起上传到服务器的特定目录中,这样就可以用来生成应用的镜像了。创建镜像的脚本有一个固定的名字: Dockerfile。

一般来说,脚本内容如下所示:

代码语言:javascript复制
FROM java:8
VOLUME / tmp
ADD demo-1 .0-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
RUN /bin/cp /usr/share/ zoneinfo/Asia/Shanghai /etc/1ocaltime 
&& echo ,Asia/Shanghai' >/etc/ timezone
EXPOSE 8080
ENTRYPOINT
I ["java", "-Djava. security. egd=file:/dev/ ./urandom" , "-jar" ,"/app.jar"]

这个脚本表示,引用Java 8镜像将项目的Jar包生成- -个由 JDK 1.8 支撑的镜像。其中,EXPOSE指定了运行服务时设定的端口号,并且设定了Shanghai时区,目的是在容器运行时,其输出的日志能够显示正确的时间。

对于我们所开发的微服务应用来说,都可以参照这个脚本创建镜像,只需修改相关的发布包文件名和端口号即可。

服务的发布 与更新

在部署服务时,可以创建- -个目录(例如demo)来放置上传的Dockerfile和打包文件,然后在其上一层目录中再创建一一个 docker-compose.yml文件,并使用这一文件编排部署脚本。对于这个例子来说,可以编排如下所示的脚本:

代码语言:javascript复制
demo:
build: . /demo
ports:
"8080:8080"

然后,使用docker-compose的up命令部署应用,代码如下所示:

代码语言:javascript复制
docker -compose up -d

这个命令已经包含了镜像的创建、容器的生成和启动等一系列操作。其中,参数-d 表示在后台中运行。

使用下列命令查看运行的容器:

代码语言:javascript复制
docker-compose ps

使用下列命令查看容器的输出日志:

代码语言:javascript复制
docker logs容器ID或名称

当需要删除已经部署的容器和已经创建的镜像时,只需使用一个down命令即可完成所有

的操作,代码如下所示:

代码语言:javascript复制
docker-compose down --rmi all

运行这个命令将停止由编排脚本管理的所有容器,同时还将刪除相关的容器和镜像。

从上面的演示可以看出,使用docker-compose来部署一一个应用是非常 方便的,我们只需使用一个简单的命令就可以完成所有操作。

使用 Docker部署日志分析平台

我们可以使用一个统一的 日志分析平台管理微服务应用生成的日志,这将给8志的查询和使用提供极大的方便。

日志分析平台ELK由三个服务组成,分别是Elasticsearch、Logstash 和Kibana。其中:

◎Elasticsearch 是- -个分布式搜索分析引擎,负责日志存储并提供搜索功能。

◎Logstash 是一个开源数据处理管道,能提供数据收集、加工和传输管道的服务,负责日志收集。

◎Kibana是一个数据可视化平台,可以将数据分析结果转化为图表等形式,即提供了Web查询的操作界面。

因为日志分析平台ELK中的三个服务都是开源的,并且已经发布到公域的镜像仓库中,所以我们可以使用docker- compose工具编写脚本进行部署和安装。

首先,在服务器上创建-一个目录,代码如下所示:

代码语言:javascript复制
mkdir /logstash

进入这个目录之后,使用如下命令创建-一个配置 文件:

代码语言:javascript复制
vi logstash. conf

文件的内容如下所示: .

代码语言:javascript复制
input
top {
port => 5000
codec => j son
udp
port => 5000
codec => json 
| output
elasticsearch { hosts => [ "elasticsearch:9200" ] }
}

其次,使用如下命令创建一-个编排脚本文件:

代码语言:javascript复制
vi docker-compose. ym1

在文件中编写如下所示内容:

代码语言:javascript复制
logstash:
image: logstash:5.4.0
volumes:
一./logstash. conf: /etc/logstash. conf
ports:
一"5000: 5000/tcp"
"5000: 5000/udp"
links:
一elasticsearch
command:
-f /etc/logstash. conf
elasticsearch:
image: elasticsearch:5.4.0
kibana:
image: kibana:5.4.0
links:
一elasticsearch
ports:
一"5601 :5601"

其中,三个服务的版本号必须统一 。最后,使用如下命令启动服务:

代码语言:javascript复制
docker-compose up -d

第一次启动时需要一定 的时间,因为需要从镜像仓库中拉取相关的镜像。

在启动成功之后,就可以使用日志分析平台了。即可以使用docker-compose中的start. stop .等命令执行平台的启动或关闭等操作。

在应用工程中,想要使用日志分析平台的日志收集功能,就必须通过日志配置文件logback.xml进行配置。一个完整的日志配置文件中的内容如下所示:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_ HOME" value="/logs" />
<appender name="STDOUT" class="ch. qos. logback . core. ConsoleAppender">
<encoder charset="UTF-8">
<pattern>d{yyYy-MM-dd HH:mm:ss .SsS} [&thread] %-51evel &1ogger{50}
8msg&n</pattern>
</encoder>
</appender>
<appender name="stash" class="net.logstash. logback. appender.
LogstashTepSocketAppender">
<destination>10. 10.10.32: 5000</destination>
<encoder charset= "UTF-8"
class="net . logstash. logback. encoder . LogstashEncoder" />
</ appender>
<appender name="async" class="ch. qos. logback.classic.AsyncAppender">
<appender-ref ref="stash" />
</ appender>
show parameters for hibernate sql 专为Hibernate 定制-->
<logger name="org . hibernate. type . descriptor . sql. BasicBinder"
level="TRACE" />
<logger name="org . hibernate. type . descriptor .sq1. BasicExtractor" 
| level="DEBUG" />
<logger name="org . hibernate .SQL" level="DEBUG" />
<logger name="org . hibernate . engine . QueryParameters" level="DEBUG" />
<logger name="org . hibernate.engine. query . HQLQueryPlan" level="DEBUG" />
<!--设置日志级别-->
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="stash" />
</ root>
</configuration>

其中,通过“10.10.10.325000”设置了日志收集平台的服务器IP地址和端口号,读者可以

根据实际情况进行更改。

基于Docker的高级部署工具.

我们可以在使用Docker引擎的基础上,使用更加高级的工具来管理,现在比较流行的工具有Docker Swarm和Kubernetes等。

私域镜像仓库

为了更好地配合高级工具的应用部署,应该创建-一个私有的镜像仓库,将需要部署的镜像存放在镜像仓库中,这样在后面需要使用部署工具时,就可以从镜像仓库直接拉取镜像了。

假设私域镜像域名为imags.demo.net, 并且在镜像仓库中创建了一个项目test,还为这个项

目指定了相关用户及其读写权限,即可使用如下命令登录镜像仓库:

代码语言:javascript复制
docker login imags. demo.net

根据提示,输入镜像仓库分配的用户名和密码。

这样,我们就可以上传Jar包和Dockerfile文件,然后在当前目录中使用下列命令来创建镜像了:

代码语言:javascript复制
docker build一七imags. demo. net/test/example:1.0.0

在这个命令中,我们指定了镜像的名字和版本号,如果创建成功,则可以看到类似于如下所示的输出信息:

代码语言:javascript复制
Successfully built 24d82a696eef
Successfully tagged imags . demo .net/test/example:1.0.0

镜像创建成功之后,即可使用如下命令将生成的本地镜像推送到镜像仓库:

代码语言:javascript复制
docker push imags. demo.net/test/example:1.0.0

如果操作成功,则可以看到如下所示的输出信息:

代码语言:javascript复制
The push refers to repository [imags. demo. net/test/example]
dd6bb0471434: Pushed
f07ed18457b0: Pushed
3929c58ac07b: Pushed
1.0.0: digest:
sha256: 4c51a34a68054524ecd31b724047c232802c7c85334499d0b7119abcf329a634 size:
2631

当把需要发布的镜像都创建成功之后,就可以使用更加高级的工具直接从镜像仓库中拉取镜像,来创建各种服务了。

Docker Swarm

Docker Swarm是Docker官方提供的一款 Docker集群管理工具,它的架构如图12-2所示。

Docker Swarm可以通过集群方式管理多个安装有Docker引擎的主机。在Docker Swarm中,是通过管理节点SwarmManager来管理集群中的所有工作节点SwarmNode的。应用部署必须在管理节点上进行,管理节点提供了集群中Docker主机的调度和服务发现等功能。

基于12.6.1 节创建的镜像,我们可以创建一一个脚本 文件example.yml,在Docker Swarm环境中发布服务,脚本内容如下所示:

代码语言:javascript复制
version: ' 3
services:
example-app:
image: imags . demo . net/test/example:1.0.0
deploy:
replicas: 2
#定义replicated 模式服务的副本数量
update_ config:
parallelism: 1
#每次更新副本数量
delay: 2s
#每次更新间隔
restart_ policy:
condition: on- failure
#定义服务的重启条件
networks:
金core
ports:
- "8080"
networks:
core:
external: true

使用如下命令发布服务:

代码语言:javascript复制
docker stack up -C example. yml --with-registry-auth example-app

使用如下命令查看服务:

代码语言:javascript复制
docker stack ps example-app
docker service list

Kubernetes

Kubernetes (简称k8s) ,是Google开源的运维管理平台,是-一个容器集群管理系统,可以非常便捷地实现容器集群的自动化部署和自动化扩容、缩容等功能。使用k8s可以最大限度地简化应用部署和管理的诸多操作,让复杂的应用运维管理工作变得简单、容易。

k8s被业界誉为下一代分布式架构的王者,在服务平台的构建中,它提供了极好的性能优势,以及高度的稳定性和可靠性。

使用k8s,不仅能快速地部署应用、快速地扩展应用、无缝对接新的应用,并且能够节省服务器等硬件资源,优化资源的配滚动鼠樣轴或单击,开始截长图k8s的特点如下:

◎可移植性:支持各种云端服务器和各种分布式服务器架构。

◎可扩展性:支持模块化、插件化,并且拥有可挂载、可组 合等功能。

自动化:可进行自动部署、自动重启、自动复制、自动伸缩和扩展管理。

为了更加深入地理解Kubernetes,下 面介绍几个核心概念。

1. Master

Master是Kubermetes集群的管理节点,负责管理集群,提供集群的资源访问入口,拥有Etcd存储服务,可运行API Server 进程、Controller Manager服务进程和Scheduler调度服务进程等,并且还能起到关联工作节点(Node) 的作用。

2. Node

Node是Kubermetes集群架构中运行Pod的服务节点(是一个物理主机)。Node 是Kubernetes集群操作的单元,用来承载被分配Pod的运行,是Pod运行的宿主主机。

3. Pod

Pod是运行于Node节点上的若干相关容器的组合。Pod 内包含的容器运行在同一-宿主主机上,使用相同的网络命名空间和IP地址,共享端口资源,能够通过localhost 进行通信。Pod 是Kurbernetes进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。

4. Replication Controller

Replication Controller 是用来管理Pod的副本,保证集群中存在指定数量的Pod副本。

Replication Controller是实现弹性伸缩、动态扩容和滚动升级的核心。

5. Service

Service定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了一个统-的服务访问入口,以及服务代理和发现机制,关联多个相同Label的Pod。

6. Label

Kubernetes中的任意API对象都是通过Label 进行标识的,Label 的本质是一系列的Key/Value (键值)对,其中key和value由用户自己指定。

图12-3是Kubernetes的架构图,从这个图中可以看出Kubemetes主要由以下几个核心组件组成:

◎ etcd保存了整个集群的状态。

◎kube-apiserver提供了资源操作的唯一 入口,并提供认证、授权、访问控制、API注册和发现等机制。

◎ controller-manager负责维护集群的状态,比如故障检测、自动扩展和滚动更新等。

◎kube-schedule 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上。

◎kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理。

◎proxy 负责为service-controller提供Cluster内部的服务发现和负载均衡。

为了更加形象地认识Kubernetes,下面我们用一个简单的实例说明Kubernetes的使用方法。

Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative) 方法,用来替代以前的Replication Controller,以更加方便的方式管理应用。典型的应用场景包括:

◎定义 Deployment来创建Pod和ReplicaSet。

◎滚动升级和回滚应用。

◎扩容和缩容。

◎暂停和继续 Deployment。

创建一个基 于Deployment的编排脚本nginx- test.yml,内容如下所示:

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
I metadata :
name: nginx
spec:
replicas: 1
selector :
matchLabels:
app: nginx
template :
metadata:
labels:
app: nginx
spec:
containers :
name: nginx
image: nginx:1.16.1
ports :
- containerPort: 8060

这是只有一个实例的Nginx服务,它使用公共镜像nginx:1.16.1,容器的名字为nginx。

使用如下命令发布服务:

代码语言:javascript复制
kubectl create一f nginx-test. yml

使用如下命令查看发布的状态:

代码语言:javascript复制
kubectl get deployments

或者使用如下命令查看Pod:.

代码语言:javascript复制
kubectl get pods

对于已经发布的服务,可以使用如下命令进行扩容:

代码语言:javascript复制
kubectl scale deployment nginx --replicas

如果集群支持horizontal pod autoscaling,则可以为Deployment设置自动扩容,即实现自动弹性伸缩控制:

代码语言:javascript复制
kubectl autoscale deployment nginx --min=2 --max=8 --cpu-percent=80

更新镜像也比较简单:

代码语言:javascript复制
kubectl set image deployment/nginx nginx = nginx:1.16.2

或者对已经部署的服务进行回滚:

代码语言:javascript复制
kubectl rollout undo deployment/nginx

更多有关Kubernetes的信息,读者可直接访问官网查看。

上面的这些操作过程全部可以在控制台中通过操作界面来完成。

需要说明的是,DockerSwarm和Kubernetes都有服务发现功能,当我们发布微服务应用时,是使用这些管理工具的服务发现功能,还是使用Consul的服务注册与发现功能呢?这里建议读者使用Consul的服务注册与发现功能,理由是:

(1) Consul 是一个专业的服务注册与发现管理工具,并且融合了远程配置管理功能。

(2)使用Consul的服务注册与发现功能,能够与开发环境的开发和调试保持一致, 这样将更方便于问题的跟踪或者故障的分析处理。

(3) Consul能够使用Kubernetes进行集群发布和管理。

小结

本文介绍了微服务应用发布环境的组建,以及基于Docker管理工具的应用部署的管理方法。从云服务环境的组建和应用部署的方法来看,我们可以有很多选择,前提是必须保证微服务运行环境的安全可靠性,然后再根据系统平台的规模选择一一种切合实际的部署工具。一般来说,对于一个小型系统,使用docker-compose工具就可以了;如果是一个大型系统平台,则建议使用Kubernetes管理工具。

本文给大家讲解的内容是微服务架构实战:云服务环境与Docker部署工具

  1. 下篇文章给大家讲解的是微服务架构实战:可扩展分布式数据库集群的搭建;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

0 人点赞