Docker
本文最后更新于 2024-05-28,文章内容可能已经过时。
1.介绍:
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行。最重要的是,他们不依赖于任何语言、框架或者包装系统。 简单来说,docker可以让开发人员免除在安装软件时需要先配置环境的痛苦,而能够直接把软件需要的环境连带着软件一起安装在需要他的地方.
除了用来安装软件,docker还有一些其他的用处,比如可以用于快速部署和扩展Web应用程序。使用Docker,开发人员可以将应用程序和所需的依赖项打包到一个容器中,并在不同的环境中轻松部署。此外,Docker还可以用于构建持续集成和持续部署(CI/CD)管道,以便自动化构建、测试和部署应用程序。
Docker还可以在开发和测试环境中使用。开发人员可以在本地开发环境中创建一个容器,其中包含所有的开发工具和依赖项。这样,他们可以在不同的环境中轻松地共享和重现开发环境。此外,Docker还可以用于创建一致的测试环境,以便开发人员和测试人员可以在相同的环境中进行测试。
1.1 容器与虚拟机:
启动速度:每个虚拟都机是一个完整的操作系统包括操作系统和内核,所以它是一个重量级的系统;而容器是轻量级的,因为容器只打包了操作系统的基础文件和库文件、还有应用程序及所有的依赖,他的运行速度就如同在系统中创建一个进程一样快,所以启动速度较快。
运行性能:由于虚拟机增加了虚拟化层用于虚拟化硬件,势必会增加一定的开销,所以运行性能有所损失;而容器是直接运行在物理操作系统上的,他本身与系统上其他进程并没有太大区别,所以运行性能是接近原生的。
磁盘占用:虚拟机是一个完整的操作系统,是 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 做了以下几个关键操作:
使用
FROM
指令选择了一个基础镜像,这里使用了 Debian 的 bullseye-slim 版本作为基础。使用
LABEL
指令添加了一个维护者信息标签,以便其他人知道谁创建了这个镜像。使用
RUN
指令更新包管理系统并安装 Redis 服务器。使用
EXPOSE
指令指定了容器将监听的端口(Redis 默认端口 6379)。使用
CMD
指令指定了容器启动后要运行的默认命令,即启动 Redis 服务器。
使用docker build命令,把编写好的dockerfile生成镜像.
3.使用:
3.1 软件下载:
1.安装docker
2.获取镜像:docker pull.
3.编辑配置(软件的配置方式可以因不同的软件而异。有些软件可以通过在 docker run
命令中提供环境变量、命令行参数或其他配置来进行简单的配置,而另一些软件可能需要专门的配置文件.)
4.启动容器:docker run.
5.使用软件.
3.2 其他常用命令:
Docker 在软件安装时的常用命令包括以下几个,这些命令用于查找、下载、运行和管理容器中的软件:
搜索 Docker 镜像:您可以使用
docker search
命令来搜索 Docker Hub 或其他镜像仓库以查找镜像。例如,要搜索官方的 Ubuntu 镜像,可以执行:docker search ubuntu
下载 Docker 镜像:要下载 Docker 镜像,可以使用
docker pull
命令。例如,要下载官方的 Ubuntu 20.04 镜像,可以执行:docker pull ubuntu:20.04
列出已下载的镜像:使用
docker images
命令可以列出已下载的镜像,以查看已安装的镜像列表。docker images
运行容器:要运行容器,可以使用
docker run
命令,并指定容器的镜像和相关配置参数。例如,要运行一个名为my-container
的容器:docker run -d --name my-container my-image
列出运行中的容器:使用
docker ps
命令可以列出正在运行的容器。要列出所有容器,包括已停止的容器,可以使用docker ps -a
。docker ps
停止容器:使用
docker stop
命令可以停止运行中的容器。例如,停止名为my-container
的容器:docker stop my-container
删除容器:使用
docker rm
命令可以删除停止的容器。例如,删除名为my-container
的容器:docker rm my-container
查看容器日志:使用
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
这样就一次性创建了多个容器了.