docker容器技术笔记

1.docker架构html

http://www.infoq.com/cn/articles/docker-source-code-analysis-part1/java

Docker架构内各模块:Client、Docker Daemon、Docker Registry、Graph、Driver、libcontainerpython

以及Docker container。linux

2.下载docker工具网址git

https://www.docker.com/docker-toolboxgithub

3.下载dockerp_w_picpath模板网址web

http://download.openvz.org/template/precreated/redis

4.dockerfile的做用docker

Dockerfile用来建立一个自定义的p_w_picpathubuntu

http://blog.csdn.net/wsscy2004/article/details/25878223

基于Dockerfile搭建JAVA Tomcat运行环境:http://www.blogjava.net/yongboy/archive/2013/12/16/407643.html

阿里云服务器:

120.25.223.73:4200

120.25.88.150:4200

112.74.22.173:4200


sudo HTTP_PROXY=http://proxyx.com.cn:80 docker -d

sudo docker pull ubuntu  # 下载最新ubuntu镜像 

Docker 主站点: https://www.docker.io 

Docker 注册中心API: http://docs.docker.com/reference/api/registry_api/ 

Docker Hub API: http://docs.docker.com/reference/api/docker-io_api/ 

Docker 迖端应用API: http://docs.docker.com/reference/api/docker_remote_api/ 

Dockerfile 参考:https://docs.docker.com/reference/builder/ 

Dockerfile 最佳实践:https://docs.docker.com/articles/dockerfile_best-practices/


docker参数详解

useage of docker

-D 默认false 容许调试模式(debugmode)

-H 默认是unix:///var/run/docker.sock tcp://[host[:port]]来绑定 或者unix://[/path/to/socket]来使用(二进制文件的时候),当主机ip host=[0.0.0.0],(端口)port=[4243] 或者 path=[/var/run/docker.sock]是缺省值,作为默认值来使用

-api-enable-cors 默认flase 容许CORS header远程api

-b 默认是空,附加在已存在的网桥上,若是是用’none’参数,就禁用了容器的网络

-bip 默认是空,使用提供的CIDR(ClasslessInter-Domain Routing-无类型域间选路)标记地址动态建立网桥(dcoker0),和-b参数冲突

-d 默认false 容许进程模式(daemonmode)

-dns 默认是空,使docker使用指定的DNS服务器

-g 默认是”/var/lib/docker”:做为docker使用的根路径

-icc 默认true,容许inter-container来通讯

-ip 默认”0.0.0.0″:绑定容器端口的默认Ip地址

-iptables 默认true 禁用docker添加iptables规则

-mtu 默认1500 : 设置容器网络传输的最大单元(mtu)

-p 默认是/var/run/docker.pid进程pid使用的文件路径

-r 默认是true 重启以前运行的容器

-s 默认是空 ,这个是docker运行是使用一个指定的存储驱动器

-v 默认false 打印版本信息和退出


docker run命令详解

Usage: docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG…]

Run a command in a new container

-a=map[]: 附加标准输入、输出或者错误输出

-c=0: 共享CPU格式(相对重要)

-cidfile=””: 将容器的ID标识写入文件

-d=false: 分离模式,在后台运行容器,而且打印出容器ID

-e=[]:设置环境变量

-h=””: 容器的主机名称

-i=false: 保持输入流开放即便没有附加输入流

-privileged=false: 给容器扩展的权限

-m=””: 内存限制 (格式:<number><optional unit>, unit单位 = b, k, m or g)

-n=true: 容许镜像使用网络

-p=[]: 匹配镜像内的网络端口号

-rm=false:当容器退出时自动删除容器 (不能跟 -d一块儿使用)

-t=false: 分配一个伪造的终端输入

-u=””: 用户名或者ID

-dns=[]: 自定义容器的DNS服务器

-v=[]: 建立一个挂载绑定:[host-dir]:[container-dir]:[rw|ro].若是容器目录丢失,docker会


建立一个新的卷

-volumes-from=””: 挂载容器全部的卷

-entrypoint=””: 覆盖镜像设置默认的入口点

