读《第一本Docker书》、 《Docker —— 从入门到实践》记一些笔记
《第一本Docker书》电子版可以从京东读书获取(我有京东会员、PC版下载一下就好)
《Docker —— 从入门到实践》 可以从GitBook获取。
后文是个人学习笔记,建议直接看上面提供的书就好。
Docker包括3个基本概念:
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
本文的主要内容就是介绍它们。
一、Docker的安装
Docker安装
这一块建议参考Docker从入门到实践这本书,它讲了各种系统的安装方式。
第一本Docker书终究还是比较老了。
我安装的方式就比较扯…我就直接 sudo apt install docker.io 就安装了…现在看起来用的,还行。
P.S. 书中是明确不建议用这种方式安装的,我因为是学习,就图个快…
加入Docker用户组
安装完毕后,就自动创建了docker用户组
然后我只需将当前用户加入到docker用户组就好了:
1 |
$ sudo usermod -aG docker $USER |
P.s. 这里将$USER替换为你自己的用户名。
二、镜像(Image)
Docker运行容器之前需要本地存在对应的镜像,如果镜像不存在,则会自动从镜像仓库下载。
获取镜像
从Docker镜像库获取镜像的命令是 docker pull ,具体命令格式可以通过 docker pull –help 来查看。
1 2 3 4 5 6 7 8 9 10 |
[xiong@AMDServer ~]$ docker pull --help Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST] Pull an image or a repository from a registry Options: -a, --all-tags Download all tagged images in the repository --disable-content-trust Skip image verification (default true) -q, --quiet Suppress verbose output |
P.s. 后文不会再给出类似–help内容。
使用举例:
1 |
docker pull ubuntu:latest |
这里 ubuntu 对应的是NAME, latest对应的是TAG。
如果想尝试运行,命令如下:
1 |
docker run -it --rm ubuntu:latest bash |
会以Ubuntu:latest为基础启动并运行容器,然后输入exit命令会退出容器。
具体参数 -i、-t、 –rm 会在后文解释。
列出镜像
命令: docker image ls 可以列出所有的已经下载的顶层镜像。
如果加上 -a 参数,则可以列出中间层镜像。
删除镜像
命令: docker image rm 命令可以删除镜像,具体使用可以 –help 来获取。
使用示例:
- 先列出镜像
- 删除对应镜像
1 2 3 4 5 6 7 8 9 10 11 12 |
[xiong@AMDServer ~]$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 1e4467b07108 12 days ago 73.9MB tkxiong/ubuntu latest 1e4467b07108 12 days ago 73.9MB hello-world latest bf756fb1ae65 7 months ago 13.3kB training/webapp latest 6fae60ef3446 5 years ago 349MB [xiong@AMDServer ~]$ docker image rm hello-world:latest Untagged: hello-world:latest Untagged: hello-world@sha256:49a1c8800c94df04e9658809b006fd8a686cab8028d33cfba2cc049724254202 Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63 |
可以看到,通过镜像名我们删除了hello-world这个镜像。
其他删除方法,看书学习。
三、容器(Container)
容器是独立运行的一个或一组应用,以及它们的运行态环境。
列出容器
其实就和列出镜像一样,命令: docker container ls -a 可以列出所有的运行中和 stopped 镜像。
如果去掉-a参数,则只列出运行中的镜像。
启动容器
启动容器有两种,一种是基于镜像新建容器并启动,另一种是将Stopped状态的容器重启。
一般来说Docker的容器十分轻量级,用户都是随时删除、新创建容器。
新建并启动
主要命令是 docker run ,比如我们用以下命令启动Ubuntu镜像,输出“Hello World”之后终止容器。
1 2 |
[xiong@AMDServer ~]$ docker run ubuntu:latest /bin/echo 'Hello World' Hello World |
重新启动
可以利用 docker container start 命令,将一个已经终止的容器启动运行。
- 列出镜像
- 根据镜像名称重启镜像
1 2 3 4 5 6 7 |
[xiong@AMDServer ~]$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82bf9430d814 ubuntu:latest "/bin/echo 'Hello Wo…" 7 minutes ago Exited (0) 25 seconds ago heuristic_ishizaka 8db7611ba42c ubuntu "/bin/bash" 15 hours ago Up 15 hours heuristic_kilby [xiong@AMDServer ~]$ docker container start -i heuristic_ishizaka Hello World |
参数解释
运行 docker container start –help 可以看到对应的参数解释。
我们讲一下之前的docker run命令: docker run -it –rm ubuntu:latest bash
-it 是两个参数, -i是交互式操作,-t是终端。
–rm 的意思是容器退出之后就直接删除。
ubuntu:latest 是镜像
bash 是命令,意思是打开交互式的Shell。
后台运行
一般来说,需要让Docker容器在后台运行,而不是直接把执行结果输出到当前宿主机下。
此时可以通过 -d 参数来实现。
然后通过 docker container logs 查看输出日志。
终止容器
使用 docker container stop 命令来终止一个运行中的容器。
或者当Docker容器中指定的应用终止时,容器也自动终止。
比如,前面我们只启用了bash的容器,用户通过exit退出终端时,所创建的容器立刻终止。
另外, docker container restart 命令会将一个运行态的容器终止,然后再重新启动。
删除容器
当容器终止之后,才可以将它删除。
命令: docker container rm
进入容器
我们使用 -d 参数让容器在后台运行,某些时候需要进入容器进行操作。
可以使用docker attch命令或者docker exec命令。
docker attach
1 2 3 4 5 |
[xiong@AMDServer ~]$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82bf9430d814 ubuntu:latest "/bin/echo 'Hello Wo…" 7 minutes ago Exited (0) 25 seconds ago heuristic_ishizaka 8db7611ba42c ubuntu "/bin/bash" 15 hours ago Up 15 hours heuristic_kilby [xiong@AMDServer ~]$ docker attach 8db7 |
注意两点:
1. 这里8db7使用的是Container ID。
2. 如果从这个stdin中exit,会导致容器的终止。
docker exec (推荐)
这种方法我们更推荐,示例如下:
1 2 |
[xiong@AMDServer ~]$ docker exec -it 8db7 bash root@8db7611ba42c:/# |
因为从这个stdin从exit不会导致容器的终止。
导入导出容器快照
导出容器快照 命令: docker export
1 |
[xiong@AMDServer ~]$ docker export 8db7 > ubuntu.tar |
然后使用 ls 或者 ll 命令就可以看到本地的 ubuntu.tar 文件。
导入容器快照 命令: docker import,可以将容器快照文件导入为镜像。
1 2 3 4 5 6 7 8 9 |
[xiong@AMDServer ~]$ cat ubuntu.tar | docker import - test/ubuntu:v1.0 sha256:85d7ffded7db294a6ed29fffa816e4446c04cf0123b11dbd6aa874c927ef0ed3 [xiong@AMDServer ~]$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE test/ubuntu v1.0 85d7ffded7db 6 seconds ago 73.9MB ubuntu latest 1e4467b07108 12 days ago 73.9MB tkxiong/ubuntu latest 1e4467b07108 12 days ago 73.9MB training/webapp latest 6fae60ef3446 5 years ago 349MB |
此外,还可以通过指定URL来导入,具体查看 –help 信息。
删除容器
使用 docker container rm 来删除一个处于中止状态的容器。
例如: docker container rm 8db7
使用 docker container prune 命令可以清理所有处于终止状态的容器。
四、仓库(Repository)
仓库是集中存放镜像地方。
公共仓库Docker Hub
可以在 DockerHub 免费注册一个Docker账号。
登录
命令 docker login 可以交互式登录 Docker Hub
命令 docker logout 退出登录。
搜索镜像
docker search 命令可以查找官方仓库中的镜像
拉取镜像
docker pull 命令可以下载镜像到本地
推送镜像
docker push 命令可以推送镜像到DockerHub
私有仓库相关的这里不讲解,看书理解。
更换镜像源
有时候会因为网络问题,镜像push不下来,就需要更换镜像源。
下面是几个国内常用的镜像源:
1 2 3 4 |
Docker官方中国区:https://registry.docker-cn.com 网易:http://hub-mirror.c.163.com 中国科技大学:https://docker.mirrors.ustc.edu.cn 阿里云:https://y0qd3iq.mirror.aliyuncs.com |
在/etc/docker目录下添加Docker的镜像源配置文件daemon.json。
该文件默认是不存的,在其中增加如下内容:
1 2 3 |
{ "registry-mirrors": ["https://y0qd3iq.mirror.aliyuncs.com"] } |
命令 systemctl restart docker 重启配置服务:
命令 docker info|grep Mirrors -A 1 查看是否生效。
1 2 3 4 |
[xiong@AMDServer ~]$ docker info|grep Mirrors -A 1 WARNING: No swap limit support Registry Mirrors: https://y0qd3iq.mirror.aliyuncs.com/ |
五、数据管理
Docker内部及容器间管理数据主要有两种方式:
- 数据卷(Volumes)
- 挂载主机目录(Bind mounts)
数据卷(Volume)
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性:
- 数据卷可以在容器之间共享、重用。
- 对数据卷的修改会立马生效
- 对数据卷的更新不会影响镜像
- 容器被删除后,数据卷依旧存在。
P.s. 数据卷的使用就和Linux下挂载目录一样。镜像中指定为挂载点的目录中的文件会被隐藏掉,显示的是挂载的数据卷。
创建数据卷
1 2 |
[xiong@AMDServer ~]$ docker volume create myvol myvol |
查看所有数据卷
1 2 3 |
[xiong@AMDServer ~]$ docker volume ls DRIVER VOLUME NAME local myvol |
查看指定数据卷信息
1 2 3 4 5 6 7 8 9 10 11 12 |
[xiong@AMDServer ~]$ docker volume inspect myvol [ { "CreatedAt": "2020-08-06T15:21:13+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/myvol/_data", "Name": "myvol", "Options": {}, "Scope": "local" } ] |
启动挂载数据卷的容器
1 2 3 4 5 6 |
[xiong@AMDServer ~]$ docker run -d -P \ > --name web \ > --mount source=myvol,target=/webapp \ > training/webapp \ > python app.py b8b27cf047983cc8b6443fc4e5c7333e58b6f458f57d5e89ea6910cb5493bb6d |
使用 –mount 标记将数据卷myvol挂载到容器的/webapp目录
查看数据卷具体信息
命令: docker inspect web 可以查看web容器的具体信息。
然后在“Mounts”可以找到数据卷信息:
1 2 3 4 5 6 7 8 9 10 11 12 |
"Mounts": [ { "Type": "volume", "Name": "myvol", "Source": "/var/lib/docker/volumes/myvol/_data", "Destination": "/webapp", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ], |
删除数据卷
1 2 |
[xiong@AMDServer ~]$ docker volume rm myvol Error response from daemon: remove myvol: volume is in use - [b8b27cf047983cc8b6443fc4e5c7333e58b6f458f57d5e89ea6910cb5493bb6d] |
数据卷被设计用来持久化数据的,数据卷还在使用的时候,是不能删除的。
同时容器被删除后,数据卷也不会自动删除。
如果需要在删除容器的同时移除数据卷,可以在删除容器的时候使用 docker rm -v 命令
无主的数据卷可能会占用很多空间,需要清理可以用 docker volume prune 命令。
挂载主机目录
挂载一个主机目录|文件作为数据卷。
使用–mount标记可以指定挂载一个本地主机目录或文件到容器中去。
具体看书学习就好。
六、网络管理
Docker允许通过外部访问容器或容器互联的方式提供网络服务。
外部访问容器
容器中可以运行一些网络应用,如果要让外部也可以访问这些应用,可以通过-P或-p参数来指定端口映射。
当使用-P标记时,Docker会随机映射一个本机端口到内部容器开放的网络端口。
P.S. 据书上说使用本机端口范围是49000~49900,看起来不太准确。
使用docker container ls 可以看到:
1 2 3 4 |
[xiong@AMDServer ~]$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b8b27cf04798 training/webapp "python app.py" 27 minutes ago Up 27 minutes 0.0.0.0:32771->5000/tcp web 8db7611ba42c ubuntu "/bin/bash" 17 hours ago Up 17 hours heuristic_kilby |
本地主机的32771端口被映射到了容器的5000端口。
此时访问本机的32771端口即为访问容器的5000端口,web应用提供界面。
同时,我们可以通过 docker logs 命令查看应用信息:
1 2 3 4 |
[xiong@AMDServer ~]$ docker logs -f web * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 192.168.1.102 - - [06/Aug/2020 07:57:38] "GET / HTTP/1.1" 200 - 192.168.1.102 - - [06/Aug/2020 07:57:38] "GET /favicon.ico HTTP/1.1" 404 - |
绑定端口
查看端口映射
1 2 |
[xiong@AMDServer ~]$ docker port web 5000/tcp -> 0.0.0.0:32771 |
映射端口
-p 则可以指定要映射的端口,并且在一个指定端口上只可以绑定一个容器。
支持的格式: hostPort:containerPort | ip:hostPort:containerPort | ip::containerPort
比如:我们可以将容器内的5000端口绑定到宿主机的5001端口
docker run -d -p 5001:5000 training/webapp python app.py
或者可以绑定到特定网络指定端口:
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
或者绑定到特定网络随机接口,没有指定宿主机端口号,所以自动分配宿主机端口号。
docker run -d -p 127.0.0.1::5000 training/webapp python app.py
还可以指定协议类型:这里用tcp指定协议类型为tcp协议
docker run -d -p 127.0.0.1::5000/tcp training/webapp python app.py
P.s. 注意127.0.0.1::5000这里的冒号(:)是两个。