Docker笔记

 

简介html

Docker 是 dotCloud 最近几个月刚宣布的开源引擎,旨在提供一种应用程序的自动化部署解决方案,简单的说就是,在 Linux 系统上迅速建立一个容器(相似虚拟机)并在容器上部署和运行应用程序,并经过配置文件能够轻松实现应用程序的自动化安装、部署和升级,很是方便。由于使用了容器,因此能够很方便的把生产环境和开发环境分开,互不影响,这是 docker 最广泛的一个玩法。更多的玩法还有大规模 web 应用、数据库部署、持续部署、集群、测试环境、面向服务的云计算、虚拟桌面 VDI 等等。python

Docker 使用 Go 语言编写,用 cgroup 实现资源隔离,容器技术采用 LXC. LXC 已经足够成熟,被多个主流 PaaS 服务商采用(好比 dotCloud),国内的一些互联网公司也在用(好比腾讯)。虽然都是企图解决自动化部署方面的问题,Docker 的解决方式有别于咱们常提到的 Puppet/Chef,他们虽然走的是不一样的路,但也能够拿来一块儿用。linux

安装 (ubuntu 12.04)nginx

Due to a bug in LXC, Docker works best on the 3.8 kernel. Precise comes with a 3.2 kernel, so we need to upgrade it. The kernel you’ll install when following these steps comes with AUFS built in. We also include the generic headers to enable packages that depend on them, like ZFS and the VirtualBox guest additions.web

sudo apt-get install python-software-properties
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
sudo rebootdocker

添加docker源并安装docker数据库

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker
上面两步也能够替换成执行curl -s https://get.docker.io/ubuntu/ | sudo sh,更简单。ubuntu

建立容器centos

首先从https://index.docker.io/下载一个预约义的镜像安全

sudo docker pull ubuntu
启动一个容器:

sudo docker run -i -t ubuntu /bin/bash
Starting a long-running worker process

# Start a very useful long-running process
JOB=$(sudo docker run -d ubuntu /bin/sh -c "while true; do echo Hello world; sleep 1; done")

# Collect the output of the job so far
sudo docker logs $JOB

# Kill the job
sudo docker kill $JOB
Bind a service on a TCP port

# Bind port 4444 of this container, and tell netcat to listen on it
JOB=$(sudo docker run -d -p 4444 ubuntu:12.10 /bin/nc -l 4444)

# Which public port is NATed to my container?
PORT=$(sudo docker port $JOB 4444 | awk -F: '{ print $2 }')

# Connect to the public port
echo hello world | nc 127.0.0.1 $PORT

# Verify that the network connection worked
echo "Daemon received: $(sudo docker logs $JOB)"
Committing (saving) a container state¶

Save your containers state to a container image, so the state can be re-used.

When you commit your container only the differences between the image the container was created from and the current state of the container will be stored (as a diff). See which images you already have using the docker images command.

# Commit your container to a new named image
sudo docker commit <container_id> <some_name>

# List your containers
sudo docker images
You now have a image state from which you can create new instances.

更多功能见http://docs.docker.io/


 

什么是docker


Docker 是 Docker.Inc 公司开源的一个基于LXC技术之上构建的Container容器引擎, 源代码托管在 GitHub 上, 基于Go语言并听从Apache2.0协议开源。 Docker在2014年6月召开DockerConf 2014技术大会吸引了IBM、Google、RedHat等业界知名公司的关注和技术支持,不管是从 GitHub 上的代码活跃度,仍是Redhat宣布在RHEL7中正式支持Docker, 都给业界一个信号,这是一项创新型的技术解决方案。

docker的基本概念

①镜像:用来建立Docker容器的只读模板 ②容器:从镜像建立而来的运行实例,各个容器之间相互隔离 ③仓库:存放镜像的场所,如https://hub.docker.com/和http://www.dockerpool.com/

安装docker
对于centos7,直接执行yum -y install docker便可安装,安装完成后须要执行systemctl start docker来启动docker服务。

其余操做系统中的安装方法见https://docs.docker.com/installation/#installation

获取镜像
从Docker Hub仓库下载一个Ubuntu 12.04操做系统的镜像

$ 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

官方镜像比较慢的时候能够从其余仓库下载镜像,如 $ sudo docker pull www.dockerpool.com:5000/library/centos:centos7

查询本地已下载的镜像