-w=””: 工做目录内的容器

-lxc-conf=[]: 添加自定义-lxc-conf=”lxc.cgroup.cpuset.cpus = 0,1″

-sig-proxy=true: 代理接收全部进程信号(even in non-tty mode)

-expose=[]: 让你主机没有开放的端口

-link=””: 链接到另外一个容器(name:alias)

-name=””: 分配容器的名称,若是没有指定就会随机生成一个

-P=false: Publish all exposed ports to thehost interfaces 公布全部显示的端口主机接口


docker经常使用命令总结

docker pull <镜像名:tag> #从官网拉取镜像

docker search <镜像名> #搜索在线可用镜像名

查询容器、镜像、日志

docker top <container> #显示容器内运行的进程

docker p_w_picpaths #查询全部的镜像,默认是最近建立的排在最上。

docker ps #查看正在运行的容器

docker ps -l #查看最后退出的容器的ID

docker ps -a #查看全部的容器,包括退出的。

docker logs {容器ID|容器名称} #查询某个容器的全部操做记录。

docker logs -f {容器ID|容器名称} #实时查看容易的操做记录。

删除容器与镜像

docker rm$(docker ps -a -q) #删除全部容器

docker rm <容器名or ID> #删除单个容器

docker rmi <ID> #删除单个镜像

docker rmi$(docker p_w_picpaths | grep none | awk ‘{print $3}’ | sort -r)#删除全部镜像

启动中止容器

docker stop <容器名or ID> #中止某个容器

docker start <容器名or ID> #启动某个容器

docker kill <容器名or ID> #杀掉某个容器

容器迁移

docker export <CONTAINER ID> > /home/export.tar #导出

cat /home/export.tar | sudo docker import – busybox-1-export:latest# 导入export.tar文件

docker save debian> /home/save.tar #将debian容器打包

docker load< /home/save.tar #在另外一台服务器上加载打包文件

save和export的对比参考地址:http://www.fanli7.net/a/bianchengyuyan/C__/20140423/452256.html

运行一个新容器

#运行一个新容器,同时为它命名、端口映射。以debian02镜像为例

docker run -h=”redis-test” –name redis-test -d -p 51000:22 -p51001:3306 -p 

51003:6379 -p 51004:6381 -p 51005:80 -p 51006:8000 -p 51007:8888 debian02 /etc/rc.local

#从container中拷贝文件,当container已经关闭后,在里面的文件还能够拷贝出来。

sudo docker cp 7bb0e258aefe:/etc/debian_version . #把容器中的/etc/debian_version拷贝到

当前目录下。


2.映像操做

cat layer.tar | sudo docker import - ubuntu:3.0#从本地文件系统导入镜像

docker p_w_picpaths

docker pull ubuntu:12.04 <=> docker pull registry.hub.docker.com/ubuntu:12.04#从docker hub下载镜像

docker rmi <p_w_picpath id>  #删除p_w_picpath

docker rmi `docker p_w_picpaths -a | awk '{if($2==0.0) print $3;}'`#删除tag==0.1的映像

docker rmi -f `docker p_w_picpaths -a -q`#强制删除全部映像

docker commit [-m "..." -a "..."] containerID rep:tag#将容器导出为映像

sudo docker save -o ubuntu_14.04.tar ubuntu:14.04#将映像ubuntu:14.04保存到本地当前目录下的ubuntu_14.04.tar(要用.tar后缀)

sudo docker load --input ubuntu_14.04.tar  

或 sudo docker load < ubuntu_14.04.tar#载入save保存的镜像,也可使用 docker import

docker tag p_w_picpathid  10.9.111.221:5000/ubuntu:12.0

docker pull 10.9.111.221:5000/ubuntu  #在私有库中拉取最新的ubuntu

docker search 10.9.111.221:5000/ubuntu#搜索私有库中的ubuntu库

curl http://104.131.173.242:5000/v1/search  #查询私有仓库

