7.3 Docker:Hello world


一、安装Docker

参照官方文档,不同Linux发行版,安装方法略有不同。 CentOS:CentOS 7 上安装 Docker 详解 Ubuntu:Ubuntu 16.04 上安装 Docker 详解

因为本人都是使用CentOS 7.2的系统,所以以下示例都将在CentOS上操作。

关于Docker的版本有必要说明下。因为跳跃比较大。

2017年3月2日,Docker 官方发布了一篇博客 ,宣布企业版到来。版本也从 1.13.x 一跃到 17.03。 之后,Docker 会每月发布一个edge版本(17.03, 17.04, 17.05…),每三个月发布一个stable版本(17.03, 17.06, 17.09…),企业版(EE) 和 stable 版本号保持一致,但每个版本提供一年维护。

由于这个重大改革,所以安装方法就会有两种 一种是各linux发行版中的Repo的Docker版本来安装(1.13.x):

yum -y install docker

一种是官网给出的最新方法,替换本地Repo,安装最新版本的方法(17.0x):

yum -y install docker-ce

以下我都按照这个版本来学习

如果有老版本的docker,需要先卸载

$ sudo yum remove docker \
                  docker-common \
                  docker-selinux \
                  docker-engine

安装依赖管理工具

$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

添加本地docker仓库

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

安装docker-ce

$ sudo yum install docker-ce

启动并加入开机自启

$ sudo systemctl start docker
$ chkconfig docker on

二、创建第一个容器

docker run -d -p 80:80 httpd

1. Docker 客户端执行 docker run 命令。
2. Docker daemon 发现本地没有 httpd 镜像。
3. daemon 从 Docker Hub 下载镜像。
4. 下载完成,镜像 httpd 被保存到本地。
5. Docker daemon 启动容器。

查看正在运行的容器

$ docker ps 或者 docker container ls

三、关于容器

3.1 相关命令

# 运行
docker run [-d] --name <contain name> --hostname <hostname> <image> /bin/bash -c "while true;do sleep 1;done"

# 进入
docker attach <contain id>          -> ctl+p+q 退出
docker exec -it <contain id> bash   -> exit 退出,bash必须指定

# 二者有什么区别
1. attach 查看命令输出,和docker log [-f] <contain id> 一样
2. exec -it 进入交互模式

# 查看日志输出
docker logs [-f] <contain id>   # -f 和 tail -f 一样时时输出

# 更名
docker rename <contain id> <new name>

# 关闭容器
docker stop <contain id>   # 久一些
docker kill <contain id>   # 快一些

# 开启容器
docker start <contain id>

# 让httpd遇到出错后,也能自动重启
docker run -d --restart=always httpd

# 暂停
docker pause <contain id>       # 这时候可以做快照了
docker unpause <contain id>

# 删除容器
docker rm <contain id> <contain id>...

# 创建一个容器
docker create <image>

3.2 内存限额

$ docker run -m 200M --memory-swap=300M ubuntu

-m 或 --memory:设置内存的使用限额,例如 100M, 2G。
--memory-swap:设置 内存+swap 的使用限额。

$ docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M

--vm 1:启动 1 个内存工作线程。
--vm-bytes 280M:每个线程分配 280M 内存。如果分配超过300,就会出错,容器退出

3.3 cpu配额

默认设置下,所有容器可以平等地使用 host CPU 资源并且没有限制。 Docker 可以通过 -c--cpu-shares 设置容器使用 CPU 的权重。如果不指定,默认值为 1024。

通过-c设置的cpu share并不是 CPU 资源的绝对数量,而是一个相对的权重值。某个容器最终能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。所以说权重值越大,能分配到的资源就越多。

# 如果当前host只有一个cpu,那运行这个容器后,用top查看,可以发现,一个容器就可以把cpu压满。
docker run --name container_A -it -c 1024 <image> --cpu 1

# 如果当前host还是只有一个cpu,那运行这个容器A和B后,用top查看,A占用2/3,B占用1/3的 CPU 资源
docker run --name container_A -it -c 1024 <image> --cpu 1
docker run --name container_B -it -c 512 <image> --cpu 1

3.4 blkio配额

Block IO 限制不同容器的读写资源分配 Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。 默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级。设置的是相对权重值,默认为 500。

# 这个例子限制A的读写带宽是B的两倍
docker run -it --name container_A --blkio-weight 600 ubuntu
docker run -it --name container_B --blkio-weight 300 ubuntu

bpsiops限制单个容器的读写速度。

  • bps 是 byte per second,每秒读写的数据量。

  • iops 是 io per second,每秒 IO 的次数。

# 可通过以下参数控制容器的 bps 和 iops:

--device-read-bps,限制读某个设备的 bps。
--device-write-bps,限制写某个设备的 bps。
--device-read-iops,限制读某个设备的 iops。
--device-write-iops,限制写某个设备的 iops。

# 举例
# 限制写入sda这块盘每秒只能写入30M
docker run -it --device-write-bps /dev/sda:30MB ubuntu
docker run -it ubuntu
time dd if=/dev/zero out=test.out bs=1M count=800 oflag=direct  # 测试速度

3.5 cgroup

cgroup全称Control GroupLinux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。

在相应路径下,每个容器都有对应一个以id命令的文件夹,里面有一些配置文件,就记录了配额信息。

1. cpu
路径:/sys/fs/cgroup/cpu/docker

2. memory
路径:/sys/fs/memory/cpu/docker

3. blkio
路径:/sys/fs/blkio/cpu/docker

3.6 namespace

namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离。

namespace 有下面六种

1. Mount namespace
让容器有自己的 / 目录,可以执行 mount 和 umount 命令。当然我们知道这些操作只在当前容器中生效,不会影响到 host 和其他容器。

2. UTS namespace
让容器有自己的 hostname。 默认情况下,容器的 hostname 是它的短ID,可以通过 -h 或 --hostname 参数设置。

3. IPC namespace
让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。

4. PID namespace
让容器拥有自己独立的一套 PID,而不与其他容器或者host冲突。

5. Network namespace
让容器拥有自己独立的网卡、IP、路由等资源。我们会在后面网络章节详细讨论。

6. User namespace
让容器能够管理自己的用户,host 不能看到容器中创建的用户。

正在运行的容器 image0 文件夹内容 image1


关注公众号,获取最新干货!