Docker

一、CentOS 系统安装

参考《Docker — 从入门到实践》 之 "CentOS 操作系统安装 Docker"

1.1 系统要求

Docker 最低支持 CentOS 7。

Docker 需要安装在 64 位的平台,并且内核版本不低于 3.10。 CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 overlay2 存储层驱动)无法使用,并且部分功能可能不太稳定。

参考升级CentOS 升级 kernel

1.2 使用脚本自动安装

Docker 官方为了简化安装流程,提供了一套安装脚本,CentOS 系统上可以使用这套脚本安装:

curl -sSL https://get.docker.com/ | sh

执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 安装在系统中。

不过,由于伟大的墙的原因,在国内使用这个脚本可能会出现某些下载出现错误的情况。国内的一些云服务商提供了这个脚本的修改版本,使其使用国内的 Docker 软件源镜像安装,这样就避免了墙的干扰。

1.2.1 阿里云的安装脚本

curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -

1.2.2 DaoCloud 的安装脚本

curl -sSL https://get.daocloud.io/docker | sh

1.3 手动安装

1.3.1 添加内核参数

默认配置下,在 CentOS 使用 Docker 可能会碰到下面的这些警告信息:

WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

添加内核配置参数以启用这些功能。

$ sudo tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

然后重新加载 sysctl.conf 即可

$ sudo sysctl -p

1.3.2 添加 yum 源

虽然 CentOS 软件源 Extras 中有 Docker,名为 docker,但是不建议使用系统源中的这个版本,它的版本相对比较陈旧,而且并非 Docker 官方维护的版本。因此,我们需要使用 Docker 官方提供的 CentOS 软件源。

执行下面的命令添加 yum 软件源。

$ sudo tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

1.3.3 安装 Docker

更新 yum 软件源缓存,并安装 docker-engine

$ sudo yum update
$ sudo yum install docker-engine

1.3.4 启动 Docker 引擎

$ sudo systemctl enable docker
$ sudo systemctl start docker

1.3.5 建立 docker 用户组

默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。

建立 docker 组:

$ sudo groupadd docker

将当前用户加入 docker 组:

$ sudo usermod -aG docker $USER

1.4 参考文档

参见 Docker 官方 CentOS 安装文档

二、基本概念

2.1 Docker images

Docker image 是一个只读类型的模板。比如一个镜像可以是一个包含 apache 和你的 web 应用的 ubuntu 操作系统。我们经常使用镜像来创建容器。Docker 提供了一种快捷的方式来构建新镜像或者更新镜像,同时你也可以下载其他人已经创建好的镜像。Docker image 是 Docker 结构中的构建组件。

2.2 Docker Registries

Docker registries 用来保存镜像。它分为公开仓库和私有仓库,你可以从仓库中上传或者下载镜像。公开的 Docker 仓库称之为 Docker Hub。它提供了你可以使用的非常多的镜像。你可以自由的创建镜像或者使用这里面其他人已经创建好的镜像。Docker registries 属于 Docker 中的分发组件。

2.3 Docker containers

Docker containers 同目录有几分相似。Docker containers 保存了执行应用所需的所有资源。每一个 Docker containers 都是由 image 创建的。Docker containers 可以 run, start, stop, restart, rm。需要注意的是,Docker containers 之间是隔离的。Docker containers 属于 Docker 中的执行组件。

三、常用命令

3.1 镜像操作

  • 拉取镜像:docker pull nginx:latest
  • 查看镜像列表:docker images
  • 删除镜像:docker rmi <image id>
  • 想要删除 untagged images(也就是那些 id 为 None 的镜像):docker rmi $(docker images | grep "^<none>" | awk '{print $3}')
  • 删除全部镜像:docker rmi $(docker images -q)

3.2 创建容器

创建一个容器并运行,例如:

docker run --name blog --privileged=true -v /home/Hexo/public:/usr/share/nginx/html:ro -d -p 80:80 docker.io/nginx
  • --name:容器名称
  • --privileged=true:设置权限
  • -v:挂载本地磁盘目录,格式为本地磁盘绝对路径:容器路径

    保证删除容器后,数据不被删除
  • :ro:只读
  • -d:后台模式
  • i:交互式操作
  • t:终端
  • -p:设置宿主计算机和容器端口映射

在Dockerfile 中有一条指令是 EXPOSE 22,如果使用 -P,宿主机会随机选择一个 没有被使用的端口 和 docker 容器的 22 端口端口映射,如果 docker 主机或者容器重启后,宿主机又会随机选择一个没有被使用的端口和 docker 容器的 22 端口做端口映射,这样端口会发生 变化

如果使用 -p,比如 2222:22,这样不管是 docker 主机或者容器重启后,2222:22 端口都是这样来映射,不会发生改变

3.3 容器操作

  • 启动:docker start blog
  • 停止:docker stop blog;停止所有容器:docker stop $(docker ps -a -q)
  • 删除:docker rm blog;删除所有容器:docker rm $(docker ps -a -q)
  • 查看:docker ps -a(查看所有容器,包括已启动的和未启动的)

3.3 进入容器

sudo docker exec -it blog /bin/bash

四、Docker 私有仓库

Docker 提供了一个中央仓库,同时也允许我们使用 registry 搭建本地私有仓库。

4.1 搭建 Docker 私有仓库

首先拉取 registry 镜像

docker pull registry

创建 register 容器并运行

docker run --name registry -d -p 5000:5000 --privileged=true -v /opt/registry:/var/lib/registry/ registry

挂载容器中存放镜像的目录到本地 /opt/registry,需要注意的一点是,容器中存放镜像的目录 registry 官方镜像示例中使用的是 /tmp/registry-dev ,但实验证明在版本 2.5.0 中,目录是 /var/lib/registry/