3.容器操做

 docker run -i  ubuntu:3.0 /usr/bin/bash    #启动容器,而且进入到Ubuntu容器的bash命令   -t伪造一个虚拟终端,当执行脚本时不能用-t选项

 docker run -i -t  --name mycontainer ubuntu:3.0  echo "liujidngd"#-i打开标准输出;-t容许伪终端;--name容器名字;--rm容器退出时强制删除容器

 docker run -i -t  --rm ubuntu:3.0  echo "liujidngd" #运行完该命令后,删除容器

 docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]

 docker ps #列出当前全部正在运行的container

 docker ps -l #列出最近一次启动的,且正在运行的container

 docker ps -a #列出全部的container

 docker rm `docker ps -a -q`#删除全部容器

 docker rm $CONTAINER_ID#删除容器id为CONTAINER_ID的容器

 docker stop CONTAINER_ID #中止docker实例

 docker logs containerName#查看后台运行的容器的日志

 ctrl +p+q 将容器推入后台运行

 docker attach containerName#从新进入容器,或将容器提到前台

 docker export CONTAINER_ID > ubuntu.tar#导出容器快照到本地当前文件夹下

 cat layer.tar | docker import - ubuntu:3.0#从本地文件系统导入容器快照为镜像

 docker commit containerID   p_w_picpathname                          #将容器导出为映像

4.Docker 数据管理 (数据卷的使用,相似亍 Linux 下对目录戒文件迕行 mount)

docker run -d -v /webapp ubuntu:0.1 echo "lk"#运行容器时在根目录下加载一个数据卷(建立了一个数据卷容器)

docker run -d -v /src/webapp:/opt/webapp ubuntu:0.1 echo "lk" #挂载本地主机目录/src/webapp到容器目录/opt/webapp

docker run -d -v /src/webapp:/opt/webapp:ro ubuntu:0.1 echo "lk"#挂载时指定只读权限

docker run -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash #将本地文件~/.bash_history挂载到主机文件/.bash_history

docker run -d -v /data --name dbdata ubuntu:0.1 echo "lk"#建立了一个数据卷容器

docker run -d --volumes-from dbdata --name db1 ubuntu:0.1 echo "lk"#挂载数据卷dbdata下全部的数据卷,用于容器目录共享

docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata#将数据卷容器的数据备份到本地目录


5.Docker 中的网络功能

容器中能够运行一些网络应用,要让外部也能够访问这些应用,能够经过 -P 或 -p 参数来指定端口映射。

当使用 -P 标记时,Docker 会映射一个 本地49000~49900 的随机端口到内部容器被开放使用的网络端口。

docker run -d -P training/webapp python app.py#使用随机端口绑定到容器在使用的端口

docker run -d -p 5000:5000 training/webapp python app.py#使用固定端口绑定到容器

docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

docker run -d -p 127.0.0.1::5000 training/webapp python app.py#映射到指定地址的任意端口

docker run --link db:dbalias --name web training/webapp env#将容器的db的随机端口与容器web使用的端口相连

docker port CONTAINER_ID portnum #查看容器中的端口port对应主机的端口号


6.命令

Docker 的命令能够采用 docker-CMD 戒者 docker CMD 的方式执行。二者一致。

docker-attach依附到一个正在运行的容器中。

docker-build从一个 Dockerfile 建立一个镜像

docker-commit从一个容器的修改中建立一个新的镜像

docker-cp(1)从容器中复制文件到宿主系统中

docker-diff(1)检查一个容器文件系统的修改

docker-events从服务端获取实时的事件

docker-export导出容器内容为一个 tar 包

docker-history显示一个镜像的历叱

docker-p_w_picpaths列出存在的镜像

docker-import导入一个文件(典型为 tar 包)路径戒目录来建立一个镜像

docker-info显示一些相关的系统信息

docker-inspect显示一个容器的底层具体信息。

docker-kill关闭一个运行中的容器 (包括迕程和全部资源)

docker-load从一个 tar 包中加载一个镜像

docker-login注册戒登陆到一个 Docker 的仏库服务器

docker-logout从 Docker 的仏库服务器登出

docker-logs获取容器的 log 信息

docker-pause暂停一个容器中的全部迕程

