1. Ubuntu 安装 Docker
  2. Docker hub
  3. 阿里云镜像仓库
  4. docker 基本命令
  5. 持久化存储和巻间状态共享
  6. 网络访问
  7. 容器隔离
  8. 构建镜像
  9. 多容器管理

关于 docker 的介绍:[10 分钟看懂 Docker 和 K8S | 小枣君 | 知乎]

关于互联网礼仪:[互联网转载礼仪 | 苏莉安 | 知乎]
前两天看了一个关于互联网礼仪的文章,觉的讲的比较好,分享一下
根据其中所说的,本博客网站中的所有引用都(几乎)没有复制原文的字,也都附上了链接地址(如上面两个).
所以应该还是属于分享的范畴的(和分享到 qq 空间啥的没差别)

关于 Docker 的实现细节(比如联合文件系统啥的)可以自行搜索,本文重点写怎么用

1. Ubuntu 安装 Docker

1.1 安装过程

[官方安装教程 | Docker]

[使用阿里镜像安装 Docker|博客园]

[Docker 安装教程 | bilibili]

> 基本方法按照官方文档来,其中添加仓库镜像地址一步按照第二个链接来

[Docker 安装教程 | aliyun]

[Docker 完整教程 | aliyun]

啊,是我傻了…阿里云上有挺好的教程

1.2 配置阿里云镜像加速

[Docker 阿里云镜像加速 | aliyun]

1.3 测试

1
sudo docker run hello-world

2. Docker hub

类似于 Github,Maven 仓库等东西,用来存放和共享镜像

[Docker hub | docker]

2.1 注册账号

需要注意两个地方

  1. 需要先注册账号,然后才能在设置里关联 github 账号
  2. docker hub 不支持直接修改头像,其把头像托管给了gravatar,在这里用同一个邮箱注册之后修改头像之后会自动同步到 docker hub

2.2 创建仓库(略)

2.3 连接 Docker hub

1
2
3
4
5
6
7
8
9
10
yishiyu@yishiyu-Lenovo:~$ sudo docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: yishiyu
Password:
WARNING! Your password will be stored unencrypted in /home/yishiyu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
yishiyu@yishiyu-Lenovo:~$

2.4 构建镜像并上传

  • 构建 Dockerfile(类似 makefile,用于构建镜像)

    1
    2
    3
    4
    cat > Dockerfile <<EOF
    FROM busybox
    CMD echo "Hello world! This is my first Docker image."
    EOF
  • 构建并上传

    1
    2
    3
    4
    5
    # 注意最后一个半角句号
    sudo docker build -t yishiyu/bibibi_docker_images .
    sudo docker run yishiyu/bibibi_docker_images
    # 这一步如果不挂全局梯子,很容易gg
    sudo docker push yishiyu/bibibi_docker_images
  • 删除本地镜像,从 docker hub 重新拉取并运行

    1
    2
    3
    4
    # 需要先用docker rm Container_id 移除容器(即使已经停止运行了)
    sudo docker rmi yishiyu/bibibi_docker_images
    # 这一步会重新拉取镜像
    sudo docker run yishiyu/bibibi_docker_images

    3. 阿里云镜像仓库

阿里云中的仓库分为三级管理:命名空间/仓库/镜像

首先创建命名空间,然后在命名空间中创建仓库,最后上传镜像

在仓库界面,点击仓库名字即可查看仓库介绍及下面的教程

