1.docker的基本概念:
Docker包括三个基本概念
镜像(Image)
容器(Container)
仓库(Repository)
理解了这三个概念,就理解了Docker 的整个生命周期。
Docker镜像
Docker 镜像就是一个只读的模板。
例如:一个镜像可以包含一个完整的ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
镜像可以用来创建Docker 容器。
2.Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
Docker容器
Docker 利用容器来运行应用。
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
Docker仓库
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,可以提供大陆用户更稳定快速的访问。
当然,用户也可以在本地网络内创建一个私有仓库。
当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上pull下来就可以了
2.Docker的安装
Centos6
$ sudo yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo yum install docker-io
安装之后启动Docker 服务,并让它随系统启动自动加载。
$ sudo service docker start
$ sudo chkconfig docker on
Centos7
$ sudo yum install docker
3.具体使用
A:获取镜像
Docker pull.....
$ sudo docker pull ubuntu:12.04
Pulling repository ubuntu
ab8e2728644c: Pulling dependent layers
511136ea3c5a: Download complete
5f0ffaa9455e: Download complete
a300658979be: Download complete
904483ae0c30: Download complete
ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
或者
Docker pull ip:host/镜像名
$ sudo docker pull registry.hub.docker.com/ubuntu:12.04命令,
即从注册服务器registry.hub.docker.com中的ubuntu仓库来下载标记为12.04的镜像。
B.列出镜像
Sudo docker images
C.创建镜像:
D:移除本地镜像:
如果要移除本地的镜像,可以使用docker rmi命令。注意docker rm命令是移除容器。
$ sudo docker rmi training/sinatra
Untagged: training/sinatra:latest
Deleted: 5bc342fa0b91cabf65246837015197eecfa24b2213ed6a51a8974ae250fedd8d
Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
*注意:在删除镜像之前要先用docker rm删掉依赖于这个镜像的所有容器。
4.docker镜像的启动
A.容器的启动
所需要的命令主要为docker run。
例如,下面的命令输出一个“Hello World”,之后终止容器。
$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world
这跟在本地直接执行/bin/echo 'hello world'几乎感觉不出任何区别。
下面的命令则启动一个bash 终端,允许用户进行交互。
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
其中,-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。
在交互模式下,用户可以通过所创建的终端来输入命令,例如
root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
当利用docker run来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个ip 地址给容器
执行用户指定的应用程序
执行完毕后容器被终止
启动已终止容器
可以利用docker start命令,直接将一个已经终止的容器启动运行。
容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用ps或top来查看进程信息。
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
可见,容器中仅运行了指定的bash 应用。这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。
B.后台运行
更多的时候,需要让Docker在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加-d参数来实现。
下面举两个例子来说明一下。
如果不使用-d参数运行容器。
$sudo docker run ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world
容器会把输出的结果(STDOUT)打印到宿主机上面
如果使用了-d参数运行容器。
$sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
此时容器会在后台运行并不会把输出的结果(STDOUT)打印到宿主机上面(输出结果可以用docker logs 查看)。
注:容器是否会长久运行,是和docker run指定的命令有关,和-d参数无关。
使用-d参数启动后会返回一个唯一的 id,也可以通过docker ps命令来查看容器信息。
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77b2dc01fe0f ubuntu:14.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute agitated_wright
要获取容器的输出信息,可以通过docker logs命令。
$ sudo docker logs [container ID or NAMES]
hello world
hello world
hello world
. . .
C.终止容器:
可以使用docker stop来终止一个运行中的容器。
此外,当Docker容器中指定的应用终结时,容器也自动终止。 例如对于上一章节中只启动了一个终端的容器,用户通过exit命令或Ctrl+d来退出终端时,所创建的容器立刻终止。
终止状态的容器可以用docker ps -a命令看到。例如
sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba267838cc1b ubuntu:14.04 "/bin/bash" 30 minutes ago Exited (0) About a minute ago trusting_newton
98e5efa7d997 training/webapp:latest "python app.py" About an hour ago Exited (0) 34 minutes ago backstabbing_pike
处于终止状态的容器,可以通过docker start命令来重新启动。
此外,docker restart命令会将一个运行态的容器终止,然后再重新启动它。
5:docker仓库
A:私有仓库
通过下面命令将最新的registry images拉下来:
# docker pull registry:latest
启动registry,这里使用本地目录作为存储,并将服务映射到主机的5000端口上。
# mkdir /var/lib/docker/registry
# docker run -e STORAGE_PATH=/registry -e SETTINGS_FLAVOR=local -p 5000:5000 -v /var/lib/docker/registry:/registry -d --name registry_instance registry
此时docker registry已经运行
# docker ps –a
检测http服务运行状态:
# curl 127.0.0.1:5000
"\"docker-registry server\""
然后可以使用tag命令把一个images标记到本地仓库中,并将本机的镜像上传到该仓库中。
# docker tag –help
# docker tag d7e093c2d142 127.0.0.1:5000/r-base1
# docker push 127.0.0.1:5000/r-base1
测试从本地registry中pull下image。
# docker pull 127.0.0.1:5000/r-base1
同样,通过查看registry的日志,可以看到images通过PUT/GET来操作
#docker logs e1efcb6528a5
......
10.0.42.1 - - [19/Jan/2015:07:40:59 +0000] "PUT /v1/images/d7e093c2d1424b2574368a574e91b859ee52bb4a2fa5f9a3d73b4e9da4f68d5c/json HTTP/1.1" 200 4 "-" "docker/1.0.1 go/go1.2.1 git-commit/990021a kernel/3.13.0-32-generic os/linux arch/amd64"
10.0.42.1 - - [19/Jan/2015:07:40:59 +0000] "PUT /v1/images/d7e093c2d1424b2574368a574e91b859ee52bb4a2fa5f9a3d73b4e9da4f68d5c/layer HTTP/1.1" 200 4 "-" "docker/1.0.1 go/go1.2.1 git-commit/990021a kernel/3.13.0-32-generic os/linux arch/amd64"
......
10.0.42.1 - - [19/Jan/2015:07:46:50 +0000] "GET /v1/images/d7e093c2d1424b2574368a574e91b859ee52bb4a2fa5f9a3d73b4e9da4f68d5c/ancestry HTTP/1.1" 200 884 "-" "docker/1.0.1 go/go1.2.1 git-commit/990021a kernel/3.13.0-32-generic os/linux arch/amd64"
.......
6.高级网络映射
A:端口映射实现
默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。
1.容器访问外部实现
容器所有到外部网络的连接,源地址都会被NAT成本地系统的IP地址。这是使用iptables的源地址伪装操作实现的。
查看主机的NAT 规则。
2.$ sudo iptables -t nat -nL
3....
4.Chain POSTROUTING (policy ACCEPT)
5.target prot opt source destination
6.MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16
7....
其中,上述规则将所有源地址在172.17.0.0/16网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE 跟传统 SNAT 的好处是它能动态从网卡获取地址。
2.容器访问外部的实现
容器允许外部访问,可以在docker run时候通过-p或-P参数来启用。
不管用那种
$ iptables -t nat -nL
...
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80
使用-p 80:80时:
$iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
注意:
·这里的规则映射了0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过-p IP:host_port:container_port或-p IP::port来指定允许访问容器的主机上的IP、接口等,以制定更严格的规则。
·如果希望永久绑定到某个固定的IP地址,可以在Docker配置文件/etc/default/docker中指定DOCKER_OPTS="--ip=IP_ADDRESS",之后重启Docker服务即可生效。
办法,其实也是在本地的iptable的nat表中添加相应的规则。
===================================================================================
或者端口映射启动容器
Dockerrun-p 127.0.0.1:5000:5000 -t -i /bin/bash
将容器5000端口映射到本机的5000端口。启动终端模式;
===================================================================================