docker-port查找一个 nat 到一个私有网口的公共口

docker-ps列出容器

docker-pull从一个Docker的仏库服务器下拉一个镜像戒仏库

docker-push将一个镜像戒者仏库推送到一个 Docker 的注册服务器

docker-restart重吪一个运行中的容器

docker-rm删除给定的若干个容器

docker-rmi删除给定的若干个镜像

docker-run建立一个新容器,幵在其中运行给定命令

docker-save保存一个镜像为 tar 包文件

docker-search在 Docker index 中搜索一个镜像

docker-start启动一个容器

docker-stop终止一个运行中的容器

docker-tag为一个镜像打标签

docker-top查看一个容器中的正在运行的迕程信息

docker-unpause将一个容器内全部的迕程从暂停状态中恢复

docker-version输出 Docker 的版本信息

docker-wait阻塞直到一个容器终止,而后输出它的退出符


7.dockerfile 文件建立分层映像

第一步:在本地的当前目录下建立Dockerfile

FROM ubuntu:test3         //使用ubuntu:test3做为基础映像

RUN mkdir work

RUN echo "Hello docker!" >/work/lj  //在该映像上加一层

第二步:编译生成一个新的映像

docker build -t="ubuntu:v1" /home/mepa/test    //使用/home/mepa/test目录(该目录下最好只有一个Dockerfile文件)下的Dockerfile生成一个新的映像ubuntu:v1

第三步:运行新的映像ubuntu:v1

docker run -d -v /home/mapa/work:/work1  ubuntu:v1     //使用dockerfile生成的映像能够没有/bin/sh命令




 1.docker与传统虚拟机的优点

a.启动快:docker的启动能够在秒级实现,而传统虚拟机须要分级

b.对系统资源的利用率高:一台主机能够同时容许数千个docker容器,而传统虚拟机通常只能运行几十个。传统的虚拟机运行10个不一样的应用须要启动10个不一样的虚拟机,而docker只须要启动10个隔离的应用便可。

c.运行效率高:Docker容器的运行不须要额外的hypervisor(中间件)支持,它是内核级的虚拟化,所以能够实现更高的性能和效率。

d.更简单的管理:使用Docker,只须要小小的修改,就能够替代以往大量的更新工做。全部的修改都以增量的方式被分发和更新,从而实现自动化而且高效的管理。

e.一次建立,随处运行

Docker底层的核心技术包括Linux上的名字空间( Namespaces)、控制组( Control groups)、Union文件系统( Union file systems)和容器格式( Container format)。传统的虚拟机经过在宿主主机中运行hypervisor来模拟一整套完整的硬件环境提供给虚拟机的

操做系统,实现了操做系统级的隔离,而docker是在操做系统的基础上实现的是进程级的隔离。

     wKiom1hcy_Pykb9qAAMb7ueaj9c630.png

 2.容器之间的网络链接

a.系统外部访问容器内部

容器中能够运行一些网络应用,要让外部也能够访问这些应用,能够经过 -P或-p参数来指定端口映射。

从而可使得互联网经过访问主机端口来访问容器

b.容器之间的访问

--link=CONTAINER_NAME:ALIAS选项会在建立容器的时候,添加一个其余容器的主机名到/etc/hosts文件中, 让新容器的进程可使用主机名ALIAS就能够链接它。(容器在建立的时候,默认就已经经过docker0网桥互联了,--link只是给容器ip取一个别名)

如:

$sudo docker run -d  --name db training/postgres    不用向外映射任何端口

$sudo docker run -d  -P--name web --link db:mydb ubuntu /bin/bash

>ping mydb

>cat /etc/hosts

当Docker服务器启动时,会自动在主机上建立一个docker0虚拟网桥,至关于一个软件交换机,能够在挂载到它的网口之间进行数据转发。

该软交换机有一个ip好比172.17.42.1/16,启动的每个容器也有一个同一网段的ip。经过这种方式,主机能够跟容器通讯,容器之间也能够相互通讯。 Docker就建立了在主机和全部容器之间一个虚拟共享网络。

