【Docker】
一、概述
1、Docker为什么出现?
开发和运维两套环境,而环境配置十分麻烦。如在Windows上开发,要发布到Linux上运行。
Docker给以上问题提出了解决方案:Java --- Jar(环境)---打包项目带上环境(镜像)---Docker仓库(应用商店)---下载镜像---直接运行
Docker的思想来自于集装箱,核心思想:隔离。即将应用打包装箱,每个箱子是互相隔离的,可以将服务器利用到极致。
虚拟机 | Docker |
---|---|
linux centos原生镜像(一个电脑) | 隔离镜像(最核心的环境 +jdk +mysql等) |
需要开启多个虚拟机 | 运行镜像就可以了 |
几GB | 几MB |
- 官方文档:Docker Documentation | Docker Documentation
- 仓库地址:Docker Hub
2、Docker能做什么?
传统虚拟机 vs Docker :
Docker的优点:
- 不模拟完整的操作系统,系统内核(kernel)非常小,更少的抽象层(GuestOS:如Centos)
- 容器内的应用直接运行在宿主机的内核,容器本身没有自己的内核,也没有虚拟硬件。
- 每个容器相互隔离,内部都有属于自己的文件系统,互不影响。
Docker实现DevOps(开发、运维):
- 应用更快速的交付和部署
打包镜像发布测试,一键运行;不再需要写大量帮助文档,安装程序 - 更便捷的升级和扩缩容?
部署应用就和搭积木一样 - 更简单的系统运维
开发和测试的环境高度一致 - 更高效的计算资源利用
内核级别的虚拟化,可以在一个物理机上运行很多的容器实例,服务器性能可以被压榨到极致。
3、Docker 平台架构
Docker运行原理:Docker是一个Client-Server结构的系统,以守护进程运行在主机上。通过Socket从客户端进行访问。
- 镜像(image):镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。相当于一个模板,通过这个模板来创建容器服务,可以通过一个镜像创建多个容器。
- 容器(container):独立运行一个或一组应用/基本命令有:启动,停止,删除等/可理解为一个简单的linux系统。
- 仓库(repository):存放镜像的地方(公有/私有)
二、安装
1、Linux 环境安装 Docker
# 1、更新系统软件包
yum update -y# 2、安装yum工具包
yum install -y yum-utils# 3、卸载 Docker
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce# 4、添加镜像(阿里云)https://download.docker.com/linux/centos/docker-ce.repo
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 5、安装Docker
yum install -y docker-ce docker-ce-cli containerd.io# 6、启动Docker
systemctl start docker# 7、允许开机自启动
systemctl enable docker# 8、验证
docker --version# 9、配置 Docker 镜像加速
tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://docker.m.daocloud.io","https://dockerproxy.com","https://docker.mirrors.ustc.edu.cn","https://docker.nju.edu.cn","https://vp5v3vra.mirror.aliyuncs.com","https://docker.registry.cyou","https://docker-cf.registry.cyou","https://dockercf.jsdelivr.fyi","https://docker.jsdelivr.fyi","https://dockertest.jsdelivr.fyi","https://mirror.baidubce.com","https://docker.m.daocloud.io","https://docker.nju.edu.cn","https://docker.mirrors.sjtug.sjtu.edu.cn","https://docker.mirrors.ustc.edu.cn","https://mirror.iscas.ac.cn","https://docker.rainbond.cc"]
}
EOF# 10、重启docker服务
systemctl daemon-reload
systemctl restart docker
卸载Docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
启动 hello-world:
docker run hello-world # 本地没有会自动到远程仓库(/etc/docker/daemon.json)取下载
docker images # 查看镜像会发现本地多出一个镜像hello-world
三、命令
Docker 常见基础命令:
1、帮助命令
1.1 Docker 版本信息
[root@localhost ~]# docker --version
Docker version 26.1.4, build 5650f9b[root@localhost ~]# docker version
Client: Docker Engine - CommunityVersion: 26.1.4API version: 1.45Go version: go1.21.11Git commit: 5650f9bBuilt: Wed Jun 5 11:32:05 2024OS/Arch: linux/arm64Context: defaultServer: Docker Engine - CommunityEngine:Version: 26.1.4API version: 1.45 (minimum version 1.24)Go version: go1.21.11Git commit: de5c9cfBuilt: Wed Jun 5 11:31:16 2024OS/Arch: linux/arm64Experimental: falsecontainerd:Version: 1.6.33GitCommit: d2d58213f83a351ca8f528a95fbd145f5654e957runc:Version: 1.1.12GitCommit: v1.1.12-0-g51d5e94docker-init:Version: 0.19.0GitCommit: de40ad0
1.2 Docker 系统信息
[root@localhost ~]# docker info
Client: Docker Engine - CommunityVersion: 26.1.4Context: defaultDebug Mode: falsePlugins:buildx: Docker Buildx (Docker Inc.)Version: v0.14.1Path: /usr/libexec/docker/cli-plugins/docker-buildxcompose: Docker Compose (Docker Inc.)Version: v2.27.1Path: /usr/libexec/docker/cli-plugins/docker-composeServer:Containers: 0Running: 0Paused: 0Stopped: 0Images: 2Server Version: 26.1.4Storage Driver: overlay2Backing Filesystem: xfsSupports d_type: trueUsing metacopy: falseNative Overlay Diff: trueuserxattr: falseLogging Driver: json-fileCgroup Driver: cgroupfsCgroup Version: 1Plugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local splunk syslogSwarm: inactiveRuntimes: io.containerd.runc.v2 runcDefault Runtime: runcInit Binary: docker-initcontainerd version: d2d58213f83a351ca8f528a95fbd145f5654e957runc version: v1.1.12-0-g51d5e94init version: de40ad0Security Options:seccompProfile: builtinKernel Version: 5.11.12-300.el7.aarch64Operating System: CentOS Linux 7 (AltArch)OSType: linuxArchitecture: aarch64CPUs: 2Total Memory: 1.425GiBName: localhost.localdomainID: c1a0a9fe-896a-4ca1-9972-16dc7dbca8f1Docker Root Dir: /var/lib/dockerDebug Mode: falseExperimental: falseInsecure Registries:127.0.0.0/8Registry Mirrors:https://docker.m.daocloud.io/https://dockerproxy.com/https://docker.mirrors.ustc.edu.cn/https://docker.nju.edu.cn/https://vp5v3vra.mirror.aliyuncs.com/https://docker.registry.cyou/https://docker-cf.registry.cyou/https://dockercf.jsdelivr.fyi/https://docker.jsdelivr.fyi/https://dockertest.jsdelivr.fyi/https://mirror.baidubce.com/https://docker.mirrors.sjtug.sjtu.edu.cn/https://mirror.iscas.ac.cn/https://docker.rainbond.cc/Live Restore Enabled: falseWARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
1.3 docker 帮助信息
[root@localhost ~]# docker --helpUsage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersCommon Commands:run Create and run a new container from an imageexec Execute a command in a running containerps List containersbuild Build an image from a Dockerfilepull Download an image from a registrypush Upload an image to a registryimages List imageslogin Log in to a registrylogout Log out from a registrysearch Search Docker Hub for imagesversion Show the Docker version informationinfo Display system-wide informationManagement Commands:builder Manage buildsbuildx* Docker Buildxcompose* Docker Composecontainer Manage containerscontext Manage contextsimage Manage imagesmanifest Manage Docker image manifests and manifest listsnetwork Manage networksplugin Manage pluginssystem Manage Dockertrust Manage trust on Docker imagesvolume Manage volumesSwarm Commands:swarm Manage SwarmCommands:attach Attach local standard input, output, and error streams to a running containercommit Create a new image from a container's changescp Copy files/folders between a container and the local filesystemcreate Create a new containerdiff Inspect changes to files or directories on a container's filesystemevents Get real time events from the serverexport Export a container's filesystem as a tar archivehistory Show the history of an imageimport Import the contents from a tarball to create a filesystem imageinspect Return low-level information on Docker objectskill Kill one or more running containersload Load an image from a tar archive or STDINlogs Fetch the logs of a containerpause Pause all processes within one or more containersport List port mappings or a specific mapping for the containerrename Rename a containerrestart Restart one or more containersrm Remove one or more containersrmi Remove one or more imagessave Save one or more images to a tar archive (streamed to STDOUT by default)start Start one or more stopped containersstats Display a live stream of container(s) resource usage statisticsstop Stop one or more running containerstag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGEtop Display the running processes of a containerunpause Unpause all processes within one or more containersupdate Update configuration of one or more containerswait Block until one or more containers stop, then print their exit codesGlobal Options:--config string Location of client config files (default"/root/.docker")-c, --context string Name of the context to use to connect to thedaemon (overrides DOCKER_HOST env var anddefault context set with "docker context use")-D, --debug Enable debug mode-H, --host list Daemon socket to connect to-l, --log-level string Set the logging level ("debug", "info", "warn","error", "fatal") (default "info")--tls Use TLS; implied by --tlsverify--tlscacert string Trust certs signed only by this CA (default"/root/.docker/ca.pem")--tlscert string Path to TLS certificate file (default"/root/.docker/cert.pem")--tlskey string Path to TLS key file (default"/root/.docker/key.pem")--tlsverify Use TLS and verify the remote-v, --version Print version information and quitRun 'docker COMMAND --help' for more information on a command.For more help on how to use Docker, head to https://docs.docker.com/go/guides/
2、镜像命令
2.1 镜像管理
docker image
命令用于管理 Docker 镜像,它提供了多个子命令来执行不同的镜像管理任务。
语法:
docker image COMMAND
参数说明:
Commands:build 从 Dockerfile 构建镜像。这个命令会读取指定的 Dockerfile,并根据其中的指令构建一个新的镜像。history 显示镜像的历史。这个命令会列出镜像的每一层以及相关的创建信息,有助于理解镜像的构建过程。import 从归档文件导入镜像。你可以将一个包含文件系统的归档文件(如 tar 包)导入为 Docker 镜像。inspect 显示镜像的详细信息。这个命令会输出镜像的 JSON 格式详细信息,包括配置、层信息、环境变量等。load 从归档文件或标准输入加载镜像。这个命令通常用于加载之前使用 docker save 命令保存的镜像。ls 列出镜像。这个命令会列出本地存储的所有 Docker 镜像。prune 移除未使用的镜像。这个命令会删除所有未被容器使用的镜像,以节省存储空间。pull 从镜像仓库下载镜像。这个命令会从指定的镜像仓库(默认为 Docker Hub)下载镜像到本地。push 将镜像上传到镜像仓库。这个命令会将本地镜像上传到指定的镜像仓库,以便其他人可以拉取和使用。rm 移除一个或多个镜像。这个命令会删除指定的 Docker 镜像。save 将镜像保存到归档文件。这个命令会将一个或多个镜像保存为 tar 归档文件,以便可以在其他地方加载和使用。tag 为镜像创建标签。这个命令会为指定的镜像创建一个新的标签(或别名),这有助于组织和引用镜像。
2.2 列出本地镜像
列出本地存储的 Docker 镜像:
docker images [OPTIONS] [REPOSITORY[:TAG]]
等价命令: docker image ls, docker image list, docker images
参数说明:
REPOSITORY:镜像的仓库名称。TAG:镜像的标签,用于指定要列出的镜像版本。如果不指定仓库和标签,则列出所有镜像。Options:-a, --all 显示所有镜像,包括中间层镜像(默认情况下,这些镜像是被隐藏的)--digests 显示镜像的摘要信息。摘要是一种唯一标识镜像内容的方式-f, --filter filter 根据提供的条件过滤输出结果。例如,你可以根据镜像的标签、创建时间或大小来过滤镜像。--format string 使用自定义模板格式化输出。Docker 提供了几种预定义的格式:'table': Print output in table format列名 (default):'table TEMPLATE': Print output in table format使用 Go 模板语言:'json': Print in JSON format'TEMPLATE': Print output using the given Gotemplate.更多格式移步 https://docs.docker.com/go/formatting/--no-trunc 不截断输出信息。默认情况下,为了节省空间,一些信息(如镜像 ID 和仓库名称)可能会被截断。使用这个选项可以显示完整的信息。-q, --quiet 仅显示镜像 ID,不显示其他信息。
2.3 搜索镜像
在Docker Hub 上搜索镜像
docker search [OPTIONS] TERMTERM:镜像名Options:-f, --filter filter # 根据提供的条件过滤输出结果--format string # 自定义输出格式--limit int # 设置最大搜索结果数量--no-trunc # 不截断输出结果
示例:
# 搜索 Docker Hub 上所有官方的 "nginx" 镜像,并且显示完整的结果信息
docker search --filter=is-official=true --no-trunc nginx
2.4 登陆镜像网
docker login 命令用于向 Docker 镜像仓库(registry)进行登录认证。当你需要推送(push)镜像到某个仓库,或者从需要认证的私有仓库拉取(pull)镜像时,你需要先使用该命令进行登录。
语法:
docker login [OPTIONS] [SERVER]
参数说明:
SERVER:指定要登录的 Docker 镜像仓库的地址。如果不指定,Docker 将会使用默认配置的仓库地址,这个地址通常由 Docker daemon 的配置文件指定。Options:-p, --password string 直接在命令行中指定登录密码。出于安全考虑,通常不推荐在命令行中直接输入密码,因为这样可能会被其他用户通过命令历史等方式获取。--password-stdin 从标准输入(stdin)读取密码。这是一个更安全的方式,因为它允许你通过管道或其他方式将密码传递给 docker login 命令,而不会在命令行历史中留下痕迹。-u, --username string 指定登录的用户名。
示例:
# 直接在命令行中指定用户名和密码(不推荐,因为不安全):
docker login -u myusername -p mypassword myregistry.com
# 使用 --password-stdin 选项从标准输入读取密码
echo "mypassword" | docker login -u myusername --password-stdin myregistry.com
# 将密码保存在一个文件中,并使用 cat 命令将其传递给 docker login:
cat mypasswordfile.txt | docker login -u myusername --password-stdin myregistry.com
# 登陆默认仓库
docker login -u myusername
2.5 登出镜像网
docker logout 命令用于从 Docker 注册中心登出。
语法:
docker logout [SERVER]
参数说明:
[SERVER]:这是可选的。它指定了你要登出的注册中心的服务器地址。如果你没有指定服务器,Docker 将使用守护进程(daemon)配置中定义的默认注册中心。
2.6 拉取镜像
从镜像仓库(默认为 Docker Hub)下载镜像.
语法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
别名(即等价命令):
docker image pull 和 docker pull
参数说明:
NAME:镜像名称。
TAG:镜像标签,用于指定镜像的版本。如果不指定标签,则默认使用 latest 标签。
DIGEST:镜像摘要,用于确保下载的镜像完全匹配特定的内容。Options:-a, --all-tags # 下载仓库中的所有标签的镜像--disable-content-trust # 跳过镜像验证。默认情况下,如果启用了内容信任(Content Trust),Docker 会验证镜像的签名。使用这个选项可以跳过签名验证。但请注意,这可能会使你下载到未签名或签名不正确的镜像。--platform string # 设置平台。如果镜像仓库支持多平台,你可以使用这个选项来指定要拉取的镜像的平台。-q, --quiet # 抑制详细输出。默认情况下,docker pull 命令会显示拉取镜像的进度和详细信息。使用这个选项可以只显示镜像的名称和标签,而不显示其他信息。
示例:
# 从 Docker Hub 下载一个名为 nginx 的镜像,并指定标签为 1.21
docker pull nginx:1.21
2.7 查看镜像信息
docker inspect 命令用于返回 Docker 对象的低级信息。这些对象可以是容器(Container)、镜像(Image)、网络(Network)、卷(Volume)等
语法:
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
参数说明:
NAME|ID [NAME|ID...]:指定要检查的 Docker 对象的名称或 ID。你可以指定一个或多个对象,每个对象之间用空格分隔。Options:-f, --format string 使用自定义模板格式化输出:'json': 以 JSON 格式打印输出。这是获取结构化数据的最简单方式'TEMPLATE': 使用指定的 Go 模板打印输出。Go 模板提供了强大的格式化能力,允许你提取和重组信息以满足特定需求。更多格式信息移步:https://docs.docker.com/go/formatting/ -s, --size 如果类型是容器,则显示总文件大小。这个选项对于了解容器占用的磁盘空间非常有用。--type string 返回指定类型的 JSON。这个选项允许你指定要返回信息的 Docker 对象类型,例如 container、image、network 或 volume。如果你只对特定类型的对象感兴趣,这个选项可以帮助你过滤掉不需要的信息。
示例:
# 以 JSON 格式获取特定容器的详细信息
docker inspect --format='{{json .}}' <CONTAINER_ID># 返回容器的名称和状态,以自定义的格式显示
docker inspect --format='{{.Name}} - {{.State.Status}}' <CONTAINER_ID>
2.8 镜像打标签
docker tag
命令用于为 Docker 镜像创建一个新的标签(tag)。这个命令允许你将一个已存在的镜像标记为一个新的名称或标签,这在很多场景下都非常有用,比如当你想要将镜像推送到远程仓库时,可能需要为其指定一个符合仓库命名规则的标签。
语法:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
别名(即等价命令):
docker image tag, docker tag
参数说明:
SOURCE_IMAGE[:TAG]:指定源镜像的名称和标签。如果标签被省略,则默认使用源镜像的最新标签(latest)。
TARGET_IMAGE[:TAG]:指定目标镜像的名称和标签。你需要为新镜像指定一个唯一的名称(可能包括仓库地址)和标签。如果标签被省略,则同样默认使用 latest。
示例:
# 创建一个新的标签 v2.0
docker tag myimage:v1.0 myimage:v2.0# 如果你想要将这个镜像推送到一个远程仓库,比如 Docker Hub 上的 myusername/myrepo,并为其指定标签 latest,你可以这样做:
docker tag myimage:v1.0 myusername/myrepo:latest
docker tag 命令只是在本地 Docker 守护进程中创建了镜像的一个新标签,它并没有复制或修改镜像数据。因此,这个操作是非常快速的。
2.9 推送镜像
docker push 命令用于将本地镜像上传到镜像仓库中.
语法:
docker push [OPTIONS] NAME[:TAG]
别名(即等价命令):
docker image push, docker push
参数说明:
Options:-a, --all-tags 上传镜像的所有标签到仓库。如果你有一个镜像有多个标签(例如,myimage:latest 和 myimage:1.0),使用这个选项可以一次性上传所有标签。--disable-content-trust 跳过镜像签名。默认情况下,如果启用了内容信任(Content Trust),Docker 会要求镜像被签名。使用这个选项可以跳过签名检查。注意,默认值是 true,但这里的描述可能有些误导,因为通常我们期望的是如果启用了内容信任,则默认行为是要求签名,而使用此选项来禁用它。-q, --quiet 抑制详细输出。使用这个选项,命令执行时不会显示详细的进度信息。
示例:
# 上传一个名为 myimage,标签为 latest 的镜像到仓库:
docker push myimage:latest
# 上传 myimage 的所有标签到仓库:
docker push -a myimage
# 安静模式下上传 myimage:latest,不显示详细输出:
docker push -q myimage:latest
使用 docker push 命令时,需要确保你有权限向目标仓库推送镜像,并且目标仓库的地址(如果不是 Docker Hub)需要在镜像名称中指定(例如,myregistry.com/myimage:latest)。
2.10 删除镜像
docker rmi 命令(或其别名 docker image rm、docker image remove)用于删除一个或多个 Docker 镜像。
语法:
docker rmi [OPTIONS] IMAGE [IMAGE...]
别名(等价命令):
docker image rm, docker image remove, docker rmi
参数说明:
Options:-f, --force 强制删除镜像,即使有容器正在使用它。这通常会导致正在运行的容器停止并删除,但请注意,这可能会丢失数据。在使用此选项时要格外小心。--no-prune 默认情况下,当删除一个镜像时,Docker 也会删除所有未被标记(untagged)的父镜像。这些父镜像可能仍然被其他镜像所依赖。使用 --no-prune 选项可以防止删除这些未被标记的父镜像。但是,请注意,这可能会导致磁盘空间占用增加,因为未被标记的父镜像仍然会保留在磁盘上。
示例:
# 删除名为 myimage 的镜像:
docker rmi myimage
# 强制删除名为 myimage 的镜像,即使有容器正在使用它:
docker rmi -f myimage
# 删除多个镜像(myimage1 和 myimage2):
docker rmi myimage1 myimage2
注意事项:
- 在删除镜像之前,请确保没有容器正在使用该镜像,除非你打算强制删除它。
- 使用 --force 选项时要格外小心,因为它可能会导致数据丢失。
- 如果你不确定哪些镜像可以安全删除,可以使用 docker images 命令来查看所有镜像及其依赖关系。
docker rmi 用于管理和清理 Docker 镜像。但是,在使用它时要谨慎,以避免意外删除重要镜像或导致数据丢失。
2.11 导出镜像
docker save 命令用于将一个或多个 Docker 镜像保存到一个 tar 归档文件中。这个命令通常用于备份镜像、迁移镜像到另一个系统或者在没有网络连接的情况下分发镜像。
语法:
docker save [OPTIONS] IMAGE [IMAGE...]
别名(即等价命令):
docker image save, docker save
参数说明:
Options:-o, --output string 将归档内容写入到指定的文件中,而不是标准输出。你需要提供一个有效的文件路径来保存 tar 归档。如果不指定 -o 选项,归档内容将被输出到标准输出。
示例:
# 将名为 myimage 的镜像保存到一个名为 myimage.tar 的文件中:
docker save -o myimage.tar myimage
# 将多个镜像(myimage1 和 myimage2)保存到一个名为 images.tar 的文件中:
docker save -o images.tar myimage1 myimage2
# 可以通过管道将其传输到另一个命令:
docker save myimage | gzip > myimage.tar.gz
使用 docker save 命令时,请确保你有足够的权限来访问和保存指定的镜像。保存成功后,你可以使用 docker load 命令来加载这个 tar 归档文件中的镜像。
2.12 导入镜像
docker load 命令用于从 tar 归档文件或标准输入(STDIN)中加载一个镜像。
语法:
docker load [OPTIONS]
别名(即等价命令):
docker image load, docker load
参数说明:
Options:-i, --input string 从 tar 归档文件中读取镜像,而不是从标准输入。你需要指定归档文件的路径。如果不使用此选项,docker load 将从标准输入读取数据。-q, --quiet 抑制加载输出。使用这个选项时,命令执行时不会显示加载的进度和成功消息。## 3、容器命令
示例:
# 从名为 myimage.tar 的 tar 归档文件中加载镜像:
docker load -i myimage.tar
# 从标准输入加载镜像(例如,通过管道传输):
cat myimage.tar | docker load
# 安静模式下加载镜像,不显示加载输出:
docker load -q -i myimage.tar
cat myimage.tar | docker load -q
使用 docker load 命令时,确保你有一个有效的 Docker 镜像 tar 归档文件,或者能够通过标准输入提供这样的数据。加载成功后,镜像将出现在你的本地 Docker 镜像存储中,并可以使用 docker images 命令查看。
3、容器命令
3.1 容器管理
[root@localhost ~]# docker container --helpUsage: docker container COMMANDManage containersCommands:attach 将本地标准输入、输出和错误流附加到正在运行的容器上。commit 从容器的更改中创建一个新镜像。cp 在容器和本地文件系统之间复制文件/文件夹。create 创建一个新容器。diff 检查容器文件系统上文件或目录的更改。exec 在正在运行的容器中执行命令。export 将容器的文件系统导出为 tar 存档。inspect 显示一个或多个容器的详细信息。kill 杀死一个或多个正在运行的容器。logs 获取容器的日志。ls 列出容器。pause 暂停一个或多个容器内的所有进程。port 列出容器的端口映射或特定映射。prune 删除所有已停止的容器。rename 重命名容器。restart 重启一个或多个容器。rm 删除一个或多个容器。run 从镜像创建并运行一个新容器。start 启动一个或多个已停止的容器。stats 实时显示容器资源使用情况的统计信息。stop 停止一个或多个正在运行的容器。top 显示容器的运行进程。unpause 取消暂停一个或多个容器内的所有进程。update 更新一个或多个容器的配置。wait 阻塞直到一个或多个容器停止,然后打印其退出代码。Run 'docker container COMMAND --help' for more information on a command.
3.2 列出容器
docker ps 命令用于列出容器,它提供了多个选项来定制输出。
语法:
docker ps [OPTIONS]
别名(即等价命令):
docker container ls, docker container list, docker container ps, docker ps
参数说明:
Options:-a, --all 显示所有容器(默认只显示正在运行的容器)-f, --filter filter 基于提供的条件过滤输出。你可以根据容器的状态、名称、标签等过滤容器。--format string 使用自定义模板格式化输出:'table': Print output in table format with column headers (default)'table TEMPLATE': Print output in table format using the given Go template'json': Print in JSON format'TEMPLATE': Print output using the given Go template.更多格式移步:https://docs.docker.com/go/formatting/ -n, --last int 显示最后创建的 n 个容器(包括所有状态)。-l, --latest 显示最新创建的容器(包括所有状态)。这实际上是 -n=1 的快捷方式。--no-trunc 不截断输出。默认情况下,为了可读性,某些输出可能会被截断。-q, --quiet 仅显示容器 ID。这在你只需要容器 ID 列表时很有用。-s, --size 显示总文件大小。这包括容器的写层大小。
示例:
# 显示所有容器
docker ps -a
# 过滤容器,列出所有状态为 exited 的容器
docker ps -a -f status=exited
# 使用自定义格式,以 JSON 格式列出容器
docker ps --format json
# 使用自定义 Go 模板,只显示容器 ID 和名称:
docker ps --format "{{.ID}} {{.Names}}"
# 显示最后创建的 5 个容器
docker ps -n 5
# 仅显示容器 ID
docker ps -q
# 显示容器大小
docker ps -s
3.3 创建容器
docker run 命令是用于从镜像创建并启动一个新容器的 Docker 命令。它提供了丰富的选项来定制容器的运行环境和资源限制。
[root@localhost ~]# docker run --helpUsage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]Create and run a new container from an imageAliases:docker container run, docker runOptions:--add-host list 添加自定义的主机到 IP 的映射。这对于容器内部需要访问特定主机名的情况很有用。--annotation map Add an annotation to the container (passed through to the OCI runtime) (default map[])-a, --attach list 附加到容器的标准输入(STDIN)、标准输出(STDOUT)或标准错误(STDERR)。这允许你与运行中的容器进行交互。--blkio-weight uint16 设置 Block IO 的相对权重,范围在 10 到 1000 之间,或者设置为 0 以禁用。这用于限制容器对磁盘 IO 的访问--blkio-weight-device list Block IO weight (relative device weight) (default [])--cap-add list 添加 Linux 功能, 这用于控制容器内的权限。--cap-drop list 删除 Linux 功能--cgroup-parent string 为容器指定可选的父 cgroup。这用于资源管理和隔离。--cgroupns string 指定 cgroup 命名空间的使用方式:'host': 在 Docker 主机的 cgroup 命名空间中运行容器'private': 在容器自己的私有 cgroup 命名空间中运行'': Use the cgroup namespace as configured by thedefault-cgroupns-mode option on the daemon (default)--cidfile string 将容器 ID 写入指定的文件。这对于需要记录容器 ID 的脚本或自动化任务很有用。--cpu-period int 设置 CPUCFS(完全公平调度器)的周期。这用于限制容器可以使用的 CPU 时间。--cpu-quota int 设置 CPUCFS(完全公平调度器)的配额。--cpu-rt-period int 设置 CPU 实时周期的微秒数。这用于限制容器可以使用的实时 CPU 时间。--cpu-rt-runtime int 设置 CPU 实时运行时间的微秒数。-c, --cpu-shares int 设置 CPU 共享权重。这是一个相对权重,用于在多个容器之间分配 CPU 资源。默认情况下,所有容器的权重都是 1024。权重越高的容器可以获得更多的 CPU 时间片。--cpus decimal 限制容器可以使用的 CPU 数量。你可以指定一个小数来限制部分 CPU 资源,例如 1.5 表示容器可以使用一个半 CPU。--cpuset-cpus string 允许容器在指定的 CPU 上执行。你可以使用逗号分隔的列表或连字符指定的范围来指定 CPU。例如,0-3 表示容器可以在 CPU 0、1、2、3 上执行。--cpuset-mems string 允许容器在指定的内存节点上执行。这对于在多节点系统上运行的容器很有用。-d, --detach 在后台运行容器,并打印容器 ID。这是启动长时间运行的服务或后台任务时的常用选项。--detach-keys string 覆盖用于分离容器的键序列。默认情况下,你可以使用 CTRL-P CTRL-Q 来分离容器,同时保持其运行。--device list 将主机设备添加到容器中。这对于需要直接访问硬件设备的容器很有用,例如 GPU 或特定类型的存储设备。--device-cgroup-rule list 向 cgroup 允许的设备列表中添加一条规则。这用于控制容器对设备的访问权限。--device-read-bps list 限制容器对设备的读写速率。你可以指定设备的路径和速率限制(以字节/秒或 IO/秒为单位)。--device-read-iops list Limit read rate (IO per second) from a device (default [])--device-write-bps list Limit write rate (bytes per second) to a device (default [])--device-write-iops list Limit write rate (IO per second) to a device (default [])--disable-content-trust 跳过镜像验证。默认情况下,如果启用了内容信任,Docker 将拒绝运行未签名的镜像。使用这个选项可以绕过这个限制,但可能会带来安全风险--dns list 设置自定义 DNS 服务器。这对于需要解析特定域名或需要使用特定 DNS 服务器的容器很有用。--dns-option list 设置 DNS 选项。这允许你指定额外的 DNS 配置,如 ndots(在查询完全限定域名之前需要多少个点)或 timeout(等待 DNS 响应的超时时间)。--dns-search list 设置自定义 DNS 搜索域。这允许你指定在解析非完全限定域名时要搜索的域列表。--domainname string 设置容器的 NIS 域名。这对于需要在容器内部使用 NIS 服务的场景很有用。--entrypoint string 覆盖镜像的默认 ENTRYPOINT。这对于需要运行镜像中不同命令的场景很有用。-e, --env list 设置环境变量。你可以使用此选项为容器设置环境变量,格式为 VAR_NAME=value。这对于配置应用程序非常有用。--env-file list 从文件中读取环境变量。你可以指定一个包含环境变量定义的文件,Docker 将在启动容器时读取该文件并设置相应的环境变量。--expose list 暴露一个端口或端口范围。此选项声明容器将监听哪些端口,但不会自动将这些端口映射到主机。通常与 -p 或 --publish 选项结合使用--gpus gpu-request 向容器添加 GPU 设备。你可以指定要传递给容器的 GPU 数量或 'all' 以传递所有 GPU。这对于需要 GPU 加速的应用程序非常有用--group-add list 向容器添加额外的用户组。这允许容器内的进程以指定的用户组身份运行。--health-cmd string 运行以检查健康状况的命令。你可以指定一个命令来定期检查容器的健康状况。如果命令退出状态码为非零,则容器被视为不健康--health-interval duration 运行检查之间的时间间隔。你可以指定时间间隔(毫秒、秒、分钟、小时)来控制健康检查的频率。--health-retries int 连续失败次数达到多少时报告不健康。如果健康检查命令连续失败指定次数,则容器被视为不健康。--health-start-interval duration 启动期间运行检查的时间间隔。在容器启动期间,你可以指定一个不同的时间间隔来控制健康检查的频率。--health-start-period duration 容器初始化开始前的启动期。在启动期结束之前,健康检查失败不会计入连续失败次数。--health-timeout duration 允许单个检查运行的最大时间。你可以指定时间限制(毫秒、秒、分钟、小时)来控制健康检查命令的运行时间--help 打印用法信息。此选项将显示 docker run 命令的完整用法和所有可用选项-h, --hostname string 设置容器的主机名。这允许你为容器指定一个唯一的主机名,这在容器间通信时非常有用。--init 在容器内运行一个 init 进程。init 进程负责转发信号和回收进程,这有助于提高容器的稳定性和安全性。-i, --interactive 即使未附加也保持 STDIN 打开。此选项允许你与容器中的进程进行交互,即使你没有通过 docker attach 命令附加到容器--ip string 设置容器的 IPv4 地址。你可以指定一个静态 IP 地址供容器使用。--ip6 string 设置容器的 IPv6 地址。与 --ip 选项类似,但用于 IPv6 地址。--ipc string 设置 IPC 模式。IPC(进程间通信)模式决定了容器如何与其他容器或主机进行进程间通信。--isolation string 设置容器隔离技术。你可以指定使用哪种隔离技术(如 default、process、hyperv)来运行容器。--kernel-memory bytes 设置内核内存限制。你可以指定容器可以使用的内核内存量(以字节为单位)-l, --label list 为容器设置元数据标签。标签以键值对的形式存在,有助于组织和筛选容器。--label-file list 从一个包含标签定义的文件中读取标签。文件应包含一行一个的键值对。--link list 添加到另一个容器的链接。此选项允许容器间安全通信,但 Docker 官方推荐使用网络和卷来替代。--link-local-ip list 设置容器的IPv4/IPv6链路本地地址。这些地址用于容器间的直接通信。--log-driver string 为容器指定日志驱动程序。Docker 支持多种日志驱动程序,如 json-file、syslog 等。--log-opt list 为日志驱动程序设置选项。这些选项依赖于所选的日志驱动程序。--mac-address string 为容器指定MAC地址。这有助于在需要固定网络配置的场景中-m, --memory bytes 设置容器的内存限制。可以指定为字节数或带有单位的字符串(如 512m)--memory-reservation bytes 设置容器的内存软限制。如果系统内存紧张,Docker 将尝试保持容器内存使用量低于此限制。--memory-swap bytes 设置容器的交换内存限制。可以设置为 -1 以启用无限交换。--memory-swappiness int 调整容器的内存交换倾向。值范围为 0 到 100,默认为 -1(由 Docker 守护进程决定)。--mount mount 将文件系统挂载到容器。这是 --volume 的更现代替代品,提供了更灵活的挂载选项。--name string 为容器指定名称。这有助于轻松识别和引用容器。--network network 将容器连接到指定的网络。Docker 支持自定义网络,允许容器间复杂的通信模式。--network-alias list 为容器在网络作用域内添加别名。这有助于简化容器间的通信。--no-healthcheck 禁用容器指定的任何健康检查。如果容器镜像包含健康检查指令,此选项将覆盖它。--oom-kill-disable 禁用 OOM(内存不足)杀手。在内存不足的情况下,Docker 通常会自动杀死占用过多内存的容器进程。使用此选项可以禁用此行为,但可能导致系统不稳定。--oom-score-adj int 调整主机的 OOM 偏好设置。值范围为 -1000 到 1000,影响 Docker 容器在内存不足时被杀死的优先级。--pid string 设置要使用的 PID 命名空间。这允许容器共享或隔离进程 ID。--pids-limit int 调整容器的 PID 限制。设置为 -1 表示无限制。--platform string 如果服务器支持多平台,则设置平台。这允许在不同架构上运行容器。--privileged 给予容器扩展权限。这允许容器执行许多通常被限制的操作,如加载内核模块。-p, --publish list 将容器的端口发布到主机。格式通常为 宿主机端口:容器端口。-P, --publish-all 将容器暴露的所有端口随机发布到主机的端口上。--pull string 在运行之前拉取镜像。选项包括 "always"(始终拉取)、"missing"(仅当镜像不存在时拉取)和 "never"(从不拉取)。-q, --quiet 抑制拉取镜像时的输出。这个选项可以让 Docker 在拉取镜像时保持安静,不显示进度条或下载信息。--read-only 以只读方式挂载容器的根文件系统。这可以增强容器的安全性,防止对文件系统的意外修改。--restart string 设置容器退出时的重启策略。可选值包括 "no"(不重启)、"on-failure"(失败时重启)、"always"(总是重启)等。默认值为 "no"。--rm 容器退出时自动移除。这个选项可以让 Docker 在容器停止后自动删除它,避免留下无用的容器实例。--runtime string 为容器指定运行时。Docker 支持多种运行时,如 runc(默认)、kata-containers 等。--security-opt list 设置安全选项。这些选项允许你调整容器的安全策略,如 SELinux 标签、AppArmor 配置等。--shm-size bytes 设置 /dev/shm 的大小。/dev/shm 是一个临时文件系统,用于存储共享内存段。--sig-proxy 代理接收到的信号给进程。默认情况下,Docker 会将发送给容器的信号代理给容器内的主进程。设置为 false 可以禁用此行为。--stop-signal string 设置停止容器的信号。默认值是 SIGTERM,但你可以指定其他信号,如 SIGKILL。--stop-timeout int 设置停止容器的超时时间(以秒为单位)。如果容器在指定时间内没有停止,Docker 将强制终止它。--storage-opt list 设置存储驱动选项。这些选项允许你调整存储驱动的行为,如文件系统的挂载选项。--sysctl map 设置 sysctl 选项。这些选项允许你调整内核参数,如网络配置、内存管理等。--tmpfs list 挂载一个 tmpfs 目录。tmpfs 是一种基于内存的文件系统,可以用于存储临时数据。-t, --tty 分配一个伪终端(pseudo-TTY)。这个选项可以让容器在运行时分配一个伪终端,使得你可以像使用本地终端一样与容器进行交互。--ulimit ulimit 设置 ulimit 选项。ulimit 用于控制 shell 进程及其子进程可以使用的资源量,如内存、CPU 时间等。-u, --user string 设置容器内运行进程的用户名或用户 ID。你还可以指定用户所属的组名或组 ID,格式为 <name|uid>[:<group|gid>]。--userns string 指定要使用的用户命名空间。用户命名空间是一种内核功能,它允许你将容器内的用户和组 ID 映射到主机上的不同用户和组 ID。--uts string 指定要使用的 UTS 命名空间。UTS 命名空间包含主机名和域名信息,允许你为每个容器设置独立的主机名和域名。-v, --volume list 绑定挂载一个卷。这个选项允许你将主机上的目录或文件挂载到容器内的指定位置,实现数据的持久化和共享。--volume-driver string 为容器指定可选的卷驱动程序。Docker 支持多种卷驱动程序,如 local(默认)、ceph、cifs 等,允许你根据需求选择适合的存储后端--volumes-from list 从指定的容器挂载卷。这个选项允许你从一个或多个已运行的容器中挂载卷,实现容器间的数据共享。-w, --workdir string 设置容器内的工作目录。这个选项允许你指定容器启动时的工作目录,即容器内进程的当前工作目录。
3.4 查询容器日志
[root@localhost app]# docker logs --helpUsage: docker logs [OPTIONS] CONTAINERFetch the logs of a containerAliases:docker container logs, docker logsOptions:--details 显示日志的额外详细信息。这个选项可能会根据Docker的版本和配置有所不同,具体效果需要你在实际环境中尝试-f, --follow 实时跟踪日志输出。这个选项非常有用,当你想要持续监控容器的日志时,可以加上这个参数。--since string 从指定的时间戳开始显示日志。时间戳可以是绝对时间(如"2013-01-02T13:23:37Z"),也可以是相对时间(如"42m"表示42分钟前)。-n, --tail string 从日志末尾显示指定数量的行。默认值是"all",表示显示所有日志。如果你只想查看最近的几条日志,可以指定一个数字,如-n 10。 -t, --timestamps 在日志输出中显示时间戳。这个选项可以帮助你更清楚地了解日志生成的时间。--until string 在指定的时间戳之前显示日志。与--since选项类似,时间戳可以是绝对时间或相对时间。
示例:
# 查看容器的所有日志
docker logs my-container# 显示容器的实时日志输出,并在新日志生成时自动刷新。你可以通过按Ctrl+C来停止跟踪
docker logs -f my-container# 查看最后10行日志
docker logs -n 10 my-container# 显示每条日志的时间戳
docker logs -t my-container# 查看过去10分钟内的日志
docker logs --since 10m my-container# 查看直到某个特定时间之前的日志
docker logs --until "2023-04-01T12:00:00Z" my-container
4、网络
4.1 网络管理
[root@localhost app]# docker network --helpUsage: docker network COMMANDManage networksCommands:connect 将一个容器连接到网络。这个命令允许你将一个已经存在的容器加入到一个指定的网络中,从而使容器能够与该网络中的其他容器通信。create 创建一个网络。使用此命令可以定义一个新的 Docker 网络,包括指定网络类型(如 bridge、overlay 等)disconnect 将容器从网络中断开连接。这个命令用于移除容器与网络之间的连接,但不会影响容器的运行。inspect 显示一个或多个网络的详细信息。使用此命令可以查看网络的配置信息、连接到的容器等。ls 列出所有网络。这个命令将显示 Docker 中当前存在的所有网络,包括默认的 bridge 网络和用户自定义的网络。prune 移除所有未使用的网络。Docker 会自动创建一些默认的网络,如果你创建了自己的网络并在之后没有使用,可以使用此命令清理这些未使用的网络。rm 移除一个或多个网络。这个命令用于删除指定的网络,但只有在网络没有被任何容器使用时才能成功删除。Run 'docker network COMMAND --help' for more information on a command.
4.2 列出网络
[root@localhost app]# docker network ls --helpUsage: docker network ls [OPTIONS]List networksAliases:docker network ls, docker network listOptions:-f, --filter filter Provide filter values (e.g. "driver=bridge")--format string Format output using a custom template:'table': Print output in table formatwith column headers (default)'table TEMPLATE': Print output in table formatusing the given Go template'json': Print in JSON format'TEMPLATE': Print output using the givenGo template.Refer to https://docs.docker.com/go/formatting/for more information about formatting output withtemplates--no-trunc Do not truncate the output-q, --quiet Only display network IDs
4.3 创建网络
[root@localhost app]# docker network create --helpUsage: docker network create [OPTIONS] NETWORKCreate a networkOptions:--attachable 允许手动将容器附加到网络上。默认情况下,只有创建容器时指定的网络才能连接到该容器。使用此选项后,您可以使用 docker network connect 命令将未附加的容器连接到该网络。--aux-address map 为网络驱动程序指定辅助的 IPv4 或 IPv6 地址。这通常用于为特定服务或功能分配静态 IP 地址。(default map[])--config-from string 从指定的网络中复制配置。这允许您创建一个新网络,其配置与现有网络相同。--config-only 创建一个仅配置的网络。这种类型的网络不会实际创建网络结构,而是用于存储和共享网络配置。-d, --driver string 指定管理网络的驱动程序。默认值为 "bridge",但也可以使用其他驱动程序,如 "overlay" 用于多主机网络。 --gateway strings 为子网指定 IPv4 或 IPv6 网关地址。网关是子网中用于与其他子网或外部网络通信的设备。--ingress 在 Swarm 模式下创建一个路由网格网络。这允许 Swarm 集群中的服务相互通信,而无需指定网络。--internal 限制外部访问网络。使用此选项创建的网络无法从 Docker 主机或其他网络访问,只能由网络内的容器访问。--ip-range strings 从指定的子范围分配容器 IP 地址。这允许您更精细地控制网络中的 IP 地址分配。--ipam-driver string 指定 IP 地址管理(IPAM)驱动程序。IPAM 负责在 Docker 网络中分配 IP 地址。(default "default")--ipam-opt map 设置 IPAM 驱动程序特定的选项。这些选项允许您配置 IPAM 驱动程序的行为,如地址池大小。 (default map[])--ipv6 启用 IPv6 网络。默认情况下,Docker 网络仅支持 IPv4。使用此选项可以创建支持 IPv6 的网络。--label list 为网络设置元数据标签。标签可以用于过滤和选择网络-o, --opt map 设置驱动程序特定的选项。这些选项允许您配置网络驱动程序的行为,如网络隔离模式。 (default map[])--scope string 控制网络的范围。对于本地网络,范围是 "local";对于 Swarm 集群中的覆盖网络,范围是 "swarm"。--subnet strings 以 CIDR 格式指定子网,表示网络段。子网定义了网络中的 IP 地址范围。
示例:
# 创建默认的桥接网络
docker network create -d bridge my-bridge-network# 创建带有自定义子网的桥接网络
docker network create --driver=bridge --subnet=192.168.0.0/16 my-custom-bridge# 创建覆盖网络(适用于Docker Swarm集群),允许集群服务和手动启动的容器进行连接。
docker network create --scope=swarm --attachable -d overlay my-multihost-network# 创建具有多个子网的覆盖网络,用于在Docker Swarm集群中提供复杂的网络配置。
docker network create -d overlay \--subnet=192.168.10.0/25 \--subnet=192.168.20.0/25 \--gateway=192.168.10.100 \--gateway=192.168.20.100 \--aux-address="my-router=192.168.10.5" \--aux-address="my-switch=192.168.10.6" \my-multi-subnet-overlay# 使用自定义桥接网络启动容器,并运行一个无限循环的busybox命令。
docker container run -d --name box3 --network mybridge busybox /bin/sh -c "while true; do sleep 3600; done"# 将容器连接到已存在的网络
docker network connect my-existing-network my-container
四、镜像
1、UnionFS(联合文件系统)
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来只能看到一个文件系统。联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
2、镜像加载原理
Docker的镜像实际由一层一层的文件系统组成:
- bootfs(boot file system)主要包含bootloader和kernel。bootloader主要是引导加载kernel,完成后整个内核就都在内存中了。此时内存的使用权已由bootfs转交给内核,系统卸载bootfs。可以被不同的Linux发行版公用。
- rootfs(root file system),包含典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同操作系统发行版(Ubuntu,Centos等)。因为底层直接用Host的kernel,rootfs只包含最基本的命令,工具和程序就可以了。
3、分层理解
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的容器层。
容器在启动时会在镜像最外层上建立一层可读写的容器层(R/W),而镜像层是只读的(R/O)。
# 编辑容器后提交容器成为一个新镜像
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[tag]
4、虚悬镜像
虚悬镜像是指那些已经被创建,但是没有被任何容器所引用的镜像。在Docker镜像仓库中,这些镜像的仓库名(镜像名)和标签(TAG)都是,因此它们处于“悬浮”状态,得名虚悬镜像。
虚悬镜像产生原因:
- 构建取消或构建失败:在构建镜像时,如果由于某种原因(如Dockerfile编写错误、构建过程中断等)导致构建取消或失败,可能会留下一些未被命名或标记的镜像,这些镜像就成为虚悬镜像。
- 删除容器时产生的中间层镜像:在删除容器时,如果某些中间层镜像没有被其他容器或镜像所引用,它们也可能成为虚悬镜像。
特点与风险:
- 占用磁盘空间:虚悬镜像虽然未被使用,但仍然会占用磁盘空间。如果虚悬镜像数量过多,可能会浪费大量磁盘资源。
- 潜在风险:虽然虚悬镜像本身不会对系统造成直接危害,但它们可能表明Docker环境中存在构建或管理上的问题。如果不及时清理,可能会增加系统管理的复杂性和潜在风险。
为了避免虚悬镜像对系统造成不必要的影响,建议定期进行清理。
# 查看所有虚悬镜像
docker images -f dangling=true# 删除所有虚悬镜像:
docker image prune# 删除特定的虚悬镜像:
docker rmi $(docker images -q -f dangling=true)
五、容器数据卷
为了实现数据持久化,使容器之间可以共享数据。可以将容器内的目录,挂载到宿主机上或其他容器内,实现同步和共享的操作。即使将容器删除,挂载到本地的数据卷也不会丢失。
1、具名挂载
docker run -d -v 卷名:容器内目录 镜像名/id
通过docker volume inspect 卷名 命令找到主机内目录
所有docker容器内的卷,在未指定主机内目录时,都在:/var/lib/docker/volumes/卷名/_data 下
2、匿名挂载
docker run -d -v 容器内目录 镜像名/id
匿名挂载后,使用docker volume ls命令查看所有挂载的卷
3、绑定挂载
dokcer run -it -v 主机内目录:容器内目录 镜像名/id
将容器内目录挂载到主机内目录上,通过docker inspect
命令查看该容器即可以看到挂载信息
4、容器挂载到另一个容器数据卷上
将两个容器进行挂载:
docker run -it --name container02 --volumes from container01 镜像名/id
六、Dockerfile
Dockerfile是用来构建docker镜像的文件
构建步骤:编写一个dockerfile文件,随后运行以下命令:
docker build -f 文件路径 -t 标签 . # 文件名为Dockerfile时可省略且最后的.不要忽略
docker run # 运行镜像
docker push # 发布镜
Dockerfile命令:
dockerfile命令#
命令 | 效果 |
---|---|
FROM | 基础镜像:Centos/Ubuntu |
MAINTAINER | 镜像作者+邮箱 |
RUN | 镜像构建的时候需要运行的命令 |
ADD | 为镜像添加内容(压缩包) |
WORKDIR | 镜像工作目录(进入容器时的目录) |
VOLUME | 挂载的目录 |
EXPOSE | 暴露端口配置 |
CMD/ENTRYPOINT | 指定这个容器启动时要运行的命令(CMD替代先前命令,ENTRYPOINT在先前命令后追加) |
COPY | 类似于ADD,将文件拷贝到镜像中 |
ENV | 构建时设置环境变量 |
七、Docker网络原理
1、Docker 启动后的系统情况
- 创建了 docker0 网桥并分配了 IP 地址
Docker Daemon 首次启动时会创建一个虚拟网桥,默认的名称是 docker0,然后按照 RPC1918 的模型在私有网络空间中给这个网桥分配一个子网。Docker Daemon 会在几个备选地址段里给 docker0 选一个地址,通常是以 172 开头的一个地址。[root@localhost ~]# ip addr | grep docker0 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
- Linux 的 ip_forward ( IPv4 的 IP 转发功能)开启
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward 1
- 添加了 iptables 规则
这些规则定义了数据包如何通过[root@localhost ~]# iptables-save | grep docker0 -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A DOCKER -i docker0 -j RETURN -A POSTROUTING_ZONES -o docker0 -g POST_docker -A PREROUTING_ZONES -i docker0 -g PRE_docker -A PREROUTING_ZONES -i docker0 -g PRE_docker -A PREROUTING_ZONES -i docker0 -g PRE_docker -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o docker0 -j DOCKER -A FORWARD -i docker0 ! -o docker0 -j ACCEPT -A FORWARD -i docker0 -o docker0 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP -A FORWARD_IN_ZONES -i docker0 -g FWDI_docker -A FORWARD_OUT_ZONES -o docker0 -g FWDO_docker -A INPUT_ZONES -i docker0 -g IN_docker
docker0
网桥进行转发和处理。-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
:对于源IP地址在172.17.0.0/16子网内的数据包,如果它们不是从docker0接口发出的,则对它们进行源地址伪装(MASQUERADE)。这通常用于NAT(网络地址转换),使得Docker容器能够访问外部网络。-A DOCKER -i docker0 -j RETURN
:如果数据包是从docker0接口进入的,则直接返回,不进行后续处理。这通常是为了避免对Docker容器内部通信的不必要干扰。- POSTROUTING_ZONES和PREROUTING_ZONES链规则:这些规则涉及到iptables的区域(zones)概念,用于处理来自或发往特定网络接口的数据包。与docker0相关的规则将数据包引导到特定的用户自定义链(如POST_docker、PRE_docker)进行处理。
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
:这条规则允许已建立连接或相关的数据包从其他接口转发到docker0接口。-A FORWARD -o docker0 -j DOCKER
:这条规则将发往docker0接口的数据包引导到DOCKER链进行处理。-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
:这条规则允许从docker0接口进入且不从docker0接口出去的数据包被接受。这通常用于允许Docker容器访问外部网络。-A FORWARD -i docker0 -o docker0 -j ACCEPT
这条规则允许在docker0接口之间循环的数据包被接受。虽然这种情况在实际应用中较少见,但它确保了规则的全面性。- DOCKER-ISOLATION-STAGE链规则:这些规则用于实现Docker容器之间的隔离。
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
:如果数据包是从docker0接口进入且不从docker0接口出去,则将其引导到DOCKER-ISOLATION-STAGE-2链进行处理。-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
则表示,如果数据包试图从docker0接口出去(在隔离阶段被检测到),则将其丢弃。- FORWARD_IN_ZONES和FORWARD_OUT_ZONES链规则:这些规则同样涉及到iptables的区域概念,用于处理进入或离开特定网络接口区域的数据包。与docker0相关的规则将数据包引导到特定的用户自定义链(如FWDI_docker、FWDO_docker)进行处理。
-A INPUT_ZONES -i docker0 -g IN_docker
:将进入docker0接口的数据包引导到IN_docker链进行处理。这通常用于对进入Docker容器的数据包进行额外的安全检查或处理。
2、Docker 的网络模式
标准的 Docker 支持 4 种网络模式,可以在使用 docker run
命令启动容器的时候通过 --net
参数指定容器的网络模式:
bridge
:-net=bridge
,Docker 默认的网络模式,新建的容器将拥有独立的网络命名空间,并连接到 Docker 的网桥 docker0 中。container
:--net=container:NAME_or_ID
,新建的容器将与指定容器使用同一个网络命名空间,共享网络栈,可以直接通过 lo 环回接口进行通信,但其他资源还是相互隔离的。host
:--net=host
,新建的容器将与宿主机使用同一个网络命名空间,但其他资源还是隔离的。容器进程可以跟主机其它 root 进程一样打开低范围的端口,如果进一步的使用 --privileged=true,容器会被允许直接配置主机的网络堆栈。none
:--net=none
,新建的容器将拥有独立的网络命名空间,但不进行网络配置,后续需要手动配置。
默认的 Docker 网络模型提供了一个IP 地址段是 172.17.0.0/16 的 docker0 网桥。每个容器都会在这个子网内获得 IP 地址,并且将 docker0 网桥的IP 地址(172.17.42.1)作为其默认网关。需要注意的是,Docker宿主机外面的网络不需要知道任何关于这个172.17.0.0/16 的信息或者知道如何连接到其内部,因为 Docker 的宿主机针对容器发出的数据,在物理网卡地址后面都做了IP伪装 MASQUERADE(隐含 NAT)。也就是说,在网络上看到的任何容器数据流都来源于该 Docker 节点的物理 P 地址。这里所说的网络都指连接这些主机的物理网络。
2.1 bridge 模式
在 bridge 模式下,针对由 Docker 建的每一个容器,都会创建一个虚拟以太网设备 —— Veth 设备对,其中一端关联到网桥 docker0 上,另一端使用 Linux 的网络命名空间技术映射到容器内的 eth0 设备,然后在网桥的地址段内给 eth0 接口分配一个没有使用过的 IP 地址。
Docker 的 bridge 模式的网络模型如下:
docker0 地址段默认情况下在宿主机外部是不可见的,所以在同一台机器内的容器之间可以相互通信,不同主机上的容器不能相互通信,实际上它们甚至有可能在相同的网络地址范围内(不同主机上的 docker0 地址段可能是一样的)。
为了让它们跨节点相互通信,就必须在主机的地址上分配端口,然后通过这个端口将网络流量路由或代理到目标容器上。这样做显然意味着一定要在容器之间小心谨慎地协调好端口的分配情况,或者使用动态端口的分配技术,而这二者都是困难且会增加复杂度的事情。这都是 Docker 的网络模型在跨主机访问时面临的问题。
# 1、创建一个 Docker 容器,将容器8080端口映射到主机的4000
[root@localhost ~]# docker run -d -p 8080:4000 --name test tomcat
032de77f49edd74a64c519528d7ce6f0fa61173480498e67fff0a1abc4465730# 2、查看容器网络模式
[root@localhost ~]# docker inspect 032de77f49ed | grep NetworkMode"NetworkMode": "bridge",
[root@localhost ~]# docker network inspect bridge | grep EndpointID"EndpointID": "412cb620715af67a104b8ff208bfe11bbbac19cc3fe9b3331402c8a6d1457309",# 3、查看网桥连接与容器路由
# 宿主机上的 Veth 设备对已经建立,连接容器与网桥 docker0。
[root@localhost ~]# ip addr | grep veth
5: veth61a051f@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
# 容器内默认停止的回环设备 lo 被启动,外面宿主机连接进来的 Veth 设备也被命名成了 eth0, 并且已经配置了地址 172.17.0 2。
# 如果容器不支持ip命令,可使用 `sudo nsenter -t $(docker inspect --format '{{ .State.Pid }}' 容器ID或名称 ) -n ip addr show` 来获取网络接口信息,当然也可以给容器安装对应的软件包(iptoute2)来支持ip命令
[root@localhost ~]# docker exec -it test ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:1c:e3:3e brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
# 容器内路由信息表包含一条到 docker0 的子网路由和一条到 docker0 的默认路由。
# 第一条路由为默认路由,意味着容器内所有不匹配任何其他路由规则的网络流量都将通过网关172.17.0.1发送出去。eth0 是容器内的默认网络接口名称。172.17.0.1通常是Docker桥接网络(如docker0桥接网络)的默认网关地址。
# 第二条路由规则指定了目的网络 172.17.0.0/16 的流量应该通过 eth0 接口发送。proto kernel 表示这条路由是由内核自动创建的。scope link 表示这条路由仅适用于直接连接的网络。src 172.17.0.2 表明发送出去的流量将使用 172.17.0.2 作为源 IP 地址。
[root@localhost ~]# docker exec -it test ip route
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2 # 4、查看 iptables 规则
# 请求宿主机 8080 端口的数据包目的地址将被转换为容器的服务地址 172.17.0.2:4000。
# 第一条规则将原地址和目的地址为容器IP 172.17.0.2/32,MASQUERADE动态地转换为可用的宿主机IP地址。
# 第二条规则用于将宿主机的 8080 端口映射到容器 172.17.0.2 的 4000 端口上。
# 第三条规则允许特定的容器内部通信通过 docker0 桥接网络
[root@localhost ~]# iptables-save | grep 4000
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 4000 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:4000
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 4000 -j ACCEPT
2.2 container 网络模式
使用 container 网络模式创建的容器将与指定容器使用同一个网络命名空间,共享网络栈,可以直接通过 lo 环回接口进行通信,但其他资源还是相互隔离的。
# 1、使用 container 网络模式创建一个容器
[root@localhost ~]# docker run -d --net=container:test --name test2 nginx
574815fdf6e8e29e6cd14ba599f53e0123c3db6735717c6554cab80a830ad49c# 2、查看容器网络模式
[root@localhost ~]# docker inspect test2 | grep NetworkMode"NetworkMode": "container:032de77f49edd74a64c519528d7ce6f0fa61173480498e67fff0a1abc4465730",# 3、查看容器网络
# 可以看到,container 模式的容器与指定容器处于同一网络命名空间,使用同一个 ip,两个容器之间可通过 lo 设备通信,使用端口不可重复。
# container 网络模式的容器无法进行端口映射。
[root@localhost ~]# sudo nsenter -t $(docker inspect --format '{{ .State.Pid }}' test2) -n ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
2.3 host 网络模式
使用 host 网络模式创建的容器将与宿主机使用同一个网络命名空间,但其他资源还是隔离的。容器进程可以跟主机其它 root 进程一样打开低范围的端口,如果进一步的使用 --privileged=true
,容器会被允许直接配置主机的网络堆栈。
# 1、使用 host 网络模式创建一个容器
[root@localhost ~]# docker run -d --net=host --name test3 nginx
b281ffed1ecdeae3acece7570e884c9e2024889448da7fe1d67219d80d43b668# 2、查看容器网络模式
[root@localhost ~]# docker inspect test3 | grep NetworkMode"NetworkMode": "host",# 3、查看容器网络
# 容器与宿主机使用同一网络命名空间,在容器中可以看到 docker0 网桥。
[root@localhost ~]# sudo nsenter -t $(docker inspect --format '{{ .State.Pid }}' test3) -n ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:1c:e3:3e brd ff:ff:ff:ff:ff:ffinet 10.100.110.111/24 brd 10.100.110.255 scope global noprefixroute dynamic ens160valid_lft 1535sec preferred_lft 1535secinet6 wwww::www:www:www:www/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ab:06:0d:13 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 ww::ww:ww:ww:ww/64 scope link valid_lft forever preferred_lft forever
5: veth61a051f@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 16:17:1f:1f:11:8c brd ff:ff:ff:ff:ff:ff link-netnsid 0inet6 ee::ee:ee:ee:ee/64 scope link valid_lft forever preferred_lft forever# 4、查看宿主机端口占用
# 容器直接占用宿主机的端口。
[root@localhost ~]# ss -tnl | grep 80
LISTEN 0 511 *:80 *:*
LISTEN 0 4096 *:8080 *:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 4096 [::]:8080 [::]:*
2.4 none 网络模式
使用 none 网络模式创建的容器将拥有独立的网络命名空间,但不进行网络配置,后续需要手动配置。
# 1、使用 none 网络模式创建一个容器
[root@localhost ~]# docker run -d --net=none --name test4 nginx
7c2564ffc43f3a5f47257b467c384f282684b7fa477f4cc7f2feea7afe23fca8# 2、查看容器网络模式
[root@localhost ~]# docker inspect test4 | grep NetworkMode"NetworkMode": "none",# 3、查看容器网络
# 只有 lo 设备,暂无 veth 设备,未设置 ip。
[root@localhost ~]# sudo nsenter -t $(docker inspect --format '{{ .State.Pid }}' test4) -n ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2.5 自定义网络
创建自定义网络时,Docker会在该网络上启动一个嵌入式的DNS服务器。这个DNS服务器专门用于解析同一网络中的容器名和服务名。
自定义网络中的DNS服务器能够动态地更新和维护容器名的解析记录,从而确保容器之间可以通过名称进行通信。
# 1、创建自定义网络
# 如果没有指定子网和子网掩码,Docker会自动选择一个默认的子网和子网掩码
# docker network create --driver bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 my_custom_network
docker network create --driver bridge my_custom_network
# 查看网络列表
docker network ls
# 查看网络详细信息,包括容器连接情况、网络配置等。
docker network inspect my_custom_network# 2、运行容器并连接到自定义网络
docker run -d --name container1 --network my_custom_network nginx
docker run -d --name container2 --network my_custom_network nginx# 3、测试容器名通信
docker exec -it container1 ping container2
2.6 使用--link
连接容器
在Docker的世界里,--link
参数曾经是用来连接两个容器,使得它们之间可以方便地通信。不过,需要注意的是,随着Docker的发展,--link
参数已经被视为一种较旧且不太推荐的方式,因为它有一些局限性,比如它创建的连接是单向的,而且在多宿主机或Swarm模式下不太适用。现代Docker更推荐使用Docker网络(networks)来实现容器间的通信。
docker run --name myapp --link db:mysql -d myappimage
2.7 删除测试数据
# 停止所有容器
docker stop $(docker ps -aq)# 删除所有容器
docker rm $(docker ps -aq)# 删除所有镜像
docker rmi $(docker images -q)# 删除自定义网络
docker network rm my_custom_network
3、容器通信
3.1 通过IP地址通信
在bridge模式下,容器拥有独立的IP地址和Network Namespace,但共享同一个子网。这实现了网络隔离和互操作性。然而,这也意味着容器之间的通信需要通过Docker的虚拟网桥进行转发。
步骤:
- 启动两个容器,确保它们都在bridge网络上(这通常是默认的,除非你指定了其他网络)。
- 使用docker inspect命令查看容器的IP地址。
- 在一个容器中使用ping或其他网络工具测试与另一个容器的连通性。
优点:
- 简单直接,无需额外的配置。
缺点:
- 需要记住容器的IP地址,这在动态环境中可能不太方便。
3.2 通过容器名通信
Docker 提供了一个DNS解析服务,允许容器通过容器名进行通信。在bridge模式下,只要容器连接在同一个自定义网络上,它们就可以通过容器名称来访问其他容器,而无需知道对方的IP地址。
步骤:
- 创建一个自定义的bridge网络。
- 启动两个容器,并将它们连接到刚才创建的自定义网络上。
- 在一个容器中使用容器名来访问另一个容器的服务(例如,通过http://container_name访问Web服务)。
优点:
- 更加灵活和方便,因为无需记住容器的IP地址。
- 容器名通常比IP地址更具可读性。
缺点:
- 依赖于Docker的DNS服务,如果DNS服务出现问题,可能会影响通信。
八、Docker Compose
1、Docker Compose 是什么?
Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。
可以将 docker-compose.yml 理解为 spring里边的 applicationContent.yml。
2、Docker Compose 能干什么?
docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来。
如果我需要同时部署好多个服务,难道要每个服务单独写Dockerile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具。
例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
3、Docker Compose 核心概念
- 一个文件:docker-compose.yml
- 两个要素:
- 服务 ( service ):⼀个应⽤的容器,实际上可以包括若⼲运⾏相同镜像的容器实例(web、redis、mysql …)。
- 项⽬ ( project ):由⼀组关联的应⽤容器组成的⼀个完整业务单元,在 docker-compose.yml ⽂件中定义(博客、web、mysql)。
4、安装Docker Compose
docker-compose
和 docker compose
是Docker Compose的两种不同使用方式:
docker-compose
:它是一个独立的可执行文件,需要单独安装和配置。通常位于/usr/local/bin/docker-compose
或/usr/bin/docker-compose
。使用docker-compose
命令时,需要确保该可执行文件在系统PATH中可访问。这种方式是Docker Compose的传统用法,在早期版本中一直沿用。docker compose
:它是Docker 19.03版本及以后引入的新用法,将Docker Compose功能集成到了Docker命令行工具中,作为一个子命令使用。因此,使用docker compose
命令时,不需要单独安装docker-compose可执行文件。这种方式提供了更好的集成和用户体验,是Docker官方推荐的新用法。
安装 docker-compose(Overview of installing Docker Compose):
# 下载docker-compose文件
curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose# 赋予一个执行权限
chmod +x /usr/local/bin/docker-compose# 验证是否安装成功
docker-compose -version
5、Docker Compose 使用步骤
- 第一步,编写Dockerfile,定义各个微服务应用并构建出对应的镜像文件
- 第二步,使用docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。
- 第三步,执行
docker-compose up
命令来启动并运行整个应用程序,完成一键部署上线
6、Docker Compose 基础命令
[root@localhost ~]# docker compose --helpUsage: docker compose [OPTIONS] COMMANDDefine and run multi-container applications with DockerOptions:--all-resources 包括所有资源,即使它们没有被服务使用。--ansi string 控制何时打印 ANSI 控制字符("never"|"always"|"auto")。 (default "auto")--compatibility 以向后兼容模式运行 Compose。--dry-run 以干运行模式执行命令,即不实际执行,只显示将会执行的操作--env-file stringArray 指定一个替代的环境文件。-f, --file stringArray Compose 配置文件。你可以指定一个或多个配置文件。--parallel int 控制最大并行度,-1 表示无限制。 (default -1)--profile stringArray 指定要启用的配置文件。--progress string 设置进度输出的类型(auto, tty, plain, quiet)。 (default "auto")--project-directory string 指定一个替代的工作目录。 (default: the path of the, first specified, Compose file)-p, --project-name string 项目名称。Commands:attach 将本地标准输入、输出和错误流附加到服务的运行容器上。build 构建或重新构建服务。config 解析、解析并呈现 Compose 文件的标准格式。cp 在服务容器和本地文件系统之间复制文件/文件夹。。create 为服务创建容器。down 停止并删除容器、网络。events 从容器中接收实时事件。exec 在运行的容器中执行命令。images 列出由创建的容器使用的镜像。kill 强制停止服务容器。logs 查看容器的输出日志。ls 列出正在运行的 Compose 项目。pause 临时停止服务的运行,而不删除容器。port 打印端口绑定的公共端口。ps 列出容器。pull 拉取服务镜像。push 推送服务镜像。restart 重启服务容器。rm 移除停止的服务容器。run 在服务上运行一次性命令。scale 扩展服务。 start 启动服务。stats 实时显示容器的资源使用情况统计信息。stop 停止服务。top 显示正在运行的进程。unpause 取消暂停服务。up 创建并启动容器。version 显示 Docker Compose 版本信息。wait 阻塞直到第一个服务容器停止。watch 监视服务构建上下文,并在文件更新时重建/刷新容器。Run 'docker compose COMMAND --help' for more information on a command.
十五、实战
1、tomcat 搭建
# 1、创建并启动容器,本地没有tomcat镜像的会自动去拉,不需要使用docker pull手动去获取镜像
docker run -d -p 8080:8080 --name tomcat tomcat# 2、查看是否启动成功
docker ps# 3、修改tomcat webapps,最新版本(10+)的webapps是个空目录
docker exec -it tomcat cp -r /usr/local/tomcat/webapps.dist /usr/local/tomcat/webapps# 4、访问 tomcat
curl locahost:8080
2、MySQL 部署
# 1、创建目录,用来数据卷挂载
mkdir -p /app/mysql/log /app/mysql/data /app/mysql/conf# 2、修改配置文件my.cnf
cat << EOF >/app/mysql/conf/my.cnf
[client]
default_character set=utf8
[mysqld]
collation_server = utf8_general_ci
character set_server = utf8
EOF# 3、创建容器,挂载数据卷以防止容器误删导致数据丢失
docker run -d -p 3307:3306 --privileged=true \
-v /app/mysql/log:/var/log/mysql \
-v /app/mysql/data:/var/lib/mysql \
-v /app/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql mysql:5.7
后续登陆MySQL操作:
# 1、进入容器
docker exec -it mysql /bin/bash# 2、登陆MySQL,密码为上述设置的123456
mysql -uroot -p# 3、查看字符集,防止中文插入失败
SHOW VARIABLES LIKE 'character%'
3、Redis 部署
# 1、创建目录,用于数据卷挂载
mkdir -p /app/redis/data /app/redis/conf# 2、修改配置文件
cat << EOF >/app/redis/conf/redis.conf
port 6379
bind 0.0.0.0
daemonize no
appendonly yes
EOF # 3、创建并启动容器
docker run -d -p 6379:6379 --name redis \
-v /app/redis/data:/data \
-v /app/redis/conf/redis.conf:/etc/redis/redis.conf \
redis redis-server /etc/redis/redis.conf
4、MySQL 主从复制
MySQL数据库为最新版本(9.2),不同版本的MySQL配置以及源配置等操作不太一致,建议对照官方文档 Chapter 19 Replication 食用。
# 1.创建目录,用于数据卷挂载
mkdir -p /app/mysql-master/log /app/mysql-master/data /app/mysql-master/conf /app/mysql-slave/log /app/mysql-slave/data /app/mysql-slave/conf# 2.修改配置文件,后续修改需重启服务 `docker restart mysql-master`
cat << EOF >/app/mysql-master/conf/my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101
## 开启二进制日志功能
log-bin=mysql-bin
EOF cat << EOF >/app/mysql-slave/conf/my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 配置中继日志
relay_log=relay-bin
## slave设置为只读(具有super权限的用户除外)
read_only=1
##指定不需要同步的数据库名称
binlog-ignore-db=mysgl
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mysgl-slave1-bin
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
replica_skip_errors=1062
## slave将复制事件写进自己的二进制日志
log_replica_updates=1
EOF# 3.新建主服务器容器实例3307
docker run -p 3307:3306 --name mysql-master --privileged=true \
-v /app/mysql-master/log:/var/log/mysql \
-v /app/mysql-master/data:/var/lib/mysql \
-v /app/mysql-master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql# 4.主库:进入mysql-master容器
docker exec -it mysql-master /bin/bash
mysql -uroot -p# 5.主库:master容器实例内创建数据同步用户
mysql> CREATE USER 'slave'@'%'IDENTIFIED BY'123456';
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
mysql> FLUSH PRIVILEGES;
mysql> SHOW CREATE USER 'slave'@'%';# 6.主库:获取主数据库二进制日志坐标(File、Position)
mysql> SHOW BINARY LOG STATUS \G# 7.新建从服务器容器实例3308
docker run -p 3308:3306 --name mysql-slave --privileged=true \
-v /app/mysql-slave/log:/var/log/mysql \
-v /app/mysql-slave/data:/var/lib/mysql \
-v /app/mysql-slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql# 8.进入mysql-slave容器
docker exec -it mysql-slave /bin/bash
mysql -uroot -p# 9.在从数据库中配置主从复制
mysql> CHANGE REPLICATION SOURCE TOSOURCE_HOST='192.168.88.88',SOURCE_PORT=3307,SOURCE_USER='slave',SOURCE_PASSWORD='123456',SOURCE_LOG_FILE='mysql-bin.000003',SOURCE_LOG_POS=123,GET_SOURCE_PUBLIC_KEY=1;# 12.在从数据库中开启主从同步
mysql> start replica;# 13.查看从数据库状态发现已经同步,此时 Slave_IO_Running、Slave_SQL_Running 这两个参数均为 Yes
mysql> show replica status \G# 14.主从复制测试,在主数据库新建库等操作
报错:Error connecting to source 'slave@192.168.160.129:3307'. This was attempt 1/10, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
错误信息显示从库无法连接到主库,原因为caching_sha2_password需要安全连接。由于MySQL 8.x默认使用此插件,可能未正确配置用户认证或SSL设置。
You can do this using either the SOURCE_PUBLIC_KEY_PATH option or the GET_SOURCE_PUBLIC_KEY=1 option for this statement.
5、Redis集群
# 1、创建自定义网络
docker network create redis --subnet 172.38.0.0/16# 2、创建六个Redis配置文件
for port in $(seq 1 6); \
do \
mkdir -p /app/redis/node-${port}/conf /app/redis/node-${port}/data
touch /app/redis/node-${port}/conf/redis.conf
cat << EOF >/app/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
# 启用Redis的集群模式
cluster-enabled yes
# 指定集群节点的配置文件名称。
# nodes.conf是集群节点自动生成的配置文件,用于存储集群的状态信息,如节点ID、槽分配、主从关系等。该文件通常位于Redis的工作目录中。
cluster-config-file nodes.conf
# 设置集群节点间的超时时间(以毫秒为单位)
cluster-node-timeout 5000
# 设置集群节点向其他节点宣布的IP地址
cluster-announce-ip 172.38.0.1${port}
# 设置集群节点向其他节点宣布的端口号
cluster-announce-port 6379
# 设置集群节点间用于集群总线通信的端口号
cluster-announce-bus-port 16379
# 持久化
appendonly yes
EOF
done# 3、启动Redis容器
for port in $(seq 1 6); \
do \
docker run -d --name redis-${port} \
--privileged=true \
-v /app/redis/node-${port}/data:/data \
-v /app/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
--network redis --ip 172.38.0.1${port} redis
-p 637${port}:6379 -p 1637${port}:16379 \
redis-server /etc/redis/redis.conf
done# 4、创建集群
docker exec -it redis-1 /bin/sh
redis-cli --cluster create --cluster-replicas 1 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379
二十、资料
- 狂神-Docker基础
- Docker基础(狂神说Docker课程笔记)同类第二篇 --转载
- Docker网络原理