Amazon Web Services容器

一文搞懂 Docker 基础 上篇 理论

简介


Docker 本身并不是 AWS 的服务,但在之前的文章中,我们已经多次用到了 Docker。

除了 AWS ECS 用到了 Docker,在 AWS EKS(K8s),Batch,CodeBuild 等很多服务中都会直接或间接地用到 Docker。

不仅是 AWS,各大云服务厂商也均支持 Docker。

自从 WSL2(Linux 的 Windows 子系统)推出之后,在 WSL 中直接使用 Docker 更为方便,这让熟悉 Linux 的朋友可以自由在 Windows 环境和 Linux 环境中切换。

我们将在下一篇文章中利用 WSL2 环境进行实战测试。本文中我们主要介绍 Docker 相关概念,术语。

Docker 介绍


“Docker 是一个软件平台,让您可以快速构建、测试和部署应用程序。Docker 将软件打包成名为容器的标准化单元,这些单元具有运行软件所需的所有功能,包括库、系统工具、代码和运行时。使用 Docker,您可以将应用程序快速部署和扩展到任何环境中。”

上面这段话摘自网络上的 Docker 介绍,下面我们用通俗易懂的话解释一下。

  1. Docker 是一种软件,可以安装在 windows 和 Linux 两种操作系统上,相当于安装了一个框架(引擎),这个框架用来管理运行在其上面的容器,以及生成容器的镜像
  2. 容器是跑在这个 Docker 引擎上的具体实例,每个容器可以理解为一个小型的操作系统,我们在这个小型操作系统里安装各种应用软件(这些单元具有运行软件所需的所有功能,包括依赖库、系统工具)
  3. 容器这个小型操作系统与 Docker 所在的操作系统是隔离开的,互相不依赖。所以一个镜像生成的容器可以运行在安装有 Docker 环境的不同系统上(标准化单元、扩展到任何环境)

Docker 主要是容器的运行环境,当然也可以管理容器。

与之类似,AWS ECS 也用来管理容器(编排服务),同样的还有 K8s,AWS EKS(AWS 提供的 k8s)。但 ECS 和 K8s 还需要 docker 作为容器的运行环境。

下面是 VM(虚拟机)与 Container(容器)的区别

虚拟机虚拟硬件,我们还要在虚拟机中安装操作系统。

容器虚拟的是操作系统,我们只需要在里面安装需要的应用软件。

简单理解就是容器虚拟在更上一层,更轻量级,使用起来更简单。

1. Docker 结构


Docker 采用的是 client-server 模式。

用户通过 client(客户端,指 docker 或 docker-compose 命令行)与 server(服务器端,Docker daemon)交互,由 server 完成构建镜像,生成容器,运行容器等任务。

docker client 和 server 通过 REST API 交互,既可以在同一个主机上,也可以分布不同主机上。

注意:这里的 server 是指 docker 的服务端程序,不是 linux 主机服务器

Docker 结构如下图所示

说明:

  • 图中 docker client 用的是 docker 命令行
  • Docker daemon 就是 docker server

2. Docker 术语


daemon

daemon(dockerd)是 docker 的服务器端,运行在主机上的软件,负责监听 docker api 即 client 发出的指令,并管理 image,容器,网络等。

当我们使用 Docker Desktop 时,WSL2 中看不到 dockerd 进程(服务器端),只能在任务管理器中查看。

而在 Linux 系统中可以用下列命令查看 dockerd 服务器端

systemctl status docker

client


client(docker)是用户使用 Docker 的主要工具。

主要有以下两种

  • docker
  • docker-compose

前者可以运行控制单个容器。后者通过定义模板,可以协同多个容器一起运行

当用户运行 docker run 时,信息被发送到 dockerd(服务器端),由服务器下载 image 并启动容器。

常用的还有

  • docker start/stop:启停容器
  • docker restart: 重启容器
  • docker inspect:查看容器信息
  • docker exec:在容器中执行命令

registries


registries 镜像仓库,用来存储 docker image,分为公共仓库和私有仓库。

Docker Hub 是公共仓库,docker 命令默认配置的是就是 Docker Hub。之前几篇文章中用到的 tansong0091/httpd-ssh 等镜像就保存在 Docker Hub 中。

我们在 docker 中注册一个帐号后就可以使用 Docker Hub 做为自己的镜像仓库,不过是公开的,任何人都可以下载。

私有仓库是自己搭建的,或者利用服务商提供的,比如说 AWS ECR registry。

我们用 docker pull 命令从仓库中下载镜像,用 docker push 命令把镜像从本地推入仓库。

Images


Images 镜像是一个只读的模板(Dockerfile),里面包含了创建容器的各种指令。

我们在模板中指定安装的软件,复制的文件,以及启动时运行的命令等。

通常,我们在另一个 image 的基础上生成我们需要的 image。

比如在之前的文章中,我们在官方 httpd 镜像的基础上添加 openid 或者 epenssh 功能生成自己的镜像。