$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 12.04 0a51fcc173d8 2 days ago 111 MB centos httpd 9ad57da2b81c 6 weeks ago 336.5 MB e01000c7bac8 6 weeks ago 336.5 MB centos latest b157b77b1a65 8 weeks ago 243.7 MB

其中,镜像id惟一标识了镜像,TAG信息用来标记来自同一个仓库的不一样镜像。例如ubuntu仓库中有多个镜像,经过TAG信息来区分发行版本,例如10.0四、12.0四、12.十、13.0四、14.04等。建立容器时,若是不指定具体的标记,则默认使用latest标记信息。

除了从容器中下载已有镜像外,也能够根据已有镜像建立新的镜像。建立新镜像有多种方法:

①修改已有镜像后commit

$ sudo docker run -t -i ubuntu:12.04 /bin/bash root@a439b6e894bb:/# apt-get update root@a439b6e894bb:/# apt-get install nginx root@a439b6e894bb:/# /etc/init.d/nginx start root@a439b6e894bb:/# exit $ sudo docker commit -m 'add ngnix' -a 'feisky' a439b6e894bb ubuntu:nginx 0a693112c443ce4fb21bc57a26d67f0648b9415e052f929be7e06701f5f3ca2d $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu nginx 0a693112c443 9 seconds ago 153.1 MB ubuntu 12.04 0a51fcc173d8 2 days ago 111 MB

②用dockerfile来建立镜像

首先建立一个Dockerfile:

$ cat Dockerfile

yet another ngnix
FROM ubuntu:12.04 MAINTAINER feisky feisky@root RUN apt-get update RUN apt-get -y install nginx

put my local site to /var/www
ADD index.html /var/www/html/

expose httpd port
EXPOSE 80

the command to run
CMD ["/usr/sbin/nginx"]

$ sudo docker build -t 'ubuntu:www' .

③导入已有镜像

要从本地文件系统导入一个镜像,可使用openvz(容器虚拟化的先锋技术)的模板来建立: openvz的模板下载地址为http://openvz.org/Download/templates/precreated

$ sudo cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04

④导入docker save保存的镜像

$ sudo docker save -o ubuntu_12.04.tar ubuntu:12.04 $ sudo docker load --input ubuntu_14.04.tar $ sudo docker load < ubuntu_14.04.tar #同上

⑤导入已保存的容器

保存一个容器的方法

$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7691a814370e ubuntu:14.04 "/bin/bash" 36 hours ago Exited (0) 21 hours ago test $ sudo docker export 7691a814370e > ubuntu.tar

从新做为镜像导入进来

$ cat ubuntu.tar | sudo docker import - test/buntu:v1.0

注:用户既可使用docker load来导入镜像存储文件到本地镜像库,也可使用docker import来导入一个容器快照到本地镜像库。这二者的区别在于容器快照文件将丢弃全部的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时能够从新指定标签等元数据信息。

镜像制做好后,能够经过docker push命令,把本身建立的镜像上传到仓库中来共享 $ sudo docker push ubuntu

若是一个镜像不须要了,能够删除它: $ sudo docker rmi e01000c7bac8

容器管理
容器是独立运行的一个或一组应用,以及它们的运行态环境。

启动容器

下面的命令输出一个"Hello World",以后终止容器: $ sudo docker run ubuntu:nginx /bin/echo 'hello world' hello world

下面的命令则启动一个bash终端,可让用户进行交互。 $ sudo docker run -t -i ubuntu:12.04 /bin/bash root@af8bae53bdd3:/# 其中,-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i则让容器的标准输入保持打开。

对于已经中止的容器,能够用start命令从新启动: $ sudo docker start 7fb349365baf 7fb349365baf $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7fb349365baf ubuntu:nginx /bin/bash 29 minutes ago Up 6 seconds goofy_ritchie0

docker run的一些有用参数: ①-d:以守护进程形式运行容器 ②

其余命令:

nsenter --target $PID --mount --uts --ipc --net --pid链接容器终端 docker attach链接容器终端 docker stop来终止一个运行中的容器 docker restart命令会将一个运行态的容器终止,而后再从新启动它 docker logs获取容器的输出信息 docker ps查看正在运行的容器 docker ps查看正在运行和已经中止的容器

注意:当多个窗口同时attach到同一个容器的时候,全部窗口都会同步显示。当某个窗口因命令阻塞时,其余窗口也没法执行操做了。

