Docker
前言
本篇文章不再赘述Docker的出身、优缺点、理念等一些概念,想要了解的可以去网上自行查阅资料,几乎每篇相关文章都会有的 - -#
一、基本组成
- image(镜像)
- Docker中image是一个只读的模板,我们可以通过镜像构建出容器,一个image可以创建多个container。
- 例如:官方的Centos7镜像相当提供了一套完整的最小化的root文件系统。
- container(容器)
- Docker可以利用镜像创建出一个对应的容器,容器是一个资源隔离的操作空间,可以看作一个简易版的Linux环境(包括 root 用户权限、进程空间、用户空间和网络空间等)
- 例如:官方的Nginx镜像可以创建出一个安装有Nginx的Linux系统,该容器资源隔离,并且存在于当前服务器上。
- registry(仓库)
- Docker和Maven一样,拥有公开的仓库存放用户制作上传的镜像,类似于GitHub的,称为DockerHub(公有仓库)。用户和企业可以搭建属于自己的私有仓库。
image相当于Java中一个具体的类。
container相当于Java中使用某个类new出来的实例对象。
二、常用命令
2.1 Docker服务
启动Docker服务
systemctl start docker
停止Docker服务
systemctl stop docker
查看Docker服务状态
systemctl status docker
重启Docker服务
systemctl restart docker
开机自动启动Docker服务
systemctl enable docker
查看Docker概要信息
docker info
Docker帮助文档
docker help
2.2 image相关命令
查看本地主机上的镜像信息:
docker images[-qa]
参数:
-q:只列出imageID
-a:列出所有image,包括历史记录
Tip:在 Docker 中镜像名称 + TAG(标签) = 镜像 ID ,容器名称 = 容器 ID 。
● 同一个仓库中可以有多个 tag 版本,代表这个镜像的不同个版本,我们使用镜像ID(镜像名称+标签)来定义不同的镜像。
● 如果不知道一个镜像的版本标签,比如:只是用了 ubuntu,Docker 将默认使用 ubuntu:latest 镜像。
搜索对应名称的镜像:
docker search 镜像名称
示例:
docker search redis
● 在实际使用中,通常直接去DockerHub搜索镜像,该命令使用频率较低!!!
从仓库中拉取镜像到本地
docker pull 镜像名称:标签
示例:
docker pull mysql:5.7(具体名称和标签可以使用search查看镜像后在拉取)
● 拉取镜像时没有添加具体的标签Docker会默认拉取latest最近的镜像。
查看当前container、images、volume所占的存储空间
docker system df
删除镜像
删除某个镜像: docker rmi 镜像名称|镜像ID
强制删除某个镜像: docker rmi -f 镜像名称|镜像ID
强制删除所有的镜像: docker rmi -f $(docker images -qa)
2.3 Container相关命令
新建/启动容器:
docker run [OPTIONS] 镜像名称|镜像ID [COMMAND] [ARG...]
OPTIONS:
-name = '容器名称': 为容器指定一个名称,可以代替容器ID
-d :后台运行容器,并返回容器ID -i :交互式运行容器,通常配合-t使用。
-t :为容器分配一个交互终端,通常和-i一起使用,启动交互式终端。
-P :随机端口映射。 -p :指定端口映射 x:y 将容器内的y端口映射到主机的x端口
-dns 8.8.8.8:指定容器使用的 DNS 服务器,默认和宿主一致。
-dns-search example.com:指定容器 DNS 搜索域名,默认和宿主一致。
-m 设置容器使用内存最大值。
-network="bridge":指定容器的网络连接类型,支持 bridge 、host 、none、container 四种类型,默认 bridge 。
-expose=[]:开放一个端口或一组端口。
-restart :指定重启策略,可以写 --restart=awlays 总是故障重启。
-volume , -v::绑定一个卷。一般格式为 主机文件或文件夹:虚拟机文件或文件夹 。
COMMAND(启动命令)
ARG(启动参数)
示例: 启动一个交互式容器。
docker run -it --name=ubuntu ubuntu:20.04 /bin/bash
列出正在运行的所有容器
docker ps [-qa]
参数:
-a :累出当前所有正在运行的容器 + 历史上运行过的容器。
-q :只显示容器编号。
容器的启动/停止/重启/删除
停止: docker stop 容器名称或容器ID
重启: docker restart 容器名称或容器ID
强制停止: docker kill 容器名称或容器ID
删除已经停止的容器: docker rm 容器名称或容器ID
删除所有容器: docker ps -qa | xargs docker rm -f
常用的创建命令为: docker run -itd --restart always 让容器在后台运行,并且退出时不会关闭。
三、Docker Volume 容器卷
Container通过共享宿主机的内核,可以运行一个或多个应用程序,这些应用程序运行在一个相对隔离的环境中,与宿主机和其他容器相互隔离。
大多数场景下,我们希望在容器中进行操作后产生的数据改变能够保留下来,制作新的镜像或许是一种方法,但是效率比较低下,因此Docker提供了容器卷的方式,通过Volume能够共享宿主机和容器的文件系统。
通过容器卷挂载,宿主机指定目录下的文件目录将和容器内指定目录下的文件在存储上共享。
容器卷Volume相关命令:
列出所有卷: docker volume ls
创建卷: docker volume create 卷名称
查询卷详情: docker inspect 卷名称
删除卷: docker volume rm 卷名称
移除无用卷: docker volume prune 卷名称
Docker允许在创建运行/创建容器的时候指定卷挂载:
- Docker 支持三种挂载方式:
- ① Docker默认在外部创建文件夹,并自动挂载到容器内部指定的文件夹中,默认存储在宿主机的/var/lib/docker/volumes/目录下,但Docker会自动管理这些目录,用户通常不需要直接访问它们。
- ② 用户可以通过Docker CLI命令(如docker volume create、docker run -v等)来创建和管理数据卷,并指定卷的名称和挂载点。
- ③ 临时文件系统将数据存储在宿主机的内存中,适用于需要快速读写的临时数据(容器停止或删除时,tmpfs挂载中的数据会被清空)。
大部分场景下,我们都会使用-v或是-mount参数指定挂载的源目录和目标路径。
3.1 匿名挂载
匿名挂载是指在创建或运行容器时,不指定数据卷的名称,而只指定容器内部的挂载路径。Docker会自动为这些数据卷生成一个随机的唯一标识符(通常是一个复杂的字符串)作为名称。
# Docker 将创建出匿名卷,并保存容器 /usr/share/nginx/html 下面的内容
docker run -d -P -v /usr/share/nginx/html nginx
匿名挂载的数据卷的生命周期通常与创建它的容器相关联,如果容器被删除,且没有其他容器或Docker命令引用该数据卷,则该数据卷也可能被删除。
匿名挂载使用起来方便快捷,但由于数据卷的名称是随机的,可能会比较难追踪到数据卷,适合容器删除的时相关数据卷也一并删除的场景。
3.2 具名挂载
具名挂载是指在创建或运行容器时,为数据卷指定一个具有实际意义的名称。这个名称可以在多个容器间共享,并且可以通过名称来管理和维护数据卷。
docker run -d -P -v /var/nginx/html:/usr/share/nginx/html nginx
Tip: -v参数可以使用多个,能够同时挂载多个数据卷
具名挂载具有持久化特性,具名数据卷的生命周期不直接关联于任何单个容器,只要不被显式删除,它就会一直存在。
如果将非空卷安装到存在某些文件或目录的容器中的目录中,则这些文件或目录会被安装遮盖,就像将文件保存到 Linux 主机上的 /mnt 中一样,然后将 USB 驱动器安装到 /mnt 中。在卸载 USB 驱动器之前,/mnt 的内容将被 USB 驱动器的内容遮盖。 被遮盖的文件不会被删除或更改,但是在安装绑定安装或卷时将无法访问。
外部目录覆盖内部容器目录内容,但不是修改。所以需要谨慎,外部空文件夹挂载方式可能会导致容器内部是空文件夹而导致容器启动失败。
四、Docker 网络模式
Docker 提供了多种网络模式,允许容器之间以及容器与宿主机之间进行通信。这些网络模式包括:bridge桥接模式、host主机模式、container容器模式、none无网络模式、Custom自定义模式。
查看docker网络 docker network ls
查看网络源数据 docker network inspect 网络ID
创建网络 docker network create 网络名称/ID
删除网络 docker network rm 网络名称/ID
Docker 默认启动的时候,会为我们创建三个网络:
4.1 bridge桥接模式
- Docker 使用 Linux 桥接,在宿主机虚拟一个 Docker 容器网桥( docker0 ),在Docker0创建一对虚拟网卡,一半在主机上以vethXXX命名,一般在容器内eth0,启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP ,同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
- docker run 创建容器的时候,没有指定 network 的话默认使用的网桥模式就是 bridge ,使用的就是 docker0 。在宿主机使用 ifconfig 命令就可以看到 docker0 和自己 create 的 network 的 eth0,eth1,eth2……代表网卡一,网卡二,网卡三……
- 网桥 docker0 创建一对对等虚拟设备接口一个叫 veth,另一个叫 eth0 ,成对匹配。
- 整个宿主机的网桥模式都是 docker0,类似一个交换机有一堆接口,每个接口叫 veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫 veth pair)。
- 每个容器实例内部也有一块网卡,每个接口叫 eth0 。
- docker0 上面的每个 veth 匹配某个容器实例内部的 eth0 ,两两配对,一一匹配。
- 综上所述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的 ip ,此时两个容器的网络是互通的。
4.2 host主机模式
容器不再拥有自己的网络空间,而是直接与主机共享网络空间,基于改模式创建的容器对应ip实际就是与主机同一个网段。
例如:
宿主机IP:192.168.113.1
容器IP:192.168.113.X
4.3 None模式
Docker拥有自己的网络空间,但是不与主机共享,这个网络模式下的容器不会被分配网卡、IP、路由等相关信息,处于不联网的状态。
- 完全隔离,不存在与外部任何服务器的网络访问,只有的本地网络127.0.0.1,处于绝对安全。
4.4 Container模式
Container模式的创建需要基于已存在的容器网络模式,即新建的容器和已经存在的一个容器共享一个网络 ip 配置而不是和宿主机共享。
- 新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
4.5 Customer模式
不使用Docker自带的网络模式,反而自己创建一个,这种模式在生产环境下比较常用。
- 自定义网络默认使用的是桥接网络 bridge 。
- 自定义网络本身就维护好了主机名和 ip 的对应关系(ip 和域名都能通),常用。
基于bridge模式创建一个名为demo的网络,并且子网范围为192.168.133.0/24,网关为192.168.113.1
docker network create --driver bridge --subset 192.168.133.0/24 --getway 192.168.133.1 demo
Docker 允许创建自定义网络,以便更好地控制容器之间的通信。自定义网络提供了比默认桥接网络更高级的网络配置选项,如网络隔离、容器间的自动 DNS 解析等。