示例(构建,运行,上传,删除本地镜像,拉取云端镜像):

  • 登录阿里云 Docker Registry

    1
    yishiyu-Lenovo#  docker login --username=遗世雨 registry.cn-beijing.aliyuncs.com

    用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。

  • 构建本地镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    yishiyu-Lenovo# cat > Dockerfile <<EOF
    heredoc> FROM busybox
    heredoc> CMD echo "Hello World! Aliyun Yes!"
    heredoc> EOF

    yishiyu-Lenovo#docker build -t yishiyu/test-images .
    Sending build context to Docker daemon 2.048kB
    Step 1/2 : FROM busybox
    ---> 018c9d7b792b
    Step 2/2 : CMD echo "Hello World! Aliyun Yes!"
    ---> Running in 1f5735e38d53
    Removing intermediate container 1f5735e38d53
    ---> 04542b096c66
    Successfully built 04542b096c66
    Successfully tagged yishiyu/test-images:latest
  • 运行镜像

    1
    2
    yishiyu-Lenovo# docker run yishiyu/test-images
    Hello World! Aliyun Yes!
  • 上传(这里的缩进有点问题,命令行里是整齐的)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    yishiyu-Lenovo# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    yishiyu/test-images latest 04542b096c66 8 minutes ago 1.22MB
    nginx latest 4bb46517cac3 4 weeks ago 133MB
    centos latest 0d120b6ccaa8 5 weeks ago 215MB
    busybox latest 018c9d7b792b 7 weeks ago 1.22MB
    hello-world latest bf756fb1ae65 8 months ago 13.3kB
    yishiyu-Lenovo# docker tag 04542b registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0

    yishiyu-Lenovo# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    yishiyu/test-images latest 04542b096c66 9 minutes ago 1.22MB
    registry.cn-beijing.aliyuncs.com/yishiyu/test 1.0 04542b096c66 9 minutes ago 1.22MB
    nginx latest 4bb46517cac3 4 weeks ago 133MB
    centos latest 0d120b6ccaa8 5 weeks ago 215MB
    busybox latest 018c9d7b792b 7 weeks ago 1.22MB
    hello-world latest bf756fb1ae65 8 months ago 13.3kB

    yishiyu-Lenovo# docker push registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0
    The push refers to repository [registry.cn-beijing.aliyuncs.com/yishiyu/test]
    514c3a3e64d4: Layer already exists
    1.0: digest: sha256:7601ec5593416591e62777f56cab721f71041f471d7b705554247943bf63bd16 size: 527
  • 删除本地镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    # 直接删除会报错:该镜像被多个仓库使用
    yishiyu-Lenovo# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    registry.cn-beijing.aliyuncs.com/yishiyu/test 1.0 04542b096c66 14 minutes ago 1.22MB
    yishiyu/test-images latest 04542b096c66 14 minutes ago 1.22MB
    nginx latest 4bb46517cac3 4 weeks ago 133MB
    centos latest 0d120b6ccaa8 5 weeks ago 215MB
    busybox latest 018c9d7b792b 7 weeks ago 1.22MB
    hello-world latest bf756fb1ae65 8 months ago 13.3kB
    yishiyu-Lenovo# docker rmi 045
    Error response from daemon: conflict: unable to delete 04542b096c66 (must be forced) - image is referenced in multiple repositories

    # 首先用名字删除一个仓库
    yishiyu-Lenovo# docker rmi yishiyu/test-images
    Untagged: yishiyu/test-images:latest

    # 再次删除,会报错有容器正在运行中
    yishiyu-Lenovo# docker rmi 045
    Error response from daemon: conflict: unable to delete 04542b096c66 (must be forced) - image is being used by stopped container fd86d88ea8e8

    # 查看所有容器,删除该容器
    yishiyu-Lenovo# docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    fd86d88ea8e8 04542b096c66 "/bin/sh -c 'echo \"H…" 16 minutes ago Exited (0) 16 minutes ago magical_stonebraker
    yishiyu-Lenovo# docker rm fd8
    fd8
    yishiyu-Lenovo# docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    # 删除镜像
    yishiyu-Lenovo# docker rmi 045
    Untagged: registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0
    Untagged: registry.cn-beijing.aliyuncs.com/yishiyu/test@sha256:7601ec5593416591e62777f56cab721f71041f471d7b705554247943bf63bd16
    Deleted: sha256:04542b096c66ad340c7e3b83120e4616a8266f2d608353c90241a7768143a0c0
  • 从阿里云拉取镜像并运行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    yishiyu-Lenovo# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    nginx latest 4bb46517cac3 4 weeks ago 133MB
    centos latest 0d120b6ccaa8 5 weeks ago 215MB
    busybox latest 018c9d7b792b 7 weeks ago 1.22MB
    hello-world latest bf756fb1ae65 8 months ago 13.3kB
    yishiyu-Lenovo# docker pull registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0
    1.0: Pulling from yishiyu/test
    61c5ed1cbdf8: Already exists
    Digest: sha256:7601ec5593416591e62777f56cab721f71041f471d7b705554247943bf63bd16
    Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0
    registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0
    yishiyu-Lenovo# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    registry.cn-beijing.aliyuncs.com/yishiyu/test 1.0 04542b096c66 22 minutes ago 1.22MB
    nginx latest 4bb46517cac3 4 weeks ago 133MB
    centos latest 0d120b6ccaa8 5 weeks ago 215MB
    busybox latest 018c9d7b792b 7 weeks ago 1.22MB
    hello-world latest bf756fb1ae65 8 months ago 13.3kB
    yishiyu-Lenovo# docker run 045
    Hello World! Aliyun Yes!
    yishiyu-Lenovo#

    4. docker 基本命令

