本文最后更新于 2024-05-28,文章内容可能已经过时。

1.介绍:

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行。最重要的是,他们不依赖于任何语言、框架或者包装系统。 简单来说,docker可以让开发人员免除在安装软件时需要先配置环境的痛苦,而能够直接把软件需要的环境连带着软件一起安装在需要他的地方.

eeb203a89a1640569cfecb2c7c50367a

除了用来安装软件,docker还有一些其他的用处,比如可以用于快速部署和扩展Web应用程序。使用Docker,开发人员可以将应用程序和所需的依赖项打包到一个容器中,并在不同的环境中轻松部署。此外,Docker还可以用于构建持续集成和持续部署(CI/CD)管道,以便自动化构建、测试和部署应用程序。

Docker还可以在开发和测试环境中使用。开发人员可以在本地开发环境中创建一个容器,其中包含所有的开发工具和依赖项。这样,他们可以在不同的环境中轻松地共享和重现开发环境。此外,Docker还可以用于创建一致的测试环境,以便开发人员和测试人员可以在相同的环境中进行测试。

1.1 容器与虚拟机:

46533aab8ca74c48a0e784a1d0f9e8f9~tplv-k3u1fbpfcp-zoom-in-crop-mark_1512_0_0_0

启动速度:每个虚拟都机是一个完整的操作系统包括操作系统和内核,所以它是一个重量级的系统;而容器是轻量级的,因为容器只打包了操作系统的基础文件和库文件、还有应用程序及所有的依赖,他的运行速度就如同在系统中创建一个进程一样快,所以启动速度较快。

运行性能:由于虚拟机增加了虚拟化层用于虚拟化硬件,势必会增加一定的开销,所以运行性能有所损失;而容器是直接运行在物理操作系统上的,他本身与系统上其他进程并没有太大区别,所以运行性能是接近原生的。

磁盘占用:虚拟机是一个完整的操作系统,是 GB 级别的,而容器只包含了一些系统启动的必要组件和程序依赖,是 MB 级别的。

数量:运行一个操作系统的开销较大,运行一个进程的开销较小,同样的服务器资源可以运行更多的容器。

隔离性:虚拟机是一个完整的操作系统级别的隔离,要比容器好很多;容器是进程级别的隔离,隔离的不彻底,因为多个容器之间使用的是同一个宿主机的操作系统内核。

封装速度:虚拟机封装会包含操作系统,封装速度比较慢,容器只封装操作系统的基础文件和库文件、应用程序、依赖,封装速度较快。

简单来说,容器只有基本的环境依赖,并没有操作系统.

1.2 Docker与容器:

容器是一种虚拟化技术,docker 是实现容器的一种工具,我们称它为容器引擎;可以驱动容器的引擎还有 podman、containerd 等,docker 是目前市面上应用范围最广的一种容器引擎。

2.基本概念:

使用docker之前,必须先要知道他的一些基本概念.

2.1 容器:

英文container.

容器是 Docker 的核心概念,它是一个独立的、轻量级的运行环境,包含应用程序和其所有依赖项(库、环境变量、配置等)。容器隔离了应用程序和主机系统,确保了可移植性和一致性。

容器可以看作是正在运行的应用程序的实例。在 Docker 中,容器是应用程序和其所有依赖项的封装,它们包括操作系统、应用程序代码、库、环境变量、配置等,以及正在执行的应用程序进程。容器是一个独立的、轻量级的运行环境,与主机系统隔离开,确保了应用程序在不同环境中的一致性和可移植性。

当您创建并运行一个容器时,实际上是启动了一个独立的、隔离的进程,其中运行着应用程序。这个容器进程可以访问容器内的文件系统、网络栈和资源,同时也可以与主机系统和其他容器进行通信。容器的隔离性确保了不同容器之间的互不干扰,使得多个应用程序可以在同一主机上并行运行,而不会相互干扰。

一般使用docker run 来创建和运行一个docker容器.

docker run -d -p 8080:80 nginx

2.2 镜像:

英文image.

Docker 镜像是 Docker 容器的基础构建块,它是一个轻量级、独立的可执行软件包,包含了一个应用程序及其所有依赖项。

Docker 镜像并不是正在运行的实例。镜像是一个静态的文件,它包含了应用程序及其所有依赖项,但它并没有在运行中。镜像是用于创建和运行 Docker 容器的模板。

