2020系统综合实践 第1次实践作业
一、课程调查
在上学期选课时看到系统综合实践时,第一印象是一个和硬件息息相关的实验课,估摸着就是搞电路板之内的,然后敲一些代码输入进去运行的内容。听老师讲课时既期待又紧张,因为用了去年软件实践的博客体系,去年软件实践1学分却耗费了我大半个学期的噩梦还历历在目。但个人对docker模块和树莓派还是稍感兴趣的,之前就听同学聊过树莓派的操作,这次可以自己实践操作,希望能在学习课程的时候也能尽情享受过程,所以希望老师可以多多提供一些有效的学习方法或途径~~
二、了解微服务
1.微服务是什么
微服务是基于Restful风格的,基于资源及资源操作一组API的集合,可以实现模块儿或者说是特定的业务范围内的一个完全独立、细粒度、自包含的一个服务。每个微服务提供一组API,供其他微服务或者应用客户端所用。
2.微服务架构是什么
-
什么是单体应用
说到单体应用,直接举例来说吧,典型的单体应用有ERP、CRM、BPM等软件。对于ERP和大型的CRM应用来说,可能一个软件就包含有数百个功能点。对于此类软件的开发、维护、部署、纠错、扩展及升级对于相关人员来说都将是大麻烦(噩梦)。
-
什么是SOA架构
SOA是解决单体应用架构的问题的一个解决方案:SOA是面向服务的体系架构,是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。既然每个服务是有不同的功能单元组成,那么这个服务的范围就非常广了。
SOA架构与微服务架构比较相似,以至于国外不少人范围微服务的原因是认为微服务只是对SOA的二次包装。这里不去讨论SOA与微服务的长短,这个要讨论估计要三天三夜了吧~~~
-
什么是微服务架构
表面上看,微服务架构范式与 SOA 非常类似,这两种架构都包括一套服务。然而,微服务架构范式被看作不包含某些功能的 SOA 。这些功能包括网络服务说明( WS- )和 Enterprise Service Bus (ESB) 的商品化和请求包。基于微服务的应用更青睐 REST 这样简单的、轻量级的协议,而不是 WS- 。他们也极力避免在微服务中使用 ESBs 及类似功能。微服务架构范式也拒绝 SOA 的其它部分,比如 canonical schema 的概念(摘自“Chris Richardson 微服务系列”)
3.微服务的优点
- 可以解决复杂性的问题,在功能不变的情况下,分解为多个相互协作的微服务,通过rest API定义边界,这样极大易于开发、理解和维护。
- 微服务架构是的每个服务可以由专门的开发团队或者个人开发者进行开发,开发者可以自由选择技术,不必受制于规定的技术和框架,只要API服务协议好交互方式即可(如restful)。这样即使重新技术过时的微服务模块儿或者重写以前的代码,也不是很困难。
- 微服务架构模式使得每个微服务独立部署,且每个服务独立扩展,开发者不再需要协调其它服务部署对本服务的影响。微服务架构模式使得持续化部署成为可能。
4.微服务的缺点
- "微服务"强调了服务大小,所以很多人的关注点主要在“微”字上,尽管小服务更容易被采用,但是微服务只是结果,而不是最终目的。微服务的目的是有效拆分应用,实现敏捷开发和部署。
- 微服务应用是分布式系统,必然会带来固有的复杂性,开发者需要协议消息传递规则的选择并完成进程间通讯。相对于单体应用,微服务下这种技术显得更加复杂一些。
- 关于微服务的数据库架构,由于同一事务更新多个业务很普遍,这种事务操作对于单体应用来说很容易解决,因为只有一个数据库,而在微服务架构中,由于每个微服务使用不同的数据库,使用分布式事务并不一定是好的选择。并且现在高扩展性的NoSQL数据库和消息传递中间件并不支持这样的需求。从而对开发者提出了更高的要求和挑战。
- 由于微服务架构的分布式特点,测试一个基于微服务架构的应用也是很复杂的任务。测试单个微服务的一套REST API 相对简单,但是往往要启动与之相关的所有服务。所以,采用了微服务架构带来的并不仅仅是敏捷开发和部署,还会带来一定的复杂性。
- 微服务架构模式下,应用的改变将会波及多个服务。比如,假设你在完成一个需求,需要修改服务A、B、C,而A依赖B,B依赖C。在单体应用中,你只需要改变相关模块,整合变化,部署就好了。对比之下,微服务架构模式就需要考虑相关改变对不同服务的影响。比如,你需要更新服务C,然后是B,最后才是A。幸运的是,许多改变一般只影响一个服务,而需要协调多服务的改变很少。
- 部署一个微服务应用也很复杂,一个单体应用只需要在复杂均衡器后面部署各自的服务器就好了。每个应用实例是需要配置诸如数据库和消息中间件等基础服务。相比之下,一个微服务应用一般由大批服务构成。根据 Adrian Cockcroft 的分享,Hailo 由 160 个不同服务构成,而NetFlix则超过600个服务。每个服务都有多个实例,这就形成大量需要配置、部署、扩展和监控的部分。除此之外,你还需要完成一个服务发现机制,以用来发现与它通讯服务的地址(包括服务器地址和端口)。传统的解决问题办法并不能解决这么复杂的问题。最终,成功部署一个微服务应用需要开发者有足够的控制部署方法,并高度自动化。(摘自“Chris Richardson 微服务系列”)
- 根据上一点的描述,在微服务架构的应用中,往往有很多个微服务实例,并且每个服务都有多个实例,那么服务的自动化部署必然与服务发现机制同样要解决。
5.微服务的部署策略
- 基于主机(物理机或虚机)的多服务实例
- 基于主机(物理机或虚机)的服务实例
- 基于容器的服务实例
- 无服务器部署
三、学习Docker技术
1.Docker的相关概念
-
Docker:世界领先的软件容器平台,使用Google公司推出的Go语言进行开发实现,基于Linux内核的cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于LXC。
-
Docker Compose: 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
-
Dockerfile:是用来构建自定义 Docker 镜像的文本文档。我们通过docker build命令用于从Dockerfile文件构建镜像。
-
Docker Machine:是 Docker 官方提供的一个工具,它可以帮助我们在远程的机器上安装 Docker,或者在虚拟机 host 上直接安装虚拟机并在虚拟机中安装 Docker。我们还可以通过 docker-machine 命令来管理这些虚拟机和 Docker。
-
Swarm:Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。
-
K8s:是一个跨主机集群的开源的容器调度平台,它可以自动化应用容器的部署、扩展和操作 , 提供以容器为中心的基础架构。
2.搭建自己的docker环境
该实践使用的环境是ubuntu(linux虚拟机)
a.Ubuntu Docker安装
更新ubuntu的apt源索引
sudo apt-get update
安装包允许apt通过HTTPS使用仓库
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
添加Docker官方GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
设置Docker稳定版仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
添加仓库后,更新apt源索引
sudo apt-get update
安装最新版Docker CE(社区版)
sudo apt-get install docker-ce
检查Docker CE是否安装正确
sudo docker run hello-world
出现:Hello Form Docker 的一段话,表示安装成功
b.Docker 容器使用(Hello World输出实例)
Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序。
(1)输出Hello world
docker run ubuntu:15.10 /bin/echo "Hello world"
各个参数解析:
- docker: Docker 的二进制执行文件。
- run: 与前面的 docker 组合来运行一个容器。
- ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
- /bin/echo "Hello world": 在启动的容器里执行的命令
(2)运行交互式的容器
我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现对话"的能力:
docker run -i -t ubuntu:15.10 /bin/bash
我们尝试在容器中运行命令 ls查看当前目录下的文件列表
(3)启动容器(后台模式)
使用以下命令创建一个以进程方式运行的容器
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。
首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:
docker ps
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
- created(已创建)
- restarting(重启中)
- running(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。
在宿主主机内使用 docker logs 命令,查看容器内的标准输出:
Docker logs 9c4ae95088c9
(4)停止容器
使用 docker stop 命令来停止容器
docker stop 9c4ae95088c9
通过 docker ps 查看,容器已经停止工作:
(5)进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
- docker attach
- docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
attach 命令
docker attach 717ce1244470
停止的容器可以通过 docker restart 重启:
$ docker restart <容器 ID>
下面演示了使用 docker exec 命令。
docker exec -it 717ce1244470 /bin/bash
如果从这个容器退出,不会导致容器的停止,如下图,容器并未停止。
(6)导出与导入容器
如果要导出本地某个容器,可以使用 docker export 命令。
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
docker export 717ce1244470 > ubuntu.tar
cat ubuntu.tar | docker import - test/ubuntu:v1
(7)删除容器
docker rm -f 717ce1244470
c.Docker 镜像使用
(1)列出镜像列表
我们可以使用 docker images 来列出本地主机上的镜像。
各个选项说明:
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
(2)查找镜像
我们可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
docker search httpd
(3)拖取镜像
我们决定使用上图中的 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。
docker pull httpd
(4)删除镜像
第一步先停止所有的container,第二步删除容器,最后删除指定镜像
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker rmi hello-world
d.Docker 仓库管理
(1)登录Docker账号
登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。
$ docker login
(2)推送镜像
用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。
用tag命令为自己的仓库标签(此处标签为15.10)
在Docker Hub上发现推送成功!