最近开始写了个后台,需要进行部署。
因为环境是 docker swarm,这里记录一下学习 docker 笔记。
一般不会在win
上面安装吧?
这里只记录linux
安装过程
debian
- 卸载旧版本
apt-get remove docker \
docker-engine \
docker.io
APT
安装
- 安装依赖
apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
lsb-release \
software-properties-common
- 添加 GPG 密钥
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add -
# 官方源
# $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
- 添加源
sudo add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/debian \
$(lsb_release -cs) \
stable"
# 官方源
# sudo add-apt-repository \
# "deb [arch=amd64] https://download.docker.com/linux/debian \
# $(lsb_release -cs) \
# stable"
- 安装
apt install docker-ce # CE 即社区版(免费,支持周期 7 个月)
- 启动
systemctl enable docker
systemctl start docker
- 建立 docker 用户组
# 建立 docker gourp
groupadd docker
# 添加 用户到docker组
usermod -aG docker $USER
- 测试安装
docker run hello-world
由于网络的原因,请使用镜像安装。
Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像。
对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
重启服务
systemctl daemon-reload
systemctl restart docker
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
7595c8c21622: Pull complete
d13af8ca898f: Pull complete
70799171ddba: Pull complete
b6c12202c5ef: Pull complete
Digest: sha256:a61728f6128fb4a7a20efaa7597607ed6e69973ee9b9123e3b4fd28b7bba100b
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
- Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
- 仓库名:即<用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。
docker run -it --rm \
ubuntu:18.04 \
bash
-
-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
-
--rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。
-
ubuntu:18.04:这是指用 ubuntu:18.04 镜像为基础来启动容器。
-
bash:放在镜像名后的是 命令,这里我们希望有个交互式 Shell,因此用的是 bash。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 2eb2d388e1a2 2 weeks ago 64.2MB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
- 镜像体积
列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 1 64.24MB 64.23MB (99%)
Containers 1 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
- 虚悬镜像
虚悬镜像是由于新镜像覆盖了原来的镜像(镜像名称不变,但是 ID 变了),于是原来的镜像名称就消失了。
# 查看虚悬镜像
docker image ls -f dangling=true
# 删除
docker image prune
- 中间层镜像
为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。默认的 docker image ls 列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加 -a 参数。
docker image rm [选项] <镜像1> [<镜像2> ...]
- 用 ID、镜像名、摘要删除镜像
docker image rm bf7
Untagged: hello-world:latest
Untagged: hello-world@sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63
因此当我们使用上面命令删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的 Untagged 的信息。因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete 行为就不会发生。所以并非所有的 docker image rm 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。
当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。镜像的多层结构让镜像复用变得非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。这就是为什么,有时候会奇怪,为什么明明没有别的标签指向这个镜像,但是它还是存在的原因,也是为什么有时候会发现所删除的层数和自己 docker pull 看到的层数不一样的原因。
除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像。之前讲过,容器是以镜像为基础,再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
- 新建并启动
docker run ubuntu:18.04 /bin/echo 'Hello world'
Hello world
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
- 启动已终止容器
可以利用 docker container start 命令,直接将一个已经终止的容器启动运行。
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。
容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。
为了确保容器可以长久运行,请确保你的程序不会崩溃。
要获取容器的输出信息,可以通过 docker container logs 命令。
docker container stop 来终止一个运行中的容器。 此外,当 Docker 容器中指定的应用终结时,容器也自动终止。
处于终止状态的容器,可以通过 docker container start 命令来重新启动。 此外,docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。
- attach
如果从这个 stdin 中 exit,会导致容器的停止。
- exec
-i -t 参数
只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。 当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
如果从这个 stdin 中 exit,不会导致容器的停止。这就是为什么推荐大家使用 docker exec 的原因。
- 导出容器
如果要导出本地某个容器,可以使用 docker export 命令。
- 导入容器快照
可以使用 docker import 从容器快照文件中再导入为镜像,例如
用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
- 删除容器
可以使用 docker container rm 来删除一个处于终止状态的容器。
- 清理所有处于终止状态的容器
docker container prune
刚刚接触docker
还是得从安装说起。
虽然有自动化的脚本,但是我们学习的时候还是要自己手动安装。
这样出了问题,至少不会一脸懵逼。
接着就是docker
的运行了。
docker 的运行就是一个后台 daemon 进程,我们在控制台上使用的docker
各种命令无非就是通过协议来操作 daemon 罢了。理解这一点就更好的理解后台的swarm
模式了。也因此,我们可以自己实现一个client
,例如docker-compose
等。
接着我们学习如何管理镜像docker image
系列命令。
image
可以看出是一个操作系统,而container
则是运行操作系统的计算机。
最好我们学习如何管理容器,就如同如何管理一台台运行的电脑一般。