Docker

Docker是什么

Docker是一个容器化平台,它以容器的形式将您的应用程序及其所有依赖项打包在一起,以确保您的应用程序在任何环境中无缝运行

Dockerfile

Dockerfile 中,常见的指令(命令)有很多,每个指令都有特定的作用,帮助我们定义 Docker 镜像的构建过程。以下是一些最常见和最重要的 Dockerfile 指令:

1. FROM

FROM 指令指定基础镜像,它是 Dockerfile 中必须的第一行。每个 Dockerfile 都必须以 FROM 开头,指定镜像的基础。

FROM <image_name>:<tag>

  • <image_name>:指定基础镜像的名称。
  • <tag>:指定镜像的标签(默认是 latest)。
示例:

FROM ubuntu:20.04

2. LABEL

LABEL 用于为镜像添加元数据(例如镜像的作者、版本等)。这种信息通常用于镜像的标识和管理。

LABEL key="value"

示例:

LABEL maintainer="example@example.com" LABEL version="1.0"

3. RUN

RUN 指令在构建镜像过程中执行命令。它用于安装软件包、执行 shell 脚本或进行其他设置,命令执行完成后会将结果保存到镜像中。

RUN <command>

示例:

RUN apt-get update && apt-get install -y python3

4. COPY

COPY 将文件或目录从构建上下文复制到镜像中的指定路径。

COPY <src> <dest>

  • <src>:要复制的文件或目录路径(相对于 Dockerfile 的上下文路径)。
  • <dest>:复制到镜像中的路径。
示例:

COPY ./app /usr/src/app

5. ADD

ADD 类似于 COPY,但是 ADD 更强大,它支持自动解压 .tar 文件和从 URL 下载文件。

ADD <src> <dest>

示例:

ADD ./app.tar.gz /usr/src/app

6. CMD

CMD 指定一个默认的命令或参数,该命令会在容器启动时运行。如果容器启动时未指定其他命令,CMD 定义的命令将被执行。

CMD ["executable", "param1", "param2"]

  • 如果使用 shell 形式:CMD echo "Hello, World!"
  • 如果使用 JSON 数组形式:CMD ["echo", "Hello, World!"]
示例:

CMD ["python3", "app.py"]

7. ENTRYPOINT

ENTRYPOINT 用于设置容器的启动命令。与 CMD 不同,ENTRYPOINT 不能被 docker run 命令替代。如果 ENTRYPOINTCMD 都指定了,则 CMD 提供默认参数给 ENTRYPOINT

ENTRYPOINT ["executable", "param1", "param2"]

示例:

ENTRYPOINT ["python3", "app.py"]

8. EXPOSE

EXPOSE 指定容器应暴露的端口。它仅仅是一个说明,Docker 不会自动将端口映射到主机上。实际的端口映射需要使用 docker rundocker-compose 配置。

EXPOSE <port>

示例:

EXPOSE 8080

9. ENV

ENV 设置环境变量,可以在容器运行时使用。

ENV <key>=<value>

示例:

ENV APP_HOME=/usr/src/app

10. VOLUME

VOLUME 指定一个或多个匿名卷,这些卷会在容器启动时创建。卷可以用于持久化存储数据。

VOLUME ["/data"]

示例:

VOLUME ["/data", "/config"]

11. WORKDIR

WORKDIR 设置工作目录。如果指定的目录不存在,WORKDIR 会自动创建。

WORKDIR <path>

示例:

WORKDIR /usr/src/app

12. USER

USER 指定在容器中运行命令时的用户。它是一个非常重要的安全措施,防止容器以 root 用户身份运行应用程序。

USER <username>

示例:

USER nobody

13. ARG

ARG 定义了在构建时可用的构建参数。与环境变量不同,ARG 只在构建阶段有效,构建完成后不可用。

ARG <name>[=<default_value>]

示例:

ARG VERSION=1.0

14. SHELL

SHELL 指定在 RUN 指令中使用的 shell 类型和参数。

SHELL ["executable", "parameters"]

示例:

SHELL ["powershell", "-Command"]

例子

java 复制代码
FROM artifacth.sail-cloud.com/saicmotorcv/java:8
MAINTAINER wanghuapeng <wanghuapeng@saicmotor.com>

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY /yl-lease-service/target/yl-lease-service-0.0.1.jar /app/app.jar
COPY /yl-lease-service/start.sh /app
COPY /yl-lease-service/skywalking-agent /app/agent
COPY /yl-lease-service/json /app/json
COPY /yl-lease-service/sitHttps /app/sitHttps
COPY /yl-lease-service/prdHttps /app/prdHttps
EXPOSE 8080
ENTRYPOINT ["/bin/bash","/app/start.sh"]

Dockerfile 中,COPYADD

在 Dockerfile 中,COPYADD 都用于将文件和目录从主机复制到 Docker 镜像中的指定位置,但它们之间有一些细微的区别。

1. COPY 命令

COPY 命令是最基本的文件复制命令,用于将本地文件或目录复制到 Docker 镜像中的指定路径。

语法:

COPY <src> <dest>

  • <src>:指定源文件或目录(相对于 Dockerfile 所在路径)。
  • <dest>:指定目标路径(在容器内的路径)。
主要特点:
  • 简单:只会复制本地文件到镜像中,不会对文件进行解压或处理。
  • 没有额外的功能COPY 不支持从远程 URL 下载文件,也不支持自动解压文件。
示例:

COPY ./local-file.txt /app/local-file.txt

将本地的 local-file.txt 文件复制到镜像中的 /app/ 目录下。


2. ADD 命令

ADD 命令比 COPY 更为复杂,功能更强大。它不仅可以像 COPY 一样复制本地文件和目录,还具有额外的功能。

语法:

ADD <src> <dest>

  • <src>:指定源文件或目录,可以是本地文件/目录,也可以是一个 URL。
  • <dest>:指定目标路径(在容器内的路径)。
主要特点:
  • 解压 :如果源文件是一个压缩包(如 .tar.tar.gz.zip 等格式),ADD 会自动解压文件到目标路径。
  • 支持 URLADD 可以从远程 URL 下载文件并将其添加到镜像中。