容器是基于镜像运行的实例。当您创建一个容器时,Docker 会使用选定的镜像来启动一个独立的、隔离的进程,这个进程才是正在运行的应用程序的实例。容器是可以启动、停止和删除的,而镜像则保持不变,直到您显式地更新或重新构建它。

镜像充当容器的基础,它包含了应用程序和其环境的快照,而容器是镜像的实例,可以在其中运行应用程序。这种分离的设计允许您轻松地管理和部署多个容器,确保了应用程序的一致性和可移植性。

一般通过下载的方式获取一个程序的镜像,通过docker pull命令

docker pull ubuntu:20.04

容器可以简单的理解为镜像+配置文件,并且进行启动.

2.3 Dockerfile:

Dockerfile 是用于构建 Docker 镜像的文本文件,它包含了一系列指令和配置,用于定义如何构建一个特定的 Docker 镜像。

Dockerfile 是用来制作(或构建) Docker 镜像的配置文件,而不是用来获取现成的镜像。

通过 Dockerfile,您可以定义如何构建自定义的 Docker 镜像,包括选择基础镜像、安装软件、设置环境变量、复制文件等操作。Dockerfile 提供了一种灵活的方式来定制镜像以满足特定的应用程序需求。

要获取已有的 Docker 镜像,您通常使用 docker pull 命令,这个命令从 Docker 镜像仓库(如 Docker Hub)中下载现成的镜像。这些现成的镜像可以作为基础镜像,用于创建自定义的 Docker 镜像。然后,您可以使用 Dockerfile 来进一步定制这些基础镜像,以满足您的需求。

以下是一个简单的dockerfile实例,看起来像是自己在安装环境中的某一段命令:

# 使用官方的 Debian-based 基础镜像
FROM debian:bullseye-slim
​
# 设置镜像的维护者信息
LABEL maintainer="your-email@example.com"
​
# 安装 Redis
RUN apt-get update && \
    apt-get install -y redis-server
​
# 暴露 Redis 默认端口
EXPOSE 6379
​
# 启动 Redis 服务器
CMD ["redis-server"]

这个 Dockerfile 做了以下几个关键操作:

  1. 使用 FROM 指令选择了一个基础镜像,这里使用了 Debian 的 bullseye-slim 版本作为基础。

  2. 使用 LABEL 指令添加了一个维护者信息标签,以便其他人知道谁创建了这个镜像。

  3. 使用 RUN 指令更新包管理系统并安装 Redis 服务器。

  4. 使用 EXPOSE 指令指定了容器将监听的端口(Redis 默认端口 6379)。

  5. 使用 CMD 指令指定了容器启动后要运行的默认命令,即启动 Redis 服务器。

使用docker build命令,把编写好的dockerfile生成镜像.

3.使用:

3.1 软件下载:

1.安装docker

2.获取镜像:docker pull.

3.编辑配置(软件的配置方式可以因不同的软件而异。有些软件可以通过在 docker run 命令中提供环境变量、命令行参数或其他配置来进行简单的配置,而另一些软件可能需要专门的配置文件.)

4.启动容器:docker run.

5.使用软件.

3.2 其他常用命令:

Docker 在软件安装时的常用命令包括以下几个,这些命令用于查找、下载、运行和管理容器中的软件:

  1. 搜索 Docker 镜像:您可以使用 docker search 命令来搜索 Docker Hub 或其他镜像仓库以查找镜像。例如,要搜索官方的 Ubuntu 镜像,可以执行:

    docker search ubuntu
  2. 下载 Docker 镜像:要下载 Docker 镜像,可以使用 docker pull 命令。例如,要下载官方的 Ubuntu 20.04 镜像,可以执行:

    docker pull ubuntu:20.04
  3. 列出已下载的镜像:使用 docker images 命令可以列出已下载的镜像,以查看已安装的镜像列表。

    docker images
  4. 运行容器:要运行容器,可以使用 docker run 命令,并指定容器的镜像和相关配置参数。例如,要运行一个名为 my-container 的容器:

    docker run -d --name my-container my-image
  5. 列出运行中的容器:使用 docker ps 命令可以列出正在运行的容器。要列出所有容器,包括已停止的容器,可以使用 docker ps -a

    docker ps
  6. 停止容器:使用 docker stop 命令可以停止运行中的容器。例如,停止名为 my-container 的容器:

    docker stop my-container
  7. 删除容器:使用 docker rm 命令可以删除停止的容器。例如,删除名为 my-container 的容器:

    docker rm my-container
  8. 查看容器日志:使用 docker logs 命令可以查看容器的日志输出。例如,查看名为 my-container 的容器的日志:

    docker logs my-container

