2020系统综合实践1 微服务与Docker 基本入门
(0) 运行环境
本文基于VirtualBox+Debian(虽然是基于Debian的,但和Ubuntu并没有什么差别)
把遇到的一些问题和解决方法放在了这里。
另外,推荐使用WSL 2运行Docker
(1) 课程调查
因为教务处没有本课程的授课计划和教学大纲,所以不知道这是一门什么样的课。根据课程名来看,大概是要对前几年学到的知识,来一次综合实践运用,提升我们的综合能力吧。作为一个考研狗,希望本课程不会占用太多时间。
(2) 了解微服务
作为一个Android开发,对后端的东西,除了使用过SpringBoot和MySQL,其他的都不是很了解。之前在一些技术论坛上有见过微服务这个名词,但具体是个啥也不清楚。上知乎搜了下微服务话题下的精华回答:什么是微服务架构?,看完后对微服务有了一个大概的了解。
什么是微服务
根据维基百科上的定义,微服务是一种软件开发技术,是面向服务的架构(SOA)结构风格的一种变体,将应用程序编排成一系列松耦合的服务。在微服务架构中,各个服务是细粒度的,协议是轻量级的。
Microservices are a software development technique —a variant of the service-oriented architecture (SOA) structural style— that arranges an application as a collection of loosely coupled services.[1] In a microservices architecture, services are fine-grained and the protocols are lightweight.
微服务的优点
- 各个服务粒度小,方便负责各模块的开发人员专注做一件事
- 各个服务可以独立测试、部署、升级、发布
- 提高容错性,一个服务发生错误不会让整个系统瘫痪
- 方便新技术的应用
- 按需定制的DFX,资源利用率,每个服务可以各自进行x扩展和z扩展,而且,每个服务可以根据自己的需要部署到合适的硬件服务器上(看不懂)
- 需要选择HA的模式,选择接受服务的实例个数(看不懂)
微服务的缺点
- 提高了系统复杂度
- 开发人员要处理分布式系统的复杂性
- 服务之间的分布式通信问题
- 服务的注册与发现问题
- 服务之间的分布式事务问题
- 数据隔离带来的报表处理问题
- 服务之间的分布式一致性问题
- 服务管理的复杂性,服务的编排
- 不同服务实例的管理
这些缺点Docker似乎能解决一部分。
微服务的几种部署方法
- 每台主机上部署多个服务实例
- 每个主机一个服务实例
- 无服务的部署(?)
(3)学习Docker技术
概览
Docker提供了在松散隔离的环境(称为容器)中打包和运行应用程序的功能。隔离和安全性使您可以在给定主机上同时运行多个容器。容器是轻量级的,因为它们不需要HyperV的额外负担,而是直接在主机的内核中运行。这意味着与使用虚拟机相比,您可以在给定的硬件组合上运行更多的容器。您甚至可以在实际上是虚拟机的主机中运行Docker容器。
Docker提供格了一系列工具和平台来管理容器的生命周期:
- 使用容器开发应用和支持组件
- 容器成为分发和测试应用的单元
- 将应用程序作为容器或编排服务进行部署到生产环境,环境可以是本地数据中心/云服务,或者两者混合
相关概念
- Docker Engine:一个C/S应用,包含以下组件:长时间运行的守护进程daemon、一个REST API用于指挥守护进程、一个命令行接口
- Docker Daemon(
dockerd
):监听Docker API请求,也可以与其他Daemon交互来管理Docker服务 - Docker Client(
docker
):用于连接Daemon并与之交互,可以连接多个Daemon - Image(镜像):容器的模板,可以根据不同的配置生成多个实例,(类似系统镜像?)
- Container(容器):镜像的实例,可以通过Docker API来开启/停止/删除,并且可以连接到多个网络,挂在多个存储,甚至可以在当前状态创建新镜像
- Docker Compose:一个定义和运行多容器Docker应用的工具,它的功能有开启/关闭服务、查看服务的运行状态输出服务的日志、运行一次性命令等。守护进程创建并管理Docker对象,例如镜像、容器、network、volumes
- Dockerfile:用于定义应用环境,使环境可以重复加载多次
- yml文件:用于定义组成应用的服务们的文件,使服务们可以在一个独立的环境中一起运行
- Docker Machine:用于安装Docker Engine到虚拟主机,并且可以使用相关命令来管理这些主机
- Swarm mode:用于编排部署多个Docker容器
- k8s:用于部署和管理容器
Docker架构图
Docker环境搭建
根据官方安装教程:
sudo apt-get remove docker docker-engine docker.io containerd runc # 移除旧版本
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# ubuntu用户需把命令中的debian改成ubuntu
curl -fsSL https://download.docker.com/linux/debian /gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
# ubuntu用户需把命令第二行的debian改成ubuntu
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian\
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
安装完成后,运行官方的Hello World示例:
sudo docker run hello-world
示例说明了Docker的运行过程:
- Docker客户端连接至Docker守护进程
- Docker守护进程从Docker Hub上拉取hello-world镜像
- Docker守护进程从拉取的镜像创建一个新容器,终端上显示的这段话就是从这个容器创建的
- Docker守护进程将输出流式传输到Docker客户端,显示到下图的终端上
使用Dockerfile定义镜像
要运行容器,首先就要定义容器基于的镜像,官方入门教程 Part2提供了一个Sample
git clone https://github.com/dockersamples/node-bulletin-board
cd node-bulletin-board/bulletin-board-app
这个镜像的Dockerfile
内容如下,每个命令的含义都给出了比较详细的注释
# Use the official image as a parent image.
FROM node:current-slim
# Set the working directory.
WORKDIR /usr/src/app
# Copy the file from your host to your current location.
COPY package.json .
# Run the command inside your image filesystem.
RUN npm install
# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 8080
# Run the specified command within the container.
CMD [ "npm", "start" ]
# Copy the rest of your app's source code from your host to your image filesystem.
COPY . .
构建并测试镜像
构建过程中需要node,国内下载速度很慢,可以修改Dockerfile,将FROM node:current-slim
替换为FROM daocloud.io/library/node:current-slim
,显著提升下载速度。
sudo docker build --tag bulletinboard:1.0 .
出现图中的两个successfully就代表构建成功。
创建并运行容器
docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0
各参数含义:
--publish
:将主机8000端口的流量转发至8080端口,容器有专用端口集,如果要从网络访问容器,必须这么做--detach
:让容器后台运行--name
:给你的容器取名,后续命令根据这个名字来引用该容器,在这里是bb
然后就可以访问容器啦。
容器的删除
docker rm --force bb
删除后localhost:8000
便无法访问了,说明删除成功。
容器的更新
可更新的选项可以在官方文档查到。图中命令限制了容器的pid最大个数为3:
docker container update [OPTIONS] CONTAINER [CONTAINER...]
容器的查询
docker ps
上传镜像到Docker Hub
- 注册登录 hub.docker.com
- Repositories→Create Repository
- 填写仓库名称,Create
- 在命令行登录
docker login
- 修改本地仓库名
docker tag bulletinboard:1.0 qyanzh/hello-docker:init
- push!
docker push qyanzh/hello-docker:init
拉取镜像
docker pull qyanzh/hello-docker:init
碎碎念
没想到这么个东西做了几乎一天才搞定……主要是踩了太多坑。看来“不要占用太多时间”的希望要破灭了 = =