示例:

ADD ./local-file.tar.gz /app/

如果 local-file.tar.gz 是一个压缩文件,ADD 会自动解压文件到 /app/ 目录。

ADD https://example.com/file.tar.gz /app/

ADD 可以直接从远程 URL 下载文件并将其添加到镜像中。


3. 区别总结

特性 COPY ADD
功能 仅将文件或目录复制到镜像中 除了复制文件外,还支持解压文件,支持 URL 下载
支持解压 不支持 支持自动解压 .tar 格式文件
支持 URL 不支持 支持通过 URL 下载文件

4. 使用建议

  • **优先使用 COPY**:对于简单的文件复制操作,推荐使用 COPY,因为它更为明确和简单,也能提升构建速度。
  • 使用 ADD 仅在需要时 :只有在你需要从 URL 下载文件或自动解压压缩文件时,才考虑使用 ADD。对于其他情况,尽量避免使用 ADD,以减少不必要的复杂性。

示例对比:

使用 COPY 复制文件:

COPY ./file.txt /app/

使用 ADD 解压文件:

ADD ./file.tar.gz /app/

ADD 会解压 file.tar.gz/app/ 目录中。

启动一个 Nginx 容器,使用随机端口映射,并且挂载本地文件目录到容器的 HTML 目

要启动一个 Nginx 容器,使用随机端口映射,并且挂载本地文件目录到容器的 HTML 目录,您可以使用以下命令:

docker run -d -p 0:80 --name nginx-container -v /path/to/your/local/directory:/usr/share/nginx/html nginx

解释:

  1. **-d**:以后台模式运行容器。
  2. **-p 0:80**:将容器的 80 端口映射到宿主机的一个随机端口。0:80 语法会自动分配一个随机端口来映射容器的 80 端口。
  3. **--name nginx-container**:为容器指定一个名称(nginx-container)。
  4. **-v /path/to/your/local/directory:/usr/share/nginx/html**:将本地目录 /path/to/your/local/directory 挂载到容器内的 /usr/share/nginx/html 目录。这样,Nginx 会使用本地文件作为其网页内容。
  5. **nginx**:使用官方的 Nginx 镜像启动容器。

检查容器的端口映射

你可以使用以下命令来查看容器的随机端口:

docker ps

输出中会显示映射的端口,例如:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5b5a34c1c8b3 nginx "/docker-entrypoint...." 3 minutes ago Up 3 minutes 0.0.0.0:49160->80/tcp nginx-container

上面的示例中,容器的 80 端口被映射到宿主机的 49160 端口。

