Docker,系统影分身之术

目录

  1. Docker安装
    1.1. Windows
    1.2. Ubuntu
  2. Docker容器的使用
    2.1. 启动一个新的容器
    2.2. 挂起运行的程序
    2.3. 重启被挂起的程序
    2.4. 终止容器运行
    2.5. 重新运行已有容器
  3. Docker资源的管理
    3.1. 管理镜像资源
    3.2. 管理容器资源
    3.3. 管理网络资源
    3.4. 创建自己的镜像
  4. References

在我电脑上没问题啊!

It works on my machine

如果你看懂了上面这句话,说明我们是同道中人。写程序有四种痛:

  1. 起早摸黑写好了代码,在自己的电脑上运行的好好,但是到了另一台电脑上各种问题层出不穷,软件越复杂依赖越多,头就越大;
  2. 想干一件大事,辛历尽千辛万苦配置好了环境,换了电脑又要从头再来。或者某天无意对电脑做了小小的改动,环境崩了;
  3. 想研究个新技术或者学个新技能,仅仅是搭建环境已经竭尽全力,你还不能确定有没有遗漏;
  4. 头发越来越少。

幸运的是,除了第四点,前三点已经有了解决方案,它就是Docker —— 容器化技术。它可以通过容器来构建、运行和分发应用程序。借用Java的口号就是:一次配置,到处运行。

或许你会问,既然已经有了虚拟机,为什么还要搞出个容器?容器化其实就是一种虚拟化技术,与传统虚拟机相比,它有着轻量、独立、可伸缩、可移植以及灵活等特点。容器直接运行于内核之上,多个容器共用系统的内核,直接通过内核获取系统资源,用多少取多少;而虚拟机则通过一个管理程序来获取宿主系统的资源,运行在其上的程序有着自己的内核,就算你跑的是个Hello World,它也占用这很大一块资源。拿吃饭打个比方,容器是按点的菜收钱:你点多少菜付多少钱;虚拟机是按人头收钱,只要你人在那,就算你只喝了一口水也照样收你这么多钱。它的区别如图1所示。

Fig 1 Container vs VM

当然,我不止一次说过,工具是不分优劣的。某种特定场合下,某个工具更合适,仅此而已。“杀鸡焉用牛刀”,说的也不是那种刀比另一种刀更好。这篇文章的主要目的是介绍Docker的用法。

0. Docker简介

Docker引擎由客户端(Client)、守护进程(Daemon)和注册表(Register)三部分组成,如图2所示。用户通过客户端发送命令来管理Docker的资源,包括镜像、容器、网络等(镜像和容器的关系就类似于程序和进程的诶关系);守护进程接收客户端以及API发过来命令来操纵容器,从而实现镜像、容器、网络等资源的管理;而注册表就是一个仓库,放着各种各样的镜像。因此,使用Docker主要就是使用Docker客户端命令。

Fig 2 Docker's architecture

Docker客户端的命令,可以大致分为三部分,每个部分又可以接着细分:

  1. Docker安装;
  2. Docker容器的使用;
  3. Docker资源的管理;

1. Docker安装

安装原本说是没有什么好说的,但是由于在Windows 10上Docker和VirtualBox不能共存,因此还是简单介绍介绍下。

1.1. Windows

  1. 首先,在Windows下,首先要打开Hyper-V选项,打开方式为:【控制面板】=>【程序】=>【程序和功能】=>【启用或关闭Windows功能】,然后勾选Hyper-V及其子选项;
Fig 3 Windows configuration
  1. 接下来,就直接到官网下载安装Windows版本即可。

值得注意的是,Docker和VirtualBox不能共存,因此你只能二选一。安装了Docker后,回头你再想用VirtualBox可能会遇到VT-x is not available (VERR_VMX_NO_VMX)这个错误,解决方法如下:

  1. 以管理员身份打开命令提示符;
  2. 输入bcdedit回车,你看到的应该看到hypervisorlaunchtype的值是auto
  3. 输入bcdedit /set hypervisorlaunchtype off并回车;
  4. 重启电脑。

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使用可分为以下三个部分:

  1. 启动新容器;
  2. 挂起一个容器;
  3. 重启被挂起的容器;
  4. 停止容器;
  5. 重新启动已有容器

这里只列举一些常用的,以及一般场景下够用的命令。

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引擎管理的重要资源,此外,还有网络资源、集群资源、插件和磁盘资源等。这里只介绍简单使用场景下常用的一些管理命令:

  1. 管理镜像资源;
  2. 管理容器资源;
  3. 管理网络资源;
  4. 创建自己的镜像。

其实管理Docker资源的命令和我们一般使用的Linux命令很类似,基本命令构成为docker <resources type> <linux/git command><resources type>可以是imagecontainernetwork等,而<linux/git command>则可以是lsrmcommit等。例如:

# 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. 管理镜像资源

  1. 远程镜像搜索;
  2. 拉取镜像到本地;
  3. 本地镜像查看;
  4. 本地镜像移除。

我们使用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. 管理容器资源

与镜像资源类似,对容器的管理也是类似的:

  1. 查看已有容器;
  2. 删除已有容器;
  3. 查看某个容器详细信息;
  4. 容器的创建、暂停、重新运行等。

查看容器:

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相比于虚拟机的优势,主要就是它能够很轻易的分享,或者说转移已经配置好的环境,并且体积相对于整个虚拟可以小很多。这个是怎么实现的呢?主要有两种方法:

  1. 将已有容器打包成镜像,然后推到远程仓库;
  2. 在已有的镜像基础上,通过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最多的命令。完整的命令请参看参考文档。

本文首发于个人微信公众号TensorBoy,微信扫描上方二维码或者微信搜索TensorBoy并关注,及时获取最新文章。C++ | Python | 推理引擎 | AI框架源码,有一起玩耍的么?

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • docker常用命令原理图概览: 按照docker官网上的说法,docker的文件系统分为两层:bootfs和ro...
    燕京博士阅读 2,959评论 2 32
  • docker基本概念 1. Image Definition 镜像 Image 就是一堆只读层 read-only...
    慢清尘阅读 8,744评论 1 21
  • 一、Docker容器概述 1、docker中的容器技术演进 lxc --> libcontainer --> ru...
    任总阅读 3,923评论 0 26
  • 特别说明: 本人平时混迹于 B 站,不咋回复这里的评论,有问题可以到 B 站视频评论区留言找我视频地址: http...
    撸帝阅读 866评论 1 3
  • 持续整整一年的奋斗,没有一刻敢停歇,没有一刻敢松懈,那种大脑用光用尽的感觉让我痛苦不堪,同时又感到无比的惬意,努力...
    千夜凡尘阅读 168评论 0 0