4.1 通用命令

命令 含义
docker version 显示 docker 的版本信息
docker info 显示 docker 的系统信息
docker [command] —help 显示命令文档

4.2 镜像命令

命令 含义
docker iamges 显示所有镜像的信息
docker search 在 docker hub 上搜索镜像
docker pull 下载镜像
docker rmi 删除容器
docker run 启动镜像(有大量可选参数)
docker commit 把一个容器(修改后)打包成一个镜像

docker run [options] imageID/imageName
可选参数:
—name: 给运行后的容器命名
-i: 交互式运行,为该容器保留 stdin(即是其是 detached 状态)
-d: 启动为后台服务进程
-t: 为该容器绑定一个伪终端(通常是当前终端)
-p: 为该容器绑定端口 [[[ip:(主机可能多个网卡)]hostsocket:]dockersocket]
-P: 随机指定端口

4.3 容器命令

命令 含义
docker ps 查看当前容器
docker create 创建一个容器(不运行),参数与 run 一致
docker start 运行一个停止的容器
docker restart 重启一个停止的容器
docker stop 停止一正在运行的容器
docker kill 强制停止一个正在运行的容器
ctrl-P ctrl-Q detach 一个容器(不退出)
docker logs 显示某一个容器的日志
docker top 显示某个容器的 top 信息
docker inspect 检查一个容器的信息
docker attach attach 一个容器(不会创建新进程)
docker exec 使用容器执行一个新命令(会创建一个新进程)
docker cp 从容器中拷贝文件到主机

5. 持久化存储和巻间状态共享

一个 Docker 镜像可能包含多个组件(Minecraft 服务器:Centos+JRE+MCServer)
其中不同的组件分为不同的层,构建一个镜像的过程也就是逐层叠加文件的过程(也可能包含其他命令)
其中最基本的层为 bootfs(通用的文件),在上面是操作系统必须组件.这些基本的组件可以被不同的容器共用

构建出来的镜像是只读的,当一个镜像运行为容器后,在其上面的更改会被 Docker 作为一个新的层叠加在原镜像上
但是这样数据被绑定在具体容器上,无法复用和共享(当容器被删除后,其中的数据也就被删除了)

存储卷卷容器解决的就是数据的持久化和容器共享

5.1 存储卷

存储卷分为绑定挂载存储卷管理存储卷两种

  • 绑定挂载存储卷:就是把主机的一个目录映射到容器中的某个挂载点,来年各个目录双向绑定
  • 管理存储卷:由 Docker 在其管理的空间内创建和管理的目录

同时 Docker 提供了卷数据的权限管理,可设置为 ro(只读)和 rw(可读)写两种模式

运行镜像的同时,使用-v(—volume)参数可以添加挂载卷(具体参考 man 手册)

-v|—volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]]
hostdir-dir:container-dir: 使用绑定挂载存储卷
[name]:container-dir: 使用管理存储卷(name 为可选的名字)

5.2 存储卷共享

5.2.1 主机依赖共享

为多个容器绑定同一个绑定挂载存储卷,其依赖于主机上同一个目录,其内的数据自然会共享
如果有多个容器,主机依赖共享维护起来比较麻烦

5.2.2 从其他容器复制挂载卷

运行容器的时候,—volumes-from 参数可以指定被复制的容器,这种方式又被称为卷容器模式
如下,reader 会复制 writer 中挂载的所有容器(即是 writer 容器不在运行状态,其挂载的卷也不会消失)

1
2
3
4
5
6
7
docker run --name writer \
-v /home/writer \
echo "writer ready"

docker run --name reader \
--volumes-from writer \
echo "reader ready"

volumes-from 共享有几个特点:

  • 容器内的挂载点无法改变
  • 如果使用多个—volumes-from 标志从多个容器内共享卷,且这些容器内的共享卷冲突,则只能成功挂载一个
  • 不能更改卷的权限

5.2.3 管理卷的生命周期