现在,您可以通过浏览器访问宿主机的随机端口(例如 http://localhost:49160),查看挂载的本地文件内容。

什么是 Docker 镜像

什么是 Docker 镜像?

Docker 镜像(Docker Image)是一个轻量级、可执行的独立软件包,包含了运行某个应用程序所需的代码、库、依赖、环境变量以及配置文件等。它是一个静态的文件系统,用于创建 Docker 容器的基础。镜像本身是不可变的,一旦创建后不会被修改。容器则是镜像的运行实例,它是镜像的一个动态副本。

1. Docker 镜像的组成

Docker 镜像是由多个层(Layer)构成的,每一层代表了镜像的一个增量。每一层都包含了应用或系统的一部分,例如某个软件包、库、配置文件等。镜像的层次结构使得 Docker 在构建镜像时能够重用已有的层,提高构建效率。

  • 镜像层:每一层都是只读的,基于上一层镜像构建,具有增量特性。例如,第一层可以是操作系统的基础镜像(如 Ubuntu),第二层可以是安装的应用程序(如 Nginx)。

  • 镜像元数据:包括镜像的基本信息,比如标签(tag)、创建者信息、命令(如启动容器时运行的命令)、环境变量等。

  • Dockerfile:镜像的构建通常是基于 Dockerfile 进行的,Dockerfile 是一个文本文件,包含了如何构建镜像的指令和步骤(例如安装软件包、复制文件、设置环境变量等)。

2. 镜像的工作原理

  • 只读层和可写层:Docker 镜像中的每一层都是只读的,当创建容器时,Docker 会为每个容器增加一个可写层。容器中的任何更改(如写入文件或修改配置)都会只影响容器的可写层,而不会影响镜像的其他层。

  • 增量更新:镜像的每一层都是增量的,可以共享相同的基础镜像层。当多个容器基于同一个镜像启动时,它们会共享相同的镜像层,减少了存储空间的浪费。

  • 镜像的缓存机制:Docker 会缓存镜像构建过程中的每一层,在重新构建镜像时,如果层没有变化,Docker 会直接使用缓存中的层,从而提高构建效率。

3. Docker 镜像与容器的关系

  • 镜像:是一个只读的模板,定义了容器的运行环境。镜像是静态的,它包含应用程序及其所有依赖的文件系统。

  • 容器:是镜像的运行实例,容器是动态的,可以启动、停止、修改,并且容器内的更改不会影响镜像。

简而言之,镜像是容器的模板,容器是镜像的运行时实例。

4. 如何构建和管理 Docker 镜像

  • 构建镜像 :通常使用 Dockerfile 来定义镜像的构建过程。通过 docker build 命令可以根据 Dockerfile 构建镜像。

    docker build -t <image_name> .

  • 查看镜像 :使用 docker imagesdocker image ls 命令可以查看本地存储的所有镜像。

    docker images

  • 拉取镜像 :从 Docker Hub(或其他注册中心)下载镜像,使用 docker pull 命令。

    docker pull <image_name>

  • 删除镜像 :使用 docker rmi 命令可以删除本地镜像。

    docker rmi <image_name>

5. 镜像的标签(Tag)

Docker 镜像可以有多个标签,标签用于标识不同版本的镜像。默认情况下,镜像标签是 latest,表示最新版本的镜像。但也可以自定义标签,以便管理不同版本。

  • 默认标签docker pull ubuntu 会拉取 ubuntu:latest 镜像。
  • 指定标签docker pull ubuntu:18.04 会拉取特定版本的 Ubuntu 镜像。

6. Docker 镜像的存储

  • 本地存储 :在本地开发环境中,Docker 镜像通常会存储在 Docker 主机的文件系统中,可以使用 docker images 命令查看本地存储的所有镜像。

  • 远程仓库:Docker Hub 是最常用的镜像仓库,也是 Docker 官方提供的公共镜像仓库。除此之外,也可以使用私有镜像仓库,或其他第三方镜像仓库(如 Google Container Registry、Amazon ECR 等)。

7. 常见的 Docker 镜像命令

  • 构建镜像

    根据 Dockerfile 构建镜像并为其打标签。

    docker build -t myimage:latest .

  • 列出镜像

    查看本地所有镜像。

    docker images

  • 拉取镜像

    从 Docker Hub 或其他镜像仓库拉取镜像。

    docker pull ubuntu:18.04

  • 删除镜像

    删除指定的镜像。

    docker rmi myimage:latest

  • 查看镜像详细信息

    查看镜像的详细信息(如镜像大小、层、标签等)。

    docker inspect myimage

8. 镜像的优缺点

优点:
  • 便于部署和移植:镜像将应用程序及其依赖项打包在一起,确保在不同环境中运行的一致性。
  • 高效的资源利用:Docker 镜像采用分层文件系统,层与层之间共享,提高了存储和网络资源的利用效率。
  • 版本控制:镜像支持标签,可以管理不同版本的应用程序。
缺点:
  • 镜像大小:镜像可能会变得很大,尤其是当包含大量依赖时,这可能导致下载和存储的开销。
  • 依赖管理:如果不小心管理镜像的层和依赖,可能会导致镜像的冗余和重复,浪费存储空间。

如何停止正在运行的容器

要停止所有正在运行的 Docker 容器,可以使用以下命令:

  1. 停止所有正在运行的容器

    docker stop $(docker ps -q)

    解释:

    • docker ps -q 会列出所有正在运行的容器的容器 ID(只显示容器 ID,不显示详细信息)。
    • docker stop $(docker ps -q) 会将 docker ps -q 的输出作为参数传递给 docker stop,从而停止所有正在运行的容器。
  2. 检查容器是否已停止: 停止所有容器后,你可以使用以下命令来确认是否所有容器都已停止:

    docker ps

    该命令将只列出正在运行的容器。如果列表为空,说明所有容器都已停止。

注意:

  • docker stop 会优雅地停止容器,即发送 SIGTERM 信号,给容器一定时间来完成正在进行的工作。如果容器在规定的时间内没有停止,Docker 会发送 SIGKILL 信号强制停止容器。

  • 如果需要强制停止所有容器,可以使用 docker kill 命令:

    docker kill $(docker ps -q)

docker kill 会立即停止容器,不会给容器处理的机会,因此只适用于容器长时间没有响应时的紧急情况。

Docker 中,镜像(Image)层(Layer)

在 Docker 中,镜像(Image)层(Layer) 是两个重要的概念,它们在 Docker 构建和运行容器的过程中扮演了不同的角色。下面是它们的主要区别和关系:

1. Docker Image(镜像)

Docker 镜像是一个可执行的包,包含了运行应用所需的所有内容,如操作系统环境、应用程序、依赖项、配置文件等。镜像是容器的模板,它是一个只读的文件系统,通常是通过执行 Dockerfile 文件中的指令构建出来的。

  • 不可变:镜像本身是只读的,不能被修改。每次对镜像的改动都会创建一个新的镜像版本。
  • 包含文件系统:镜像包含了应用运行时的整个文件系统,它是容器的启动模板。
  • Docker Hub 和私有仓库:镜像通常被存储在 Docker Hub 或其他私有镜像仓库中,以便可以共享和分发。

2. Docker Layer(层)

Docker 层是镜像的组成部分。镜像是由多个层(Layer)构成的,每一层都代表镜像构建过程中某一步骤的结果。每执行一条 Dockerfile 中的指令(如 RUN, COPY, ADD 等),就会创建一层。

  • 分层:每一层都是镜像的一个增量部分。层是以只读的方式存在的,每一层都包含了与前一层的差异。
  • 共享:如果多个镜像使用相同的层,Docker 会复用这些层。也就是说,相同的层不会重复存储,而是共享,节省存储空间。
  • 层的构成 :每当你构建一个镜像时,Docker 会将每个指令(如 RUN, COPY, ADD 等)产生的文件系统变化分成一个新的层。

层和镜像的关系

  • 镜像是由层构成的。每个镜像包含若干层,层之间是堆叠的,镜像的最终文件系统是所有层的组合。
  • 镜像与容器的关系:容器是镜像的一个运行实例。容器会基于镜像启动并运行,同时容器会有一个可写层,用于存储容器在运行时产生的数据和修改。

层的具体例子

假设你有一个简单的 Dockerfile,如下所示:

FROM ubuntu:20.04 RUN apt-get update COPY ./app /app

  • 第一层(Base layer)FROM ubuntu:20.04,它指定了一个基础镜像。这个层包含了 Ubuntu 20.04 操作系统的文件系统。
  • 第二层(RUN layer)RUN apt-get update,这个层会修改基础镜像,在其上添加新的文件(如更新包列表)。
  • 第三层(COPY layer)COPY ./app /app,这个层将当前目录中的 app 文件复制到容器中的 /app 目录。

每一层都会记录 Dockerfile 中每个指令的变动,并生成一个只读层。当构建完成后,这些层会被缓存并被作为镜像的一部分。

3. 层的优化

由于每个 Docker 镜像是由多个层组成的,因此优化 Docker 镜像的构建过程时,要尽量减少层的数量。以下是一些优化技巧:

  • 合并 RUN 指令 :将多个 RUN 指令合并成一个,这样可以减少层的数量。例如:

    RUN apt-get update && apt-get install -y nginx && apt-get clean

    这样所有的操作都在一个层中执行,减少了无用层的产生。

  • 合理顺序 :在 Dockerfile 中将更常变动的操作(如 COPY)放在文件的后面,这样可以利用 Docker 的缓存机制,在不改变的情况下避免重新构建前面的层。

4. 镜像与层的共享和复用

  • 层的共享 :当你有多个镜像共享相同的基础层(如使用相同的 ubuntu 镜像作为基础),Docker 会共享这些层,而不会重复存储。这样能显著减少存储空间的浪费。

  • 镜像缓存机制:Docker 在构建镜像时会缓存每一层,以加快后续构建过程。如果某一层的内容没有变化,Docker 会跳过该层的重新构建。

容器与主机之间的数据拷贝

在 Docker 中,容器与主机之间的数据拷贝可以通过以下两种方式进行:

1. 从容器复制文件到主机

使用 docker cp 命令可以将容器内的文件或目录复制到主机上。

命令格式:

docker cp <container_id>:<container_path> <host_path>

示例:

假设你想将容器 nginx-container 内的 /usr/share/nginx/html/index.html 文件复制到主机的 /tmp/index.html 文件:

docker cp nginx-container:/usr/share/nginx/html/index.html /tmp/index.html

2. 从主机复制文件到容器

使用 docker cp 命令可以将主机上的文件或目录复制到容器内。

命令格式:

docker cp <host_path> <container_id>:<container_path>

示例:

假设你想将主机上的 /tmp/index.html 文件复制到容器 nginx-container 内的 /usr/share/nginx/html/ 目录:

docker cp /tmp/index.html nginx-container:/usr/share/nginx/html/

常用的 Docker 命令

以下是一些常用的 Docker 命令,涵盖了容器的管理、镜像的操作以及其他相关操作:

1. Docker 容器管理命令

  • 启动容器

    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

    启动一个新的容器。

    示例:

    docker run -d -p 8080:80 --name my-nginx nginx

    启动一个 Nginx 容器,并将容器的 80 端口映射到主机的 8080 端口。

  • 查看正在运行的容器

    docker ps

    显示当前运行的容器列表。

    示例:

    docker ps -a

    显示所有容器(包括已停止的容器)。

  • 停止容器

    docker stop <container_id>

    停止一个运行中的容器。

    示例:

    docker stop my-nginx

  • 启动一个已停止的容器

    docker start <container_id>

    启动一个已停止的容器。

    示例:

    docker start my-nginx

  • 重启容器

    docker restart <container_id>

    重启容器。

    示例:

    docker restart my-nginx

  • 删除容器

    docker rm <container_id>

    删除一个已停止的容器。

    示例:

    docker rm my-nginx

  • 查看容器的日志

    docker logs <container_id>

    查看容器的日志输出。

    示例:

    docker logs my-nginx

  • 进入容器的终端

    docker exec -it <container_id> /bin/bash

    进入正在运行的容器,打开一个交互式的 Bash 终端。

    示例:

    docker exec -it my-nginx /bin/bash

  • 查看容器资源使用情况

    docker stats <container_id>

    查看容器的实时资源使用情况(CPU、内存、网络等)。

    示例:

    docker stats my-nginx

2. Docker 镜像管理命令

  • 查看本地镜像

    docker images

    列出所有本地镜像。

  • 下载镜像(拉取镜像)

    docker pull <image_name>

    从 Docker Hub 或其他 Docker 仓库拉取镜像。

    示例:

    docker pull nginx

  • 删除镜像

    docker rmi <image_id>

    删除本地的镜像。

    示例:

    docker rmi nginx

  • 构建镜像

    docker build -t <image_name>:<tag> .

    从 Dockerfile 构建一个镜像。

    示例:

    docker build -t myapp:latest .

  • 标记镜像

    docker tag <image_id> <new_image_name>:<tag>

    为镜像打标签。

    示例:

    docker tag myapp:latest mydockerhubusername/myapp:v1

  • 推送镜像到仓库

    docker push <image_name>:<tag>

    将本地镜像推送到 Docker Hub 或私有仓库。

    示例:

    docker push mydockerhubusername/myapp:v1

3. Docker 容器与镜像数据操作命令

  • 复制文件到容器

    docker cp <host_path> <container_id>:<container_path>

    将文件从主机复制到容器内。

    示例:

    docker cp /tmp/index.html my-nginx:/usr/share/nginx/html/

  • 从容器复制文件到主机

    docker cp <container_id>:<container_path> <host_path>

    将文件从容器复制到主机。

    示例:

    docker cp my-nginx:/usr/share/nginx/html/index.html /tmp/index.html

4. Docker 网络管理命令

  • 查看 Docker 网络

    docker network ls

    列出所有 Docker 网络。

  • 创建自定义网络

    docker network create <network_name>

    创建一个自定义的网络。

    示例:

    docker network create my_network

  • 查看网络详细信息

    docker network inspect <network_name>

    查看网络的详细信息。

    示例:

    docker network inspect my_network

5. Docker 容器日志和调试命令

  • 查看容器的实时日志

    docker logs -f <container_id>

    实时查看容器日志(跟踪日志)。

    示例:

    docker logs -f my-nginx

  • 查看容器的进程

    docker top <container_id>

    查看容器内的进程列表。

    示例:

    docker top my-nginx

6. Docker 容器和镜像的清理命令

  • 删除所有停止的容器

    docker container prune

    删除所有停止的容器。

  • 删除所有未使用的镜像

    docker image prune

    删除所有未使用的镜像。

  • 删除所有未使用的镜像、容器、网络和缓存

    docker system prune

    清理所有不再使用的 Docker 资源(容器、镜像、网络等)。

7. Docker 查看系统状态命令

  • 查看 Docker 版本

    docker --version

    查看 Docker 的版本信息。

  • 查看 Docker 系统信息

    docker info

    查看 Docker 的系统信息,包括安装的驱动、容器数、镜像数等。

8. 其他常用命令

  • 查看所有 Docker 容器(包括停止的容器)

    docker ps -a

  • 进入容器并使用 shell 命令

    docker exec -it <container_id> bash

Docker 容器的运行状态

要确定一个 Docker 容器的运行状态,可以使用以下几种方法:

1. 使用 docker ps 命令

这是最常见的方法,它会列出所有正在运行的容器及其状态信息。

docker ps

该命令会显示正在运行的容器的 ID、镜像、创建时间、状态、端口映射和容器名称等信息。

  • 列出所有容器(包括已停止的) : 如果想查看所有容器(包括已停止的容器),可以加上 -a 选项:

    docker ps -a

输出示例

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5c07d2f72a9f nginx "/docker-en..." 2 hours ago Up 2 hours 80/tcp nginx-container

在这个输出中:

  • STATUS 列显示容器的状态,如 "Up 2 hours" 表示容器正在运行。
  • 如果容器已停止,会显示类似 "Exited (0) 2 hours ago"。

2. 使用 docker inspect 命令

docker inspect 命令可以获取关于容器的详细信息,包括容器的运行状态、网络设置、挂载卷等。

docker inspect <container_id_or_name>

要检查特定容器的运行状态,可以通过以下命令查看 State 部分的详细信息:

docker inspect --format '{``{.State.Status}}' <container_id_or_name>

  • 返回值可能是 runningexitedpaused 等,表示容器的当前状态。

示例

docker inspect --format '{``{.State.Status}}' nginx-container

返回:

running

你也可以查看其他信息,如是否健康(Health),是否存在错误等:

docker inspect --format '{``{.State.Health.Status}}' <container_id_or_name>

3. 查看容器日志

通过查看容器的日志,也可以了解容器是否正常运行。可以使用以下命令来查看容器的输出日志:

docker logs <container_id_or_name>

这将显示容器的标准输出(stdout)和标准错误(stderr)日志。

如果容器运行正常,日志会显示相应的应用程序输出。如果容器停止或者出现错误,日志可能会显示错误信息。

4. 使用 docker top 查看容器进程

docker top 命令会列出容器中的当前进程,这有助于判断容器是否正常运行。

docker top <container_id_or_name>

该命令会显示容器中运行的进程列表,包括进程 ID、用户名、进程状态等信息。如果容器中没有进程,可能说明容器已经停止。

5. 检查 Docker 容器的健康状态(如果定义了健康检查)

Docker 支持健康检查,允许用户定义容器是否处于健康状态的检测方法。如果 Dockerfile 中有定义 HEALTHCHECK 指令,Docker 会定期检查容器的健康状态。

使用以下命令查看容器的健康状态:

docker inspect --format '{``{.State.Health.Status}}' <container_id_or_name>

健康状态可能是以下几种:

  • healthy:容器健康。
  • unhealthy:容器不健康,可能需要重新启动或修复。
  • none:没有定义健康检查。

6. 监控容器的资源使用情况

如果容器正在运行但你需要查看它的资源使用情况(如 CPU、内存、磁盘等),可以使用 docker stats 命令:

docker stats

该命令会实时显示所有正在运行容器的资源使用情况。如果只关注某个特定容器,可以指定容器 ID 或名称:

docker stats <container_id_or_name>

使用 Docker 技术创建与环境无关的容器系统

使用 Docker 技术创建与环境无关的容器系统,主要是通过构建 Docker 容器镜像来实现的。Docker 容器是轻量级的虚拟化环境,它可以确保你的应用程序在任何环境中以一致的方式运行,而不受底层操作系统或硬件配置的影响。下面是如何通过 Docker 创建与环境无关的容器系统的步骤:

1. 创建一个标准化的 Dockerfile

Dockerfile 是一个文本文件,包含一系列构建 Docker 镜像的指令。通过编写 Dockerfile,可以指定应用的运行环境,包括操作系统、依赖库、工具等,而这些都与实际运行环境无关。因此,确保 Dockerfile 的构建过程是标准化和一致的,是实现环境无关性的关键。

示例 Dockerfile:

# 使用官方的 Python 3.9 镜像作为基础镜像 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 复制应用的代码文件到容器中 COPY . /app # 安装应用的依赖 RUN pip install -r requirements.txt # 设置容器启动时执行的命令 CMD ["python", "app.py"]

2. 创建 Docker 镜像

根据编写好的 Dockerfile,你可以使用 docker build 命令创建镜像:

docker build -t myapp:latest .

这条命令会根据当前目录下的 Dockerfile 文件构建一个新的 Docker 镜像,并给这个镜像打上标签 myapp:latest

3. 使用 Docker 容器运行应用

一旦镜像构建完成,你可以通过 docker run 命令在任何支持 Docker 的环境中启动容器。例如:

docker run -d -p 8080:8080 --name myapp-container myapp:latest

这条命令会基于你构建的 myapp:latest 镜像启动一个容器,并将容器的 8080 端口映射到宿主机的 8080 端口。

4. 镜像与环境无关

通过这种方式,Docker 镜像不仅包含了应用程序的代码,还包括了应用程序运行所需的所有依赖和系统环境配置。因此,无论你是在开发环境、测试环境、生产环境,还是在不同操作系统(Linux、Windows、Mac)上,只要你能够运行 Docker,就能够以相同的方式运行这个容器。

5. 使用 Docker Compose 管理多容器系统

在一些情况下,应用可能会由多个容器组成(例如,一个容器用于数据库,一个容器用于应用服务器)。Docker Compose 允许你通过 YAML 文件定义和管理多容器应用,从而实现应用系统的环境无关性。

示例 docker-compose.yml 文件:

version: '3' services: web: build: . ports: - "8080:8080" db: image: postgres:13 environment: POSTGRES_PASSWORD: example

然后使用以下命令启动所有服务:

docker-compose up -d

这将根据 docker-compose.yml 文件启动一个包括 web 应用和数据库的多容器应用。

6. 镜像版本控制与推送到 Docker Hub

为了使得应用完全与环境无关,你可以将构建好的 Docker 镜像推送到公共或私有的 Docker 镜像仓库(如 Docker Hub、Harbor 等)。这样,不论在哪里运行,只要拉取相同的镜像版本,就可以获得完全相同的环境和应用。

例如,推送到 Docker Hub:

docker login docker tag myapp:latest mydockerhubusername/myapp:latest docker push mydockerhubusername/myapp:latest

7. 隔离与资源限制

Docker 容器提供了一种资源隔离机制,通过限制 CPU、内存和网络等资源,确保应用能够在任何环境中稳定运行。可以在 docker run 命令中指定资源限制:

docker run -d -p 8080:8080 --name myapp-container --memory="512m" --cpus="1.0" myapp:latest

8. 利用 Docker 容器实现开发与生产环境一致

通过 Docker,你可以保证开发人员、测试人员、运维人员使用的容器镜像一致,无需担心由于开发环境和生产环境不同导致的问题。容器会在所有环境中表现一致,避免了 "works on my machine" 的问题。

9. 持续集成与部署

通过结合 CI/CD 工具(如 Jenkins、GitLab CI、GitHub Actions 等)和 Docker,你可以将 Docker 镜像的构建与部署自动化。这样,当代码更新时,可以自动构建并推送 Docker 镜像,实现快速一致的应用交付。

Docker 与虚拟机(VM)

Docker 与虚拟机(VM)是两种不同的技术,它们都可以在同一台物理机器上运行多个独立的应用程序或服务,但在架构、资源管理、性能等方面有很多不同。以下是 Docker 和虚拟机的主要区别:

1. 架构差异

  • 虚拟机

    • 在虚拟机中,每个虚拟机都运行一个完整的操作系统(Guest OS),该操作系统包括内核及其所有应用程序和库。
    • 虚拟机运行在物理硬件上,通过 虚拟化管理程序(Hypervisor),如 VMware、Hyper-V、KVM 等进行管理。虚拟机通过虚拟化技术隔离不同操作系统之间的资源。
    • 每个虚拟机都需要完整的操作系统(包括内核和文件系统),这导致虚拟机通常较大,占用的资源也较多。
  • Docker

    • Docker 是基于 容器化(Containerization)技术的,它在操作系统层面上进行虚拟化。
    • 容器共享宿主操作系统的内核,每个容器内只运行应用程序和相关的依赖库,而不需要额外的操作系统。
    • 容器通过 Docker 引擎(Docker Daemon)来管理,它们利用 Linux 内核的 cgroups 和 namespaces 进行隔离,但它们共享宿主机的操作系统内核。

2. 资源隔离和效率

  • 虚拟机

    • 每个虚拟机需要独立的操作系统和内核,因此每个虚拟机的资源开销较大。
    • 启动虚拟机通常需要几分钟时间。
    • 由于每个虚拟机都运行一个完整的操作系统,因此虚拟机的性能较低,资源利用率较低。
  • Docker

    • Docker 容器通过共享宿主机的操作系统内核来提高效率,因此它们的资源开销非常小,启动速度很快(通常是秒级)。
    • 容器之间的隔离较轻,但依然能确保应用的独立性,性能通常比虚拟机高。
    • Docker 容器的启动和关闭时间非常短,因为没有操作系统的启动过程。

3. 操作系统

  • 虚拟机

    • 每个虚拟机有自己独立的操作系统(包括内核),可以运行不同的操作系统(例如在同一台服务器上运行 Linux 和 Windows 虚拟机)。
    • 虚拟机支持多种操作系统,不需要宿主操作系统的兼容性。
  • Docker

    • Docker 容器依赖于宿主操作系统的内核,通常只能运行与宿主操作系统内核兼容的操作系统(例如,Linux 宿主机上的容器运行 Linux 操作系统内核,Windows 上的 Docker 容器也只能运行 Windows 内核)。
    • 不需要为每个应用程序安装操作系统,只需要在容器内包含应用程序及其依赖项。

4. 性能

  • 虚拟机

    • 由于虚拟机需要为每个虚拟化的操作系统提供完整的硬件仿真,因此会导致较高的性能开销。资源的隔离较为彻底,但也意味着性能消耗较大。
    • 每个虚拟机都运行一个完整的操作系统,因此虚拟机的开销较大,启动时间也较长。
  • Docker

    • Docker 容器因为共享宿主机的操作系统内核,性能开销非常小。容器的启动时间也比虚拟机更短。
    • Docker 容器只隔离用户空间,因此更轻量、启动更快、资源消耗更少。

5. 隔离性

  • 虚拟机

    • 虚拟机的隔离性较强,每个虚拟机拥有独立的操作系统和内核,系统崩溃时不会影响其他虚拟机。
    • 虚拟机提供硬件级别的隔离,可以运行完全不同的操作系统,并且每个虚拟机内的应用和服务彼此完全隔离。
  • Docker

    • Docker 容器的隔离性比虚拟机差。容器之间共享宿主操作系统的内核,因此容器在内核级别上是相互依赖的,虽然 Docker 使用 cgroups 和 namespaces 等技术实现容器隔离,但容器之间的隔离性不如虚拟机。
    • 容器适用于隔离应用级别的环境,而不适用于隔离操作系统或硬件。

6. 使用场景

  • 虚拟机

    • 适用于需要完整操作系统环境的场景,尤其是需要运行不同操作系统的场景(如在同一台机器上同时运行 Linux 和 Windows 环境)。
    • 常用于传统的企业数据中心和多操作系统环境的虚拟化管理。
  • Docker

    • 适用于需要快速部署和扩展、轻量级的应用程序的场景,尤其是在微服务架构中,Docker 容器能够快速启动和销毁。
    • 更适合开发、测试、持续集成、容器化应用和云原生应用等场景。

7. 镜像与部署

  • 虚拟机

    • 虚拟机使用虚拟硬盘镜像(如 VMDK、VHD 等)存储操作系统及应用,通常镜像文件较大,需要更多的存储空间。
    • 虚拟机的部署通常需要安装和配置操作系统,构建虚拟化环境较为复杂。
  • Docker

    • Docker 使用镜像文件来打包应用和依赖项,镜像文件较小(相比虚拟机镜像),可以轻松推送到 Docker Hub 等镜像仓库。
    • Docker 的镜像是可重用的,可以用作多个容器的基础。

8. 资源利用率

  • 虚拟机

    • 资源利用率较低。每个虚拟机都需要分配独立的计算资源(如 CPU、内存、存储),即使某些虚拟机没有运行应用程序,它们也会占用一定的资源。
  • Docker

    • 资源利用率较高。Docker 容器共享宿主机的内核,因此可以在相同硬件上运行更多的容器。

9. 管理与扩展

  • 虚拟机

    • 虚拟机的管理通常由虚拟化平台(如 VMware vSphere、OpenStack)进行,扩展和迁移虚拟机相对较复杂,尤其是在多节点集群中。
  • Docker

    • Docker 容器的管理更加灵活,可以通过 Docker Compose 管理多容器应用,或使用 Kubernetes 进行容器的编排和管理,支持高效的扩展和自动化部署。

总结:

特性 虚拟机 Docker
架构 完整的操作系统(包括内核) 容器共享宿主操作系统的内核
资源隔离 强隔离,完全独立的操作系统 较弱隔离,共享操作系统内核
启动时间 较长,需要启动完整的操作系统 非常快,秒级启动
性能开销 较高,资源开销大 较低,资源消耗小
适用场景 多操作系统支持,虚拟化硬件资源 微服务、快速部署、轻量级应用
资源利用率 较低,每个虚拟机占用固定资源 较高,可以在相同硬件上运行更多容器
管理与扩展 较复杂,使用虚拟化平台(如 VMware) 轻量,支持 Docker Compose、Kubernetes 等现代工具

监控 Docker 容器和相关资源

在使用 Docker 技术的产品中,监控 Docker 容器和相关资源的运行非常重要,以确保系统的稳定性、性能和健康状态。Docker 的监控不仅仅是监控容器本身,还包括监控 Docker 主机、网络、存储、日志等多个层次。

以下是常见的 Docker 监控方法及工具:

1. Docker 自带的监控工具

1.1 docker stats

Docker 提供了一个命令 docker stats,可以用来查看容器的实时资源使用情况,包括 CPU、内存、网络和磁盘的使用情况。

docker stats

该命令会显示每个容器的实时性能数据:

  • CPU 使用率
  • 内存使用量(包括已使用和可用内存)
  • 网络流量
  • 磁盘 I/O
1.2 docker events

docker events 命令可以用来查看 Docker 事件的实时流,包括容器的启动、停止、重启、崩溃等操作。

docker events

这可以帮助您跟踪容器状态的变化,并检测系统中的潜在问题。

2. 使用第三方监控工具

2.1 Prometheus 和 Grafana

Prometheus 是一个开源的监控和告警工具,适合与 Docker 集成。Prometheus 通过抓取 Docker 容器和主机上的指标数据来进行监控。

  • Prometheus 用于收集和存储指标数据。
  • Grafana 用于展示 Prometheus 收集到的数据,并可以配置告警规则。

步骤:

  1. 安装 Prometheus:可以通过 Docker 容器或者传统方式安装 Prometheus。
  2. 配置 Docker Exporter :Prometheus 需要通过 cAdvisornode_exporter 等工具来收集 Docker 容器和主机的监控数据。
  3. 配置 Grafana:Grafana 可以从 Prometheus 获取数据,并展示容器的性能指标,如 CPU 使用率、内存、磁盘、网络等。

这种组合非常适合生产环境,能够帮助您全面监控 Docker 集群中的容器、服务和主机。

2.2 cAdvisor

cAdvisor(Container Advisor)是 Google 提供的一个容器监控工具,可以实时收集并展示容器的资源使用情况,如 CPU、内存、网络和磁盘 I/O 等。

  • 它可以作为一个单独的服务运行,或者通过 Docker 运行。
  • 提供 Web UI,用户可以通过浏览器查看各个容器的监控数据。

运行 cAdvisor:

docker run -d --name=cadvisor --volume=/:/rootfs:ro --volume=/var/run:/var/run:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080 google/cadvisor:latest

然后可以通过 http://<docker_host>:8080 查看各个容器的性能数据。

2.3 Datadog

Datadog 是一个全面的监控和分析平台,支持容器、云基础设施、应用程序等的监控。它提供了 Docker 集成,可以监控 Docker 容器和主机的性能数据,并将其展示在 Datadog 的控制面板中。

Datadog 提供了很多强大的功能,包括:

  • 容器运行时指标(如 CPU、内存、磁盘、网络)
  • 容器健康检查
  • 日志管理和追踪

Datadog 支持与其他监控工具(如 Prometheus)一起使用,能够提供丰富的可视化和告警功能。

2.4 ELK Stack(Elasticsearch, Logstash, Kibana)

ELK Stack 是用于日志管理和分析的工具,可以用于收集、分析和展示容器的日志。

  • Elasticsearch:存储和索引日志数据。
  • Logstash:收集和处理日志数据,支持 Docker 日志格式。
  • Kibana:展示日志数据,帮助进行日志分析。

ELK Stack 可以与 Docker 集成,实时收集和分析容器产生的日志,以便于追踪容器的错误、性能问题等。

2.5 Zabbix

Zabbix 是一个企业级的开源监控解决方案,支持 Docker 集群的监控。它可以用于监控容器、主机、网络、应用程序等。

通过安装 Zabbix Agent,Zabbix 可以收集 Docker 容器的性能数据,并通过其 Web 界面提供实时监控。

3. 日志管理与监控

Docker 容器运行时,所有的日志都会输出到容器的标准输出(stdout)和标准错误输出(stderr)。这些日志可以通过 Docker 命令访问,也可以通过集成的日志管理工具(如 ELK Stack)进行监控。

3.1 Docker 日志查看

可以使用以下命令查看容器的日志输出:

docker logs <container_name_or_id>

此外,Docker 支持多种日志驱动程序(如 json-file、syslog、fluentd 等),可以配置容器将日志发送到外部的日志系统,便于进一步分析和告警。

4. 容器健康检查

Docker 提供了容器健康检查功能,可以通过 docker inspect 命令查看容器的健康状态。健康检查可以定期对容器内部的应用或服务进行检查,并报告容器是否健康。

例如,定义容器健康检查:

HEALTHCHECK CMD curl --fail http://localhost:8080/health || exit 1

这将定期检查容器的 /health 路由。如果健康检查失败,Docker 会将容器标记为不健康。

5. 容器调度和编排工具

在大型分布式系统中,容器的监控和管理通常需要通过调度和编排工具来实现:

  • Kubernetes:Kubernetes 提供了强大的容器管理功能,能够自动监控和管理容器的生命周期、状态和资源。它也集成了健康检查、日志、指标收集、告警等功能。
  • Docker Swarm:Docker Swarm 是 Docker 原生的集群管理工具,提供了容器的部署、扩展和监控功能。

这类工具能够提供跨主机的容器监控、自动化部署和扩容等功能。

6. 自动化告警

无论是使用 Prometheus、Datadog 还是 Zabbix,监控系统通常都能集成告警机制。当容器或主机的某些性能指标(如 CPU、内存、磁盘使用率等)超过预设的阈值时,可以自动触发告警并通知管理员。

Docker Swarm

Docker Swarm 是 Docker 的原生集群管理和容器编排工具。它允许用户将多个 Docker 主机组合在一起,形成一个集群(Swarm),并在集群中管理和调度容器。Swarm 提供了自动化的容器部署、负载均衡、扩展和故障恢复等功能,使得用户能够以集群的方式管理和运行 Docker 容器。

Docker Swarm 的主要功能和特点:

  1. 集群管理

    • Docker Swarm 将多个 Docker 主机组织成一个集群,集群中的每个主机被称为 节点(Node)。
    • 每个节点都运行 Docker 引擎,并参与容器的调度和管理。
  2. 服务和任务

    • Swarm 的核心概念是 服务 (Service)和 任务(Task)。
    • 服务:定义了容器的规格和运行模式(如镜像、数量、端口等)。一个服务可以在多个节点上运行多个容器副本。
    • 任务:服务的实际运行实例,代表了容器在集群中的一个副本。
  3. 负载均衡

    • Swarm 可以自动将流量负载均衡到集群中的所有服务实例(容器)。当有多个容器副本时,Swarm 会根据负载情况自动分配流量。
    • Swarm 内建负载均衡功能,可以通过服务名称来访问不同节点上的容器,而无需关心容器的具体 IP 地址。
  4. 服务发现

    • Swarm 集群中的节点可以通过内置的 DNS 服务发现 来找到其他节点和容器。你可以通过服务名称访问集群中运行的容器实例,而不需要知道具体的 IP 地址。
    • Docker Swarm 自动为服务创建一个虚拟 IP(VIP)并在集群内部实现服务发现。
  5. 高可用性

    • Swarm 支持 高可用性:即使某个节点发生故障,Swarm 会自动在其他节点上重新调度容器,确保服务的持续可用。
    • 在 Docker Swarm 中,节点分为两种角色:
      • 管理节点(Manager Node):负责管理整个 Swarm 集群,调度服务,分配任务等。
      • 工作节点(Worker Node):负责运行服务的任务和容器。
  6. 扩展性和弹性

    • Swarm 允许用户根据负载需求 水平扩展 服务,即增加更多容器副本来处理流量。
    • 用户可以通过简单的命令来增加或减少服务的副本数,Swarm 会自动处理容器的调度和部署。

    docker service scale <service_name>=<replica_count>

  7. 滚动更新

    • Swarm 支持 滚动更新:用户可以在不中断服务的情况下,逐步更新服务的容器实例。Swarm 会按照指定的策略逐步替换容器,确保高可用性和无缝更新。

    docker service update --image <new_image> <service_name>

  8. 安全性

    • Swarm 支持 集群内部通信加密,所有节点之间的通信默认使用 TLS 加密,确保数据传输的安全性。
    • 用户可以使用 Docker Secrets 来安全地存储敏感信息(如数据库密码、API 密钥等),这些信息可以在容器中安全地使用。
  9. 简化操作

    • Docker Swarm 是 Docker 官方提供的集群管理工具,因此它与 Docker CLI 紧密集成。用户可以使用常规的 Docker 命令(如 docker run, docker ps, docker logs)来操作集群中的容器。
    • Docker Swarm 的学习曲线较低,适合那些已经熟悉 Docker 的用户,集群管理和容器调度变得更加简单。

Docker Swarm 的工作原理:

  1. 初始化集群:首先,需要在一台主机上初始化 Swarm 集群,指定它为管理节点。之后可以将其他主机加入到集群中作为工作节点。

    初始化命令:

    docker swarm init --advertise-addr <MANAGER-IP>

  2. 添加工作节点:在其他主机上,通过提供管理节点的加入令牌来将其添加为工作节点。

    加入命令:

    docker swarm join --token <worker-token> <MANAGER-IP>:2377

  3. 服务部署 :使用 docker service 命令来部署服务。例如,部署一个基于 Nginx 的服务:

    docker service create --name web --replicas 3 -p 80:80 nginx

    这条命令会创建一个名为 web 的服务,并将其副本数设置为 3,监听 80 端口。

  4. 查看服务状态:你可以使用以下命令查看服务的状态和运行情况:

    docker service ls docker service ps <service_name>

  5. 管理集群:Swarm 集群管理节点会定期监控集群状态,发现容器失败时,会自动重新调度任务,确保服务稳定运行。

Docker Swarm 与 Kubernetes 比较:

  • Kubernetes 是更复杂、更功能强大的容器编排工具,适合大规模、复杂的生产环境,提供更多的自动化管理、网络配置、存储管理等功能。
  • Docker Swarm 则是一个较为简单的容器集群管理工具,适用于中小型项目,集成度高、易于使用,并且对 Docker 用户友好。
相关推荐
熬夜苦读学习25 分钟前
Linux文件系统
linux·运维·服务器·开发语言·后端
荔枝荷包蛋6661 小时前
【网络】高级IO——Reactor版TCP服务器
运维·服务器
GGGGGGGGGGGGGG.2 小时前
hapxory-ACL基础介绍及案例
运维·服务器·网络
黑牛先生2 小时前
【Linux】匿名管道
linux·运维·服务器
流星白龙2 小时前
【Linux】35.封装 UdpSocket(2)
linux·运维·windows
是码农没错了2 小时前
银河麒麟系统安装mysql5.7【亲测可行】
linux·运维·kylin
亲持红叶4 小时前
open-webui安装
docker·open-webui
伪装成塔的小兵4 小时前
Windows使用docker部署fastgpt出现的一些问题
windows·docker·容器·oneapi·fastgpt
技术小齐4 小时前
网络运维学习笔记 017HCIA-Datacom综合实验01
运维·网络·学习
大囚长5 小时前
AI工作流+专业知识库+系统API的全流程任务自动化
运维·人工智能·自动化