Docker是一个开源的容器化平台,可以让开发者在容器中构建、打包、运行和发布应用程序,从而实现应用程序的快速部署和可移植性。Docker将应用程序和依赖项打包在一个轻量级的可移植容器中,这个容器可以在任何平台上运行,不会受到环境变化的影响,使得应用程序在不同环境下的部署变得非常方便和高效。Docker还提供了一系列的工具和服务,例如Docker Compose和Docker Swarm等,可以更好地支持容器化应用程序的开发、测试和部署。
一、Docker 的基本概念
Docker 是一个基于容器技术的开源项目,可以将应用程序和依赖项打包成一个容器,然后在任何地方运行,无需担心环境的变化和配置问题。Docker 的基本概念包括:Docker 镜像、Docker 容器、Docker 仓库和 Dockerfile。
- Docker 镜像 是一个只读的文件系统,包含了运行应用程序所需的所有内容,如操作系统、软件包、应用程序代码、配置文件等。Docker镜像的核心是分层存储结构,每个镜像层都是只读的,并且可以复用。这意味着在构建 Docker镜像时,只需要添加新的层,不需要重新复制原有的层,从而大大减小了镜像的大小和构建时间。
- Docker 容器 是 Docker镜像的运行实例,是一个独立、轻量级的应用程序运行环境。每个容器都有自己的文件系统、网络配置和进程空间,可以隔离应用程序和依赖项,实现不同应用程序的互不干扰。Docker容器可以快速创建、启动、停止和删除,具有高度可移植性和灵活性,可以在本地、云端或者边缘设备上运行。
- Docker 仓库 是 Docker 镜像的集合和管理中心,类似于代码仓库的概念。Docker仓库分为公共仓库和私有仓库两种,公共仓库包括 Docker Hub 和其他一些第三方仓库,可以免费获取、共享和下载 Docker镜像。私有仓库则是企业内部自建的 Docker 镜像仓库,可以用于管理、分享和分发内部使用的 Docker 镜像。
- Dockerfile 是 Docker 镜像构建的脚本文件,用于自动化地构建 Docker 镜像。Dockerfile包含了一系列构建镜像所需的命令和参数,可以指定基础镜像、添加依赖项、设置环境变量、运行脚本等操作。
二、docker架构图
Docker架构图中包含了以下组件:
- Docker Client:与Docker Daemon交互的命令行工具或者UI界面,可以通过REST API或者UNIXSocket与Docker Daemon通信。
- Docker Daemon:Docker的核心组件,守护进程,负责管理本地的Docker镜像、容器、网络等资源,并与DockerHub等远程仓库通信。
- Docker Registry:存储Docker镜像的仓库,包括Docker官方提供的公共仓库DockerHub和用户自己搭建的私有仓库。
- Docker Image:Docker镜像,包含应用程序代码、运行时环境、系统工具、系统库等内容的只读文件。
- DockerContainer:Docker容器,是从Docker镜像创建出来的实例,包含应用程序、运行时环境、系统工具、系统库等内容的可读写文件系统。
- Docker Network:Docker网络,为Docker容器提供网络通信能力,容器可以通过网络连接到其他容器、主机、外部服务等。
- Docker Volume:Docker卷,为Docker容器提供数据持久化能力,容器可以通过卷将数据保存到本地磁盘、云存储等。
三、docker组成
(一)Docker Engine
Docker引擎是Docker的核心组件,用于构建和运行Docker容器。它包含一个守护进程,可以在宿主机上创建和管理Docker容器。Docker引擎使用客户端-服务器模型进行交互。
(二)Docker守护进程
Docker守护进程是一个后台进程,负责管理Docker容器的创建、启动、停止、删除等操作,同时它还提供了一系列RESTful API供客户端调用。
Docker守护进程通过与Linux内核的API进行交互来管理容器。其中最核心的技术是Linux容器技术,它是Linux内核提供的一种轻量级虚拟化技术,可以隔离应用程序及其运行环境,实现类似于虚拟机的隔离效果,但是比虚拟机更加轻量级,可以在同一物理机上运行多个容器。
Docker守护进程的工作原理可以简单概括为以下几个步骤:
- Docker客户端通过Docker API向Docker守护进程发送指令,例如创建容器、启动容器、停止容器等。
- Docker守护进程根据指令创建或管理容器,通过Linux容器技术隔离应用程序及其运行环境,通过Cgroups限制容器所使用的资源,通过Namespace实现容器之间的隔离。
- Docker守护进程将容器的标准输出和标准错误输出输出到容器的日志文件中,方便查看容器运行的状态和输出信息。
- Docker守护进程通过Docker API向Docker客户端发送容器运行的状态和输出信息。
(三)Docker客户端
Docker客户端则是一个命令行工具,用于与Docker守护进程进行通信,发送命令以管理Docker容器。通过Docker客户端,我们可以在本地或远程机器上创建、运行、停止、删除容器,查看容器的状态、日志信息等。同时,Docker客户端还支持构建、上传、下载Docker镜像等操作。
(四)Docker Hub
Docker Hub是Docker官方提供的一个公共注册中心,用于存储和分享Docker镜像。Docker Hub包含了大量的官方和社区创建的Docker镜像,用户可以通过Docker Hub搜索、下载和分享Docker镜像。Docker Hub是Docker官方提供的一个云服务平台,它可以作为Docker镜像的中央仓库,供开发者上传和下载Docker镜像,是一个Docker生态系统中重要的组成部分。Docker Hub提供了公共和私有两种类型的仓库,可以免费创建和使用公共仓库,而私有仓库则需要付费使用。使用Docker Hub,开发者可以方便地在全球范围内分享和管理Docker镜像,从而提高了应用程序的可移植性和部署效率。
私有库有何作用?
虽然Docker Hub作为公共的Docker镜像库已经包含了很多常用的镜像,但是在企业内部或一些特定场景下,可能需要使用一些私有的镜像。这时,就需要使用私有的Docker镜像库来存储和管理这些镜像。私有库可以提供更安全的环境,允许用户自定义访问权限和控制镜像的版本,以便满足组织内部的特定需求。此外,企业也可以在私有库中存储一些商业机密信息的镜像,而不需要将它们上传到公共库中。
私有库如何的搭建?
使用Docker Registry软件搭建私有库的步骤如下:
- 安装Docker Registry可以通过Docker官方提供的Docker Registry镜像来启动Registry容器。
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
这个命令会从Docker Hub上拉取Registry镜像并启动一个名为“registry”的容器,使用端口5000映射容器的5000端口。
- 配置Docker客户端,要使用私有库,需要在Docker客户端中配置私有库的地址。可以通过修改Docker客户端的配置文件/etc/docker/daemon.json来实现。
{
"insecure-registries": ["my-registry.com:5000"]
}
这个配置文件中的insecure-registries字段指定了需要信任的私有库的地址。
- 推送和拉取镜像要将镜像推送到私有库,可以使用docker push命令,例如:
$ docker push my-registry.com:5000/my-image:latest
- 要从私有库中拉取镜像,可以使用docker pull命令,例如:
$ docker pull my-registry.com:5000/my-image:latest
这样就可以使用私有库来管理自己的镜像了。
如何才能让自己先从私有库拉镜像呢?
在使用Docker时,可以通过修改Docker客户端的配置文件来更改默认拉取镜像的地址。
具体操作如下:
编辑Docker客户端的配置文件/etc/docker/daemon.json(Linux系统),或者在Windows系统上的Docker Desktop中选择“Settings” -> “Docker Engine” -> “Advanced” -> “JSON”进行编辑。在daemon.json文件中添加以下内容:
{
"registry-mirrors": ["https://<your-registry-mirror>"]
}
其中,是你私有镜像仓库的地址。保存daemon.json文件,并重启Docker服务。这样配置之后,Docker客户端每次拉取镜像时会优先从你的私有镜像仓库拉取,如果没有找到则会从公共镜像仓库拉取。
如何才能把共有库的镜像拉到自己的私有库中保存呢?
可以使用docker pull命令将公共库的镜像拉取到本地,然后再使用docker tag命令将其打上私有库的标签,最后使用docker push命令将镜像推送到私有库。
具体步骤:
- 拉取公共库中的镜像
docker pull <公共库镜像名>:<标签>
- 为镜像打上私有库的标签
docker tag <公共库镜像名>:<标签> <私有库地址>/<镜像名>:<标签>
- 推送镜像到私有库
docker push <私有库地址>/<镜像名>:<标签>
可以批量拉取公共库中常用的镜像吗?
可以通过编写Docker Compose文件来批量拉取公共库中常用的镜像,具体步骤如下:
在本地创建一个新的目录,并在其中创建一个名为 docker-compose.yml 的文件。编辑 docker-compose.yml 文件,添加需要拉取的镜像和其它配置信息
例如:
version: '3.7'
services:
nginx:
image: nginx:latest
mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: example_db
ports:
- "3306:3306"
redis:
image: redis:latest
这个例子中,我们将拉取最新版本的 nginx、mysql 和 redis 镜像,并将 mysql 镜像映射到主机的 3306 端口。执行 docker-compose pull 命令来拉取这些镜像。执行成功后,镜像就会被下载到本地的 Docker 引擎中,可以通过 docker images 命令来查看。
注意:这种方式只适用于批量拉取已有的镜像,如果需要自定义镜像,还需要使用 Dockerfile 来构建镜像。
(五)Docker Compose
Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。它可以通过一个配
置文件来定义多个服务,这些服务可以作为一个整体来启动、停止和管理。这样可以方便地管理多个相关的Docker 容器,同时也方便了在不同环境中部署应用程序,如开发、测试、生产环境等。
使用 Docker Compose,可以使用一个 YAML 文件来定义多个容器、容器之间的依赖关系、容器的网络和数据卷等信息。通过一个命令即可启动、停止、重启和管理这些容器。
Docker Compose 可以极大地简化 Docker 容器的管理和部署,特别是在复杂应用程序中,包含多个容器的情况下,使用 Docker Compose 可以使管理容器变得更加简单和高效。
使用场景举例:
比如我有一个gateway服务(端口:73)、一个admin服务(端口:7001)、一个sap服务(端口:7002)、一个prodplan服务(端口:7003)、一个basicdata服务(端口:7004),如果不用Docker
Compose,我会给他们分别创建镜像和容器,然后分别docker run他们,那我如果使用了Docker
Compose,我会得到什么好处呢?
使用Docker Compose 可以带来以下好处:
-
简化管理和维护:使用Docker
Compose,可以将所有的微服务相关的容器定义在一个文件里,这样就能够一次性启动、停止、重启、删除等操作所有的容器,而不用一个一个地操作。
管理依赖关系:有时不同的微服务之间会存在依赖关系,例如某个微服务需要依赖于另一个微服务的数据库,而Docker
Compose可以通过定义依赖关系来自动管理这些依赖关系,从而简化了管理和部署。 -
简化开发环境的搭建:使用Docker
Compose可以帮助开发人员快速搭建出一个与生产环境相似的本地开发环境,这样就能够快速迭代开发,加快开发周期。 -
可重复性:使用Docker Compose可以确保在不同的环境下容器的启动顺序和配置是相同的,从而增加了应用的可重复性。
yaml文件怎么写?还需要分别写dockerfile文件吗?
当然需要为每个服务编写Dockerfile文件,以定义如何构建该服务的Docker镜像。然后,在Docker Compose文件中,可以使用build字段指定每个服务使用哪个Dockerfile文件来构建它们的镜像。
下面是一个例子,假设你有以下目录结构:
markdownCopy code
myapp/
├── docker-compose.yml
├── gateway/
│ ├── Dockerfile
│ └── ...
├── admin/
│ ├── Dockerfile
│ └── ...
├── sap/
│ ├── Dockerfile
│ └── ...
├── prodplan/
│ ├── Dockerfile
│ └── ...
└── basicdata/
├── Dockerfile
└── ...
然后,你可以编写以下的 docker-compose.yml 文件:
version: '3'
services:
gateway:
build: ./gateway
ports:
- "73:73"
admin:
build: ./admin
ports:
- "7001:7001"
sap:
build: ./sap
ports:
- "7002:7002"
prodplan:
build: ./prodplan
ports:
- "7003:7003"
basicdata:
build: ./basicdata
ports:
- "7004:7004"
这将告诉Docker Compose构建每个服务的镜像,使用指定的Dockerfile文件,然后在每个服务中运行容器,将服务的端口映射到主机的端口。
统一打包完jar包后,还需要分别构建docker镜像吗?
需要为每个服务构建对应的 Docker 镜像,以便在 Docker Compose 文件中引用。一般来说,您需要为每个服务编写 Dockerfile 文件来构建相应的 Docker 镜像。在 Dockerfile 文件中,您需要指定基础镜像、复制应用程序文件、设置工作目录、安装依赖项、暴露端口等操作。完成 Dockerfile 文件编写后,您可以使用 Docker 命令构建对应的 Docker 镜像。
例如:
docker build -t your-image-name:tag your-dockerfile-directory
其中,-t 参数用于指定镜像名称和标签,your-image-name 是您的镜像名称,tag 是您的镜像标签,your-dockerfile-directory 是 Dockerfile 文件所在目录。
在 Dockerfile 文件构建完成后,您可以使用 docker-compose 命令启动服务。当您执行 docker-compose up 命令时,Docker Compose 会在各个服务之间自动创建网络,启动对应的容器,并根据 Docker Compose 文件中定义的依赖关系依次启动服务。
我还需要docker run命令来启动服务了吗?
使用Docker Compose可以统一管理多个容器,只需要在Docker Compose文件中定义好需要启动的容器,然后使用docker-compose up命令启动所有容器即可。不需要手动运行每个容器的docker run命令了。
docker-compose怎么安装?
docker-compose可以通过多种方式安装,最简单的方式是使用pip命令安装。
具体步骤如下:
确认已经安装了Docker。如果还没有安装,可以参考Docker官方文档进行安装。安装pip。如果系统中没有安装pip,可以使用以下命令进行安装:
$ sudo apt-get update
$ sudo apt-get install -y python3-pip
$ sudo pip3 install docker-compose
注意:使用pip3命令可以确保安装的是Python 3版本的docker-compose。
$ docker-compose --version
如果安装成功,会显示docker-compose的版本号。
(六)Docker Registry
Docker Registry是一个私有的Docker镜像注册中心,用于存储和分享私有的Docker镜像。用户可以在本地部署Docker Registry,以便在企业内部共享Docker镜像。
什么是镜像?
在 Docker 中,镜像(image)指的是一个轻量级、可执行的包,其中包含了运行应用程序所需的所有内容,包括代码、运行时、库、环境变量和配置文件等。镜像是 Docker 容器运行的基础。可以将镜像看作是一个只读的模板,用来创建 Docker 容器。使用 Docker 镜像,可以快速地构建、部署和运行应用程序,同时保证应用程序的环境一致性。
镜像和普通jar包的区别?
首先,JAR包是Java应用的一种打包格式,而镜像是一种文件系统格式,它包含了操作系统、应用程序和相关的依赖库等所有运行应用程序所需的组件。因此,镜像不仅仅包含了应用程序本身,还包含了操作系统和所有的依赖库。
其次,JAR包是面向特定的应用程序和运行环境的,而镜像则可以在任何支持Docker运行时的环境中运行,因为镜像中已经包含了所有应用程序所需的组件和依赖库。这使得镜像可以在不同的操作系统、不同的硬件架构上运行。
最后,JAR包通常只包含应用程序的代码和资源,而镜像则可以包含应用程序、操作系统和运行时环境等所有组件,因此可以更方便地进行部署和管理。
四、总结
上面对 Docker 进行了基础知识的全解析。我们了解了 Docker 是什么以及它的核心概念,包括 Docker 镜像、Docker 容器、Dockerfile 和 Docker Compose。我们还介绍了如何使用 Docker 来管理应用程序和构建容器化的应用程序。特别是用这种提问方式来进行分享,我学到了很多,在没有提问之前,总感觉自己好像都会了,但是真正实践的时候发现很多问题还是一窍不通。