Docker大全
注:
Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境。
Docker 实质上是在已经运行的 Linux 下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的 Linux 主机
Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境,例如windows系统想用就要开启Hyper-V服务或者安装一个Linux虚拟机。
一.Docker介绍
概述:
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
核心概念:
1、镜像 (Image)
定义:镜像是一个只读的模板,包含了运行应用所需的所有内容:代码、运行时、库文件、环境变量和配置文件。定义了容器的运行环境(如操作系统、软件配置等)。通过分层存储(Layer)优化空间和构建速度。
特点:
- 分层存储:镜像由多个层组成,每一层代表一次修改
- 只读性:镜像本身是只读的,不能直接修改
- 可复用:同一个镜像可以创建多个容器
- 版本管理:通过标签(tag)进行版本管理
类比理解:镜像就像是一个安装程序或者模板,它定义了应用运行所需的一切,但本身不能直接运行。
2、容器 (Container)
定义:容器是镜像的运行实例,是一个轻量级、可移植的执行环境。包含应用代码、运行时环境和依赖库。基于镜像创建,与其他容器隔离,共享主机操作系统内核(比虚拟机更高效)。
特点:
- 隔离性:每个容器都有自己的文件系统、网络和进程空间
- 临时性:容器可以被创建、启动、停止、删除
- 可写层:容器在镜像基础上添加了一个可写层
- 进程级:容器内通常运行一个主进程
类比理解:如果镜像是类,那么容器就是对象实例。一个镜像可以创建多个容器,就像一个类可以创建多个对象。
3、仓库 (Repository)
定义:仓库是存储和分发镜像的地方,可以包含一个镜像的多个版本。
分类:
- 公共仓库:如 Docker Hub,任何人都可以使用
- 私有仓库:企业内部搭建,用于存储私有镜像
- 官方仓库:由软件官方维护的镜像仓库
Registry vs Repository:
- Registry:仓库注册服务器,如 Docker Hub
- Repository:具体的镜像仓库,如 nginx、mysql
4. Dockerfile
文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等)。
Docker容器化技术
容器共享主机内核,轻量、隔离且高效,不像虚拟机需要完整的操作系统,下图展示了 Docker 容器的基本架构:
- 上层 是多个容器(App A~F),每个容器独立运行一个应用。
- 中间层 是 Docker,负责管理这些容器。
- 底层 是主机操作系统(Host OS)和基础设施,为容器提供硬件和系统支持。
二.Docker的优点
Docker应用场景
-
微服务架构:每个服务独立容器化,便于管理和扩展。服务可以独立管理和跟新,不同服务使用不同技术
-
CI/CD流水线:与 Jenkins/GitLab CI 集成,实现自动化构建和测试。构建环境:标准化的构建环境,测试隔离:每个测试在独立容器中运行,部署一致性:相同镜像在不同环境部署
-
开发环境标准化:新成员一键启动全套依赖服务(如数据库、消息队列)。快速搭建:新成员快速获得开发环境,版本同步:团队使用相同的开发环境,依赖管理:避免本地环境冲突
-
云原生基础:Kubernetes 等编排工具基于 Docker 管理容器集群。
-
应用现代化:遗留系统:将传统应用容器化,云迁移:帮助应用迁移到云平台,混合云:在不同云环境间移植
Docker核心优势
- 跨平台一致性:解决"在我机器上能跑"的问题,确保开发、测试、生产环境一致。
- 资源高效:容器直接共享主机内核,无需虚拟化整个操作系统,节省内存和 CPU比虚拟机占用更少的资源。
- 快速部署:秒级启动容器,支持自动化扩缩容。
- 隔离性:每个容器拥有独立的文件系统、网络和进程空间。
传统应用方式及Docker解决方案
1、传统应用部署的痛点
在传统的应用部署中,我们经常遇到以下问题:
- 环境不一致:应用在开发环境运行正常,但在测试或生产环境出现问题
- 依赖管理复杂:不同应用需要不同版本的运行时、库文件等
- 资源利用率低:传统虚拟机需要完整的操作系统,占用大量资源
- 部署复杂:需要手动配置环境、安装依赖,容易出错
2、容器化技术的解决方案
容器化技术通过以下方式解决了这些问题:
- 环境标准化:将应用及其依赖打包在一起,确保在任何环境中都能一致运行
- 轻量级:容器共享宿主机的操作系统内核,比虚拟机更轻量
- 快速部署:容器可以在几秒内启动,大大提高了部署效率
- 可移植性:一次构建,到处运行
虚拟机与Docker的区别
1.架构对比
2.使用场景对比
虚拟机适用场景: Docker容器适用场景:
需要完全隔离的环境 微服务架构,开发环境标准化
运行不同操作系统的应用 CI/CD流水线
需要硬件级别的安全隔离 应用快速部署和扩展
三.docker的使用
开启和关闭docker
systemctl start docker
systemctl status docker //查看docker服务状态
systemctl stop docker
docker run hello-world会先从本地搜索名为hello-world的镜像,若没有找到,则先从docker hub中pull该镜像,拉取镜像到本地成功后,再通过run指令来启动容器运行该镜像。
docker 镜像的使用
注:如果忘记了命令可以用docker -help提示
1.查看所下载的镜像
docker images 或 docker image ls
2.拉取下载镜像
使用命令 docker pull 来下载镜像。
3.查找镜像
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为:Docker Hub
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。并且是在docker hub上查找镜像,但是目前国内打不开这个网址
改进 :docker search docker.1ms.run/tomcat //docker.1ms.run 就是一个国内的镜像加速的地址
4.启动镜像
启动镜像可以通过docker run 镜像名:tag或者 docker run 镜像id。
5.删除镜像
删除镜像 docker rmi
- docker rmi -f 镜像id # 删除指定镜像, -f表示强制删除
- docker rmi -f 镜像id 镜像id 镜像id # 同时删除多个镜像
- docker rmi -f $(docker images -aq) # 全部删除
docker 容器的使用
Docker 常用命令
命令 | 功能 | 示例 |
---|---|---|
docker run | 启动新容器并运行命令 | docker run -d ubuntu |
docker ps | 列出运行中的容器 | docker ps |
docker ps -a | 列出所有容器(含已停止) | docker ps -a |
docker build | 通过 Dockerfile 构建镜像 | docker build -t my-image . |
docker images | 列出本地存储的镜像 | docker images |
docker pull | 从仓库拉取镜像 | docker pull ubuntu |
docker push | 推送镜像到仓库 | docker push my-image |
docker exec | 在运行中容器内执行命令 | docker exec -it container_name bash |
docker stop | 停止容器 | docker stop container_name |
docker start | 启动已停止的容器 | docker start container_name |
docker restart | 重启容器 | docker restart container_name |
docker rm | 删除容器 | docker rm container_name |
docker logs | 查看容器日志 | docker logs container_name |
docker inspect | 获取容器/镜像的详细信息 | docker inspect container_name |
docker exec -it | 进入容器的交互式终端 | docker exec -it container_name /bin/bash |
docker network ls | 列出所有 Docker 网络 | docker network ls |
docker volume ls | 列出所有 Docker 卷 | docker volume ls |
docker-compose up | 通过 docker-compose.yml 启动多容器应用 | docker-compose up |
docker-compose down | 停止并删除 Compose 启动的资源 | docker-compose down |
docker info | 显示 Docker 系统信息 | docker info |
docker version | 显示 Docker 版本信息 | docker version |
docker stats | 实时监控容器资源使用 | docker stats |
docker login | 登录 Docker 仓库 | docker login |
docker logout | 登出 Docker 仓库 | docker logout |
常用选项说明:
-d:后台运行容器,例如 docker run -d ubuntu。
-it:以交互式终端运行容器,例如 docker exec -it container_name bash。
-t:为镜像指定标签,例如 docker build -t my-image .。
启动容器
以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:
docker run -it --name=c1 ubuntu:7 /bin/bash
- 如果以镜像名启动一个容器,则会创建一个新的容器,在启动这个容器
- -i: 交互式操作。
- -t: 终端。
- ubuntu: ubuntu 镜像。
- /bin/bash:让容器启动后运行 Bash Shell,配合 -it 实现可交互的终端环境。这是调试、操作容器的标准方式。
何时需要加/bin/bash:
1.需要交互式调试:如手动检查容器内部状态、测试命令。
2.镜像无持久化进程:如基础 Ubuntu 镜像默认无服务,需手动启动 Shell 防止退出。
- --name:为创建的容器命名
进入后台启动的容器
在使用 -d 参数时启动容器时,容器会运行在后台,这时如果要进入容器,可以通过以下命令进入:
- docker attach:允许你与容器的标准输入(stdin)、输出(stdout)和标准错误(stderr)进行交互。
- docker exec:推荐大家使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。
退出容器
- exit # 直接停止容器并退出
- ctrl+p+q # 不停止容器,只退出,在linux下有效
删除容器
- docker rm 容器id # 删除指定容器,不能删除正在运行的容器,可用 rm -f 强制删除
- docker rm -f `docker ps -aq ` # 删除所有容器
docker 数据卷
1.概念:
- 数据卷是宿主机的一个目录或文件
- 当容器目录和数据卷目录绑定后,对方的修改会立即同步
- 一个数据卷可以被多个容器同时挂载
- 一个容器也可以被挂载多个数据卷
2.作用:
- 容器数据持久化
- 外部机器和容器间接通信
- 容器之间数据交换
3.配置:
在创建启动容器时,使用 -v 参数设置数据卷
docker run ...-v 宿主机目录(文件):容器内目录(文件)
注意:
- 目录必须是绝对路径
- 目录不存在,会自动创建
- 可以挂载多个数据卷
- 可以让两个容器同时挂载一个目录或文件下,从而实现两个容器间数据交换
4.数据卷容器
概念:将一个容器与宿主机挂载,作为一个数据卷容器,然后将其他容器与该数据卷容器挂载,实现多容器间数据交换
创建:
1.创建启动c3数据卷容器,使用-v 参数,不用设置宿主机目录会自动创建
docker run -it --name=c3 -v /volume mysql /bin/bash
2.创建启动c1,c2 容器,使用--volumes-from 参数设置数据卷
docker run -it --name=c1 --volumes-from c3 mysql /bin/bash
3.如果数据卷容器被删了,其他的容器依然能通信
docker 仓库管理
仓库(Repository)是集中存放镜像的地方。以下介绍一下 Docker Hub。当然不止 docker hub,只是远程的服务商不一样,操作都是一样的。但是由于,docker hub网址国内打不开,可以用阿里云镜像仓库管理
可以在阿里云官网,在容器镜像服务中,创建个人版实例镜像仓库,根据官网上操作配置打开。
阿里云容器管理仓库
四.dockfile
1.镜像原理及定义:
原理:
- Docker镜像是由特殊的文件系统叠加而成
- 最底端是bootfs,并使用宿主机的bootfs(内核)
- 第二层是root文件系统rootfs,称为baseimage然后再往上可以叠加其他的镜像文件
- 统一文件系统(UnionFileSystem)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
- 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
- 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器
定义:
- Dockerfile 是一个文本文件,包含了构建 Docker 镜像的所有指令。
- Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
- 通过定义一系列命令和参数,Dockerfile 指导 Docker 构建一个自定义的镜像。
2.Docker镜像的制作
2.1容器转镜像
docker commit 容器id 镜像名称:版本号 //将容器转化为镜像
docker save -o 压缩文件名称 镜像名称:版本号 //将镜像转化为压缩文件
docker load -i 压缩文件名称 //将压缩文件转化为镜像
2.2 Dockerfile(重要)
构建三步骤:
1.编写Dockerfile文件
2.docker build 命令构建镜像
3.docker run 根据镜像运行容器实例
注:
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都创建一个新的镜像层并对镜像进行提交
- Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大
2.3 Dockerfile指令(用于自定义镜像)
上下文路径
上一节中,有提到指令最后一个 . 是上下文路径,那么什么是上下文路径呢?docker build -t nginx:v3 .
- 上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制ADD,COPY),docker build 命令得知这个路径后,会将路径下的所有内容打包。
- 在此目录下查找 Dockerfile(除非用 -f 指定)。
- 将此目录下的文件提供给 COPY/ADD 指令使用。
FROM: nginx 定制的镜像都是基于FROM的镜像,nginx就是基础镜像
RUN 用于执行后面跟着的命令行命令,有两种格式
shell 格式:
RUN <命令行参数>
exec 格式:
RUN ["可执行文件","参数1","参数2"] 例如 RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
MAINTAINER 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)
WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。也就是指定落脚点,开启容器指定进入的目录。docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:WORKDIR <工作目录路径>
USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。格式: USER <用户名>[:<用户组>]
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量,相当于创建一个变量。格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用
ADD
ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
格式:
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
[--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行,即启动后执行。
- RUN 是在 docker build时运行。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。
EXPOSE
仅仅只是声明端口。作用:
帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
五.docker network
定义:
Docker 通过网络驱动来实现不同的网络功能。当你运行一个容器时,如果没有明确指定网络,它通常会连接到 Docker 默认创建的某个网络。
- 网络隔离:每个 Docker 容器都拥有自己的独立网络栈,包括 IP 地址、网络接口、路由表等。这意味着容器在网络层面是相互隔离的,除非你明确地将它们连接起来或进行端口映射。
- DOS服务发现:在同一个 Docker 网络中的容器,可以通过容器名或服务名进行相互通信,而不是必须使用 IP 地址。Docker 内置了 DNS 服务,可以自动解析这些名称到对应的 IP 地址。这极大地简化了多容器应用的配置。
常用命令:
1.查看全部网络
2.管理网络
# 新建(默认为网桥模式)
docker network create my-app-network#指定网络类型
docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
# 删除
docker network rm my-app-network#查看网络数据源
docker network inspect bridge
#查看网络链接
ip add
#用于将容器连接到网络。可以按名称或ID连接容器。 一旦连接,容器可以与同一网络中的其他容器通信。
docker network connect 网络名 正在运行的容器
docker run -itd --network=网络名 即将启动的容器
docker network connect --ip 10.10.10.10 网络名 容器
#删除无用网络
docker network prune
#强制断开
docker network disconnect 网络名 容器
网络类型
bridge
当你安装 Docker 时,它会默认创建一个名为 bridge(或 docker0)的虚拟网桥。所有未指定网络的容器默认都会连接到这个桥接网络。每个连接到桥接网络的容器都会获得一个私有 IP 地址,它们可以相互通信。
容器可以通过端口映射 (-p 参数) 将其内部端口暴露给宿主机。宿主机以及外部网络可以通过宿主机的 IP 地址和映射的端口访问容器内的服务。
自定义网络 (推荐):
虽然 Docker 有一个默认的 bridge
网络,但强烈建议你创建自己的自定义桥接网络。这是因为:
- 更好的隔离: 将你的应用程序容器放在一个独立的网络中,与默认网络中的其他无关容器隔离。
- 自动 DNS 服务发现(非常好用): 在自定义桥接网络中,容器可以通过容器名称互相解析和通信。这是默认桥接网络不具备的功能(需要使用 --link,但 --link 已被弃用)。
- 更易管理: 清晰地组织你的容器网络
- 自定义网络本身就维护好了主机名和IP的对应关系,也就是IP和域名都能联通
host
直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换。
容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
none
直接禁用了网络功能,没有IP地址,没有网关,没有相关配置,有的是有一个lo回环地址127.0.0.1
contain
新建的容器和已经存在的一个容器共享一个网络IP配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
六.compose(服务编排)
定义:
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建,启动,管理所有服务
步骤:
1.利用Dockerfile定义运行环境镜像
2.使用docker-compose.yml定义组成应用的各服务
3.运行docker-composeup启动应用命令:
- 启动所有服务: docker-compose up(-d后台运行,-f指定配置文件)
- 停止所有服务: docker-compose down
- 构建服务镜像: docker-compose build
- 查看服务状态: docker-compose ps
- 查看服务日志: docker-compose logs
目录结构:
└── compose_test
├── docker
│ └── docker-compose.yml
├── Dockerfile
└── src
├── app.py
└── requirements.txt
docker-compose.yaml文件:
这是 Docker Compose 的核心。它是一个 YAML 格式的配置文件,用于定义应用程序的服务、网络和数据卷。在该文件中
- services (服务):应用程序的各个组件,例如 web、app、db 等。每个服务都对应一个 Docker 容器。你可以指定每个服务使用的镜像、构建方式、端口映射、数据卷、环境变量等。
- networks (网络):定义容器之间用于通信的自定义网络。Compose 会为你的应用创建一个默认网络,但你也可以定义自己的网络以便更好地隔离或组织服务。
- volumes (数据卷):定义用于持久化数据的命名卷。