CentOS 系统挂载目录需要加上 --privileged=true 解决挂载的目录没有权限的问题。

打开浏览器输入 register 容器宿主计算机地址加端口(如:http://192.168.237.128:5000/v2/ ),如果出现 {},即表明 register 容器运行成功。

4.2 测试使用私有仓库

首先给需要 push 到仓库的 images 打 TAG,前面需要带上私有仓库的地址。

$ docker tag docker.io/registry:latest 192.168.237.128:5000/registry:2.5.0

push 到私有仓库

$ docker push 192.168.237.128:5000/registry:2.5.0

通过以下命令删除镜像 192.168.237.128:5000/registry:2.5.0

$ docker rmi 192.168.237.128:5000/registry:2.5.0

然后通过以下命令即可拉取私有仓库的镜像:

$ docker pull 192.168.237.128:5000/hexo:latest

如果 docker push 的时候出现以下错误信息:

$ docker push 192.168.237.128:5000/registry:2.5.0
The push refers to a repository [192.168.237.128:5000/registry]
unable to ping registry endpoint https://192.168.237.128:5000/v0/
v2 ping attempt failed with error: Get https://192.168.237.128:5000/v2/: http: server gave HTTP response to HTTPS client
 v1 ping attempt failed with error: Get https://192.168.237.128:5000/v1/_ping: http: server gave HTTP response to HTTPS client

修改文件 /etc/sysconfig/docker 添加以下代码,然后重启 docker 服务即可重新 push。

ADD_REGISTRY='--add-registry 192.168.237.128:5000'

INSECURE_REGISTRY='--insecure-registry 192.168.237.128:5000'

五、Dockerfile

5.1 什么是Dockerfile?

Dockerfile 是自动构建 docker 镜像的配置文件,Dockerfile 中的命令非常类似 linux shell 下的命令
Dockerfile,可以让用户自定义构建 docker 镜像,支持以 # 开头的注释行

一般,Dockerfile分为4部分

  • 基础镜像(父镜像)信息
  • 维护者信息
  • 镜像操作命令
  • 容器启动命令

5.2 Dockerfile 介绍

FROM centos:centos7.1.1503

基于 父镜像 构建其他 docker 镜像,_父镜像_:可以通过 docker pull 命令获得,也可以自己制作

MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>

Dockerfile 维护者

ENV TZ "Asia/Shanghai"

ENV(environment)设置环境变量,一个 Dockerfile 中可以写多个。以上例子是:设置 docker 容器的时区为 Shanghai

Dockerfile 中有 2 条指令可以拷贝文件

ADD aliyun-mirror.repo /etc/yum.repos.d/CentOS-Base.repo

拷贝本地文件到 docker 容器里,还可以拷贝 URL 链接地址下的文件,ADD 还具有解压软件包的功能(支持 gzip, bzip2 or xz)

COPY test /mydir

拷贝本地文件到 docker 容器

RUN yum install -y curl wget....

RUN 命令,非常类似 Linux 下的 shell 命令 (the command is run in a shell - /bin/sh -c - shell form)
在 Dockerfile 中每执行一条指令(ENV、ADD、RUN等命令),都会生成一个 docker image layer

ADD supervisord.conf /etc/supervisord.conf

添加 supervisor 的主配置文件,到 docker 容器里

EXPOSE 22

端口映射 EXPOSE <host_port>:<container_port>
推荐使用 docker run -p <host_port>:<container_port> 来固化端口

ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]

一个 Dockerfile 中只有最后一条 ENTRYPOINT 生效,并且每次启动 docker 容器,都会执行 ENTRYPOINT

ONBUILD ADD . /app

ONBUILD 在生成当前docker镜像的时候不生效,在子镜像生效;ONBUILD在产品发布时起着非常重要的作用!举例
A镜像中有ONBUILD指令,在构建A镜像时ONBUILD指令不执行;B镜像FROM A,在构建B镜像时ONBUILD指令开始执行;

VOLUME ["/var/lib/mysql"]

指定 docker 容器和宿主机做映射的文件目录

5.3 生成 docker 镜像

以上文件就是用来生成第一个 docker 镜像的 Dockerfile,通过 docker build 指令来生成 docker 镜像

docker build -t csphere/centos:7.1 .

如果 Dockerfile 在当前目录下,输入点 . 就可以进行加载当前目录下的 Dockerfile
如果不在当前目录下需要运行 docker build -t csphere/centos:7.1 <Dockerfile_dir> 加载相对路径下的 Dockerfile

docker 镜像的命名规则 registry_url/namespace/image_name:tag 默认 taglatest

在构建 Docker 镜像时,如果有自己内部的 yum 源,替换成自己内部的 yum 地址,可以加快构建速度。
如果第一次构建失败,会有部分镜像 layer 生成,第二次构建会基于第一次构建所生成的 layer(use cache),继续构建
Step 10 : EXPOSE 22
 ---> Running in 0ed1c5479ebc
 ---> c57a5bac41c8
Removing intermediate container 0ed1c5479ebc
Step 11 : ENTRYPOINT /usr/bin/supervisord -n -c /etc/supervisord.conf
 ---> Running in e16c7ac2fd45
 ---> 185ef7b101a8
Removing intermediate container e16c7ac2fd45
Successfully built 185ef7b101a8

可以看到每执行一条 Dockerfile 的指令都会生成一个镜像的 layer c57a5bac41c8 185ef7b101a8 最后 185ef7b101a8 这个是 docker 镜像的ID,185ef7b101a8 是由 c57a5bac41c8 185ef7b101a8...layers 叠加而成,体现了 docker 镜像是分层的


未完待续...
— The End —
Last modification:January 1, 2020
If you think my article is useful to you, please feel free to appreciate