一、什么是容器技术
Docker 是一个开源的应用容器引擎,要了解Docker的前提就是要了解什么是容器技术。说到容器技术,这里就要联系一下我们经常使用到的虚拟机中的虚拟化技术了,两者在功能、目的上相似,都是将一系列的程序进行打包,建立一个独立的运行环境,也就是我们所说的沙盒,但在实现的环节与特点方面,两者截然不同。
1.1 虚拟化技术
虚拟化技术是指在同一台计算机上通过hypervisor(运行在基础物理服务器和操作系统之间的中间软件层,让多个操作系统和应用共享硬件),虚拟出多个包括完整虚拟机系统镜像,每个虚拟机拥有独立的操作系统和硬件资源。
虽然虚拟化技术可以在按需构建操作系统实例的过程当中为系统管理员提供极大的灵活性,但hypervisor虚拟化技术存性能和资源使用效率方面的问题,从而大大增加应用开发的消耗,而容器技术的诞生就是为了解决这问题。
1.2 容器技术
容器技术直接将一个应用程序所需的相关程序代码、函式库、环境配置文件都打包起来建立沙盒执行环境,从而有效的将单个操作系统的资源划分到孤立的组中,以便更好的在独立的组之间平衡有冲突的资源使用需求,创建好的这个沙盒执行环境就被称作为容器。
1.3 容器引擎
容器引擎不是只有docker一家,除了docker还有coreos等,而在众多的容器引擎中,Docker几乎是容器引擎的代表,下面就最典型的容器技术Docker进行介绍。
二、 什么是Docker
2.1 Docker简介
Docker 是一个开源的应用容器引擎,开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器完全使用沙箱机制,相互之间不会有任何接口,同时容器性能开销极低。
2.2 Docker基本概念
镜像 (Image):
镜像简单的来说,就是面向对象中的类,相当于一个模板。从本质上来说,镜像相当于一个文件系统。Docker 镜像是一个特殊的文件系统,提供了容器运行时所需的程序、库、资源、配置等。同时镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器 (Container):
与上面的镜像相对应,容器就是类创建的实例,是以某一个镜像为模板创建出来的实体。容器的实质是进程,但与直接在系统运行的进程不同,容器进程有自己独立的命名空间。因此容器可以拥有自己的root 文件系统、网络配置、内存空间,从而创建出一个隔离的环境里,就好像是一个独立于Host系统的系统。
仓库 (Registry):
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,仓库(Docker Registry) 就是这样的服务。仓库存放了每个类别镜像不同的版本,通过仓库可以获得需要的目的镜像。
客户端/服务器:
Docker 使用客户端/服务器体系结构。Docker 客户端通过接受命令与用户进行交互, Docker 客户端与 Docker 服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像,以及对应镜像容器的创建。最典型的Docker 客户端就是docker的命令行程序。
分层存储:
镜像需要包含操作系统完整的root 文件系统,而Docker将其设计为分层存储的架构,镜像构建时,会一层层构建,同时在修改、删除的时候也是在镜像最上面添加相应的操作层。该存储结构方便了镜像的复用,使得代码的构建变得简单起来,我们可以通过在原有的镜像添加、修改配置,从而实现自己的镜像。
2.3 Docker优势
-
更高效的利用系统资源。docker 容器直接与内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化
-
更快速的启动时间。传统的虚拟机技术启动应用服务往往需要数分钟,而Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。
-
实现自动化测试和持续的集成、部署。使用Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile 来进行镜像构建,并结合持续集成系统进行集成测试,而运维人员则可以直接快速部署该镜像,同时结合持续部署系统可以集进行自动部署。
-
兼容性。不需要再去考虑操作系统、依赖环境的影响,各种依赖环境都可以在docker中安装体现,而不是依赖于操作系统的环境。
从下面可以更加明显看出,与虚拟机相比容器的优势:
特性 |
容器 |
虚拟机 |
启动 |
秒级 |
分钟级 |
硬盘使用 |
一般为MB |
一般为GB |
性能 |
接近原生 |
弱于 |
系统支持量 |
单机支持上千个容器 |
一般是几十个 |
三、CentOS下Docker配置
Docker 分为 CE 和 EE 两大版本。 CE 即社区版(免费,支持周期 7 个月), EE 即企业版,强调安全,付费使用,支持周期 24 个月。
docker安装
在Centos安装docker需要先配置docker仓库,配置docker仓库成功后,就可以直接使用yum命令进行docker的安装了。
安装好需要的软件包后,就可以使用yum-config-manager命令设置docker安装的仓库了。
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
-
docker engine-community安装
添加完docker的仓库,就可以直接使用yum install 命令安装docker
$ sudo yum install docker-ce docker-ce-cli containerd.io
Docker 启动
Docker镜像测试
-
在安装并启动好docker后,可以获取并运行一个最简单的镜像hello-world,这个事docker社区中自带的一个镜像,可以直接输入run进行运行。当docker发现本地没有该镜像时,会直接去docker社区进行下载,然后再运行该镜像。下面可以看到docker下载镜像的过程,已经镜像运行的过程,同时该镜像在运行后就会自动退出。
sudo docker run libray/hello-world
另外也可以通过pull命令先拉取镜像,然后在运行。 library/hello-world 是 image 文件在仓库里面的位置,其中 library 是镜像文件所在的组, hello-world是镜像文件的名字,因为library是docker默认的组,所以可以省略不写。
sudo docker pull libray/hello-world
配置国内镜像
因为Docker的镜像仓库在国外,下载的速度都比较慢,所以这里可以配置国内的加速镜像仓库。
四、Docker 容器使用
Mysql容器使用
参数说明:
-p 3306:3306
:表示将容器服务的 3306 端口映射到到宿主机的 3306 端口,这样就可以直接通过宿主机的3306端口访问到容器的Mysql的服务器了。
-e MYSQL_ROOT_PASSWORD=root
: -e表示后面设置环境变量,后面表示的是mysql的root账号密码。
--name mysql2
:创建容器的名字,不能重复。
-d
:表示容器创建运行后不进入容器。
参数说明:
-it
:表示主机的输入输出流与容器终端的连接。
"sh"
:表示启动容器的终端。
五、镜像创建
1. Dockerfile
镜像的构建需要使用到dockerfile,Dockerfile是用来构建镜像的文本文件,文本由多条的命令组成。
常用命令
FROM
镜像的创建一般都是在其他镜像的基础上创建的,FROM命令一般用于dockerfile的开头,用于指定基础的镜像,多次使用可以指定多个基础镜像。
FROM <image>
或者
FORM <image>:<tag>
RUN
用于在构建镜像(docker build)过程过程中执行后面给出的命令,有两种不同的使用方法格式。
shell 格式:
RUN <命令>
Exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
COPY
复制指令,从源路径复制文件到目标路径,这可以设置多个源路径。
shell 格式:
COPY <源路径1>... <目标路径>
Exec 格式:
COPY ["源路径1",... "<目标路径>"]
同时可以使用通配符进行作为源路径
COPY hom* /mydir/
COPY hom?.txt /mydir/
ENV
用于设置、定义环境变量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷,避免重要的数据,因容器重启而丢失。
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
CMD
启动的容器指定默认要运行的命令,与RUN命令不同,命令在镜像运行时(docker run)进行,同时如果Dockerfile 中存在多个 CMD 指令,仅最后一个生效。
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] //提供ENTRYPOINT时才能使用
同时CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖,如上面运行镜像的终端:
docker run -it --net host mysql:5.7 "sh"
其中"sh"就是替代的命令。
ENTRYPOINT
类似于 CMD 指令,但不会被 docker run 的命令行参数指定的指令所覆盖。同时如果Dockerfile 中存在多个 ENTRYPOINT指令,仅最后一个生效。
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
EXPOSE
声明端口,给用户说明使用的端口,以方便配置映射。
EXPOSE <端口1> [<端口2>...]
2. 创建简单镜像
- 创建一个新文件夹,在文件夹中创建好名为dockerfile的文件。
六、阿里云镜像服务实践
上面介绍了如何在本地构建镜像,但单单在本地构建的对象是不够的,我们往往还需要一个平台来发布并且管理自己构建的镜像,这时就可以使用阿里云提供的镜像服务。
1.建立仓库
- 首先访问阿里云官方网站
https://cr.console.aliyun.com
,选择登录,没有账号就注册一个账号。
- 仓库信息填写完后,系统还要求选择代码源,因为接下来是直接在CentOs中上传镜像的,所以这里选择的代码源是本地仓库。
- 创建成功后回到仓库列表,就可以看到刚刚创建好的仓库的状态与信息。
2. 上传镜像
-
仓库创建完成后回到CentOs终端,使用docker的login命令进行登录该命令中username 为创建好的阿里云用户名,命令的参数为阿里云的镜像地址,这里根据上面创建好仓库的地域选择,其中shenzhen 代表的是镜像服务器在深圳的地址,另外还有许多的镜像地址,自己看情况选择一个,不过接下来要用相同的地址进行操作。同时,login命令输入后会要求用户输入密码,输入成功后会有登录成功的提示。
docker login --username=ouzj5 registry.cn-shenzhen.aliyuncs.com
-
在上传镜像前,还需要根据刚刚创建好的仓库名字对将要上传的镜像进行标记,标记的作用是将其归入某一仓库。这里的镜像名字前依次是响应仓库的地址、命名空间以及仓库的名字,同时还可以在镜像名字后面添加:tag
作为标签,这里使用hello-wrold作为标签,默认的则为latest
。
docker tag registry.cn-shenzhen.aliyuncs.com/ouzj5/repo:hello-world
- 上传成功后可以点进刚刚创建好的仓库,选择镜像版本,在仓库中可以看到对应标签的镜像已经成创建好了,同时有该标签镜像的各种信息。
3.获取仓库中的镜像
七、docker hub自动构建实践
上面介绍了如何去上传自己构建好的镜像了,但是每一个版本的更新还要进行登录上传,就会感觉十分的麻烦,所以下面实践的是如何利用github 以及 docker hub实现应用的自动构建化,通俗来讲就是每当docker hub检测到github有更新(push),其会自动调用github上的dockerfile进行镜像构建,并且上传到仓库中。
1. 创建账号并且链接github账号
- 这里使用到的平台是外国的docker hub平台,提供与阿里云类似的镜像管理服务,在使用前同样需要先注册一个用户账号,其网站为https://hub.docker.com/,注册成功后进入以下页面。
- 因为这里实现的是对github上面仓库的自动构建,所以需要将docker hub的账号和github 的账号链接起来,选择右上角菜单的Account Setting选项,进入用户设置页面,然后选择Linked Accounts选项。
- 进入到Linked Accounts页面后,可以看到有GitHub链接的选项,可以看到新的账号没有链接,这里选择github上的Connect选项,接下来页面就会要求输入github的账号密码。
- 登录成功后,就可以看到Linked Account中的GitHub项变成了对应的账号了。
2.创建自动化构建镜像仓库
- 在设置自动化构建前,需要在github仓库中给出对应的dockerfile
- 选择菜单上的Repositories选项,进入仓库管理页面,该页面的右上方有一个Create仓库按钮,点下开始创建仓库。
- 进入镜像仓库页面,填写好仓库的基本信息,点击创建仓库后进入仓库页面。
- 进入builds页面后会要求选择构建的仓库的源,这里选择刚刚登录上的额github账号。
- 选择github后,会要求填写github中需要自动构建的源码仓库,填写好其他基本信息点击save and build保存并构建。
- 设置保存后,仓库的build页面就变成了以下的状态,证明开始构建了。
- 设置好后,可以尝试随便push更新github上的代码,可以看到push后build会再次运行,自动构建就弄好了。