第1次实践作业
一、课程调查
课程名称给我的第一印象是,这是一门偏向硬件的课程,需要将所学知识综合应用,并且预感这是一门比较耗时的课程,果不其然,正式上课以后了解到需要用到虚拟机,并且提交形式是博客,就知道这门课确实耗时,但是关关难过关关过,相信学完之后,会有不错的收获的。docker和树莓派在学期初有所耳闻,也想通过这门课认真学习,get到新技能。
二、了解微服务
(1)微服务是什么
微服务是SOA(Service-Oriented Architecture)面向服务的体系架构下的最终产物,是一个新兴的软件架构,其设计目标是肢解业务。
概念:把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议。
定义:围绕业务领域组件来创建应用,这些应用可独立地进行开发、管理和迭代。在分散的组件中使用云架构和平台式部署、管理和服务功能,使产品交付变得更加简单。
本质:用一些功能比较明确、业务比较精练的服务去解决更大、更实际的问题。
查阅资料的过程中,在什么是微服务?为什么你要用微服务?中看到了一个通俗易懂的举例:
看军事新闻的同学应该都知道,一艘航空母舰作战能力虽然很强,但是弱点太明显,就是防御能力太差,单艘的航空母舰很少单独行动,通常航空母舰战斗群才是主要军事力量,你可以把单艘航母理解为的单体应用(防御差,机动性不好),把航母战斗群(调度复杂,维护费用高)理解为微服务。
(2)特点
-
单一职责:对于每个服务而言,在服务架构层面遵循单一职责原则。符合高内聚、低耦合,不同的服务通过“管道”的方式灵活组合,从而构建出庞大的系统。
-
轻量级通信:服务之间应通过轻量级的通信机制,实现彼此间的互通互联,相互协作。所谓轻量级通信机制,通常指语言无关、平台无关的交互方式。对于微服务而言,通过使用轻量级通信机制,使服务与服务之间的协作变得更加标准化,也就意味着在保持服务外部通信机制轻量级的情况下,团队可以选择更适合的语言、工具或者平台来开发服务本身。
-
独立性:在单块架构中,功能的开发、测试、构建以及部署耦合度较高,相互影响。而在微服务架构中,每个服务都是一个独立的业务单元,当对某个服务进行改变时,对其它服务不会产生影响。无论是从开发、测试还是部署这些阶段来看,服务与服务之间都是高度解耦的。
-
进程隔离:所有的功能都运行在同一个进程中,就意味着,当对应用进行部署时,必须停掉当前正在运行的应用,部署完成后,再重新启动进程,无法做到独立部署。但在微服务架构中,应用程序由多个服务组成,每个服务都是一个具有高度自治的独立业务实体。通常情况下,每个服务都能运行在一个独立的操作系统进程中,这就意味着,不同的服务能非常容易地被部署到不同的主机上。
(3)相较于传统的软件架构的优缺点
传统软件架构:
优点:
-
开发简单,集中式管理
-
基本不会重复开发
-
功能都在本地,没有分布式的管理和调用消耗
缺点:
-
效率低:开发都在同一个项目改代码,相互等待,冲突不断
-
维护难:代码功功能耦合在一起,新人不知道何从下手
-
不灵活:构建时间长,任何小修改都要重构整个项目,耗时
-
稳定性差:一个微小的问题,都可能导致整个应用挂掉
-
扩展性不够:无法满足高并发下的业务需求
微服务架构:
优点:
关键点:复杂度可控,独立按需扩展,技术选型灵活,容错,可用性高
-
它解决了复杂性的问题。它会将一种怪异的整体应用程序分解成一组服务。虽然功能总量不变,但应用程序已分解为可管理的块或服务。每个服务都以RPC或消息驱动的API的形式定义了一个明确的边界;Microservice架构模式实现了一个模块化水平。
-
这种架构使每个服务都能够由专注于该服务的团队独立开发。开发人员可以自由选择任何有用的技术,只要该服务符合API合同。当然,大多数组织都希望避免完全无政府状态并限制技术选择。然而,这种自由意味着开发人员不再有义务使用在新项目开始时存在的可能过时的技术。在编写新服务时,他们可以选择使用当前的技术。此外,由于服务相对较小,因此使用当前技术重写旧服务变得可行。
-
Microservice架构模式使每个微服务都能独立部署。开发人员不需要协调部署本地服务的变更。这些变化可以在测试后尽快部署。
-
Microservice架构模式使每个服务都可以独立调整。可以仅部署满足其容量和可用性限制的每个服务的实例数。此外,可以使用最符合服务资源要求的硬件。
缺点:
关键点(挑战):多服务运维难度,系统部署依赖,服务间通信成本,数据一致性,系统集成测试,重复工作,性能监控等
-
过度强调服务规模。但这是一种手段,而不是主要目标。微服务的目标是充分分解应用程序,以便于敏捷应用程序开发和部署。
-
分布式系统而产生的复杂性。开发人员需要选择和实现基于消息传递或RPC的进程间通信机制。此外,他们还必须编写代码来处理部分故障,因为请求的目的地可能很慢或不可用。
-
分区数据库架构。更新多个业务实体的业务交易是相当普遍的。但是,在基于微服务器的应用程序中,需要更新不同服务所拥有的多个数据库。使用分布式事务通常不是一个选择,而不仅仅是因为CAP定理。许多今天高度可扩展的NoSQL数据库都不支持它们。最终不得不使用最终的一致性方法,这对开发人员来说更具挑战性。
-
测试微服务应用程序也更复杂。服务类似的测试类将需要启动该服务及其所依赖的任何服务(或至少为这些服务配置存根)。再次,重要的是不要低估这样做的复杂性。
-
实现跨越多个服务的更改。
-
部署基于微服务的应用程序也更复杂。单一应用程序简单地部署在传统负载平衡器后面的一组相同的服务器上。每个应用程序实例都配置有基础架构服务(如数据库和消息代理)的位置(主机和端口)。相比之下,微服务应用通常由大量服务组成。例如,每个服务将有多个运行时实例。更多的移动部件需要进行配置,部署,扩展和监控。此外,还需要实现服务发现机制,使服务能够发现需要与之通信的任何其他服务的位置(主机和端口)。传统的基于故障单和手动操作的方法无法扩展到这种复杂程度。因此,成功部署微服务应用程序需要开发人员更好地控制部署方法,并实现高水平的自动化。
(4)部署
- 每台主机上部署多个服务实例
- 每个主机一个服务实例
- 每台容器一个服务实例
- 松耦合,可独立部署
三、学习docker技术
(1)学习了解docker的相关概念
- Docker:一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
Docker 包括三个基本概念:
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):仓库可看着一个代码控制中心,用来保存镜像。 - Docker Compose:用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
- Dockerfile:一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
- Docker Machine:一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。
- Swarm:Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。
- k8s:一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非常的方便,而且可以做到故障自愈,例如一个服务器挂了,可以自动将这个服务器上的服务调度到另外一个主机上进行运行,无需进行人工干涉。
(2)搭建docker环境
1.Ubuntu Docker 安装
1.1 使用 Docker 仓库进行安装
在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库
1.1.1 设置仓库
更新 apt 包索引
sudo apt-get update
安装 apt 依赖包,用于通过HTTPS来获取仓库
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
设置稳定版仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
1.1.2 安装 Docker Engine-Community
更新 apt 包索引
sudo apt-get update
装最新版本的 Docker Engine-Community 和 containerd
sudo apt-get install docker-ce docker-ce-cli containerd.io
测试 Docker 是否安装成功
sudo docker run hello-world
历经千辛万苦,耗时一整天,终于安装成功啦!
2.Docker 容器使用
2.1 获取镜像
没有 ubuntu 镜像,使用 docker pull 命令来载入 ubuntu 镜像
sudo docker pull ubuntu
2.2 启动容器
sudo docker run -t -i ubuntu /bin/bash
参数说明:
- -i: 交互式操作。
- -t: 终端。
- ubuntu: ubuntu 镜像。
- /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
2.2.1 运行命令查看当前系统的版本信息
cat /proc/version
2.2.2 创建一个文件夹,并进入
mkdir test
cd test
2.2.3 退出容器
exit
或CTRL+D
2.3 启动已停止运行的容器
查看所有的容器命令如下:
sudo docker ps -a
使用 docker start 启动一个已停止的容器:
sudo docker start <容器 ID>
再次查看容器状态可知容器被启动:
2.4 后台运行
创建后台运行容器:
sudo docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hi; sleep 1; done"
查看容器获得容器ID:
查看容器内的标准输出:
sudo docker logs <容器 ID>
2.5 停止和重启容器
sudo docker stop <容器 ID>
查看容器状态可知容器被停止:
sudo docker restart <容器 ID>
查看容器状态可知容器被启动:
2.6 进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
-
docker attach
-
docker exec:推荐使用,因为此退出容器终端,不会导致容器的停止。
2.6.1 attach 命令
sudo docker attach <容器 ID>
2.6.1 exec 命令
sudo docker exec -it <容器 ID> /bin/bash
查看容器可知容器没有停止工作:
2.7 更新容器
查看可选操作
docker container update --help
sudo docker container update [操作参数] CONTAINER [容器id]
我选择的是内存软限制--memory-reservation bytes
2.8 删除容器
sudo docker rm -f <容器 ID>
查看可知容器已被删除:
3.Docker 镜像使用
3.1 列出镜像列表
使用如下命令来列出本地主机上的镜像
sudo docker images
3.2 获取一个新的镜像
本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果想预先下载这个镜像,可以使用如下命令来下载它。
sudo docker pull
3.3 查找镜像
可以从Docker Hub 网站来搜索镜像
sudo docker search httpd
3.4 拖取镜像
使用上图中的 httpd 官方版本的镜像,使用 docker pull 命令下载镜像
sudo docker pull httpd
3.5 删除镜像
删除用镜像创建的容器
sudo docker rm -f <容器 ID>
删除镜像
sudo docker rmi hello-world
4.Docker 仓库管理
4.1 docker hub仓库
4.1.1 登录
登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像
sudo docker login
4.1.2 push镜像到仓库
sudo docker tag ubuntu cathy/ubuntu
sudo docker push cathy/ubuntu
4.1.3 从仓库中获取镜像
sudo docker pull cathy/ubuntu
难过,用了加速器,挂VPN,依然卡我进度条,三天了,我放弃它了,改用阿里云。
4.2 阿里云仓库
4.2.1 创建阿里云仓库
4.2.2 登录阿里云Docker Registry
sudo docker login --username=cathyccathy registry.cn-shanghai.aliyuncs.com
4.2.3 将镜像推送到Registry
sudo docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/cathy-hub/cathy-docker:[镜像版本号]
sudo docker push registry.cn-shanghai.aliyuncs.com/cathy-hub/cathy-docker:[镜像版本号]
4.2.4 从Registry中拉取镜像
sudo docker pull registry.cn-shanghai.aliyuncs.com/cathy-hub/cathy-docker:[镜像版本号]
感人,这也太快了:)
四、 遇到的问题及解决方法
(1)打开很久没用的虚拟机,结果报错显示无法正常访问
问题原因:非法操作或虚拟机损坏
解决方法:在虚拟机所在目录下,即错误信息中显示的目录下找到扩展名为.vbox-prev的文件,把-prev去掉,重启虚拟机,就会有惊喜。
(2)进行apt-get update
出现问题如下,导致 Docker 无法安装
原因及解决方法:按照如下教程里的第一种方法解决了
Ubuntu系统 apt-get update失败解决办法
(3)进行sudo docker run hello-world
出现如下问题
网上的解决方法是输入:
systemctl daemon-reload
sudo service docker restart
sudo service docker status
然而在我输入sudo service docker restart
时,出现了:
Job for docker.service failed because the control process exited with error code
原因:一般是由于/etc/docker/daemon.json里面配置有误
解决方法:正确配置例子
sudo gedit /etc/docker/daemon.json
打开相应文件,将内容按照如下修改
{
"registry-mirrors": ["https://xepp8w8o.mirror.aliyuncs.com"]
}
这个是我自己的阿里云镜像加速器
重新输入:
systemctl daemon-reload
sudo service docker restart
sudo service docker status
问题就解决啦
五、小结
比我想象中更耗时,主要是遇到了几个问题,查阅资料和尝试解决的过程真挺坎坷的,有时候半天都没法解决一个问题,最头疼和膈应的就是仓库管理的时候遇到的卡进度条的问题,我本来很执着于用docker hub的仓库,尝试使用了加速器和梯子都没能成功解决问题,最后还是使用的阿里云的仓库。总之虽然过程很痛苦,但是看到结果的时候开心是加倍的,同时也是收获满满。通过实验初步接触了docker,搭建了docker环境,学习了一些docker的基本操作,对docker有了基础的了解,希望在后续的实践中能够更加耐心一些,收获更多。