目录
- Docker安装
1.1. Windows
1.2. Ubuntu - Docker容器的使用
2.1. 启动一个新的容器
2.2. 挂起运行的程序
2.3. 重启被挂起的程序
2.4. 终止容器运行
2.5. 重新运行已有容器 - Docker资源的管理
3.1. 管理镜像资源
3.2. 管理容器资源
3.3. 管理网络资源
3.4. 创建自己的镜像 - References
在我电脑上没问题啊!
如果你看懂了上面这句话,说明我们是同道中人。写程序有四种痛:
- 起早摸黑写好了代码,在自己的电脑上运行的好好,但是到了另一台电脑上各种问题层出不穷,软件越复杂依赖越多,头就越大;
- 想干一件大事,辛历尽千辛万苦配置好了环境,换了电脑又要从头再来。或者某天无意对电脑做了小小的改动,环境崩了;
- 想研究个新技术或者学个新技能,仅仅是搭建环境已经竭尽全力,你还不能确定有没有遗漏;
- 头发越来越少。
幸运的是,除了第四点,前三点已经有了解决方案,它就是Docker —— 容器化技术。它可以通过容器来构建、运行和分发应用程序。借用Java的口号就是:一次配置,到处运行。
或许你会问,既然已经有了虚拟机,为什么还要搞出个容器?容器化其实就是一种虚拟化技术,与传统虚拟机相比,它有着轻量、独立、可伸缩、可移植以及灵活等特点。容器直接运行于内核之上,多个容器共用系统的内核,直接通过内核获取系统资源,用多少取多少;而虚拟机则通过一个管理程序来获取宿主系统的资源,运行在其上的程序有着自己的内核,就算你跑的是个Hello World
,它也占用这很大一块资源。拿吃饭打个比方,容器是按点的菜收钱:你点多少菜付多少钱;虚拟机是按人头收钱,只要你人在那,就算你只喝了一口水也照样收你这么多钱。它的区别如图1所示。
当然,我不止一次说过,工具是不分优劣的。某种特定场合下,某个工具更合适,仅此而已。“杀鸡焉用牛刀”,说的也不是那种刀比另一种刀更好。这篇文章的主要目的是介绍Docker的用法。
0. Docker简介
Docker引擎由客户端(Client)、守护进程(Daemon)和注册表(Register)三部分组成,如图2所示。用户通过客户端发送命令来管理Docker的资源,包括镜像、容器、网络等(镜像和容器的关系就类似于程序和进程的诶关系);守护进程接收客户端以及API发过来命令来操纵容器,从而实现镜像、容器、网络等资源的管理;而注册表就是一个仓库,放着各种各样的镜像。因此,使用Docker主要就是使用Docker客户端命令。
Docker客户端的命令,可以大致分为三部分,每个部分又可以接着细分:
- Docker安装;
- Docker容器的使用;
- Docker资源的管理;
1. Docker安装
安装原本说是没有什么好说的,但是由于在Windows 10上Docker和VirtualBox不能共存,因此还是简单介绍介绍下。
1.1. Windows
- 首先,在Windows下,首先要打开
Hyper-V
选项,打开方式为:【控制面板】=>【程序】=>【程序和功能】=>【启用或关闭Windows功能】,然后勾选Hyper-V
及其子选项;
- 接下来,就直接到官网下载安装Windows版本即可。
值得注意的是,Docker和VirtualBox不能共存,因此你只能二选一。安装了Docker后,回头你再想用VirtualBox可能会遇到VT-x is not available (VERR_VMX_NO_VMX)
这个错误,解决方法如下:
- 以管理员身份打开命令提示符;
- 输入
bcdedit
回车,你看到的应该看到hypervisorlaunchtype
的值是auto
; - 输入
bcdedit /set hypervisorlaunchtype off
并回车; - 重启电脑。
1.2. Ubuntu
在Ubuntu下安装Docker,依次输入以下命令即可:
# Commands for install docker on Ubuntu,if command fail, consult [https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
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
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
# x86_64 / amd64
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# Test
sudo docker run hello-world
2. Docker容器的使用
Docker使用可分为以下三个部分:
- 启动新容器;
- 挂起一个容器;
- 重启被挂起的容器;
- 停止容器;
- 重新启动已有容器
这里只列举一些常用的,以及一般场景下够用的命令。
2.1. 启动一个新的容器
启动一个新容器的命令为docker run
,常用命令大致如下:
docker run -it -v <host dir>:<container dir> -w/<container dir> --name <your container name> --rm <your docker image name>
-it
表示启动一个交互式的容器,也就是你可以在命令行输入命令进行交互;
-v
将本地目录和容器中的一个目录做映射,这样在容器中就能直接访问该目录下的内容;
-w
指定容器启动后的工作目录;
--name
用于个这个容器分配一个名字,方便表明该容器的目的以及后续管理;
--rm
表示当容器退出后自动删除。
例如:
docker run -it -v `pwd`/docker:/workspace -w/workspace --name ubuntu:16.04 ubuntu:16.04
上面命令中通过ubuntu:16.04这个镜像创建了一个名叫ubuntu:16.04的容器可交互的。使用docker run
的时候,如果本地没有指定的镜像,Docker会尝试从远程注册表(仓库)中寻找,找到后拉取(pull)到本地再创建。
2.2. 挂起运行的程序
docker pause CONTAINER [CONTAINER...]
2.3. 重启被挂起的程序
docker unpause CONTAINER [CONTAINER...]
2.4. 终止容器运行
如果是交互式的容器,直接输入exit
便退出了容器。如果是非交互式的容器,通过以下命令:
docker stop <container id or name>
有时候容器运行了很久,我都不记得容器名字和ID了,怎么办?可以通过以下命令获取所有容器信息:
docker container ls -a
2.5. 重新运行已有容器
# -i , optional, starting interactive
docker start -i <container id or name>
3. Docker资源的管理
Docker的镜像和容器的关系,就类似于程序和进程的关系。镜像是一个只读文件,它里面包含了如何创建一个容器的指令和模板;而容器就是一个镜像的实例。镜像和容器都是Docker引擎管理的重要资源,此外,还有网络资源、集群资源、插件和磁盘资源等。这里只介绍简单使用场景下常用的一些管理命令:
- 管理镜像资源;
- 管理容器资源;
- 管理网络资源;
- 创建自己的镜像。
其实管理Docker资源的命令和我们一般使用的Linux命令很类似,基本命令构成为docker <resources type> <linux/git command>
。<resources type>
可以是image
、container
、network
等,而<linux/git command>
则可以是ls
、rm
、commit
等。例如:
# list local images
docker image ls -a
# remove local images
docker image rm <image id/name>
docker container ls -a
docker container rm <container id>
实际使用过程中,也可以类似Linux中man COMMAD
去查看某个命令用法一样,可以使用直接使用`docker <resources type>查看具体命令的用法,例如:
$ docker network
Usage: docker network COMMAND
Manage Docker networks
Options:
--help Print usage
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
3.1. 管理镜像资源
- 远程镜像搜索;
- 拉取镜像到本地;
- 本地镜像查看;
- 本地镜像移除。
我们使用Docker的时候,首先,可以向看看本地有没有我们想要的镜像:
docker images # or docker image ls -a
如果本地没有,可以使用以下命令搜索注册表上有没有我们想要的:
docker search [OPTIONS] TERM
# 例如:docker search ubuntu
搜索出来所有可用的镜像后选择自己想要的,拉取到本地:
docer pull <image name>
# 例如:docker pull ubuntu:16.04
其实,当我们直接使用docker run
的时候,docker run
就是首先执行上面三步。
当有些镜像我们不再需要了,我们可以删除
docker image rm <image id/name>
3.2. 管理容器资源
与镜像资源类似,对容器的管理也是类似的:
- 查看已有容器;
- 删除已有容器;
- 查看某个容器详细信息;
- 容器的创建、暂停、重新运行等。
查看容器:
docker container ls -a
通过列出的容器,可以获取到容器的ID或者名字,进而可以删除容器:
docker container rm <container id/name>
或者,查看容器的详细信息:
docker container inspect <container id/name>
而对于容器的创建、重启等操作前面已经介绍过了。
3.3. 管理网络资源
网络资源,其实就是专门给容器使用虚拟网络设备。默认情况下会有个一个名字是brigde
的路由器,所有容器如果未经指定都会链接到上面,组成一个局域网。对网络资源的管理可以使用以下命令:
查看已有的网络资源:
docker network ls
查看某个网络资源的详细信息:
docker network inspect <network id/name>
网络资源的创建和删除:
docker network create
docket network rm <network id/name>
网络的链接和断开:
docker network connect <network> <container>
docker network disconnect <network> <container>
3.4. 创建自己的镜像
Docker相比于虚拟机的优势,主要就是它能够很轻易的分享,或者说转移已经配置好的环境,并且体积相对于整个虚拟可以小很多。这个是怎么实现的呢?主要有两种方法:
- 将已有容器打包成镜像,然后推到远程仓库;
- 在已有的镜像基础上,通过Dockerfile中的命令创建一个新的镜像。
从已有容器打包可以使用以下命令:
docker container commit --author <author name> -m <new image description> <container id/name> <image name>
例如,我运行了一个Ubuntu16.04的容器,并为它配置了adb(Android Debug Bridge)环境。为了能在别的机器上使用Ubuntu16.04的时候可以不用再配置adb,我将它打包成了一个新的镜像,命令和结果显示如下:
zhou@zhou:~$ docker container commit --author SunnyZhou -m 'Add adb' dbc7bdb56f2a ubuntu_with_adb:16.04
sha256:de247093e26e4e91eb4470d14067cdde094bddb46c063964ff254967282de113
zhou@zhou:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu_with_adb 16.04 de247093e26e 11 seconds ago 128MB
ubuntu 16.04 77be327e4b63 2 months ago 124MB
第二种方法是通过Dockerfile来创建新的容器,一个简单的例子是,还是创建一个带adb的Ubuntu16.04:
首先编写Dockerfile(完整的Dockerfile命令参看文末参考文档):
FROM ubuntu:16.04
COPY platform-tools/adb /sbin/adb
然后使用docker build
来创建:
zhou@zhou:~/docker$ vi Dockerfilezhou@zhou:~/docker$ docker build . --tag ubuntu-adb:16.04Sending build context to Docker daemon 26.95MB
Step 1/2 : FROM ubuntu:16.04
---> 77be327e4b63
Step 2/2 : COPY platform-tools/adb /sbin/adb
---> 1a5e2b476d20
Successfully built 1a5e2b476d20
Successfully tagged ubuntu-adb:16.04
这篇文章知识Docker的一篇概览,也是我日常使用Docker最多的命令。完整的命令请参看参考文档。
References
[1] https://docs.docker.com/engine/reference/commandline/docker/
[2] https://docs.docker.com/get-started/overview/
[3] https://docs.docker.com/docker-for-windows/install/
[4] https://docs.docker.com/engine/reference/builder/#usage
[5] https://github.com/docker/labs