查看容器

列出容器的命令为:docker container ls,等价的别名为:

docker container ps
docker container list
docker ps

常用的参数说明如下:

  • -a, --all:列出所有的容器,包括停止运行的容器

  • -s, --size:显示容器的大小

  • -q, --quiet:仅显示容器ID

  • -f, --filter:过滤器,支持key=value的格式进行过滤,多个过滤器使用-f "key=value" -f "key=value"格式

-a列出所有容器:

➜  ~ docker ps -a
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                    PORTS                               NAMES
1c4bc2440cff        docker.elastic.co/elasticsearch/elasticsearch:7.7.0   "/tini -- /usr/local…"   7 days ago          Exited (130) 5 days ago                                       sweet_lovelace
da242f09324e        mysql:8.0.19                                          "docker-entrypoint.s…"   7 weeks ago         Up 15 minutes             0.0.0.0:3306->3306/tcp, 33060/tcp   freeimmi_mini_db_1

-s列出容器的大小:

➜  ~ docker ps -s
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES                SIZE
da242f09324e        mysql:8.0.19        "docker-entrypoint.s…"   7 weeks ago         Up 16 minutes       0.0.0.0:3306->3306/tcp, 33060/tcp   freeimmi_mini_db_1   105B (virtual 547MB)

SIZE列显示的是容器的可写层占用的空间,括号中的virtual表示容器镜像的只读层和容器的可写层总共占用的空间。

-q仅显示容器ID:

➜  ~ docker ps -q
da242f09324e
➜  ~ docker stop $(docker ps -a -q)
1c4bc2440cff
da242f09324e

-f可以通过容器名称(name)、退出状态(exited)、容器状态(status)、创建时间(before|since|after)等进行过滤:

➜  ~ docker ps -f 'name=freeimmi_mini_db_1'
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
da242f09324e        mysql:8.0.19        "docker-entrypoint.s…"   7 weeks ago         Up 12 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   freeimmi_mini_db_1
​
➜  ~ docker stop freeimmi_mini_db_1
freeimmi_mini_db_1
➜  ~ docker ps -a -f 'exited=0'
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
da242f09324e        mysql:8.0.19        "docker-entrypoint.s…"   7 weeks ago         Exited (0) 48 seconds ago                       freeimmi_mini_db_1
​
➜  ~ docker start freeimmi_mini_db_1
freeimmi_mini_db_1
➜  ~ docker kill freeimmi_mini_db_1
freeimmi_mini_db_1
➜  ~ docker ps -a -f 'exited=137'
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
da242f09324e        mysql:8.0.19        "docker-entrypoint.s…"   7 weeks ago         Exited (137) 5 seconds ago                       freeimmi_mini_db_1

停止容器

停止容器使用docker container stop或者docker stop命令,该命令会向容器内的主进程发送SIGTERM信号,等待一段时间后,再发送SIGKILL命令。

可以使用-t, --time设置kill之前的等待时间,默认是10s:

➜  ~ docker container start freeimmi_mini_db_1
freeimmi_mini_db_1
➜  ~ docker stop -t 20 freeimmi_mini_db_1
freeimmi_mini_db_1

删除容器

删除容器使用docker container rm或者docker rm命令。

➜  ~ docker ps -a
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                     PORTS               NAMES
58a0b9865684        alpine                                                "/bin/sh"                44 seconds ago      Up 43 seconds                                  my_alpine3
1c4bc2440cff        docker.elastic.co/elasticsearch/elasticsearch:7.7.0   "/tini -- /usr/local…"   7 days ago          Exited (130) 5 days ago                        sweet_lovelace
da242f09324e        mysql:8.0.19                                          "docker-entrypoint.s…"   7 weeks ago         Exited (0) 8 minutes ago                       freeimmi_mini_db_1
➜  ~ docker rm 1c4bc2440cff
1c4bc2440cff

docker rm不能直接删除运行中的容器,可是使用-f, --force参数,表示强制删除,即直接向容器中的主进程发送SIGKILL信号,一般不推荐这么做,建议先使用docker stop停止容器,然后再使用docker rm删除容器,给容器留出一些时间进行清理等工作:

➜  ~ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
58a0b9865684        alpine              "/bin/sh"           2 minutes ago       Up 2 minutes                            my_alpine3
➜  ~ docker rm -f 58a0b9865684
58a0b9865684

