devin0910

全干工程师

Docker入门到实践

Dcoker是一个用来编译、迁移和执行应用程序的开源容器引擎,开发者可以借助它把应用程序及其依赖的类库等打包成Docker容器,然后发布到支持任何支持Docker的平台上,就可以正常运行。Docker可以解决”只在我的电脑中可以正常运行”的问题。在团队开发中,使用Docker可以统一开发环境,减少新成员在开发环境搭建上花费的时间,隔离不同成员开发环境间的影响,提高生产效率。

 

Docker与虚拟机的区别

Docker vs 虚拟机

左侧为虚拟机,右侧为Docker

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。Hypervisor,又称虚拟机器监视器(英语:virtual machine monitor,缩写为 VMM),是用来建立与执行虚拟机器的部分电脑软件、固件或硬件。

特性 Docker 虚拟机
虚拟化 硬件层次虚拟化 操作系统层次虚拟化
启动 秒级 分钟级
大小 一般为 MB 一般为 GB
性能 接近原生 比较慢
占用资源 轻量级、单机支持上千个容器 重量级、一般几十个

相关概念

Docker架构图

Docker 架构图

Docker client 是一个命令行工具,使用它与 Docker daemon 进行通信

Docker daemon 是一个常驻进程,它管理着Docker镜像,容器,网络等

Docker Image 用来创建容器的只读模板,每个镜像都有一系列层构成(使用union file system),用户对镜像进行修改后,一个新的层会叠加到原来的最上面层上。

Docker container 是程序运行的最终容器,在Docker Image的上层增加了一个可读写的容器层,每个容器互相隔离,保证安全。

Docker Image分层示例及Container层

Docker Image分层示例及Container层

Dockerfile 一个包含一系列如何构建容器的指令的文件,一般会包含在代码管理中

Registry 是一个存储和分发Docker镜像的服务端程序,官方提供的公用Registry为Docker Hub,上面有很多Docker官方或第三方维护的镜像。

Hello World

curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
sudo usermod -a -G docker $USER

退出命令行才能生效。

Hello World Demo

在命令行中运行 docker run hello-world

docker run 会创建一个新的容器并在里面运行脚本。前面我们提到过,容器是以Docker镜像为模板创建的,这里hello-world是一个docker镜像。创建容器的时候会先查找本地是否存在这个Docker镜像,如果不存在,会从Docker Registry(Docker Hub)上拉取到本地。需要注意的是每个镜像都有个tag,如果不指定tag,默认会使用latest。

列出本地所有的ubuntu镜像

docker images 列出本地所有的ubuntu镜像

使用只读的docker image为模板创建docker container并保持最上层(the container layer)可写入,所有的数据修改都保存在the container layer。image不保存用户状态,只用于创建模板、新建和复制使用。多个正在运行的container可以使用同一个底层image,只保持container layer不同。

多个container共享同一个image

多个container共享同一个image

更多docker run示例

启动nginx并在后台运行

docker run --name nginx-server -p 80:80 -d nginx

–name 指定container名称

-p

-d 容器在后台运行并打印容器ID

生成一个交互式容器

以ubuntu:12.04镜像为模板运行一个新的容器,并在容器退出后删除

如果我们不用–name来指定容器名,默认的容器名是一串随机字符串,在这个例子里是awesome_raman。-i告诉docker engine 即使容器在后台运行也保持容器内的STDIN打开,-t分配一个伪终端,这样我们可以使用docker client与容器进行交互。 我们可以使用 <Ctrl+p, Ctrl+q> 使终端与容器的伪终端分离开,我们可以通过 docker ps 查看正在运行的容器,加 -a 选项会列出所有的已创建的容器。如果想要再进入容器的命令行呢?我们可以使用 docker attatch 命令,在命令后加要进入的容器ID。在容器中可以用/exit退出容器。由于上面使用了–rm选项,在容器停止后,容器也会随之删除。

我们可以像git仓库一样去操作Docker容器,下面我们介绍如何从docker registery拉取一个php-cli镜像,通过这个镜像生成一个新的镜像,提交修改到docker registery中。首先我们把php-cli镜像拉取到本地 docker pull php:7.1.7-cli ,这里我们指定使用 7.1.7-cli这个tag。以这个镜像为模板运行一个新的容器 docker run -it --name php-cli php:7.1.7 /bin/bash 。使用 <Ctrl+p, Ctrl+q> 快捷键使终端与容器的伪终端分离,使用 docker ps 快捷键查看正在运行的容器。 查看正在运行的容器 docker commit -m 'init php-cli-demo' a76dbb919b90 devin0910/php-cli-demo 创建一个新的模板。 创建新的镜像 docker attach php-cli 进入容器,这个镜像中默认没有mysql扩展,运行 docker-php-ext-install pdo_mysql 命令安装mysql扩展,安装完成后再次使用 <Ctrl+p, Ctrl+q> 退出容器。执行 docker commit -m 'install pdo_mysql extension' a76dbb919b90 devin0910/php-cli-demo:with-mysql 提交我们对容器的修改,这里新建了个with-mysql的tag。接下来我们通过docker login登录到docker hub(一个让你与工作伙伴、顾客或社区分享镜像的仓库)上,使用 docker push devin0910/php-cli-demo:with-mysql 推送到docker hub上。 在Docker hub上查看个人镜像 docker stop a76dbb919b90 停止正在运行的容器。

这一篇我们简单的介绍了容器与虚拟机的区别、镜像与容器的区别,了解docker的一些基本操作,并提交到docker hub上。下一篇我们将使用 docker compose 搭建lnmp开发环境。

留言