Docker 一体化 1️⃣
定义 Docker:Docker 是一个开源平台,可自动执行在轻量级、可移植容器中部署应用程序的过程。
定义 Docker 镜像:Docker 镜像是一种模板,它包含在容器中运行应用程序所需的代码、依赖项或环境变量。
定义容器:容器是一个软件包,它包含了应用程序无缝运行和工作所需的一切。
定义 Docker 守护进程:一个长时间运行的后台进程,用于管理 Docker 对象,例如镜像、容器、网络和存储卷。
定义 Docker 引擎:用于创建和运行容器的技术。
定义 Docker Desktop: Docker Desktop 是一款易于安装的应用程序,适用于 Mac、Windows 或 Linux 环境,可让您构建和共享容器化应用程序和微服务。
定义 Docker 镜像仓库: Docker 镜像仓库用于存储 Docker 镜像。Docker Hub 是一个任何人都可以使用的公共镜像仓库,Docker 默认配置为从 Docker Hub 上查找镜像。您甚至可以运行自己的私有镜像仓库。
- Docker架构:
- Docker 生命周期?
-> 我们可以使用上面的图片作为参考来了解 Docker 的生命周期。
有三件重要的事情,
docker build -> 从 Dockerfile 构建 Docker 镜像
docker run -> 从 Docker 镜像运行容器
docker push -> 将容器镜像推送到公共/私有注册表以共享 Docker 镜像。
图片与容器:
镜像:模板
容器:包含应用程序无缝运行所需软件包的镜像的运行实例。
什么是端口映射以及为什么需要它:一种可以将容器的网络服务暴露给主机或网络上的其他设备的技术。
什么是 Docker 层:Docker 层是 Docker 镜像的构建模块,每条指令都会创建一个新的层。最终镜像的创建方式也类似。因此,层是逐步构建的。逐步构建的好处在于我们可以将层缓存起来以供将来使用。
Docker 卷:它是一个文件系统,用于在容器外部存储数据。当容器被删除或宕机时,容器内的数据也会被删除,因此为了维护数据,我们需要 Docker 卷。
什么是 Docker 网络?:它是一种允许容器之间或容器与外部主机通信的功能。
-> 容器创建时默认会有一个桥接网络,也称为 Docker 0。这些网络使用 VEth 与本地主机连接。
Veth是什么?->它是一个虚拟以太网设备,充当连接容器和主机桥接网络的电缆。
绑定挂载是什么:它用于将主机上的文件或目录绑定到容器。
基本命令:
docker run <image_name>:运行镜像docker images:列出镜像docker pull <image_name>:从 Docker Hub 仓库拉取镜像docker ps:列出正在运行的容器:docker kill <container_id>终止容器docker rmi <image_name>:删除镜像docker build -t <image_name>:latest(构建源位置)docker exec -it <container_id or container_name> /bin/bashdocker volume create <volume_name>:创建卷docker volume ls:列出已创建的卷docker run -v <volume_name>:<location> -p <port_mapping> <image_name>docker network create <network_name>docker logs <container_id>:获取容器日志(如果以分离模式运行docker -v <host_location>:<container_location> <image_name>):用于绑定挂载docker netwok ls:获取网络列表docker inspect <container_name>:获取容器详细信息docker volume inspect <volume_name>:获取卷详细信息docker volume rm <volume_name>:删除卷。
属性 :
-d:分离模式,在后台运行容器并释放终端
;-p:端口映射;
-t:指定标签;-e
:传递环境变量
;-it:以交互方式运行
;--name:为容器命名
;--network:将网络连接到容器
;-v:指定卷。
Docker 命令示例:
docker build -t test:latest .
docker network create check
docker run -p 3000:3000 --network=check test
docker run -p 3000:3000 --name=test_container --network=check test
docker -v /host_app:/container_app node:16-alpine or
docker run -d --mount source=<volume_name>, target=/app <image_name>
docker run -it --name=test_mount \
--mount type=bind,source=$(pwd)/app,target=/usr/src/app \
node:16-alpine
在Ubuntu上安装Docker的命令:
您可以在 AWS 上创建一个 Ubuntu EC2 实例,然后运行以下命令来安装 Docker。
sudo apt update
sudo apt install docker.io -y
您可以使用以下命令来验证 Docker 守护进程是否已启动并处于活动状态。
sudo systemctl status docker
如果您发现 Docker 守护进程未运行,可以使用以下命令启动该守护进程:
sudo systemctl start docker
要授予您的用户运行 Docker 命令的权限,您应该将该用户添加到 Docker Linux 用户组。Docker 用户组在 Docker 安装时默认创建。
sudo usermod -aG docker ubuntu
docker run hello-world
示例 Docker 文件:
FROM ubuntu:latest
WORKDIR /app
COPY . /app
RUN apt-get update && apt-get install -y python3 python3-pip
ENV 'key' 'value'
CMD ['python', 'app.py']
Docker 多阶段示例:
###########################################
# BASE IMAGE
###########################################
FROM ubuntu AS build
RUN apt-get update && apt-get install -y golang-go
ENV GO111MODULE=off
COPY . .
RUN CGO_ENABLED=0 go build -o /app .
############################################
# HERE STARTS THE MAGIC OF MULTI STAGE BUILD
############################################
FROM scratch
# Copy the compiled binary from the build stage
COPY --from=build /app /app
# Set the entrypoint for the container to run the binary
ENTRYPOINT ["/app"]
示例 compose.yaml 文件
services:
backend:
build: ./mern/backend
ports:
- "5050:5050"
networks:
- mern_network
environment:
MONGO_URI: mongodb://mongo:27017/mydatabase
depends_on:
- mongodb
frontend:
build: ./mern/frontend
ports:
- "5173:5173"
networks:
- mern_network
environment:
REACT_APP_API_URL: http://backend:5050
mongodb:
image: mongo:latest
ports:
- "27017:27017"
networks:
- mern_network
volumes:
- mongo-data:/data/db
networks:
mern_network:
driver: bridge
volumes:
mongo-data:
driver: local # Persist MongoDB data locally
容器使用的来自宿主机操作系统的文件和文件夹:
主机的文件系统: Docker 容器可以使用绑定挂载访问主机文件系统,从而允许容器读取和写入主机文件系统中的文件。
网络协议栈:宿主机的网络协议栈用于为容器提供网络连接。Docker 容器可以直接连接到宿主机的网络,也可以通过虚拟网络连接到宿主机的网络。
系统调用:主机内核处理来自容器的系统调用,容器正是通过系统调用来访问主机的资源,例如 CPU、内存和 I/O。
命名空间: Docker 容器使用 Linux 命名空间为容器进程创建隔离环境。命名空间为文件系统、进程 ID 和网络等资源提供隔离。
控制组(cgroups): Docker 容器使用 cgroups 来限制和控制容器可以访问的资源量,例如 CPU、内存和 I/O。
- 在生产环境中使用 Docker 会遇到什么问题?如何解决?
即使是较小的应用程序,Docker 容器的大小也会显著增加,而且由于我们使用一个基础镜像并创建了一个单阶段 Docker 文件,因此会产生与操作系统相关的漏洞。为了克服这个问题,我们使用了多阶段 Docker 文件和 distroless 镜像。
-
定义无发行版镜像:无发行版镜像是指仅包含运行应用程序或服务所需的基本组件的 Docker 镜像。
-
无分发图像有哪些优势?
-> 它显著减小了 Docker 容器的大小,并且由于它包含的软件最少,因此提供了最高级别的安全性,使用 distortoless 镜像消除了与操作系统相关的漏洞。
容器在文件系统方面存在什么问题?
容器本质上是临时性的,这意味着它没有永久存储,因此当容器宕机时,所有文件都会丢失。为了解决这个问题,有两种方法:1)绑定挂载;2)卷。
定义绑定挂载:这是一种将容器的文件系统绑定到主机的文件系统的方法,允许您将文件写入主机系统。
定义卷:它是一个持久数据存储,允许用户在容器外部管理和存储数据。
绑定挂载和卷挂载的区别:
-> Bind 将特定文件夹附加到 Docker,但是,卷会在主机上的 Docker 存储目录中创建一个新目录。
Bind 由主机文件系统管理,而卷由 Docker 管理。
卷可以在容器之间共享,但绑定挂载不能。
此外,卷也有生命周期,这意味着你可以创建卷或销毁卷。
如果主机系统空间不足,也可以使用外部源创建卷。
Docker COPY 和 ADD 的区别: Docker add 将文件从 URL 复制到 Docker 容器,而 copy 只是从本地主机复制文件。
Docker CMD 和 ENTRYPOINT 的区别: CMD 命令可以被覆盖,而 ENTRYPOINT 命令则不能。
Docker 网络类型:
桥接网络:默认网络类型,适用于大多数场景。
覆盖网络:用于允许不同 Docker 主机上的容器相互通信。Macvlan
网络:用于将 Docker 容器连接到主机网络接口,使其在主机网络上显示为物理设备。
主机网络:用于将端口直接绑定到主机接口。
在 Docker 中定义多阶段构建:这意味着分多个阶段构建容器,并允许您将工件从一个阶段复制到另一个阶段。
保护容器的步骤:您可以使用 distroless 镜像,使用同步扫描容器,并确保网络配置正确。
实时挑战: Docker 守护进程崩溃,整个系统将无法运行;此外,如果我们创建大量体积巨大的容器,进程可能会变慢;守护进程以 root 用户身份运行,这会在根级别造成漏洞。
文章来源:https://dev.to/jemmyasjd/docker-all-in-one-1-449a