删除所有停止的容器:

➜  ~ docker rm $(docker ps -a -q)
da242f09324e

-v参数表示删除与容器关联的所有匿名的卷:

➜  ~ docker create -v awesome:/foo -v /bar --name hell-redis redis
7da82099f278dd15c6ee16ea5a1e347feb1f3f45b9c8890c830cd7f095e1c63f
➜  ~ docker ps  -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
7da82099f278        redis               "docker-entrypoint.s…"   7 seconds ago       Created                                 hell-redis
➜  ~ docker rm -v hell-redis
hell-redis
➜  ~ docker volume ls | grep awesome
local               awesome

删除容器,还可以使用docker container prune,表示删除所有停止的容器,-f, --force参数表示不需要交互式确认:

➜  ~ docker container prune -f
Deleted Containers:
72a9df4be93f1fa11dc61d73ef48211b507949a1aaa0231a5ef0383cd61c4d45
73d22e04a8ae342174e0069029066d4f03f3a94b373b6d0c253654ee926592fb
44c829e75011bb913c7af9bf095ccec865084db1905a80dfacbb3e4b47209b17
​
Total reclaimed space: 0B

--filter支持过滤,目前支持的过滤器有:unitl(删除指定时间之前的容器)label(删除指定标签的容器):

➜  ~ docker container prune -f --filter "until=1m"
Deleted Containers:
633cb0d9b525e7e595442e8545ef6458c9dbf342fd12c00616acd63ee73bcafb
​
Total reclaimed space: 0B

3.3 构建镜像:

自己编写docker file,构建镜像.

给出一个镜像的demo:

FROM centos:7.9.2009
​
WORKDIR /opt
​
ADD nginx-1.24.0.tar.gz /opt
​
RUN yum install -y nc net-tools gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel && \
yum clean all && \
rm -rf /tmp/* rm -rf /var/cache/yum/* && \
cd /opt/nginx-1.24.0 && \
./configure --user=nobody --group=nobody --prefix=/opt/nginx --with-http_gzip_static_module --with-http_ssl_module --with-stream && \
make && make install && \
rm -rf /opt/nginx-1.24.0
​
CMD /opt/nginx/sbin/nginx && tail -f /dev/null

下面是文件中各种命令的解释:

FROM    #构建镜像需要一个基础镜像,centos:7.9.2009 就是一个基础镜像
WORKDIR #指定工作目录
ADD     #将宿主机目录的文件拷贝到容器中并自动解压,宿主机的文件与 dockerfile 位于相同目录中
RUN     #在基础镜像上要执行的命令
CMD     #指定启动容器时执行的命令

使用docker bulid命令构建镜像.

3.4 docker-compose:

docker-compose 是一个容器编排工具(自动化部署、管理);它用来在单台 Linux 服务器上运行多个 Docker 容器;

docker-compose 使用YAML文件来配置所有需要运行的 Docker 容器,该 YAML 文件的默认名称为 docker-compose.yml

3.4.1 安装:

3.4.1.1 Windows:

curl -L "https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
//查看安装成功
docker-compose version

3.4.1.2 Mac:

下载地址: https://github.com/docker/compose/releases

下载docker-compose-linux-aarch64文件

将下载的文件放入指定的目录

//后面的地址为本机的一个安装位置
mv docker-compose-linux-aarch64 /Users/tyyc/docker

将文件名修改成docker-compose

mv docker-compose-linux-aarch64 docker-compose

修改文件权限

sudo chmod 774 docker-compose

设置环境变量

vim ~/.zsh_rc
DOCKER_COMPOSE_HOME=/Users/tyyc/docker/docker-compose

激活环境变量

source ~/.zsh_rc

查看版本

docker-compose --version

3.4.2 启动:

编写yml文件:

version: '2.1'
services:
​
  nginx:
    image: nginx:latest
    container_name: nginx_host1
    ports:
      - 8081:80
    volumes:
      - /opt/nginx:/opt/nginx/html
    networks:
      - host1-network
​
  redis:
    image: redis:latest
    container_name: redis_host1
    ports:
      - 63790:6379
    networks:
      - host1-network
​
networks:
  host1-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.11.0/24
          gateway: 192.168.11.254

networks 定义容器网络,host1-network 为定义的网络名称,config 网络配置,subnet 代表网段,gateway 代表网关。

执行命令:

docker-compose up -d

这样就一次性创建了多个容器了.