docker自动创建的网络模型以下:!()[https://github.com/liujin123/sundry/blob/master/docker_soft_switch.png?raw=true]


>docker run -it --link pedantic_borg:myubunutu ubuntu /bin/sh

#ping myubunutu

PING myubunutu (172.17.0.3): 56 data bytes   #能够看到myubunutu的ip地址

64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.187 ms

64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.165 ms

其实不须要--link选项容器与容器之间也是能够ping通的,只是要先知道另一个容器的ip,这个能够attach到容器中,而后在/etc/hosts文件中查看。

或者在本容器/etc/hosts中添加一个其它容器ip与主机名的映射,也能够经过主机名访问其它容器。

c.经常使用的与网络相关的命令

-bBRIDGEor--bridge=BRIDGE--指定容器挂载的网桥

--bip=CIDR--定制docker0的掩码

-HSOCKET...or--host=SOCKET...--Docker服务端接收命令的通道

--icc=true|false--是否支持容器之间进行通讯

--ip-forward=true|false--本地linux系统转发本容器数据本

--iptables=true|false--禁止Docker添加本地系统的iptables规则

--mtu=BYTES--容器网络中的MTU

下面2个命令选项既能够在启动服务时指定,也能够Docker容器启动( dockerrun) 时候指定。在

Docker服务启动的时候指定则会成为默认值,后面执行 dockerrun时能够覆盖设置的默认值。

--dns=IP_ADDRESS...--使用指定的DNS服务器

--dns-search=DOMAIN...--指定DNS搜索域

最后这些选项只有在 dockerrun执行时使用,由于它是针对容器的特性内容。

-hHOSTNAMEor--hostname=HOSTNAME--配置容器主机名

--link=CONTAINER_NAME:ALIAS--添加到另外一个容器的链接

--net=bridge|none|container:NAME_or_ID|host--配置容器的桥接模式

-pSPECor--publish=SPEC--映射容器端口到宿主主机

-Por--publish-all=true|false--映射容器全部端口到宿主主机



 3.容器的访问控制 

容器的访问控制主要经过linux的防火墙软件iptables进行管理实现。每一个容器的虚拟网卡veth都须要链接到linux系统建立的docker0网桥上才能工做。

a.容器访问外部网络 

容器访问外部网络须要本地linux系统的支持:网卡设置容许网络转发

$sysctlnet.ipv4.ip_forward   #查看

net.ipv4.ip_forward=0

$sysctl-wnet.ipv4.ip_forward=1  #设置

/etc/init.d/procps.sh restart      #生效

默认状况下,容器能够主动访问到外部网络的链接,可是外部网络没法访问到容器。

容器全部到外部网络的链接,源地址都会被NAT成本地系统的IP地址。 这是使用 iptables的源地址假装操做实现的。

$sudo iptables -t nat -nL   #查看主机的NAT(网络地址转换)规则。

...

ChainPOSTROUTING(policyACCEPT)

targetprotoptsourcedestination

MASQUERADEall--172.17.0.0/16!172.17.0.0/16

...

其中,上述规则将全部源地址在 172.17.0.0/16网段,目标地址为其余网段(外部网络)的流量动态假装为从系统网卡发出。 MASQUERADE跟传统SNAT的好处是它能动态从网卡获取地址。容器容许外部访问,能够在 dockerrun时候经过 -p或 -P参数来启用。

无论用那种办法,其实也是在本地的 iptable的nat表中添加相应的规则。

$sudo iptables -t nat -nL

...

ChainDOCKER(2references)

target  protopt  source destination

DNATtcp--0.0.0.0/0 0.0.0.0    tcpdpt:49153to:172.17.0.2:80

 b.容器之间的访问 (默认互联)

** 容器的网络拓扑是否已经互联。默认状况下,全部容器都会被链接到docker0网桥上。

** 本地系统的防火墙软件--iptables是否容许经过。

* c.网桥 

每一个容器都有虚拟网卡ceth,而docker网桥只是将这些虚拟网卡桥接。

c1.默认网桥docker0 

Docker服务默认会建立一个 docker0网桥。在内核层连通了全部的虚拟网卡,可是并无链接到物理网卡,而且docker0网桥没有配置文件,要想桥接物理网卡,只能从新新建一个虚拟网桥。

每次建立一个新容器的时候, Docker从可用的地址段中选择一个空闲的IP地址分配给容器的eth0端口。使用本地主机上docker0接口的IP做为全部容器的默认网关。

>brctl show  #显示网桥桥接了那些网卡

c2.自定义网桥 《docker技术入门与实践pdf》

在启动Docker服务的时候,使用-b BRIDGE或--bridge=BRIDGE 来指定使用的网桥,也能够修改配置文件。

自定义网桥是linux系统的功能,若是docker服务已经运行,那须要先中止服务,并删除旧的网桥。

[root@opnvz~]#brctl show   #显示linux主机上的网桥

bridgenamebridgeidSTPenabledinterfaces

docker08000.56847afe9799noveth0889

$sudo service docker stop

$sudo iplink set dev docker0 down

$sudo brctl del br docker0


而后建立一个网桥 bridge0

$sudo brctl add br bridge0

$sudo ipaddr add 192.168.5.1/24 dev bridge0

$sudo iplink set dev bridge0 up

查看确认网桥建立并启动。

$ipaddr show bridge0

配置Docker服务,默认桥接到建立的网桥上。

$echo'DOCKER_OPTS="-b=bridge0"'>>/etc/default/docker

$sudo service docker start

          wKioL1hcy8rRHozCAAAyVxGQYEU007.png

c3.跨物理网络的容器为何能通讯?

本地系统上运行的虚拟机或容器在访问外网时与本地进程使用相同的一套主机端口,于是数据准确送达容器进程或本地主机进程。

容器全部到外部网络的链接,源地址都会被NAT成本地系统的IP地址。 这是使用iptables的源地址假装操做实现的。互联网访问容器也是经过端口一一映射实现的。

d.ambassador 容器实现跨物理主机的容器间通讯

《docker技术入门与实践pdf》

ambassador 容器提供C/S模型,可让容器只存在本机的局域网,而使用ambassador 容器来提供网络互联。

 4.联合文件系统 UnionFS

联合文件系统( UnionFS)是一种分层、 轻量级而且高性能的文件系统,它支持对文件系统的修改做为一次提交来一层层的叠加,同时能够将不一样目录挂载到同一个虚拟文件系统下(uniteseveraldirectoriesintoa

singlevirtualfilesystem)。联合文件系统是Docker镜像的基础。 镜像能够经过分层来进行继承,基于基础镜像(没有父镜像),能够制做各类具体的应用镜像。



 5.数据卷

在容器中管理数据主要有两种方式:数据卷和数据卷容器

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,能够提供不少有用的特性:

*数据卷能够在容器之间共享和重用

*对数据卷的修改会立马生效

*对数据卷的更新,不会影响镜像

*卷会一直存在,直到没有容器使用

在用docker run命令的时候,使用-v标记来建立一个数据卷并挂载到容器里。在一次run中屡次使用能够挂载多个数据卷

$sudo docker run -d --name web -v /webapp  training/webapp   python  app.py  在容器中挂载一个数据卷

$sudo docker run -d --name web -v /src/webapp:/opt/webapp  training/webapp   python  app.py 挂载一个主机目录做为数据卷

$sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash 挂载一个主机文件做为数据卷


数据卷容器:其实就是一个正常的容器, 专门用来提供数据卷供其它容器挂载的。

$sudo docker run -d --name web -v /dbdata --name dbdatatraining/db   专门被其它容器挂载:凡是存在数据卷的容器均可以被其它容器挂载

$sudo docker run -d --volumes-from dbdata --name db1training/postgres   挂载其它容器的数据卷

$sudo docker run -d --volumes-from db1 --name db2training/postgres   从db1挂载

从数据卷中迁移数据:

$sudo docker run --volumes-fromdbdata-v $(pwd):/backup ubuntu tar cvf /backup/backup.tar  新建一个容器从而能够将数据备份到主机目录

相关文章
相关标签/搜索