Docker学习笔记
- Ubuntu 安装 Docker
- Docker hub
- 阿里云镜像仓库
- docker 基本命令
- 持久化存储和巻间状态共享
- 网络访问
- 容器隔离
- 构建镜像
- 多容器管理
关于 docker 的介绍:[10 分钟看懂 Docker 和 K8S | 小枣君 | 知乎]
关于互联网礼仪:[互联网转载礼仪 | 苏莉安 | 知乎]
前两天看了一个关于互联网礼仪的文章,觉的讲的比较好,分享一下
根据其中所说的,本博客网站中的所有引用都(几乎)没有复制原文的字,也都附上了链接地址(如上面两个).
所以应该还是属于分享的范畴的(和分享到 qq 空间啥的没差别)
关于 Docker 的实现细节(比如联合文件系统啥的)可以自行搜索,本文重点写怎么用
1. Ubuntu 安装 Docker
1.1 安装过程
> 基本方法按照官方文档来,其中添加仓库镜像地址一步按照第二个链接来
啊,是我傻了…阿里云上有挺好的教程
1.2 配置阿里云镜像加速
1.3 测试
1 | sudo docker run hello-world |
2. Docker hub
类似于 Github,Maven 仓库等东西,用来存放和共享镜像
2.1 注册账号
需要注意两个地方
- 需要先注册账号,然后才能在设置里关联 github 账号
- docker hub 不支持直接修改头像,其把头像托管给了gravatar,在这里用同一个邮箱注册之后修改头像之后会自动同步到 docker hub
2.2 创建仓库(略)
2.3 连接 Docker hub
1 | yishiyu@yishiyu-Lenovo:~$ sudo docker login |
2.4 构建镜像并上传
构建 Dockerfile(类似 makefile,用于构建镜像)
1
2
3
4cat > 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_images3. 阿里云镜像仓库
阿里云中的仓库分为三级管理:命名空间/仓库/镜像
首先创建命名空间,然后在命名空间中创建仓库,最后上传镜像
在仓库界面,点击仓库名字即可查看仓库介绍及下面的教程
示例(构建,运行,上传,删除本地镜像,拉取云端镜像):
登录阿里云 Docker Registry
1
docker login --username=遗世雨 registry.cn-beijing.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
构建本地镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15cat > Dockerfile <<EOF
FROM busybox
CMD echo "Hello World! Aliyun Yes!"
EOF
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
2docker 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
22docker 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
docker tag 04542b registry.cn-beijing.aliyuncs.com/yishiyu/test:1.0
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
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直接删除会报错:该镜像被多个仓库使用
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
docker rmi 045
Error response from daemon: conflict: unable to delete 04542b096c66 (must be forced) - image is referenced in multiple repositories
首先用名字删除一个仓库
docker rmi yishiyu/test-images
Untagged: yishiyu/test-images:latest
再次删除,会报错有容器正在运行中
docker rmi 045
Error response from daemon: conflict: unable to delete 04542b096c66 (must be forced) - image is being used by stopped container fd86d88ea8e8
查看所有容器,删除该容器
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
docker rm fd8
fd8
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
删除镜像
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
22docker 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
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
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
docker run 045
Hello World! Aliyun Yes!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 | docker run --name writer \ |
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 | 创建 mysql 服务 |
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 gitexec 格式:不同的命令放在一个数组中(包括参数)
如 RUN [“apt-get”,”install”,”-y”,”git”]感觉 exec 格式比较好看
支持 exec 格式的命令:
RUN COPY ADD VOLUME CMD ENTRYPOINTshell 格式实质上是把命令作为 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-compose.yml 文件为一个服务配置一系列容器及其依赖关系
9.1 安装 Docker Compose
简单来说,可以去 Github 上下一个二进制文件
放在/usr/local/bin 文件夹中,然后添加执行权限就行了
9.2 Docker Compose 教程
先看第一个过一遍大概概念,再看看官方示例和 docker-compose.yml 配置方法就行了(懒得写了…)