仓库管理
对于默认Docker Hub仓库,经过执行docker login命令来输入用户名、密码和邮箱来完成注册和登陆。 注册成功后,本地用户目录的.dockercfg中将保存用户的认证信息。

能够经过sudo docker search centos来搜索镜像,经过sudo docker pull centos来下载镜像。

https://registry.hub.docker.com/builds/add/提供的自动构建功能对于须要常常升级程序的镜像比较有用,目前仅支持Github和BitBucket。

私有仓库的搭建

① $ sudo docker run -d -p 5000:5000 registry

② $ sudo pip install docker-registry

③ $ cp config/config_sample.yml config/config.yml

④ $ sudo gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000 -w 4 --max-requests 100 docker_registry.wsgi:application

如何向私有仓库上传镜像

① $ sudo docker tag ba58 192.168.7.26:5000/test

② $ sudo docker push 192.168.7.26:5000/test

经过$ curl http://192.168.7.26:5000/v1/search能够查询私有仓库的镜像,经过sudo docker pull 192.168.7.26:5000/test能够下载私有仓库的镜像。

 

数据管理


建立一个web容器,并加载一个数据卷到容器的/webapp目录:

$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py

挂载一个主机目录做为数据卷:

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

Docker挂载数据卷的默认权限是读写,用户也能够经过:ro指定为只读:

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

也能够挂载一个本地主机文件做为数据卷:$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash,注意这会致使报错误信息,最好仍是直接挂载文件的父目录

若是你有一些持续更新的数据须要在容器之间共享,最好建立数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的:

$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

而后,在其余容器中使用--volumes-from来挂载dbdata容器中的数据卷。

$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres

$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres

 

网络管理

当Docker启动时,会自动在主机上建立一个docker0虚拟网桥,其实是Linux的一个bridge,能够理解为一个软件交换机。它会在挂载到它的网口之间进行转发。

同时,Docker随机分配一个本地未占用的私有网段(在RFC1918中定义)中的一个地址给docker0接口。好比典型的172.17.42.1,掩码为255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段.

① 端口映射: 使用docker port 来查看当前映射的端口配置

$ sudo docker run -P ... #随机映射一个49000~49900的端口到内部容器开放的网络端口

$ sudo docker run -d -p 5000:5000 #映射到指定端口

$ sudo docker run -d -p 127.0.0.1:5000:5000 #映射到指定HOST+端口

$ sudo docker run -d -p 127.0.0.1::5000 #映射到指定HOST,端口随机生成

$ sudo docker run -d -p 127.0.0.1:5000:5000/udp #映射到指定UDP端口

② 容器互联

启动容器时指定容器名称: $ sudo docker run -d --name db training/postgres

根据名称链接db容器 $ sudo docker run -d -P --name web --link db:db training/webapp python app.py

注意:--link参数的格式为--link name:alias,其中name是要连接的容器的名称,alias是这个链接的别名;若是名称未知,能够经过下面的命令查询: $ sudo docker inspect -f "{{ .Name }}" aed84ee21bde

Docker在两个互联的容器之间建立了一个安全隧道,并且不用映射它们的端口到宿主主机上。在启动db容器的时候并无使用-p和-P标记,从而避免了暴露数据库端口到外部网络上。

Docker 经过2种方式为容器公开链接信息:

其一是环境变量:

$ sudo docker run --rm --name web2 --link db:db training/webapp env . . . DB_NAME=/web2/db DB_PORT=tcp://172.17.0.5:5432 DB_PORT_5000_TCP=tcp://172.17.0.5:5432 DB_PORT_5000_TCP_PROTO=tcp DB_PORT_5000_TCP_PORT=5432 DB_PORT_5000_TCP_ADDR=172.17.0.5 . . .

其二是hosts:

$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash root@aed84ee21bde:/opt/webapp

# cat /etc/hosts 172.17.0.7 aed84ee21bde . . . 172.17.0.5 db

③ 其余选项

只有在Docker服务启动的时候才能配置:

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

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

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

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

--ip-forward=true|false --请看下文容器之间的通讯

-iptables=true|false --禁止Docker添加iptables规则

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

既能够在启动服务时指定,也能够Docker容器启动(docker run)时候指定:

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

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

只有在docker run执行时使用:

-h HOSTNAME or --hostname=HOSTNAME --配置容器主机名

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

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

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

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

相关文章
相关标签/搜索