从零开始学Docker

1.什么是 Docker

Docker 是 Docker 公司的开源项目,使用 Google 公司推出的 Go 语言开发的,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。

下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

2.为什么要使用 Docker?

2.1 更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

2.2 更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

2.3 一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码在我机器上没问题啊” 这类问题。

2.4 持续交付和部署

对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

2.5 更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

2.6 更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

2.7 对比传统虚拟机总结

3 基本概念

Docker 包括三个基本概念

  • 镜像(Image)
  • 容器(Container)
  • 仓库(Repository)

理解了这三个概念,就理解了 Docker 的整个生命周期。

3.1 Docker 镜像

我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像,就相当于是一个 root 文件系统。比如 Docker 官方镜像 ubuntu:14.04 就包含了完整的一套 Ubuntu 14.04 最小系统的 root 文件系统。

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

3.2 Docker 容器

镜像和容器的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失。

3.3 Docker 仓库

镜像构建完成后,可以很容易的在当前宿主上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

3.4 安装 Docker

官方网站上有各种环境下的 安装指南,这里主要介绍下 CentOS 的安装。

4 CentOS 操作系统安装 Docker

4.1 系统要求

Docker 需要安装在 CentOS 7 64 位的平台,并且内核版本不低于 3.10. CentOS 7.× 满足要求的最低内核版本要求,但由于 CentOS 7 内核版本比较低,部分功能(如 overlay2 存储层驱动)无法使用,并且部分功能可能不太稳定。所以建议大家升级到最新的 CentOS 版本,并且内核也更新到最新的稳定版本。

4.2 使用阿里云的安装脚本自动安装

为了简化 Docker 安装流程,我们可以使用阿里云提供的一套安装脚本,CentOS 系统上可以使用这套脚本安装 Docker :

首先,查看阿里云ECS Linux服务器系统内核版本:

1
uname -r

安装epel

1
yum install epel-release -y

1
yum clean all

1
yum list

会出现非常多的包

yum安装docker-io

1
sudo yum -y install docker-io

安装成功,最终会出现Complete字样

启动Docker

1
systemctl start docker

检查Docker服务,一般出现下图的信息说明Docker初步是安装成功的

1
docker info

执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 安装在系统中。

Docker 通过运行 hello-world 映像验证是否正确安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ docker run hello-world

> Unable to find image 'hello-world:latest' locally
> latest: Pulling from library/hello-world
> b04784fba78d: Pull complete
> Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
> Status: Downloaded newer image for hello-world:latest

> Hello from Docker!
> This message shows that your installation appears to be working correctly.

> To generate this message, Docker took the following steps:
> 1. The Docker client contacted the Docker daemon.
> 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
> 3. The Docker daemon created a new container from that image which runs the
> executable that produces the output you are currently reading.
> 4. The Docker daemon streamed that output to the Docker client, which sent it
> to your terminal.

> To try something more ambitious, you can run an Ubuntu container with:
> $ docker run -it ubuntu bash

> Share images, automate workflows, and more with a free Docker ID:
> https://cloud.docker.com/

> For more examples and ideas, visit:
> https://docs.docker.com/engine/userguide/

此命令下载测试镜像并在容器中运行它。当容器运行时,它打印一条信息消息并退出。如果你没有配置镜像加速器的话,运行 hello-world 映像验证也是不会成功的.因为国内网络的原因,无法下载测试镜像,更别说运行测试镜像了,所以这一步可以先跳过,继续往下看,等一下配置完镜像加速器再来验证.

查看当前 Docker 的版本
1
2
3
$ docker -v

> Docker version 17.05.0-ce, build 89658be

可以看出当前的 Docker 为 Docker CE 17.05.0 版本,CE 代表 Docker 社区版,EE 代表 Docker 企业版.

卸载 Docker CE

卸载Docker软件包:

1
$ yum remove docker-ce
卸载旧版本 Docker

较老版本的 Docker 被称为 docker 或 docker-engine。如果这些已安装,请卸载它们以及关联的依赖关系。

1
$ yum remove docker docker-common docker-selinux docker-engine

主机上的图像,容器,卷或自定义配置文件不会自动删除。必须手动删除任何已编辑的配置文件。删除所有图像,容器和卷:

1
$ rm -rf /var/lib/docker

给镜像打标签

1
docker tag ubuntu ubuntu1

改变tag值,区分标签

