docker是什么?解决了什么问题?特性有哪些
Docker 解决了传统应用部署中的多个痛点:一致性:容器打包应用及其依赖,确保在不同环境中保持一致的运行状态,避免了开发、测试、生产环境差异带来的问题。高效性:容器共享宿主机操作系统内核,避免了虚拟机的冗余开销,启动速度更快,资源占用更低,提升了部署效率。隔离性:容器之间相互隔离,避免了端口冲突和依赖干扰。即使在同一机器上运行多个容器,它们的环境也不会互相干扰。可移植性:容器将应用及其依赖打包在
言简意赅的讲解Docker解决的痛点
Docker的背景与意义
Docker 是一个开源的容器化平台,旨在帮助开发者简化应用程序的构建、打包、部署和运行。通过将应用程序及其所有依赖打包到一个容器中,Docker 使得应用能够在任何环境中以相同的方式运行。最初,Docker 是 Kubernetes 默认的容器运行时(container runtime),但为了适配更多的容器运行时,Kubernetes 将 Docker 更底层的容器运行时管理工具——containerd
(Kubernetes 的 CRI 工具)作为核心容器运行时,这样就实现了容器运行时管理的灵活切换。除了 containerd
,还可以将容器运行时管理切换为其他工具,比如 CRI-O 或 gVisor,它们都能与 Kubernetes 集成,帮助 Kubernetes 实现容器的隔离和管理。
Docker 解决的问题
-
一致性:
Docker 的最大优势之一是容器的一致性。通过 Docker 镜像生成的容器在任何环境中都能保持相同的运行状态,不论是在开发、测试、生产等环境中,容器中的应用始终是相同的。例如,你可以在本地开发机器中使用:docker start {容器名}
这个命令就能在任何环境中启动一个一致的容器,确保应用的一致性。
-
高效性:
Docker 容器通过共享宿主机的操作系统内核,而不是像虚拟机那样每个实例都需要一个完整的操作系统内核。这种方式显著降低了资源开销,解决了传统虚拟机在启动速度、占用空间方面的瓶颈。容器在宿主机内核之上直接运行,避免了冗余的资源消耗,因此启动速度更快,资源占用更低。用例:
假设你需要部署一个 Web 应用(例如 Node.js),如果使用虚拟机,每次启动都需要启动一个完整的操作系统,而 Docker 容器只需启动应用所需的部分资源,启动时间可能从几分钟缩短到几秒钟。比如:docker run -d -p 8080:80 nginx
上述命令可以在几秒钟内启动一个 Nginx 容器,而不需要虚拟化的完整操作系统。
-
隔离性:
Docker 的容器化特性实现了强隔离性,这是很多人选择 Docker 的核心原因之一。容器内的应用及其运行环境相互隔离,不会互相干扰。例如,如果你在同一台机器上运行两个需要使用8080
端口的应用,Docker 可以通过端口映射来解决端口冲突问题。你可以为两个容器分别映射不同的端口:docker run -d -p 8080:8080 container1 docker run -d -p 9090:8080 container2
这样,即使容器内部使用的是相同的端口,宿主机上不同的端口(如 8080 和 9090)会指向不同的容器,解决了端口占用冲突的问题。
用例:
假设你有两个不同版本的数据库应用,分别运行在不同的容器中,你可以通过端口映射将它们的数据库端口暴露到宿主机上:docker run -d -p 3306:3306 mysql:5.7 # MySQL 5.7 容器 docker run -d -p 3307:3306 mysql:8.0 # MySQL 8.0 容器
宿主机的 3306 端口映射到 MySQL 5.7 容器,3307 端口映射到 MySQL 8.0 容器,这样就解决了端口冲突的问题。
-
可移植性:
由于 Docker 容器将应用程序与其依赖打包在一起,因此容器可以在任何支持 Docker 的平台上运行,无论是在开发者的本地环境、云服务器,还是其他任何支持 Docker 的系统。这种高度的可移植性使得开发、测试和生产环境中的一致性变得更加容易保证。用例:
假设你开发了一个 Python 应用,并且在本地使用 Docker 容器进行调试。当你准备部署到生产环境时,可以直接将这个容器镜像推送到 Docker Hub 或私有镜像仓库,然后在生产环境的服务器上拉取并运行这个容器:docker pull myusername/my-python-app docker run -d myusername/my-python-app
这使得开发、测试、生产环境之间的过渡变得极其顺畅。
-
可扩展性:
Docker 支持容器的水平扩展,能够通过增加更多的容器实例来扩展应用的容量。此外,Docker 容器也与容器编排工具(如 Kubernetes)紧密集成,后者可以自动化管理容器的部署、扩展和负载均衡等。用例:
假设你有一个负载均衡的 Web 应用,需要处理大量并发请求。你可以通过 Kubernetes 或 Docker Swarm 启动多个容器实例来实现水平扩展:docker service scale my-web-app=5 # 使用 Docker Swarm 启动 5 个容器实例
Kubernetes 也可以根据负载自动扩展容器实例:
kubectl scale deployment my-web-app --replicas=5
Docker 的核心用法
Docker 的主要功能是容器的构建、打包、部署和运行。与容器编排工具 Kubernetes 相结合,Docker 解决了容器的生命周期管理问题。
-
Dockerfile:构建 Docker 镜像的核心文件,定义了如何从基础镜像创建新镜像并运行应用程序。Dockerfile 使得容器镜像的创建过程自动化。
用例1:
你可以创建一个简单的Dockerfile
来构建一个 Node.js 应用的镜像:FROM node:14 WORKDIR /app COPY . /app RUN npm install CMD ["npm", "start"]
说明:
- 这个 Dockerfile 从官方的 Node.js 14 镜像开始,拷贝当前目录下的应用代码并安装依赖,最后指定运行命令为
npm start
。
用例2:
你还可以进阶的使用dockerfile完成更多更复杂的操作,比如下面这个项目中同时启动多个端口,即build了前端静态又同时启动了一个后端服务。这样的话这个镜像构建出来直接完成了前后端的部署,在同一个容器中。可玩性非常高:# 使用官方 Node.js 镜像 FROM node:18-alpine AS builder ARG REACT_APP_HOMEPAGE_KEYCLOAK_REALMS ARG REACT_APP_HOMEPAGE_KEYCLOAK_CLIENTID # 设置工作目录 WORKDIR /app # 复制项目文件 COPY . . # 安装 pnpm RUN npm install -g pnpm # 安装依赖 RUN pnpm install ENV REACT_APP_HOMEPAGE_KEYCLOAK_REALMS=${REACT_APP_HOMEPAGE_KEYCLOAK_REALMS} ENV REACT_APP_HOMEPAGE_KEYCLOAK_CLIENTID=${REACT_APP_HOMEPAGE_KEYCLOAK_CLIENTID} # 生成生产构建 RUN pnpm run build # 使用轻量级的 Node.js 镜像来运行构建后的文件 FROM node:18-alpine # 设置工作目录 WORKDIR /app # 只复制构建后的文件 COPY --from=builder /app/build ./build COPY . . # 安装 serve 和 concurrently RUN npm install -g serve concurrently # 设置后端工作目录 WORKDIR /app/.docker-node RUN npm install -g pnpm RUN pnpm install # 暴露端口 EXPOSE 3000 4000 # 启动命令 CMD ["concurrently", "serve -s ../build -l 3000", "node index.js"]
说明:
- 该
Dockerfile
分为两阶段:第一个阶段(builder
)用于构建前端应用,第二个阶段用于创建运行时容器,确保最终镜像的大小更小。 - 使用了
pnpm
来安装依赖,避免了 npm 带来的一些性能问题。 serve
用于提供构建后的前端静态文件,concurrently
用于同时启动前端和后端服务。- 最终通过
CMD
命令运行前端和后端,前端服务监听 3000 端口,后端服务监听 4000 端口。
- 这个 Dockerfile 从官方的 Node.js 14 镜像开始,拷贝当前目录下的应用代码并安装依赖,最后指定运行命令为
-
Docker镜像与容器:
镜像是容器的模板,每次创建容器时,都会从镜像中复制出一个新的实例。镜像是只读的,而容器是镜像的可执行实例,容器的变更不会影响到原始镜像。用例:
假设你已经有了一个基础镜像python:3.8
,你可以通过docker build
命令从 Dockerfile 构建出自己的镜像:# 使用 Python 3.8 镜像作为基础镜像 FROM python:3.8 # 设置工作目录 WORKDIR /app # 复制项目文件 COPY . . # 安装项目依赖 RUN pip install -r requirements.txt # 设置容器启动时的命令 CMD ["python", "app.py"]
docker build -t my-python-app .
构建完成后,你就可以基于这个镜像启动容器:
docker run -d my-python-app
-
Docker命令:
Docker 提供了许多常用的命令来管理容器和镜像:
- docker pull:从 Docker Hub 或其他镜像仓库拉取镜像。
docker pull ubuntu
- docker build:从 Dockerfile 构建镜像。
docker build -t myimage .
- docker run:启动一个新的容器。
docker run -d -p 8080:80 nginx
- docker ps:列出正在运行的容器。
docker ps
- docker stop:停止一个正在运行的容器。
docker stop container_name
- docker exec:在容器中执行命令。
docker exec -it container_name /bin/bash
- docker pull:从 Docker Hub 或其他镜像仓库拉取镜像。
通过上述内容,你就已经基本理解了这个产品,基础用法我也都有展示。如果你能融会贯通,我相信你会很强
Best
Wenhao (楠博万)
更多推荐
所有评论(0)