Docker时微服务的基础,学习Docker命令能有效的完成一些简单的问题定位工作等。下面介绍的是一些常用的Docker命令。
命令 | 作用 |
---|---|
docker version |
查看docker版本 |
docker search centos |
搜索可用的docker镜像 |
docker images |
查看当前所有镜像 |
docker pull centos |
拉取镜像 |
docker run centos yum install ntpdate |
在docker容器中安装ntpdate工具 |
docker ps -l |
获取最后一个容器的id |
docker ps -a |
查看所有的容器 |
docker commit 容器id 镜像名:版本号 |
提交刚刚修改的容器 |
docker export 容器id > centos6.tar |
把容器信息导出为镜像 |
cat centos6.tar | docker import - centos |
把镜像导入为容器 |
docker run -it 镜像id /bin/bash |
在容器中启动一个/bin/bash 的shell环境,可以登录进入操作。其中-t 表示打开终端,-i 表示交互输入。 |
docker run -d 镜像名 /bin/bash |
-d 表示后台启动,以daemon方式启动 |
docker stop 容器id |
关闭容器 |
docker start 容器id |
启动某个容器 |
docker tag 老镜像名 含新标签的新镜像名 |
给指定镜像添加一个新的友好标签名 |
补充说明
1 docker export
docker export
命令可以使用定向符号进行容器的文件导出,同样也可以使用-o
选项进行导出目标的指定。例如下面两条命令,在功能上是一致的。
docker export -o test_for_run.tar e812617b41f6
# 等价于
docker export e812617b41f6 > test_for_run.tar
补充一些有用的运维命令
1. 简单运维命令简表
命令 | 功能 |
---|---|
docker logs |
从容器中获取日志。(你也可以使用自定义日志驱动,不过在 1.10 中,它只支持 json-file 和 journald) |
docker inspect |
查看某个容器的所有信息(包括 IP 地址)。该命令返回的是一个JSON格式的消息,如果我们只要其中一项内容时候,可以使用-f 参数来指定,例如,获取镜像的Architecture信息:docker inspect -f {{".Architecture"}} ,输出结果amd64
|
docker events |
从容器中获取事件(events)。 |
docker port |
查看容器的公开端口。 |
docker top |
查看容器中活动进程。 |
docker stats |
查看容器的资源使用情况统计信息。 |
docker diff |
查看容器的 FS 中有变化文件信息。 |
docker ps --filter "name=nostalgic" |
根据条件过滤查询 |
2. 容器的重启策略
创建容器时也可以容器的重启策略,即是当容器出错退出或者宿主机重启时候,容器的应对策略;重启策略同样会保证相关联的容器以正确的顺序重启,避免意外的错误。
- no:不进行重启
- on-failure:当容器以非零状态码退出时重启容器
- unless-stopped:当某个容器被显性关闭或者 Docker 本身关闭或重启时重启
- always:无论出现任何情况都重启容器
# 设置重启策略
# Off, On-failure, Unless-stopped, Always
$ docker run -dit --restart unless-stopped [CONTAINER]
3. 资源配置
我们可以使用 docker stats
命令来查看 Docker 容器的性能状态与资源占用,例如:
$ docker stats redis1 redis2
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
redis1 0.07% 796 KB / 64 MB 1.21% 788 B / 648 B 3.568 MB / 512 KB
3.1 设置容器内存
docker run -it -m 300M ubuntu:14.04 /bin/bash
3.2 设置容器CPU使用
在线上环境中,我们即希望能够尽量避免 CPU 空间时间片,最大化资源利用率,也要保障重点业务的资源占用,避免因某个异常容器占用或不合理使用整机 CPU 资源,造成宿主机上大量容器异常;此时单容器的 CPU 资源约束及上限将变得非常重要,既不能限得太死,又不能限不住,将通过内核和调度系统的限制机制来保障资源稳定性。Docker 允许使用 cpus
,cpuset-cpus
,cpu-shares
等来限制容器的计算资源占用:
# 指定容器可占用的 CPU 核编号,0-3 表示占用四个核,1、3 表示占用两个核
$ docker run -it --cpuset-cpus="1,3" ubuntu /bin/bash
# 最多允许占用单 CPU 50% 的计算资源,如果双核 CPU,则可以设置为 1.5 等
$ docker run -it --cpus=".5" ubuntu /bin/bash
# 不同的值能够指定不同的容器权重,用于动态分配 CPU 资源
$ docker run -it --cpu-shares="512" ubuntu /bin/bash
-
CPU Set
保障了容器的 CPU 核数,安全性较强,但是整体资源利用率低。如果容器实际并不需要如此多核的 CPU 资源来处理任务则会造成资源浪费,并且导致其他容器上的任务无法利用该容器上的 CPU 空闲时间片,人为阻断了 CPU 闲时复用的能力。 -
CPU Share
允许通过共享的方式获得 CPU 资源,不同的容器共享一定总量的 CPU 计算能力,每个容器都绑定全量核,而每个容器获取一定份额的 CPU 计算力。该模式下,每个容器的 CPU 资源分配不再以整核分配,而是可精细到 CPU 时间片份额的粒度,并且是连续的 CPU 核能力值。当整机闲时,可以让较为繁忙的业务获得整机空闲。采用 CPU 资源共享的机制,其资源隔离性没有 set 模式强,对于极个别 CPU 资源敏感型业务,有可能出现偶尔等待 CPU 时间片的情况,而影响业务稳定性。对于极少数的这类业务,我们容许继续使用 CPU set 模式。
3.3 容器的存储设置
如果使用 Device Mapper 作为底层存储驱动,则可以通过 Docker daemon 的如下参数来全局限制单个容器占用空间的大小:
# 限制单个容器最多占用 20G 空间,将应用于任何新建容器。
$ --storage-opt dm.basesize=20G
如果是 btrfs 存储驱动,可使用其提供的 subvolume 功能来实现。一个容器会对应一个 subvolume。针对容器对应的 subvolume 启用并配置 quota 即可限制其磁盘空间:
$ btrfs qgroup limit -e 50G /var/lib/docker/btrfs/subvolumes/<CONTAINER_ID>
授予对单个设备访问权限:
docker run -it --device=/dev/ttyUSB0 debian bash
授予所有设备访问权限:
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
也可以指定挂载一个本地主机的目录 / 文件到容器中去:
# 挂载目录
$ sudo docker run -d -P --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
# Docker 挂载数据卷的默认权限是读写,用户也可以通过 `:ro` 指定为只读。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
3.4 容器的网络设置
Linux 在网络栈中引入网络命名空间,将独立的网络协议栈隔离到不同的命名空间中,彼此间无法通信;Docker 利用这一特性,实现不容器间的网络隔离,并且引入 Veth 设备对 来实现在不同网络命名空间的通信。
Linux 系统包含一个完整的路由功能,当 IP 层在处理数据发送或转发的时候,会使用路由表来决定发往哪里。Netfilter 负责在内核中执行各种挂接的规则(过滤、修改、丢弃等),运行在内核模式中;Iptables 模式是在用户模式下运行的进程,负责协助维护内核中 Netfilter 的各种规则表;通过二者的配合来实现整个 Linux 网络协议栈中灵活的数据包处理机制。
Docker 的网络子系统采用了基于驱动的可插拔机制,其默认包含了如下驱动模式:
- bridge:默认的网络驱动,常用于多个应用运行与独立容器中并且需要相互通讯的时候。
- host:移除容器与 Docker 主机之间的网络隔离,直接使用宿主机所在的网络。底层与宿主机共用一个 Network Namespace,容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
- Overlay:Overlay 网络用语连接多个 Docker Daemon,保证 Docker Swarm 服务的正常运行;独立的容器与 Swarm 服务,或者不同宿主机上的容器同样能够通过 Overlay 进行通信。
- none:对于指定容器禁止所有的网络通信。
- Macvlan:Macvlan 网络会允许直接为容器分配 MAC 地址,使其作为真正的物理设备接入到宿主机所在的网络中。
我们使用 network 命令可以查看到默认的网络:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
f707aa0ef50d bridge bridge local
97dd7a032d96 host host local
d5a1bed0b12d none null local
桥接模式下,当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥,即软件交换机,在挂载到它的网口之间进行转发。同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1 ,掩码为 255.255.0.0 。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。
桥接模式下,创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0 ;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
# 创建新的网络
$ docker network create --driver bridge isolated
# 指定网段,宿主机会作为默认网关
$ docker network create --driver=bridge --subnet=192.168.2.0/24 --gateway=192.168.2.10 new_subnet
# 创建时将某个容器连接到网络
$ docker run --network=isolated -itd --name=docker-nginx nginx
# 将某个运行中容器连接到某个网络
$ docker network connect multi-host-network container1
3.5 DNS
默认情况下,容器从 Docker 守护进程继承 DNS 设置,包括 /etc/hosts
和 /etc/resolv.conf
。可以基于每个容器覆盖这些设置。
-
-h HOSTNAME
or--hostname=HOSTNAME
设定容器的主机名,它会被写到容器内的/etc/hostname
和/etc/hosts
。但它在容器外部看不到,既不会在 docker ps 中显示,也不会在其他的容器的/etc/hosts
看到。 -
--link=CONTAINER_NAME:ALIAS
选项会在创建容器的时候,添加一个其他容器的主机名到/etc/hosts
文件中,让新容器的进程可以使用主机名 ALIAS 就可以连接它。 -
--dns=IP_ADDRESS
添加 DNS 服务器到容器的/etc/resolv.conf
中,让容器用这个服务器来解析所有不在/etc/hosts
中的主机名。 -
--dns-search=DOMAIN
设定容器的搜索域,当设定搜索域为.example.com
时,在搜索一个名为 host 的 主机时,DNS 不仅搜索 host,还会搜索 host.example.com 。 注意:如果没有上述最后 2 个选项, Docker 会默认用主机上的 /etc/resolv.conf 来配置容器。
3.6 空间清理
Docker 使用过程中,可能会发现宿主节点的磁盘容量持续增长,譬如 volume 或者 overlay2 目录占用了大量的空间;如果任其发展,可能将磁盘空间耗尽进而引发宿主机异常,进而对业务造成影响。Docker 的内置 df 指令可用于查询镜像(Images)、容器(Containers)和本地卷(Local Volumes)等空间使用大户的空间占用情况。而容器的占用的总空间,包含其最顶层的读写层(writable layer)和底部的只读镜像层(base image layer,read-only),我们可以使用 ps -s
参数来显示二者的空间占用情况:
# 查看当前目录下的文件空间占用
$ du -h --max-depth=1 | sort
# 空间占用总体分析
$ docker system df
# 输出空间占用细节
$ docker system df -v
# 输出容器的空间占用
$ docker ps -s
docker system prune 指令能够进行自动地空间清理,其默认会清除已停止的容器、未被任何容器所使用的卷、未被任何容器所关联的网络、所有悬空镜像:
# 一并清除所有未使用的镜像和悬空镜像
$ docker system prune --all
# 列举悬空镜像
$ docker images -f dangling=true
# 删除全部悬空镜像
$ docker image prune
# 删除所有未被使用的镜像
$ docker image prune -a
# 删除指定模式的镜像
$ docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
# 删除全部镜像
$ docker rmi $(docker images -a -q)
# 删除全部停止的容器
$ docker rm $(docker ps -a -f status=exited -q)
# 根据指定模式删除容器
$ docker rm $(docker ps -a -f status=exited -f status=created -q)
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
# 删除全部容器
$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)
# 列举并删除未被使用的卷
$ docker volume ls -f dangling=true
$ docker volume prune
# 根据指定的模式删除卷
$ docker volume prune --filter "label!=keep"
# 删除未被关联的网络
$ docker network prune
$ docker network prune --filter "until=24h"
复制代码我们也可以手动指定日志文件的尺寸或者清空日志文件:
# 设置日志文件最大尺寸
$ dockerd ... --log-opt max-size=10m --log-opt max-file=3
# 清空当前日志文件
truncate -s 0 /var/lib/docker/containers/*/*-json.log
4 关于CPU和内存分配的相关测试资料
CPU和内存设置的值:在创建容器的阶段,是下限(至少要满足这些资源才能创建出容器),但是在使用时候,是上限(最多能够使用这么多资源)
参考资料:
http://www.cnblogs.com/sparkdev/p/8032330.html
https://www.cnblogs.com/sparkdev/p/8052522.html