1
docker tag ubuntu ubuntu2:123

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
docker run -itd centos //把镜像启动为容器,-i表示让容器的标准输入打开,-t表示分配一个伪终端,-d表示后台启动
docker ps //查看运行的容器,加上-a选项后可以查看所有容器,包括未运行的
docker rmi centos //用来删除指定镜像,其中后面的参数可以是tag,如果是tag时,实际上是删除该tag。当后面的参数为镜像ID时,则会彻底删除整个镜像,所有标签也会一同删除

##### 参考文档

参见 Docker 官方 CentOS 安装文档.

##### 镜像加速器

国内访问 Docker Hub 有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了加速器服务,例如:

阿里云加速器
注册用户并且申请加速器,会获得如 https://jxus37ad.mirror.aliyuncs.com 这样的地址。我们需要将其配置给 Docker 引擎。

用 systemctl enable docker 启用服务后,编辑 /etc/systemd/system/multi-user.target.wants/docker.service 文件,找到 ExecStart= 这一行,在这行最后添加加速器地址 --registry-mirror=<加速器地址>,如:

ExecStart=/usr/bin/dockerd --registry-mirror=https://jxus37ad.mirror.aliyuncs.com
注:对于 1.12 以前的版本,dockerd 换成 docker daemon。

重新加载配置并且重新启动。

``` bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
检查加速器是否生效

Linux系统下配置完加速器需要检查是否生效,在命令行执行 ps -ef | grep dockerd,如果从结果中看到了配置的 –registry-mirror 参数说明配置成功。

1
2
3
$ sudo ps -ef | grep dockerd

> root 5346 1 0 19:03 ? 00:00:00 /usr/bin/dockerd --registry-mirror=https://jxus37ad.mirror.aliyuncs.com
使用 Docker 镜像

Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下载(默认是 Docker Hub 公共注册服务器中的仓库)。

获取镜像

阿里云镜像库 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像并运行。

获取镜像的命令是 docker pull。其命令格式为:

docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
具体的选项可以通过 docker pull –help 命令看到,这里我们说一下镜像名称的格式。

Docker Registry地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
仓库名:如之前所说,这里的仓库名是两段式名称,既 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像.一定要配置镜像加速器,不然下载速度很慢。
比如:

1
2
3
4
5
6
7
8
9
10
$ docker pull ubuntu:14.04

14.04: Pulling from library/ubuntu
bf5d46315322: Pull complete
9f13e0ac480c: Pull complete
e8988b5b3097: Pull complete
40af181810e7: Pull complete
e6f7c7e5c03e: Pull complete
Digest: sha256:147913621d9cdea08853f6ba9116c2e27a3ceffecf3b492983ae97c3d643fbbe
Status: Downloaded newer image for ubuntu:14.04

上面的命令中没有给出 Docker Registry 地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:14.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 14.04 的镜像。

查看已下载的镜像

要想列出已经下载下来的镜像,可以使用 docker images 命令。

1
2
3
4
5
$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 1815c82652c0 3 weeks ago 1.84kB
ubuntu 14.04 4a2820e686c4 2 weeks ago 188 MB

列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间。

运行

有了镜像后,我们就可以以这个镜像为基础启动一个容器来运行。以上面的 ubuntu:14.04 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ docker run -it --rm ubuntu:14.04 bash

root@e7009c6ce357:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="14.04.5 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.5 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
root@e7009c6ce357:/# exit
exit

docker run 就是运行容器的命令,具体格式我们会在后面的章节讲解,我们这里简要的说明一下上面用到的参数。

-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
–rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间。
ubuntu:14.04:这是指用 ubuntu:14.04 镜像为基础来启动容器。
bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。
进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了 cat /etc/os-release,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 14.04.5 LTS 系统。

最后我们通过 exit 退出了这个容器。

定制镜像

现在让我们以定制一个 Web 服务器为例子,来讲解镜像是如何构建的。

安装nginx

1
docker run -it --name my-nginx -d -p 80:80 nginx

这条命令会用 nginx 镜像启动一个容器,命名为 webserver,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器。

如果是在 Linux 本机运行的 Docker,或者如果使用的是 Docker for Mac、Docker for Windows,那么可以直接访问:http://localhost;如果使用的是 Docker Toolbox,或者是在虚拟机、云服务器上安装的 Docker,则需要将 localhost 换为虚拟机地址或者实际云服务器地址,还要配置安全组放通对应的端口。

直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。

5 Docker的使用

5.1 Docker通过容器创建镜像

通过docker run -it –rm centos bash启动容器后,bash为进入容器后我们要执行的命令,这样就可以打开一个终端

进入到改容器中,我们做一些变更,比如安装一些东西,然后针对这个容器进行创建新的镜像

想要查看net信息,ifcongif出现command not found,在容器中执行yum install -y net-tools

1
docker commit -m "change somth" -a "somebody info" container_id new_image_name //container_id通过docker ps -a 获取,后面的new_image_name为新镜像的名字

例如:docker commit -m “install net-tools” -a “amingLinux” ea4d8441675e centos_nettools

这个命名有点像svn的提交,-m 加一些改动信息,-a 指定作者相关信息,ea4d8441675e这一串为容器Id,再后面为新镜像的名字。

5.2 Docker使用模板创建镜像

首先去下载一个模板 https://openvz.org/Download/templates/precreated

导入改镜像的命令为:cat centos-6-x86-minimal.tar.gz|docker import - centos6

docker images查看导入的镜像

把现有镜像导出为一个文件:docker save -o aming-centos.tar

我们还可以用该文件恢复本地镜像:docker load –input aming-centos.tar 或者 docker load < aming-centos.tar

docker push image_name //可以把自己的镜像传到dockerhub官方网站上去,但前提是需要先注册一个用户,后续如果有需求在间就吧

5.3 Docker容器管理

docker create -it centos6 bash //这样就可以创建一个容器,但该容器并没有启动

docker start container_id //启动容器后,可以使用docker ps 查看到,有start就有stop和restart

之前我们使用的docker run 相当于先create再start

docker run -it centos bash

这样就进入到了一个虚拟终端里面,我们可以运行一些命令,使用命令exit或ctrl d 退出该bash,当退出后这个容器也会停止

docker run -d 可以让容器在后台运行

比如:docker run -d centos bash -c “while :;do echo “123”;sleep 2;done”

docker run –name web -itd centos bash //–name给容器自定义名字

docker run –rm -it centos bash -c “sleep 30” //–rm可以让容器退出后直接删除,在这里命令执行完容器就会退出

docker logs 可以获取容器运行历史信息,用法如下

1
docker logs container_id

docker attach 可以进入一个后台运行的容器,比如

docker attach container_id //但是attach命令不算好用,比如我们想退出终端,就得exit了,这样容器也就退出了,还有一种方法

docker exec -it container_id bash //可以临时打开一个虚拟终端,但exit后容器依然运行着

docker rm container_id //container_id是ps的时候查看到的,这样就可以把container删除,如果是运行的容器可以加-f

docker export container_id > file.tar //导出容器,可以迁移到其他机器上,需要导入

cat file.tar |docker import -aming_test //这样会生成aming_test的镜像

5.4 Docker仓库管理

配置私有仓库

docker pull registry //下载registry镜像,registry为Docker官方提供的一个镜像,我们可以用它来创建本地的Docker私有仓库

docker run -d -p 5000:5000 registry //以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口

curl 127.0.0.1:5000/v2/_catalog //可以访问它

下面我们来把其中一个镜像上传到私有仓库

第一步打tag

1
docker tag aming_test 172.7.15.113:5000/centos   //标记一下tag,必须要带有私有仓库的ip:port

第二步push

docker push 172.7.15.113:5000/centos //把标记的镜像给推送到私有的仓库

出现:The push refers to a repository [47.95.112.137:5000/centos6]
An image does not exist locally with the tag: 47.95.112.137:5000/centos6

此时并不会成功需指定私有仓库地址,更改配置文件,vi /etc/docker/daemon.json,添加{“insecure-registries”:[“172.7.15.113:5000”]}

重启systemctl restart docker , docker ps -a 查看容器已经关闭,还需要重启

docker start id //这里的id为registry容器id

再次push

docker push 172.7.15.113:5000/centos

curl 127.0.0.1:5000/v2/_catalog //可以查看到推送上来的镜像

从私有仓库下载镜像

docker pull 172.7.15.113:5000/centos

5.5 Docker数据管理

1 挂载本地的目录到容器里

docker run -tid -v /data/:/data centos bash //-v用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动创建

2 挂载数据卷

其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如上面我们没有指定,它就生成了一个名字为relaxed_franklin,这个名字可以使用命令docker ps 看最右侧一列

docker run -itd –volumes-from relaxed_franklin aming123 bash //relaxed_franklin为容器名,docker ps可知

这样,我们使用aming123镜像创建了新的容器,并且使用了relaxed_franklin容器的数据卷

3 定义数据卷容器

有时候,我们需要多个容器之间相互共享数据,类似于linux里的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂在改数据卷

首先建立数据卷容器

docker run -itd -v /data/ –name testvol centos bash //注意这里的/data/是容器的/data目录,并非本地的/data/目录

然后让其他容器挂载改数据卷

docker run -itd –volumes-from testvol aming123 bash //testvol为数据卷容器名,aming123为镜像

如果想home目录也共享 mv /home/ /home.1; ln -s /data/ home //软链接

4 数据卷管理 - 数据卷的备份与恢复
备份
1
2
mkdir /vol_data_backup
docker run --volumes-from testvol -v /vol_data_backup/:/backup aming centos tar cvf /backup/data.tar /data/

说明:首先我们需要使用testvol数据卷新开一个容器,同时我们还需要把本地的/vol_data_backup/目录挂载到改容器的/backup下,这样在容器中/backup目录里面新建的文件

我们就可以直接在/vol_data_backup/目录中看到了。然后再把/data/目录下面的文件打包成data.tar文件放到/backup目录下面

恢复

思路:先新建一个数据卷容器,在建一个新的容器并挂载该数据卷容器,然后再把tar包解压。

新建数据卷容器:docker run -itd -v /data/ –name testvol2 aming/centos bash

挂载数据卷新容器,并解包:docker run –volumes-from testvol2 -v /vol_data_backup/:/backup aming/centos tar xvf /backup/data.tar

5 Docker网络模式
  • host模式,使用docker run 时使用–net=host指定

docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机ip

  • container模式,使用–net=container:container_id/container_name

多个容器使用共同的网络,看到的ip是一样的

  • none模式,使用–net=none指定,这种模式下,不会配置任何网络

  • bridge模式,使用–net=bridge指定默认模式,不用指定默认就是这种网络模式

这种模式会为每个容器分配一个独立的Network Namespace。 类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。

6 Docker网络管理 - 外部访问容器

首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务并启动

再把该容器导成一个新的镜像(centos-httpd),然后再使用新镜像创建容器并指定端口映射

docker run -itd -p 5123:80 centos-httpd bash //-p 可以指定端口映射,本例中将容器的80端口映射为本地的5123端口

docker exec -it container_id bash

启动httpd:httpd -k start

编辑1.html:vi/var/www/html/1.html 随便写点东西

退出该容器:exit

测试:curl 127.0.0.1:5123/1.html

-p后面也支持IP:port:ip:port的格式,比如:-p 127.0.0.1:8080:80

也可以不写本地的端口,只写ip,这样会随意分配一个端口

-p 127.0.0.1::80 //注意这里是两个冒号

***例如:
进入容器里下载nginx
yum install -y epel-release
yum install -y nginx

此时启动nginx会报错systemctl start nginx Failed to get D-Bus connection: Operation not permitted

安装完成nginx,将容器打包成镜像,

运行镜像映射端口:

内网curl localhost和外网curl 宿主机ip:8088均可访问

Operation not permitted

新建的容器,启动nginx或者httpd服务的时候会报错

Failed to get D-Bus connection:Operation not permitted,这是因为dbus-daemon没有启动,解决该问题可以这样做

启动容器时,要加上–privileged -e “container=docker” , 并且最后面的命令改为/usr/sbin/init

docker run run -itd –privileged -e “container=docker” -p 8088:80 centos_with_nginx /usr/sbin/init

7 Docker网络管理 - 容器互联

下载一个mysql镜像 docker pull mysql

新建一个容器命名为db , docker run -it -d -p 13306:3306 –name db mysql bash

在新建一个web容器,并和db互联

docker run -it -d -p 12308:80 –name web –link db:db centos-httpd bash //db:db意思为db容器在web容器里的别名为db

在web上运行env命令可以查看到关于db环境变量

8 Docker网络管理 - 配置桥接网络

为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上ip就可以了。

cd /etc/sysconfig/network-scripts/; cp ifcfg-eth0 ifcfg-br0

vi ifcfg-eth0 //增加BRIDGE=br0, 删除IPADDR,NETMASK,GATEWAY, DNS1

vi ifcfg-br0 //修改DEVICE为br0, Type为bridge,把eth0的网络设置到这里来

systemctl restart network

安装pipwork

git clone https://github.com/jpetazzo/pipwork

cp pipework/pipework /usr/local/bin/

开启一个容器

docker run -itd –net=none –name aming123 centos_with_nettool bash

pipework br0 aming123 172.7.15.201/24@172.7.15.3 // #201为容器的ip,@后面的ip为网关ip

docker exec -it aming123 bash //#进去后ifconfig查看就可以看到新添加的ip

9 Dockerfile创建镜像 - dockerfile格式
  1. FROM //指定基于哪个基础镜像

格式 FROM 或者 FROM :,比如:FROM centos , FROM centos:latest

  1. MAINTAINER //指定作者信息

格式:MAINTAIN , 比如:MAINTAINER aming aming@aminglinux.com

  1. RUN //镜像操作指令

格式为 RUN 或者 RUN [“executable”,”param1”,”param2”]

比如:RUN yum install httpd , RUN [“/bin/bash”,”-c”,”echo hello”]

  1. CMD //三种格式

CMD [“executable”,”param1”,”param2”]
CMD command param1 param2
CMD [“param1”,”param2”]

RUN和CMD看起来挺像,但是CMD用来指定容器启动时用到的命令,只能有一条。比如:

CMD [“/bin/bash”,”/usr/local/nginx/sbin/nginx”,”-c”,”/usr/local/nginx/conf/nginx.conf”]

  1. EXPOSE

格式为 EXPOSE […],比如 EXPOSE 22 80 8443

这个用来指定要映射出去的端口,比如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴露出去。这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。

  1. ENV

格式 ENV , 比如

ENV PATH /usr/local/mysql/bin:$PATH

它主要是为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量

ENV MYSQL_version 5.6

  1. ADD 格式add

将本地的一个文件或目录拷贝到容器的某个目录里。其实src为Dockerfile所在目录的相对路径,它也可以是一个url。比如: ADD <conf/vhosts> </usr/local/nginx/conf>

  1. COPY

格式同add,使用方法和add一样,不同的是,它不支持url

  1. ENTRYPOINT 格式类似CMD

容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条生效。和CMD不同是:

CMD是可以被docker run 指令覆盖的,而ENTRYPOINT不能覆盖。比如,容器名字为aming,我们在Dockerfile中指定如下CMD:

CMD [“/bin/echo”,”test”]

启动容器的命令是docker run aming 这样会输出test, 假如启动容器的命令是docker run -it aming /bin/bash 什么都不会输出

ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行

ENTRYPOINT [“echo”,”test”]

docker run -it aming 123

则会输出test 123 ,这相当于要执行命令echo test 123

  1. VOLUME

格式 VOLUME [“/data”]

创建一个可以从本地主机或其他容器挂载的挂载点

  1. USER

格式 USER daemon

指定运行容器的用户

  1. WORKDIR /path/to/workdir

为后续的RUN、CMD或者ENTRYPOINT指定工作目录

  1. Dockerfile创建镜像 - Dockerfile示例

先下载nginx的配置文件

wget http://www.apelearn.com/study_v2/nginx_conf

vim Dockerfile //内容如下

##Set the base image to CentOS
FROM centos

#File Author / Maintainer
MAINTAINER aming aming@aminglinux.com

#Install necessary tools
RUN yum install -y pcre-devel wget net-tools gcc zlib-devel make openssl-devel

#Install Nginx
ADD http://nginx.org/download/nginx-1.8.0.tar.gz .
RUN tar zxvf nginx-1.8.0.tar.gz
RUN mkdir -p /usr/local/nginx
RUN cd nginx-1.8.0 && ./configure –prefix=/usr/local/nginx && make && make install
RUN rm -fv /usr/local/nginx/conf/nginx.conf
ADD http://www.apelearn.com/study_v2/ .nginx_conf /usr/local/nginx/conf/nginx.conf

Expose ports

EXPOSE 80

Set the default command to execute when creating a new container

ENTRYPOINT /usr/local/nginx/sbin/nginx && tall -f /etc/passwd

创建镜像

docker build -t centos_nginx . //.表示在哪个路径下

docker images //可以看到我们新建的镜像

docker run -itd -p 8088:80 centos_nginx bash