一、Docker是什么?
KVM, Virtualbox, Vmware是虚拟出机器,让每个实例看到一个单独的机器;而Docker是虚拟出操作系统,实现应用之间的隔离,让各个应用觉得自己有一个自己的操作系统,而且彼此之间隔离。假设没有Docker,然后有进程1和进程2,它们的运行将类似下图,进程1和进程2共享kernel,它们是同一OS下2个进程,因此必须拥有不同PID,但是又共享网卡,共享IP地址,看到一样的根文件系统(不chroot的情况下)等,可以用Linux IPC手段进程间通信。
有Docker的情况下,假设进程1和进程2运行于不同的容器,那么进程1和进程2都觉得自己和对方没有半毛钱关系,都觉得自己拥有自己的根文件系统,自己的网卡等,然后进程1和进程2的PID还可以一样,比如假设2个都是100。但是,此100非彼100。
Virtualbox等虚拟机的思路则完全不一样,如果进程1和进程2运行于不同的虚拟机,则操作系统都是双份的,它们感觉自己在不同的虚拟电脑上面跑。
由于可见,Docker达到了类似虚拟机的效果,但是又没有虚拟机的开销,增加了系统资源的利用率,它虚拟的层次更加高。Docker不虚拟机器,仅仅虚拟应用的运行环境。
二、你为什么要使用 Docker?
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
首先,Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。 其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
具体说来,Docker 在如下几个方面具有较大的优势。
更快速的交付和部署
对开发和运维(devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。 Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
更高效的虚拟化
Docker 容器的运行不需要额外的 hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。 这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
更简单的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
对比传统虚拟机总结
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
三、Docker重要概念
要理解 Docker 内部构建,需要理解以下三种部件:
- Docker 镜像 - Docker images
- Docker 仓库 - Docker registeries
- Docker 容器 - Docker containers
Docker 镜像
Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。UnionFS 允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新 的层被添加或升级了。现在你不用重新发布整个镜像,只需要升级,层使得分发 Docker 镜像变得简单和快速。
Docker 仓库
Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。Docker 仓库是 Docker 的分发部分。
Docker 容器
Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。
深度好文推荐 http://www.cnblogs.com/bethal/p/5942369.html
四、安装Docker
官方直接支持 64 位 Linux 系统安装 Docker,下面说说我在 CentOS-7 下的安装,其他系统的安装请参考官网。
1. 更新yum包索引
$ sudo yum makecache fast
2. 安装指定版本(默认最新)Docker
Docker现在分社区版(CE)和企业版(EE),笔者安装的是CE的
sudo yum install docker-ce
or
sudo yum install docker-ce-<VERSION>
3. 编辑 /etc/docker/daemon.json
. 如果不存在则创建,加上下面的内容
{
"storage-driver": "devicemapper"
}
4. 开启Docker
$ sudo systemctl start docker
5. 通过运行 hello-world 镜像来核查是否正确安装
$ sudo docker run hello-world
五、Docker基础用法
5.1 Search images (搜索镜像)
$ sudo docker search ubuntu
5.2 Pull images (获取镜像)
$ sudo docker pull ubuntu # 获取 ubuntu 官方镜像 $ sudo docker images # 查看当前镜像列表
5.3 Running an interactive shell (运行容器)
$ sudo docker run -i -t ubuntu:14.04 /bin/bash
- docker run - 运行一个容器
- -t - 分配一个(伪)tty (link is external)
- -i - 交互模式 (so we can interact with it)
- ubuntu:14.04 - 使用 ubuntu 基础镜像 14.04
- /bin/bash - 运行命令 bash shell
注: ubuntu 会有多个版本,通过指定 tag 来启动特定的版本 [image]:[tag]
六、Docker命令帮助
6.1 docker help
docker command
$ sudo docker # docker 命令帮助 Commands:
attach Attach to a running container # 当前 shell 下 attach 连接指定运行镜像
build Build an image from a Dockerfile # 通过 Dockerfile 定制镜像
commit Create a new image from a container's changes # 提交当前容器为新的镜像
cp Copy files/folders from the containers filesystem to the host path
# 从容器中拷贝指定文件或者目录到宿主机中
create Create a new container # 创建一个新的容器,同 run,但不启动容器
diff Inspect changes on a container's filesystem # 查看 docker 容器变化
events Get real time events from the server # 从 docker 服务获取容器实时事件
exec Run a command in an existing container # 在已存在的容器上运行命令
export Stream the contents of a container as a tar archive
# 导出容器的内容流作为一个 tar 归档文件[对应 import ]
history Show the history of an image # 展示一个镜像形成历史
images List images # 列出系统当前镜像
import Create a new filesystem image from the contents of a tarball
# 从tar包中的内容创建一个新的文件系统映像[对应 export]
info Display system-wide information # 显示系统相关信息
inspect Return low-level information on a container # 查看容器详细信息
kill Kill a running container # kill 指定 docker 容器
load Load an image from a tar archive # 从一个 tar 包中加载一个镜像[对应 save]
login Register or Login to the docker registry server
# 注册或者登陆一个 docker 源服务器
logout Log out from a Docker registry server # 从当前 Docker registry 退出
logs Fetch the logs of a container # 输出当前容器日志信息
port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
# 查看映射端口对应的容器内部源端口
pause Pause all processes within a container # 暂停容器
ps List containers # 列出容器列表
pull Pull an image or a repository from the docker registry server
# 从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to the docker registry server
# 推送指定镜像或者库镜像至docker源服务器
restart Restart a running container # 重启运行的容器
rm Remove one or more containers # 移除一个或者多个容器
rmi Remove one or more images
# 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run Run a command in a new container
# 创建一个新的容器并运行一个命令
save Save an image to a tar archive # 保存一个镜像为一个 tar 包[对应 load]
search Search for an image on the Docker Hub # 在 docker hub 中搜索镜像
start Start a stopped containers # 启动容器
stop Stop a running containers # 停止容器
tag Tag an image into a repository # 给源中镜像打标签
top Lookup the running processes of a container # 查看容器中运行的进程信息
unpause Unpause a paused container # 取消暂停容器
version Show the docker version information # 查看 docker 版本号
wait Block until a container stops, then print its exit code
# 截取容器停止时的退出状态值
Run 'docker COMMAND --help' for more information on a command.
docker option
Usage of docker:
--api-enable-cors=false Enable CORS headers in the remote API # 远程 API 中开启 CORS 头
-b, --bridge="" Attach containers to a pre-existing network bridge # 桥接网络
use 'none' to disable container networking
--bip="" Use this CIDR notation address for the network bridge's IP, not compatible with -b
# 和 -b 选项不兼容,具体没有测试过
-d, --daemon=false Enable daemon mode # daemon 模式
-D, --debug=false Enable debug mode # debug 模式
--dns=[] Force docker to use specific DNS servers # 强制 docker 使用指定 dns 服务器
--dns-search=[] Force Docker to use specific DNS search domains # 强制 docker 使用指定 dns 搜索域
-e, --exec-driver="native" Force the docker runtime to use a specific exec driver # 强制 docker 运行时使用指定执行驱动器
--fixed-cidr="" IPv4 subnet for fixed IPs (ex: 10.20.0.0/)
this subnet must be nested in the bridge subnet (which is defined by -b or --bip)
-G, --group="docker" Group to assign the unix socket specified by -H when running in daemon mode
use '' (the empty string) to disable setting of a group
-g, --graph="/var/lib/docker" Path to use as the root of the docker runtime # 容器运行的根目录路径
-H, --host=[] The socket(s) to bind to in daemon mode # daemon 模式下 docker 指定绑定方式[tcp or 本地 socket]
specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
--icc=true Enable inter-container communication # 跨容器通信
--insecure-registry=[] Enable insecure communication with specified registries (no certificate verification for HTTPS and enable HTTP fallback) (e.g., localhost: or 10.20.0.0/)
--ip="0.0.0.0" Default IP address to use when binding container ports # 指定监听地址,默认所有 ip
--ip-forward=true Enable net.ipv4.ip_forward # 开启转发
--ip-masq=true Enable IP masquerading for bridge's IP range
--iptables=true Enable Docker's addition of iptables rules # 添加对应 iptables 规则
--mtu= Set the containers network MTU # 设置网络 mtu
if no value is provided: default to the default route MTU or if no default route is available
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file # 指定 pid 文件位置
--registry-mirror=[] Specify a preferred Docker registry mirror
-s, --storage-driver="" Force the docker runtime to use a specific storage driver # 强制 docker 运行时使用指定存储驱动
--selinux-enabled=false Enable selinux support # 开启 selinux 支持
--storage-opt=[] Set storage driver options # 设置存储驱动选项
--tls=false Use TLS; implied by tls-verify flags # 开启 tls
--tlscacert="/root/.docker/ca.pem" Trust only remotes providing a certificate signed by the CA given here
--tlscert="/root/.docker/cert.pem" Path to TLS certificate file # tls 证书文件位置
--tlskey="/root/.docker/key.pem" Path to TLS key file # tls key 文件位置
--tlsverify=false Use TLS and verify the remote (daemon: verify client, client: verify daemon) # 使用 tls 并确认远程控制主机
-v, --version=false Print version information and quit # 输出 docker 版本信息
6.2 docker search
$ sudo docker search --help Usage: docker search TERM Search the Docker Hub for images # 从 Docker Hub 搜索镜像 --automated=false Only show automated builds
--no-trunc=false Don't truncate output
-s, --stars= Only displays with at least xxx stars
示例: $ sudo docker search -s ubuntu # 查找 star 数至少为 的镜像,找出只有官方镜像 start 数超过 ,默认不加 s 选项找出所有相关 ubuntu 镜像 NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Official Ubuntu base image [OK]
6.3 docker info
$ sudo docker info
Containers: # 容器个数 Images: # 镜像个数 Storage Driver: devicemapper # 存储驱动 Pool Name: docker-:--pool
Pool Blocksize: 65.54 kB
Data file: /data/docker/devicemapper/devicemapper/data
Metadata file: /data/docker/devicemapper/devicemapper/metadata
Data Space Used: 1.83 GB
Data Space Total: 107.4 GB
Metadata Space Used: 2.191 MB
Metadata Space Total: 2.147 GB
Library Version: 1.02.-RHEL7 (--) Execution Driver: native-0.2 # 存储驱动 Kernel Version: 3.10.-.el7.x86_64
Operating System: CentOS Linux (Core)
6.4 docker pull && docker push
$ sudo docker pull --help # pull 拉取镜像 Usage: docker pull [OPTIONS] NAME[:TAG] Pull an image or a repository from the registry -a, --all-tags=false Download all tagged images in the repository $ sudo docker push # push 推送指定镜像 Usage: docker push NAME[:TAG] Push an image or a repository to the registry
示例: $ sudo docker pull ubuntu # 下载官方 ubuntu docker 镜像,默认下载所有 ubuntu 官方库镜像 $ sudo docker pull ubuntu:14.04 # 下载指定版本 ubuntu 官方镜像
$ sudo docker push 192.168.0.100:/ubuntu # 推送镜像库到私有源[可注册 docker 官方账户,推送到官方自有账户] $ sudo docker push 192.168.0.100:/ubuntu:14.04 # 推送指定镜像到私有源
6.5 docker images
列出当前系统镜像
$ sudo docker images --help Usage: docker images [OPTIONS] [NAME] List images -a, --all=false Show all images (by default filter out the intermediate image layers) # -a 显示当前系统的所有镜像,包括过渡层镜像,默认 docker images 显示最终镜像,不包括过渡层镜像 -f, --filter=[] Provide filter values (i.e. 'dangling=true') --no-trunc=false Don't truncate output
-q, --quiet=false Only show numeric IDs
示例:
$ sudo docker images # 显示当前系统镜像,不包括过渡层镜像 $ sudo docker images -a # 显示当前系统所有镜像,包括过渡层镜像 $ sudo docker images ubuntu # 显示当前系统 docker ubuntu 库中的所有镜像 REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 12.04 ebe4be4dd427 4 weeks ago 210.6 MB
ubuntu 14.04 e54ca5efa2e9 4 weeks ago 276.5 MB
ubuntu 14.04-ssh 6334d3ac099a 7 weeks ago 383.2 MB
6.6 docker rmi
删除一个或者多个镜像
$ sudo docker rmi --help Usage: docker rmi IMAGE [IMAGE...] Remove one or more images -f, --force=false Force removal of the image # 强制移除镜像不管是否有容器使用该镜像 --no-prune=false Do not delete untagged parents # 不要删除未标记的父镜像
6.7 docker run
$ sudo docker run --help Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container
关于cpu优先级:
By default all groups have 1024 shares. A group with 100 shares will get a ~10% portion of the CPU time -archlinux cgroups
6.8 docker start|stop|kill... ...
dockerstart|stop|kill|restart|pause|unpause|rm|commit|inspect|logs
- docker start CONTAINER [CONTAINER...]
- # 运行一个或多个停止的容器
- docker stop CONTAINER [CONTAINER...]
- # 停掉一个或多个运行的容器-t选项可指定超时时间
- docker kill [OPTIONS] CONTAINER [CONTAINER...]
- # 默认 kill 发送 SIGKILL 信号-s可以指定发送 kill 信号类型
- docker restart [OPTIONS] CONTAINER [CONTAINER...]
- # 重启一个或多个运行的容器-t选项可指定超时时间
- docker pause CONTAINER
- # 暂停一个容器,方便 commit
- docker unpause CONTAINER
- # 继续暂停的容器
- docker rm [OPTIONS] CONTAINER [CONTAINER...]
- # 移除一个或多个容器
- -f, --force=false Force removal of running container
- -l, --link=false Remove the specified link and not the underlying container
- -v, --volumes=false Remove the volumes associated with the container
- docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- # 提交指定容器为镜像
- -a, --author="" Author (e.g., "John Hannibal Smith hannibal@a-team.com")
- -m, --message="" Commit message
- -p, --pause=true Pause container during commit
- # 默认 commit 是暂停状态
- docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]
- # 查看容器或者镜像的详细信息
- docker logs CONTAINER
- # 输出指定容器日志信息
- -f, --follow=false Follow log output
- # 类似 tail -f
- -t, --timestamps=false Show timestamps
- --tail="all" Output the specified number of lines at the end of logs (defaults to all logs)
参考文档:Docker Run Reference