docker volume 提供了一系列卷管理命令(docker volume —help 查看)
同时在删除容器的时候(docker rm),可以追加-v 参数,以删除所有与该容器相关的匿名卷(没有命名的管理卷)

但是该数据卷只有在所有容器都不再使用它的时候才被删除

6. 网络访问

Docker 的网络访问方式一共有 4 个

  • Close 容器
    使用—net none 指定
    该容器仅有自身回环地址,无法与外界通过网络交流

  • Bridged 容器
    使用—net bridge 指定(默认模式)
    该容器通过回环地址和一个 Linux 虚拟网络设备进行网络访问
    可以通过虚拟的网络接口进行网络交流

  • Joined 容器
    使用—net container:容器名指定
    该容器与被连接的容器共用一套网络接口

  • Open 容器
    使用—net host 指定
    该容器直接使用宿主机的网络接口(肥肠危险)

其中最常用的就是 Bridge 模式(也是默认模式)
所以重点介绍 Bridge 模式

6.1 访问外部网络

-p, —publish [ip:[hostPort]]:containerPort
公开端口,主机和其他容器都可以看到
指定 hostPort 后,把容器的端口映射到主机的指定端口
同时也可以指定相同长度的两个范围,进行范围映射
如果没有指定,则映射到主机的随机端口

-P, —publish-all
公开所有端口(随机映射)

—expose=[]
暴露端口,但是仅限其他容器可见,主机不可见
可以是单个端口,也可以用范围指定多个端口

6.2 跨容器通信

创建容器的时候,可以使用—link 指定被链接的目的容器

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建 mysql 服务
docker run -d --name importantData \
--expose 3306 \
mysql
# 创建web服务器
# 该容器可以通过 db:3306 访问数据库服务
docker run -d --name importantWebapp \
--link importantData:db \
webapp
# 创建其他应用
# 该容器没有通往 mysql 服务的路由
docker run -d --name otherWebapp \
webapp

6.3 自定义网络

docker network 提供了一系列自定义网络的命令

Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks

创建完自定义网络后,可以使用 connect 命令把容器接入网络
这种接入不会替换掉原本的网络,相当于给容器增加了一个网卡

可以使用 docker network disconnect 把一个容器从网络中断开
自检网络可以把不同的容器连接起来(就不再需要—link 连接了)

如果使用默认的网络,不同的容器只能使用 ip 地址互相连接
使用自定义网络,不同的容器可以把不同的容器名作为域名进行连接访问

7. 容器隔离

容器隔离可以防止一个容器中的应用耗费大量资源,影响系统的其他服务
仅介绍最常用的两个:cpu 和内存,其他可以参考\<\>

7.1 限制内存

在使用 run 或 create 命令的同时,使用参数—memroy 可以添加内存限制

—memory size
size 由一个数字和一个单位字母组成
单位字母:b,k,m,g

添加内存限制后,如果内存满足不了容器需求,其中的软件有多种失败方法
有的可能由于内存访问错误而失败,有的可能会记录内存溢出错误
Docker 既不检测也不记录这种错误,也不尝试缓解…
只能通过 run 命令的—restart 选项指定重启逻辑
(可以通过 man docker run 查看详细参数)

7.2 显示 CPU

在使用 run 或 create 命令的同时
使用—cpu-shares 可以设定 CPU 限制
使用—cpuset-cpus 可以设定限制使用的 CPU 核

—cpu-shares 比重数字
指定该容器最大占用 CPU 的比重(具体占用比例还与所有容器比重之和有关)
—cpuset-cpus 0,1,2/0-2
使用数字(逗号分隔)或者范围指定该容器所有的 CPU 核

8. 构建镜像

构建镜像有两种方式:从容器中构建,使用 Dockerfile 构建

8.1 从容器中构建

8.1.1 commit

commit 从一个容器中创建新的镜像

Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Options:
-a, —author string Author (e.g., “John Hannibal Smith hannibal@a-team.com“)
-c, —change list Apply Dockerfile instruction to the created image
-m, —message string Commit message
-p, —pause Pause container during commit (default true)

8.1.2 export

把文件系统打包成 tar 归档

export 把一个容器的文件系统(从容器角度能观察到的所有文件)输出为 tar 归档
该归档不再分层,而是一个扁平的文件系统

Usage: docker export [OPTIONS] CONTAINER
Options:
-o, —output string Write to a file, instead of STDOUT