利用模板 Dockerfile 创建镜像时,Dockerfile 中的每条指令(准确的说并不是任意指令)会创建一个镜像层(layer)。

下面这个图中在 Debian 的原始镜像中,加了两个应用形成了两个 layer

当我们对 Dockerfile 做出改动(包括复制到镜像中的文件内容有改动)并重新创建镜像时,只有变动的镜像层(layer)会重新构建,其它镜像层会重用。

同样,满足条件的不同镜像间相同的 layer 也会被重用,这个共享特性帮助减少了 image 大小,并且使部署容器更快捷。

创建镜像可以在本地或者有运行 docker 服务端的任何环境中进行,创建好的本地镜像在推入公共仓库或私有仓库后就可以被分享使用。

containers


上面说过镜像只是一块模板,一堆命令的集合,本身不能运行。镜像需要通过生成的容器来运行,容器就是镜像运行的具体实例。

默认情况下,容器中的环境和 docker 所在的主机环境是隔绝的,但我们可以通过改变网络(指 docker 网络),存储等配置来控制隔绝程度。

比如,我们把容器内的端口映射到主机上,或者把主机上的文件夹映射到容器内(通过在生成容器时加各种参数实现)。

在一台主机上的不同容器,默认情况下也是彼此隔绝的。

除了像上面提到的,把端口映射到主机上或者改变容器所在的网络来实现容器间的互通,我们还可以用 docker-compose 来协同多个容器一起工作。

docker-compose 可以把多个容器定义在一个 docker 网络内,彼此之间端口互通,但对主机只暴露特定端口。

Docker、K8s(Kubernetes)、Openshift、ECS、EKS 的关系


Docker vs K8s

Docker 是容器化技术的一种,其它的还有 containerd, CRI-O 等,Docker 作为一种运行环境(Runtime)安装在独立的 VM 或者主机上。

K8s 是容器管理编排工具,需要与其它容器运行环境一起协同运行,提供管理集群,自动扩展,容器生命周期等功能。

简单地理解就是,先安装有 Docker 之后才可以运行容器,这时我们再安装上 K8s,K8s 就可以帮我们管理 Docker 容器以及 Docker 的 host 集群。

K8s 不只可以与 Docker 紧密配合,K8s 也可以与其它容器技术协同工作,只要其兼容 Kubernetes CRI (Container Runtime Interface)。

提示:未来新 K8s 版本将不再支持 Docker 做为运行环境

K8s vs Openshift

“红帽 ® OpenShift® 是一个 Kubernetes 发行版”,Openshift 是红帽在 K8s 基础上开发的商用软件,也是容器编排工具,但增加了很多功能,使 OpenShift 作为商用软件可以开包即用。

K8s 本身更像是一个框架,在实际使用时很多功能还是需要自己添加。

总的来说,OpenShift 是一个把各种功能打包好的 K8s,功能强大。但是做为商用软件,只有试用是免费的,生产商用要付钱购买。

ECS vs EKS

ECS 是 AWS 自己开发的容器编排工具,目前只支持 docker。

ECS 有两种模式

  • EC2:ECS 运行在 EC2 之上,Elastic beantalk 使用此模式
  • Fargate:无服务器模式,用户看不到下层服务器,只需要指定 CPU 和内存大小

之前的文章中我们多次使用 Farget 运行容器,使用方便,又免去了维护下层服务器的麻烦。

EKS(Elastic Kubernetes Service)AWS 提供的 K8s 服务,提供了 K8s 的全部功能,并可以与 AWS 服务很好的结合。

有了 EKS 我们可以把自己或其它云上的 K8s 服务,方便地迁移到 AWS 上。

EKS 支持 EC2 模式,也支持把容器运行在 Fargate 上,但中国区 EKS 目前只支持 EC2 模式

总结


Docker 容器技术是比较复杂的,但是对使用来说并没有那么难。

在下一篇中,我们将会看到使用 Docker 建立应用服务器是非常容易的事情。

熟悉了 docker 之后,我们就可以尝试 AWS Fargate,K8s 这些容器编排服务了。

引申


Docker 除了可以在云上做为 AWS EKS(k8s),ECS 的运行环境大显身手,在 VM 上或者本机也可以很好的利用起来。

比如,我们想在自己本机上部署一套应用服务器(Apache,tomcat,mysql),之前的操作是分别下载 Apache,tomcat,mysql 软件,然后挨个双击安装配置。

现在我们只需要下载三个镜像,然后生成容器,把需要的内容映射到本地,一个应用服务器就建好了。

本机测试好了,准备部署到 VM 或者服务器上时,也可以按同样的方法建一套应用服务器,非常快捷高效,还不会破坏服务器上原来的环境。

删除也很方便,把容器删掉就好了,镜像可以留下也可以一并删掉。删除容器和镜像操作对本机的其它软件完全没有影响。

对于有特别需求的应用服务器,我们只需要在官方镜像的基础上加以修改来满足需求。