从归档中创建文件系统

import 从 tar 归档中创建一个文件系统

Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Options:
-c, —change list Apply Dockerfile instruction to the created image
-m, —message string Set commit message for imported image
—platform string Set platform if server is multi-platform capable

export 的其他作用

在 docker 的联合文件系统中,对镜像的所有改动都会被记录在一层新的层上,而不是修改原来的层
即是是删除原本的一些东西,镜像的大小也只会增加,同时层数也会增加
同时联合文件系统有最大层数限制:42 层
使用 export 可以把已有的文件系统压缩成一层
但是同时也会丢失改动的历史信息等

8.1.3 save

把镜像保存为归档

save 把一个镜像或多个镜像输出位 tar 归档

Usage: docker save [OPTIONS] IMAGE [IMAGE…]
Save one or more images to a tar archive (streamed to STDOUT by default)
Options:
-o, —output string Write to a file, instead of STDOUT

从归档中创建镜像

load 从归档中创建镜像

Usage: docker load [OPTIONS]
Options:
-i, —input string Read from tar archive file, instead of STDIN
-q, —quiet Suppress the load output

8.2 使用 Dockerfile 构建

除了手动修改镜像然后导出,也可以使用类似 Makefile 的 Dockerfile 来自动构建
Dockerfile 中的每个命令都会穿件一个新层
下面列出简单介绍,详细可以参考官方的文档()
[Dockerfile Reference | Docker]

指令 作用
FROM 从一个基础镜像开始进行构造
MAINTAINER 设置维护者的信息
RUN 运行哪些命令(如 RUN apt-get insatll XXX)
ENTRYPOINT 设置镜像的入口点
ENV A “app” B “book” 类似 run 时的—env 参数,添加环境变量
LABEL 定义键值对,会被记录为额外元数据,和—label 参数一致
WORKDIR 设置初始工作目录
EXPOSE 设置对外开放端口,同—expose 参数一致
USER 设置用户和用户组,一般不用设置
COPY 复制文件到镜像中
VOLUME 与—volume 参数一致,为镜像挂载数据卷(无法挂载绑定卷)
ADD 复制文件到镜像中,如果是 url 会自动拉取,如果是归档会自动解压
CMD 设定初始命令
ONBUILD 在本镜像作为基础镜像再次构建时触发(不常用)
SHELL 指定 shell 类型

命令格式:

shell 格式:就是 shell 命令的格式
如 RUN apt-get install -y git

exec 格式:不同的命令放在一个数组中(包括参数)
如 RUN [“apt-get”,”install”,”-y”,”git”]

感觉 exec 格式比较好看
支持 exec 格式的命令:
RUN COPY ADD VOLUME CMD ENTRYPOINT

shell 格式实质上是把命令作为 shell 的子命令来执行的(先启动 shell,后运行命令)
exec 格式则是直接运行,而不再通过 shell

CMD 和 ENTRYPOINT 的区别

CMD 和 ENTRYPOINT 命令都可以指定镜像的初始命令
其都有 shell 和 exec 两种格式,且都有覆盖之前相同命令的特性
CMD 多用于灵活使用命令的镜像,用户在 run 的时候可以方便地覆盖
ENTRYPOINT 多用于只执行一个具体程序,用户在 run 时指定的内容会追加到 ENTRYPOINT 之后作为参数

9. 多容器管理

Docker 直接使用只能相当于一个虚拟机
再加上 Docker Compose,可以批量管理一个项目下的一系列容器
再加上 Swarm,可以联合多个服务器,使得服务变得更有高可用性

主机数量比较少的话可以使用 Swarm,多的时候可以使用 K8S
这里直接省略了(没钱买那么多服务器哈哈哈哈,回头用的时候再学)

[Docker Compose 文档 | Docker]

Docker Compose 可以使用 docker-compose.yml 文件为一个服务配置一系列容器及其依赖关系

9.1 安装 Docker Compose

[安装 Docker Compose | Docker]

简单来说,可以去 Github 上下一个二进制文件
放在/usr/local/bin 文件夹中,然后添加执行权限就行了

9.2 Docker Compose 教程

先看第一个过一遍大概概念,再看看官方示例和 docker-compose.yml 配置方法就行了(懒得写了…)

[Docker Compose 教程 | 简书]

[官方示例 | Docker Compose]

[docker-compose.yml reference | Docker Compose]