Docker入门(Windows)

视频链接Docker | 狂神说

环境说明

Windows For Docker + WSL2

概念

Docker是什么?

百度百科:百度百科

Docker 是一个开源的平台,它利用操作系统级虚拟化技术来打包和运行应用程序。通过使用容器化技术,Docker 提供了一种标准化的方式,在任何环境中一致地部署、管理和扩展应用程序。

Docker架构图
  • **Docker 客户端(Docker Client)**是用户与 Docker 守护进程(Docker Daemon)进行交互的主要工具。它通常指的是命令行界面(CLI),但也可以指其他形式的客户端,如图形用户界面(GUI)、编程语言的 SDK 或者 REST API 客户端。Docker 客户端发送指令给守护进程来管理镜像、容器、网络和卷等资源。

  • DOCKER_HOST 是一个环境变量,用于指定 Docker 客户端连接到哪个 Docker 守护进程(Docker daemon)。通过设置 DOCKER_HOST,你可以控制 Docker 命令行工具(CLI)或 SDK 连接到本地或远程的 Docker 守护进程。这对于管理多个 Docker 环境、跨机器部署容器或者在没有直接安装 Docker 的机器上执行 Docker 操作非常有用。

  • Docker 守护进程(Docker Daemon),通常简称为 Docker daemon 或 dockerd,是 Docker 架构中的核心组件之一。它是一个常驻后台的进程,负责管理 Docker 对象如镜像、容器、网络和卷等。守护进程监听来自 Docker 客户端(CLI 或其他 API 客户端)的请求,并执行相应的操作,例如创建、启动、停止或删除容器。

  • Docker 容器是基于 Docker 镜像创建的运行实例,它提供了一个轻量级、可移植且自包含的环境来运行应用程序。容器将应用程序与其依赖项打包在一起,确保其在任何环境中都能一致地运行。每个容器都是独立的,拥有自己的文件系统、网络栈和进程空间,从而实现了良好的隔离性。

  • Docker 镜像是一个轻量级、独立且可执行的软件包,它包含了运行某个应用程序所需的一切:代码、运行时环境、库、环境变量和配置文件。镜像是构建容器的基础,每个容器都是从镜像启动的一个实例。Docker 镜像使得开发者可以在任何环境中一致地部署应用,确保了“在我的机器上能正常工作”的问题不再出现。

  • Docker Registry 是一个存储和分发 Docker 镜像的服务。它允许用户上传(推送)他们构建的镜像,并从中下载(拉取)镜像用于部署或进一步开发。Docker Registry 可以是公共的,如 Docker Hub,也可以是私有的,供组织内部使用。通过 Registry,团队可以更方便地管理和共享容器化应用程序。

在这里插入图片描述

Docker主要组成部分

1. Docker 客户端 (Docker CLI)

  • 定义:这是用户与 Docker 守护进程(Docker Daemon)进行交互的主要工具。它通常指的是命令行界面(CLI),但也可以指其他形式的客户端,如图形用户界面(GUI)、编程语言的 SDK 或 REST API 客户端。
  • 功能
    • 发送指令给守护进程以管理镜像、容器、网络和卷等资源。
    • 提供丰富的命令集来执行各种操作,如构建 (docker build)、推送 (docker push)、拉取 (docker pull) 镜像,启动 (docker run)、停止 (docker stop) 容器等。

2. Docker 守护进程 (Docker Daemon)

  • 定义:Docker Daemon 是一个常驻后台的进程,负责管理 Docker 对象如镜像、容器、网络和卷等。它监听来自 Docker 客户端的请求,并执行相应的操作。
  • 功能
    • 管理镜像、容器、网络和卷的生命周期。
    • 提供 RESTful API 接口,允许第三方工具和服务与 Docker 进行交互。
    • 使用 Linux 控制组(cgroups)和命名空间(namespaces)来为容器设置资源限制,确保良好的隔离性和安全性。

3. Docker 注册表 (Docker Registry)

  • 定义:这是一个存储和分发 Docker 镜像的服务。它可以是公共的,如 Docker Hub,也可以是私有的,供组织内部使用。
  • 功能
    • 存储由开发者构建的 Docker 镜像,以便可以在不同环境中重复使用。
    • 支持对镜像进行标签(tags)管理,帮助追踪不同版本的应用程序。
    • 提供权限管理机制,确保只有授权用户才能推送或拉取特定镜像。

4. Docker 镜像 (Image)

  • 定义:Docker 镜像是一个轻量级、独立且可执行的软件包,它包含了运行某个应用程序所需的一切:代码、运行时环境、库、环境变量和配置文件。
  • 特点
    • 不可变性:一旦创建,镜像内容不能被修改;如果需要更新,则需基于现有镜像创建新的镜像。
    • 分层存储:镜像由多个只读层(layers)组成,每一层代表镜像的一个特定状态或更改。
    • 标准化:通过 Dockerfile 定义如何构建一个镜像,这为应用程序提供了一种标准化的打包方式。

5. Docker 容器 (Container)

  • 定义:容器是从镜像创建的运行实例。它提供了一个轻量级、可移植且自包含的环境来运行应用程序。
  • 特点
    • 隔离性:每个容器都在自己的命名空间中运行,拥有独立的文件系统、进程 ID、用户 ID 和网络接口。
    • 轻量化:容器共享宿主机的操作系统内核,因此比虚拟机更轻量,启动速度更快,并且占用较少的资源。
    • 可移植性:由于容器包含了应用程序及其所有依赖项,所以可以在不同的环境中无缝迁移。

6. Docker Compose

  • 定义:Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件(docker-compose.yml),你可以配置应用程序的服务,并使用一条命令启动所有服务。
  • 功能
    • 定义多个服务之间的关系和依赖。
    • 简化了复杂应用的部署流程,特别是对于微服务架构的应用。

7. Docker Swarm

  • 定义:Docker 自带的集群管理和编排工具,可以管理多个 Docker 主机组成的集群。
  • 功能
    • 创建和管理 Docker 节点集群。
    • 实现服务的自动发现、负载均衡和服务扩展。

8. Docker 网络 (Networking)

  • 定义:Docker 提供了多种网络驱动来管理容器之间的通信以及容器与外部世界的连接。
  • 类型
    • 桥接网络(Bridge Network):默认情况下,容器连接到一个名为 bridge 的网络。
    • 主机网络(Host Network):容器直接使用宿主机的网络栈。
    • 覆盖网络(Overlay Network):用于跨多个 Docker 守护进程的容器之间通信。

9. Docker 卷 (Volume)

  • 定义:卷是 Docker 中用于持久化数据的一种机制。它们提供了独立于容器生命周期的数据存储方式。
  • 功能
    • 持久化容器内的数据,即使容器被删除,数据仍然保留。
    • 共享数据:允许多个容器访问同一个卷中的数据。

10. Docker 插件 (Plugins)

  • 定义:插件用于扩展 Docker 的核心功能,例如添加新的网络驱动、卷驱动或其他特性。
  • 功能
    • 增强 Docker 的功能,使其更加灵活和强大。

安装教程(Windows11)

安装步骤:

  1. 打开PowerShell作为管理员:可以通过在开始菜单中搜索PowerShell,然后右键点击它并选择“以管理员身份运行”。

  2. 启用WSL2 和 虚拟机平台

    • 在PowerShell中执行以下命令:
      C:\Windows\System32\dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
      C:\Windows\System32\dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestar
      
  3. 重启计算机:重启计算机使上述更改生效。

  4. 设置默认的WSL版本为2

    • 在PowerShell中输入并执行:
      wsl --set-default-version 2
      
  5. 下载并安装Docker Desktop:访问Docker官网下载适用于Windows的Docker Desktop安装程序并安装。

    在这里插入图片描述

  6. 启动Docker Desktop:安装完成后,启动Docker Desktop并根据提示完成设置。

  7. 查看Docker是否正常运行:

    docker --version
    docker run hello-world
    

可自行配置阿里云镜像加速器

问题解决:

解决镜像不能下载问题:

windows 安装docker_windows docker下载-CSDN博客

Docker Hub访问不了:

我出现这个问题,排查了半天,发现是加速器问题

我下载的是这个:apnetwork

使用教程

命令文档:https://docs.docker.com/reference/

常用命令:

docker --version #显示docker版本信息

docker --info # 显示docker的系统信息,包括镜像和容器数量

docker --help # 帮助命令

docker 命令 --help # 帮助命令

镜像命令

官方文档:Docker image

在这里插入图片描述

docker images ls

PS C:\Users\Lenovo> docker images      
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    d2c94e258dcb   20 months ago   13.3kB

### 输出解释
REPOSITORY 	镜像的仓库源    
TAG         镜像的标签
IMAGE ID    镜像的id
CREATED     镜像的创建时间
SIZE		镜像的大小

### 可选项
  -a, --all             # 列出所有镜像(包括悬空和未标记的镜像)
      --digests         #显示摘要信息(Digests)
  -f, --filter filter   #根据提供的条件过滤输出
      --format string   #使用自定义模板格式化输出:
                        'table':            以表格格式打印输出,并包含列标题(默认)
                        'table TEMPLATE':   使用给定的 Go 模板以表格格式打印输出
                        'json':             以 JSON 格式打印输出
                        'TEMPLATE':         使用给定的 Go 模板打印输出
                        #关于使用模板格式化输出的更多信息,请参阅 https://docs.docker.com/go/formatting/
      --no-trunc        #不截断输出(显示完整信息)
  -q, --quiet           #只显示镜像 ID
      --tree            #以树状结构列出多平台镜像(实验性功能)

常用命令:

docker image ls : 查看全部镜像

docker search 镜像 : 查找

docker pull 镜像:下载镜像( docker image pull | Docker Docs

docker rmi : 删除镜像

容器命令

注意:必须先下载镜像,才能运行容器

下载镜像
docker pull centos
新建容器并启动

官方文档:docker run

docker run [可选参数] image
# 参数说明
 --name="Name" 		容器名字
 -d 				后台方式运行,ja nohup
 -it				使用交互方式运行,进入容器查看内容
 -p					指定容器的端口
 	-p ip:主机端口:容器端口
 	-p 主机端口:容器端口(常用)
 	-p 容器端口
 	容器端口
 -P 				随机指定端口
 
启动并进入容器
docker run -it centos /bin/bash
查看运行中的容器
docker ps


#docker ps命令
-a # 列出当前正在运行的容器+历史运行过的容器
-n=? #显示最近创建的容器(?是表示显示几个)
-q #只显示容器的编号


查看曾经运行过的容器
docker ps -a
退出容器
exit #直接停止容器并退出到主机

Ctrl + P + Q #容器不停止退出
删除容器
docker rm 容器id  #删除指定容器,不能删除正在运行的容器

docker rm -f $(docker ps -aq) #删除所有容器

docker ps -a -q|xargs docker rm #删除所有容器
启动容器
docker start 容器id
重启容器
docker restart 容器id
停止容器
docker stop 容器id #停止当前正在运行的容器

docker kill 容器id #强制停止当前容器

常用其他命令:

后台启动
docker run -d centos /bin/bash

问题:通过后台启动容器,发现centos停止了

答案: docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止(即使有前台进程,例如nginx,如果nginx启动后发现没有提供服务,也会立刻停止,就是没有程序了)

查看日志
docker logs

### 输出结果
PS C:\Users\Lenovo> docker logs"docker logs" requires exactly 1 argument.
See 'docker logs --help'.

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

### 可选
Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g.
                       "2013-01-02T13:23:37Z") or relative (e.g. "42m"
                       for 42 minutes)
  -n, --tail string    Number of lines to show from the end of the logs
                       (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g.
                       "2013-01-02T13:23:37Z") or relative (e.g. "42m"
                       for 42 minutes)

docker logs -f -t --tail number 容器id

### 问题
发现没有日志输出:
	--自己编写shell脚本:	
	 	(1)docker run -d centos /bin/sh -c 脚本
		(2)docker logs -f -t --tail number 容器id
						
查看容器中进程信息
docker top 容器id
查看镜像元数据
docker inspect 容器id
###PS C:\Users\Lenovo> docker inspect d2a4619249c5
[
    {
        "Id": "d2a4619249c5e16fbca3d5ec3f63511ae09d2fa31fa9f37f06b024587eb4fe1a",
        "Created": "2025-01-24T07:02:52.721200131Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo happy;sleep 1;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 1731,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2025-01-24T07:02:52.86930599Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/d2a4619249c5e16fbca3d5ec3f63511ae09d2fa31fa9f37f06b024587eb4fe1a/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/d2a4619249c5e16fbca3d5ec3f63511ae09d2fa31fa9f37f06b024587eb4fe1a/hostname",
        "HostsPath": "/var/lib/docker/containers/d2a4619249c5e16fbca3d5ec3f63511ae09d2fa31fa9f37f06b024587eb4fe1a/hosts",
        "LogPath": "/var/lib/docker/containers/d2a4619249c5e16fbca3d5ec3f63511ae09d2fa31fa9f37f06b024587eb4fe1a/d2a4619249c5e16fbca3d5ec3f63511ae09d2fa31fa9f37f06b024587eb4fe1a-json.log",
        "Name": "/determined_hypatia",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "bridge",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "ConsoleSize": [
                13,
                106
            ],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": [],
            "BlkioDeviceWriteBps": [],
            "BlkioDeviceReadIOps": [],
            "BlkioDeviceWriteIOps": [],
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": [],
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware",
                "/sys/devices/virtual/powercap"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/accb45a7ce8467253f6aadfb117c44d99501cc5913e2bcc6685e3a32f62c1c84-init/diff:/var/lib/docker/overlay2/a1d31160bfdf442acdb6d93c031a2e754585228a3d4d88da74a1f9b8d0f73e5a/diff",
                "MergedDir": "/var/lib/docker/overlay2/accb45a7ce8467253f6aadfb117c44d99501cc5913e2bcc6685e3a32f62c1c84/merged",
                "UpperDir": "/var/lib/docker/overlay2/accb45a7ce8467253f6aadfb117c44d99501cc5913e2bcc6685e3a32f62c1c84/diff",
                "WorkDir": "/var/lib/docker/overlay2/accb45a7ce8467253f6aadfb117c44d99501cc5913e2bcc6685e3a32f62c1c84/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "d2a4619249c5",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true;do echo happy;sleep 1;done"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "a824215687398e1c83cb35ac6341854de3d091b7a496de0ad9f2d91f385337ca",
            "SandboxKey": "/var/run/docker/netns/a82421568739",
            "Ports": {},
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "4dca6640fa35ab2c50740577fe9306ac82a749d06a43f6bb744a975db085395a",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null,
                    "NetworkID": "dd25f4f3216eeedd203889d3e347fc0baea75b53caa9de5af771e11c49353c09",      
                    "EndpointID": "4dca6640fa35ab2c50740577fe9306ac82a749d06a43f6bb744a975db085395a",     
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DNSNames": null
                }
            }
        }
    }
]
进入当前正在运行的容器
#docker exec -it 容器id bashShell
#docker attach 容器id

区别:

– docker exec : 进入容器后开启一个新的终端,可以在里面操作
– docker attach : 进入容器正在执行的终端,不会启动新的进程

# 通常容器是以后台方式运行的,若想要进入容器修改配置

### 方式一:
PS C:\Users\Lenovo> #docker ps        
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS     NAMES
d2a4619249c5   centos    "/bin/sh -c 'while t…"   17 minutes ago   Up 17 minutes             determined_hypatia
PS C:\Users\Lenovo> #docker exec -it d2a4619249c5 /bin/bash
[root@d2a4619249c5 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var


### 方式二:
PS C:\Users\Lenovo> #docker attach d2a4619249c5    
正在执行当前代码
从容器内拷贝文件到主机上

[!IMPORTANT]

docker cp 容器id:容器内路径 目的主机路径
PS C:\Users\Lenovo\test> #docker cp 0fb7995c2965:/home/test.java ./    
Successfully copied 1.54kB to C:\Users\Lenovo\test\.\

小结

在这里插入图片描述

# 常用命令
run         # 从镜像创建并运行一个新的容器
exec        # 在运行中的容器中执行命令
ps          # 列出所有容器
build       # 从Dockerfile构建镜像
pull        # 从仓库下载镜像
push        # 将镜像上传到仓库
images      # 列出镜像
login       # 登录到仓库进行认证
logout      # 从仓库登出
search      # 在Docker Hub中搜索镜像
version     # 显示Docker版本信息
info        # 显示系统范围的信息

# 管理命令
ai*         # 向Gordon提问 - Docker代理(注:此条目可能是特定环境下的自定义命令)
builder     # 管理构建过程
buildx*     # Docker Buildx(用于高级构建功能)
compose*    # Docker Compose(用于多容器应用的编排)
container   # 容器管理
context     # 上下文管理
debug*      # 进入任何镜像或容器的shell进行调试
desktop*    # Docker Desktop相关命令(测试版)
dev*        # Docker开发环境
extension*  # 管理Docker扩展
feedback*   # 在终端内直接提供反馈
image       # 镜像管理
init*       # 创建与Docker相关的项目启动文件
manifest    # 管理Docker镜像清单和清单列表
network     # 网络管理
plugin      # 插件管理
sbom*       # 查看基于包的软件物料清单(SBOM)对于一个镜像
scout*      # Docker Scout(具体用途未知,可能为特定服务或工具)
system      # Docker系统管理
trust       # 管理Docker镜像的信任
volume      # 卷管理

# Swarm命令
swarm       # 管理Swarm集群

# 其他命令
attach      # 将本地标准输入、输出和错误流附加到正在运行的容器
commit      # 根据容器的更改创建新的镜像
cp          # 在容器和本地文件系统之间复制文件/文件夹
create      # 创建一个新的容器但不启动它
diff        # 检查容器文件系统中文件或目录的变化
events      # 获取服务器的实时事件
export      # 将容器的文件系统导出为tar归档文件
history     # 显示镜像的历史
import      # 从tarball导入内容以创建文件系统镜像
inspect     # 返回Docker对象的低级信息
kill        # 终止一个或多个正在运行的容器
load        # 从tar归档文件或STDIN加载镜像
logs        # 获取容器的日志
pause       # 暂停一个或多个容器内的所有进程
port        # 列出容器的端口映射,或指定映射
rename      # 重命名容器
restart     # 重启一个或多个容器
rm          # 移除一个或多个容器
rmi         # 移除一个或多个镜像
save        # 将一个或多个镜像保存为tar归档文件(默认情况下流向STDOUT)
start       # 启动一个或多个已停止的容器
stats       # 显示容器资源使用情况的实时流
stop        # 停止一个或多个正在运行的容器
tag         # 创建指向SOURCE_IMAGE的新标签TARGET_IMAGE
top         # 显示容器中运行的进程
unpause     # 解除暂停一个或多个容器内的所有进程
update      # 更新一个或多个容器的配置
wait        # 阻塞直到一个或多个容器停止,然后打印它们的退出代码

# 全局选项
--config string      # 客户端配置文件的位置 (默认 "C:\\Users\\Lenovo\\.docker")
-c, --context string # 使用连接到守护程序的上下文名称 (覆盖DOCKER_HOST环境变量和默认上下文)
-D, --debug          # 启用调试模式
-H, --host list      # 要连接的守护程序套接字
-l, --log-level string   # 设置日志级别 ("debug", "info", "warn", "error", "fatal") (默认 "info")
--tls                # 使用TLS;由--tlsverify隐含
--tlscacert string   # 仅信任由该CA签名的证书 (默认 "C:\\Users\\Lenovo\\.docker\\ca.pem")
--tlscert string     # TLS证书文件路径 (默认 "C:\\Users\\Lenovo\\.docker\\cert.pem")
--tlskey string      # TLS密钥文件路径 (默认 "C:\\Users\\Lenovo\\.docker\\key.pem")
--tlsverify          # 使用TLS并验证远程方
-v, --version        # 打印版本信息并退出

部署Nginx

# 1.搜索镜像 search 建议去docker hub
# 2.下载镜像 docker pull nginx
# 3.运行 docker run -d --name nginx01 -p 3344:80 nginx
# 4.测试 http://localhost:3344/
# 5.进入容器:docker exec -it nginx01 /bin/bash

可以访问到你所部署的nginx服务器(windows访问步骤):

1.查看本机ip地址:以管理员身份打开命令行工具,输入

ipconfig

2.在浏览器中搜索:http://本机ip地址:3344/ 即可访问到nginx

解释:

docker run -d --name nginx01 -p 3344:80 nginx

当docker中的nginx01运行起来,本地就相当于一个服务器,端口为3344,那么就意味着在任何一台设备中,通过ip地址可以找到本机(服务器),通过端口映射可以找到docker中的nginx

部署Tomcat

# 官方的使用
docker run -it --rm tomcat:9.0

#我们之前的启动都是后台,停止了容器之后,容器还是可以查到 docker run -it --rm 一般用来测试,用完就删除

# 下载在启动
docker pull tomcat:9.0

# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0

#测试访问没有问题
http://本机ip地址:3355/

# 进入容器
docker exec -it tomcat01 /bin/bash

# 发现问题:1.Linux命令少了 2.没有webapps 阿里云镜像的原因。默认最小的镜像,所有的不必要的都剔除掉。
# 保证最小可运行环境
# 解决方法:将webapps.dist目录下的所有文件复制到webapps目录下
root@b532969c54d6:/usr/local/tomcat/webapps.dist# cp -r * ../webapps/

在这里插入图片描述

curl工具下载

#步骤 1:安装 Chocolatey
	-- 以管理员身份打开 PowerShell:
    -- 按 Win + X 键,选择 Windows PowerShell (管理员) 或 终端 (管理员)。
	-- 运行以下命令来安装 Chocolatey:

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

#步骤 2:使用 Chocolatey 安装 curl
choco install curl -y

# 步骤3:将curl.exe添加到环境变量

在这里插入图片描述

#步骤3:验证安装:
	-- 关闭并重新打开 PowerShell 窗口,然后运行:
curl.exe --version

可视化

  • portainer(先用这个)

    (powershell中的换行符是反引号)

    docker run -d -p 8088:9000 `
        --restart=always `
        -v /var/run/docker.sock:/var/run/docker.sock `
        --privileged=true `
        portainer/portainer
    
  • Rancher

portainer

什么是portainer?

Docker图形化界面管理工具!提供一个后台面板供我们操作!

在这里插入图片描述

访问链接:http://本机ip地址:8088/

Docker镜像讲解

镜像是什么?

指的是一个轻量级、独立且可执行的软件包,包含运行某个应用或服务所需的所有内容,包括代码、运行时环境、系统工具、库和设置等

所有的应用,直接打包成为一个Docker镜像,就可以直接跑起来!

如何得到镜像?
  1. 从远程仓库下载
  2. 拷贝
  3. 自己制作镜像
Docker镜像加载原理

Docker镜像加载原理主要基于联合文件系统(UnionFS)和分层存储技术。

Docker的镜像实际上由一层一层的文件系统组成。

Docker镜像的基本概念

一个Docker镜像是由多个只读层组成的,每一层代表了镜像的一个变更。这些层是叠加在一起的,形成最终的文件系统视图。当创建一个新的容器时,会在镜像的顶层添加一个可写的层,所有对容器的修改都会在这个可写层中进行。

联合文件系统(UnionFS)

Docker使用了一种称为联合文件系统的技术来实现镜像的分层结构。联合文件系统允许将多个目录合并成一个单一的虚拟文件系统。在Docker中,每个镜像层都是这个虚拟文件系统中的一个独立层,它们可以被不同的容器共享。

分层结构
  1. bootfs(boot file system):这是Docker镜像的最底层,包含了引导加载器(bootloader)和内核(kernel)。当启动容器时,bootfs会被加载到内存中,并且一旦内核被加载完毕,bootfs就会被卸载以释放资源。所有的镜像都共享这一层。

  2. rootfs(root file system):位于bootfs之上,包含了一个典型Linux系统中的标准目录和文件,如/dev, /proc, /bin, /etc等。rootfs可以根据不同的操作系统发行版有所不同,比如Ubuntu、CentOS等。

镜像加载过程

在这里插入图片描述

当Docker需要加载一个镜像时,它会执行以下步骤:

  1. 查找镜像:首先,Docker会在本地的镜像仓库中查找该镜像。如果找不到,则会去远程的镜像仓库(例如Docker Hub)查找并下载镜像。

  2. 下载镜像:如果镜像不在本地,Docker会从远程仓库下载镜像。由于镜像是分层的,所以下载也是按层进行的。如果某些层已经存在于本地,则不会重复下载。

  3. 加载镜像:下载完成后,Docker会将镜像的各个层解压并存储在Docker的存储驱动中。然后,根据这些层构建出完整的文件系统视图。

  4. 创建容器:当创建容器时,Docker会在镜像的最上层添加一个可写的层。这个可写层允许容器运行时进行修改,而不会影响到底层的镜像层。

分层的好处
  • 资源共享:由于镜像层是可以共享的,因此多个容器可以共享同一基础镜像的不同层,节省磁盘空间。
  • 快速部署:因为只需要传输发生变化的部分,所以镜像的传输速度更快,部署也更迅速。
  • 版本控制:镜像层的变化可以看作是一次提交,这使得我们可以轻松地回滚到之前的某个状态。
存储引擎

为了管理镜像层的堆栈并保证多镜像层对外展示为统一的文件系统,Docker使用了不同的存储引擎。常见的存储引擎包括AUFS、Overlay2、Device Mapper、Btrfs以及ZFS等。每种存储引擎都有其特定的性能特点和适用场景。

实际操作示例

当你使用命令docker pull ubuntu下载一个名为ubuntu的镜像时,实际上是在下载多个镜像层。每个镜像层可能对应着操作系统的基础部分、软件包安装、配置文件等。下载完成后,你可以使用docker images查看已有的镜像列表,并用docker run命令基于这些镜像创建新的容器实例。

通过docker image inspect <image_name>命令,你可以查看镜像的具体信息,包括它的层结构等细节。

commit镜像

[!IMPORTANT]

docker commit 提交容器成为一个新的副本

# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

实战测试

# step1:运行tomcat镜像
docker run -it -p 8080:8080 tomcat:9.0
# step2:进入容器内部,修改配置文件
docker exec -it 容器id /bin/bash
root@b7b1b360aaa9:/usr/local/tomcat# cp -r webapps.dist/* webapps
# step3:通过commit提交镜像
docker commit -a="kkkwang2" -m="add webapps application" b7b1b360aaa9 tomcat02:1.0

PS C:\Users\Lenovo> docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
tomcat02              1.0       2ab0c1a9784f   9 seconds ago   487MB

容器数据卷

什么是容器数据卷(Volume)?

在 Docker 中,数据卷是一种用于持久化存储数据的机制。它独立于容器的生命周期,即使容器被删除,数据卷中的数据依然存在。

数据卷容器是指专门用来管理数据卷的容器。通常,我们会创建一个专门的数据卷容器来挂载和共享数据卷,以便其他容器可以使用这些数据卷。

总结一句话:容器的持久化和同步操作,容器间也是可以数据共享的

使用数据卷
# 挂载 -v 数据卷
docker run -it -v .\test\test:/home centos /bin/bash 
    
# 查看容器详细信息
docker inspect 容器id

在这里插入图片描述

容器外和容器内挂载的目录内容保持同步

进一步测试:

  1. 将容器停止

  2. 修改主机内挂载目录内容

    在这里插入图片描述

  3. 开启容器

  4. 查看容器挂载目录内容

好处:我们修改只需要在本地修改即可,容器内会自动同步!

安装MySQL

下载SQLyog:

SQLyog下载教程

# 1.获取镜像
docker pull mysql:5.7
# 2.运行容器,需要做数据挂载
-d		后台运行
-p		端口映射
-v		卷挂载
-e		环境配置
--name	容器名字
docker run -d -p 3310:3306 -v .\test\test\mysql\conf:/etc/mysql/conf.d -v .\test\test\mysql\data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

# 启动成功后 在本地用SQLyog测试一下
# SQLyog-连接到服务器的3310 --- 3310和容器内的3306映射

# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok
# 容器删除,挂载到本地的数据卷依旧没有丢失,这就实现了数据持久化

在这里插入图片描述

具名挂载和匿名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

#查看所有卷的情况
docker volume ls
# 这种就是匿名挂载,我们 -v 只写了容器内的路径,没有写容器外的路径!

在这里插入图片描述

# 具名挂载
# 通过 -v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

在这里插入图片描述

# 查看卷信息
PS C:\Users\Lenovo> docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2025-02-05T06:20:38Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

如果是使用wsl的,在资源管理器中查找如下,就能快速找到数据卷存放地址了

\\wsl$\docker-desktop\mnt\docker-desktop-disk\data\docker\volumes

通过具名挂载可以方便找到卷

然后确定是具名挂载还是匿名挂载呢?

-v	容器内路径  		  #匿名挂载

-v 	卷名:容器内路径	#具名挂载

-v 	.\容器外路径:容器内路径 #指定路径挂载

拓展:

# 通过 -v 容器内路径:ro rw 可以改变读写权限
-ro readonly 只读
-rw readwrite 可读可写

# 一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了
# ro:挂载出来的文件内容只能通过宿主机来操作,容器内部是无法操作的
# rw:默认
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
DockerFile概述

Dockerfile 就是用来构建Docker镜像的构建文件,其实就是一段命令脚本,通过这个脚本可以生成镜像

镜像是一层一层的,脚本一个个的命令,每个命令都是一层

dockerfile1内容如下

# 使用官方 CentOS 镜像作为基础镜像
FROM centos:latest

# 定义卷
VOLUME ["/volume01", "/volume02"]

CMD echo "---end---"
# 默认命令:启动一个交互式的 bash shell
CMD ["/bin/bash"]

构建镜像

PS C:\Users\Lenovo\docker-home\docker-test-volume> # docker build -f .\dockerfile1 -t kkkwang2/centos:1.0 

在这里插入图片描述

在这里插入图片描述

测试自己写的镜像

docker run -it kkkwang2/centos:1.0 /bin/bash

在这里插入图片描述

在容器内挂载目录创建文件,看宿主机挂载目录有没有同步

在这里插入图片描述

成功同步!

数据卷容器

多个容器同步数据
在这里插入图片描述

测试

# 启动centos01
docker run -it --name centos01 kkkwang2/centos:1.0
# 启动centos02,并与centos02保持同步
docker run -it --name centos02 --volumes-from centos01 kkkwang2/centos:1.0
# 启动centos03,并与centos03保持同步
docker run -it --name centos03 --volumes-from centos01 kkkwang2/centos:1.0

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

centos03也自动同步了centos01和centos02里面的内容

在这里插入图片描述

删除centos01后,centos02和centos03依旧可以访问这个文件,并且centos02和centos03中的挂载目录下的内容保持同步

三个容器相当于挂载在宿主机的同一个目录下

多个mysql容器实现同步

# 启动mysql01
docker run -d -p 3310:3306 -v .\test\test\mysql\conf:/etc/mysql/conf.d -v .\test\test\mysql\data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

# 启动mysql02
docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

#mysql01与mysql02两个容器数据同步

在这里插入图片描述

数据卷容器的生命周期
  1. 创建数据卷容器

    • 这是数据卷容器的“出生”阶段。
    • 我们通过 docker createdocker run 命令创建一个容器,并指定要使用的数据卷。
    • 例如:
      docker create -v /volume01 --name data_container centos
      
      这里我们创建了一个名为 data_container 的容器,并定义了一个名为 /volume01 的数据卷。
  2. 使用数据卷容器

    • 创建好数据卷容器后,其他容器可以通过 --volumes-from 参数来挂载这个数据卷容器的数据卷。
    • 例如:
      docker run -it --rm --volumes-from data_container centos bash
      
      这个命令启动了一个新的容器,并从 data_container 挂载了 /volume01 数据卷。
  3. 读写数据

    • 在挂载了数据卷的容器中,你可以像操作普通文件系统一样读写数据卷中的文件。
    • 例如,在新启动的容器中,你可以执行以下命令来查看或修改 /volume01 目录下的文件:
      echo "Hello, World!" > /volume01/hello.txt
      cat /volume01/hello.txt
      
  4. 停止和删除容器

    • 当你停止并删除挂载了数据卷的容器时,数据卷本身不会被删除。
    • 例如:
      docker stop <container_id>
      docker rm <container_id>
      
      即使你删除了这些容器,data_container 中的数据卷仍然存在。
  5. 删除数据卷容器

    • 如果你不再需要数据卷容器及其数据卷,可以通过以下命令删除它们:
      docker rm -v data_container
      
      注意:-v 参数会同时删除未被其他容器使用的数据卷。
  6. 数据卷的持久性

    • 数据卷是独立于容器存在的,因此即使删除了所有使用该数据卷的容器,只要数据卷容器没有被删除,数据卷中的数据仍然保留。
    • 如果你希望手动删除某个数据卷,可以使用以下命令:
      docker volume rm <volume_name>
      

举个生活中的例子

想象一下你有一个带锁的保险箱(数据卷),而你有几个不同的房间(容器)。你把保险箱放在其中一个房间里(创建数据卷容器),然后你可以在其他房间里通过钥匙(--volumes-from)打开这个保险箱并存取东西(读写数据)。

  • 创建保险箱(数据卷容器):你买了一个保险箱并把它放在一个房间里。
  • 使用保险箱(挂载数据卷):你用钥匙打开保险箱,取出或存放物品。
  • 关闭房间(停止容器):你离开房间,但保险箱里的东西还在。
  • 删除房间(删除容器):即使你拆掉了房间,保险箱还在原地,里面的物品也不会丢失。
  • 删除保险箱(删除数据卷容器):如果你不再需要保险箱了,你可以选择彻底销毁它,这样里面的物品也会消失。

DockerFile

什么是Dockerfile?

Dockerfile 是一个文本文件,其中包含了构建 Docker 镜像所需的所有指令。这些指令按照特定的顺序排列,定义了如何从一个基础镜像开始,逐步构建出一个新的 Docker 镜像。每个指令会在镜像中创建一个新的层(layer),这些层组合在一起构成了最终的镜像。

通过编写 Dockerfile,开发者可以自动化地创建一致且可重复使用的环境,确保在不同的机器或平台上运行的应用程序具有相同的配置和依赖项。这极大地简化了应用程序的部署过程,并提高了开发、测试和生产环境之间的一致性。

dockerfile是面向开发的,我们以后开发项目就需要编写dockerfile文件

构建过程

基础知识:

  1. 每个保留关键字(指令)都必须是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个镜像层

在这里插入图片描述

在这里插入图片描述

  • DockerFile:构建文件,定义了一切步骤,源代码
  • DockerImages: 通过DockerFile构建生成的镜像,最终发布运行产品
  • Docker容器:容器就是运行起来提供服务器
Dockerfile文件

在这里插入图片描述

  1. FROM:指定基础镜像,必须是第一个非注释命令,格式为FROM <image>:<tag>
  2. LABEL:为生成的镜像添加元数据标签信息,如LABEL maintainer="admin@example.com"
  3. RUN:执行命令并创建新的镜像层,常用于安装软件包,例如RUN apt-get update && apt-get install -y vim
  4. CMD:提供启动容器时默认执行的命令和参数,但可以被docker run命令行参数覆盖。只能有一条CMD指令生效。
  5. EXPOSE:声明运行时容器提供服务的端口,如EXPOSE 80
  6. ENV:设置环境变量,在容器内可通过$VARIABLE引用,如ENV MY_NAME World
  7. ADD:从主机复制文件、目录或远程文件URL到容器中,并自动解压tar文件。
  8. COPY:类似于ADD,但不会自动解压缩文件或处理远程URLs。
  9. ENTRYPOINT:配置容器启动后执行的命令,并且不可被docker run命令行参数覆盖,适合用来构建不可改变的容器。
  10. VOLUME:创建一个挂载点,将主机或其他容器的一个目录共享给容器使用。
  11. USER:设置启动容器时使用的用户名或UID。
  12. WORKDIR:配置工作目录,后续的RUN, CMD, ENTRYPOINT命令都会在此目录下执行。
FROM		#基础镜像,一切从这里开始
MAINTAINER	#镜像是谁写的,姓名+邮箱
RUN 		#docker镜像构建的时候需要运行的命令
ADD 		#步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR 	#镜像的工作目录 
VOLUME 		#容器卷,挂载点目录位置
EXPOSE 		#暴露端口
RUN 		#运行
CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	#指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 	#当构建一个被继承DockerFile这个时候就会运行ONBUILD的指令,触发指令
COPY		#类似ADD,将我们文件拷贝到镜像中
ENV 		#构建的时候设置环境变量

练习:创建一个自己的centos

# 1.编写Dockerfile文件
FROM centos:7
MAINTAINER kkkwang2

ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && \
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum clean all && \
    yum makecache
    
RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash

# 2.通过这个文件构建镜像
# 命令:docker build -f dockerfile文件名 -t 镜像名:[TAG]
docker build -f mydockerfile-centos -t mycentos:7 .

#构建结果:
[+] Building 54.0s (9/9) FINISHED                                                      docker:desktop-linux
 => [internal] load build definition from mydockerfile-centos                                          0.0s
 => => transferring dockerfile: 482B                                                                   0.0s 
 => WARN: MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2)  0.0s 
 => WARN: LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" form  0.0s 
 => WARN: JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior rela  0.0s 
 => WARN: MultipleInstructionsDisallowed: Multiple CMD instructions should not be used in the same st  0.0s 
 => WARN: JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior rela  0.0s 
 => WARN: MultipleInstructionsDisallowed: Multiple CMD instructions should not be used in the same st  0.0s 
 => WARN: JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior rela  0.0s 
 => [internal] load metadata for docker.io/library/centos:7                                            0.0s
 => [internal] load .dockerignore                                                                      0.0s 
 => => transferring context: 2B                                                                        0.0s 
 #=> [1/5] FROM docker.io/library/centos:7                                                              0.0s 
 #=> CACHED [2/5] WORKDIR /usr/local                                                                    0.0s 
 #=> [3/5] RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup &&     c  44.7s 
 #=> [4/5] RUN yum -y install vim                                                                       6.9s 
 #=> [5/5] RUN yum -y install net-tools                                                                 1.4s 
 => exporting to image                                                                                 0.8s 
 => => exporting layers                                                                                0.8s 
 => => writing image sha256:9a26892417b26691cc04203f25da31f5f880d662bc0c8ba22ea7faf1e0faf093           0.0s 
 => => naming to docker.io/library/mycentos:7  

在这里插入图片描述

#测试

PS C:\Users\Lenovo\docker-home\dockerfile> docker run -it mycentos:7 /bin/bash
[root@98291ee0a2e9 local]# pwd
/usr/local
[root@98291ee0a2e9 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 9  bytes 1046 (1.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536        inet 127.0.0.1  netmask 255.0.0.0        inet6 ::1  prefixlen 128  scopeid 0x10<host>        loop  txqueuelen 1000  (Local Loopback)        RX packets 0  bytes 0 (0.0 B)        RX errors 0  dropped 0  overruns 0  frame 0        TX packets 0  bytes 0 (0.0 B)        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@98291ee0a2e9 local]# vim test
[root@98291ee0a2e9 local]#
# 查看镜像构建历史
# docker history 镜像

PS C:\Users\Lenovo\docker-home\dockerfile> docker history sha256:9a26892417b26691cc04203f25da31f5f880d662bc0c8ba22ea7faf1e0faf093
IMAGE          CREATED          CREATED BY                                       SIZE      COMMENT
9a26892417b2   8 minutes ago    CMD ["/bin/sh" "-c" "/bin/bash"]                 0B        buildkit.dockerfile.v0
<missing>      8 minutes ago    CMD ["/bin/sh" "-c" "echo \"---end---\""]        0B        buildkit.dockerfile.v0
<missing>      8 minutes ago    CMD ["/bin/sh" "-c" "echo $MYPATH"]              0B        buildkit.dockerfile.v0
<missing>      8 minutes ago    EXPOSE map[80/tcp:{}]                            0B        buildkit.dockerfile.v0
<missing>      8 minutes ago    RUN /bin/sh -c yum -y install net-tools # bu…   221MB     buildkit.dockerfile.v0
<missing>      8 minutes ago    RUN /bin/sh -c yum -y install vim # buildkit     276MB     buildkit.dockerfile.v0
<missing>      8 minutes ago    RUN /bin/sh -c mv /etc/yum.repos.d/CentOS-Ba…   532MB     buildkit.dockerfile.v0
<missing>      10 minutes ago   WORKDIR /usr/local                               0B        buildkit.dockerfile.v0
<missing>      10 minutes ago   ENV MYPATH=/usr/local                            0B        buildkit.dockerfile.v0
<missing>      10 minutes ago   MAINTAINER kkkwang2                              0B        buildkit.dockerfile.v0
<missing>      3 years ago      /bin/sh -c #(nop)  CMD ["/bin/bash"]             0B
<missing>      3 years ago      /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>      3 years ago      /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB
PS C:\Users\Lenovo\docker-home\dockerfile>
使用dockerfile构建镜像

[!IMPORTANT]

docker build -f dockerfile文件名 -t 镜像名:[TAG]

CMD和ENTRYPOINT的区别

  • CMD 提供容器启动时的默认命令及其参数,但可以被 docker run 命令覆盖。
  • ENTRYPOINT 配置容器启动时固定的可执行文件,并允许通过 docker run 传递额外参数来修改其行为。
实战:Tomcat镜像

1.准备镜像文件:tomcat压缩包、jdk压缩包

omcat:Tomcat下载

JDK8:jdk8

2.编写Dockerfile文件

FROM centos:7

# 使用 LABEL 替代 MAINTAINER
LABEL maintainer="kkkwang2"

# 复制 readme.txt 文件到容器中
COPY readme.txt /usr/local/readme.txt

# 添加适用于 Linux 的 JDK 和 Tomcat 压缩包并解压
ADD jdk-8u441-linux-i586.tar.gz /usr/local/
ADD apache-tomcat-9.0.98.tar.gz /usr/local/

# 重命名解压后的目录(如果需要)
RUN mv /usr/local/jdk1.8.0_441 /usr/local/jdk8
RUN mv /usr/local/apache-tomcat-9.0.98 /usr/local/apache-tomcat

# 更新 yum 源并安装 vim 和 32 位库支持
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && \
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
    yum clean all && \
    yum makecache && \
    yum -y install vim glibc.i686 libstdc++.i686

# 设置工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 设置环境变量
ENV JAVA_HOME /usr/local/jdk8
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat
ENV CATALINA_BASH /usr/local/apache-tomcat
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin

# 暴露端口
EXPOSE 8080

# 启动 Tomcat 并保持容器运行
CMD ["sh", "-c", "$CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out"]

3.构建镜像

docker build -t mytomcat .

4.启动镜像

 docker run -d -p 3333:8080 --name mytomcat01 `
   -v .\docker-home\dockerfile\tomcat\test:/usr/local/apache-tomcat/webapps/test `
   -v .\docker-home\dockerfile\tomcat\logs:/usr/local/logs `
   mytomcat

5.测试

1.在test目录下新建WEB-INF和index.jsp

在这里插入图片描述

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Welcome to My Web App</title>
</head>
<body>
    <h1>Welcome to My Simple Web Application!</h1>
    <p>This is a simple JSP page.</p>
    <p>The current date and time is: <%= new java.util.Date() %></p>
    
    <h2>Links:</h2>
    <ul>
        <li><a href="hello">Go to Hello Servlet</a></li>
    </ul>
</body>
</html>

2.在WEB-INF中创建web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>Simple Web Application</display-name>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.example.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

</web-app>
发布自己的镜像

官方文档:Docker push

前提条件
  1. Docker 已安装并运行:确保 Docker 已正确安装并在你的机器上运行。
  2. Docker 登录凭证:如果你要推送镜像到 Docker Hub 或其他需要认证的 Docker Registry,你需要登录。
步骤
1. 登录 Docker Registry

如果你要推送镜像到 Docker Hub,首先需要登录:

docker login

系统会提示你输入 Docker Hub 的用户名和密码。

2. 标记镜像

在推送镜像之前,你需要给镜像打标签(tag),以便指定目标仓库和镜像名称。格式如下:

docker tag <本地镜像名>:<标签> <仓库地址>/<命名空间>/<镜像名>:<标签>
  • <本地镜像名>:你本地构建的镜像名称。
  • <标签>:镜像的标签,通常是 latest 或者版本号。
  • <仓库地址>:Docker Registry 的地址,如果是 Docker Hub 可以省略。
  • <命名空间>:通常是你在 Docker Hub 上的用户名或组织名。
  • <镜像名>:你在仓库中的镜像名称。
docker tag mytomcat kkwang2/mytomcat:latest
3. 推送镜像

使用 docker push 命令将标记好的镜像推送到 Docker Registry:

docker push <仓库地址>/<命名空间>/<镜像名>:<标签>
docker push kkwang2/mytomcat:latest

Docker小结

在这里插入图片描述

在这里插入图片描述

Docker 网络

官方文档:Docker|network

什么是Docker网络?

Docker网络是指容器之间以及容器与外部系统之间进行通信的方式。

原理

Docker使用了虚拟网络来隔离容器,并通过不同的网络驱动实现容器间的通信。默认情况下,Docker会创建一个名为 docker0 的桥接网络(bridge network),所有新启动的容器都会连接到这个默认的桥接网络上。

–Link(已弃用)

它允许一个容器与另一个容器进行通信,并通过别名解析容器名称。然而,随着 Docker 网络功能的增强(如自定义桥接网络和覆盖网络),–link 已经被标记为已弃用,并且不再推荐使用。

1.两个容器建立连接 tomcat03 --> tomcat02

 docker run -d -P --name tomcat03 --link tomcat02 tomcat

2.测试连通

docker exec -it tomcat03 ping tomcat02

# 问题
PS C:\Users\Lenovo> docker exec -it tomcat03 ping tomcat02
OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown

What's next:
    Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug tomcat03
    Learn more at https://docs.docker.com/go/debug-cli/
#解决方法:
	-- 进入容器内部输入:
		apt-get update && apt-get install -y iputils-ping
		
		
	-- 再次输入:
		docker exec -it tomcat03 ping tomcat02
		
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.404 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.163 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.158 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=5 ttl=64 time=0.176 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=6 ttl=64 time=0.172 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=7 ttl=64 time=0.177 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=8 ttl=64 time=0.255 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=9 ttl=64 time=0.161 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=10 ttl=64 time=0.200 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=11 ttl=64 time=0.167 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=12 ttl=64 time=0.163 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=13 ttl=64 time=0.160 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=14 ttl=64 time=0.159 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=15 ttl=64 time=0.159 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=16 ttl=64 time=0.171 ms
^C
--- tomcat02 ping statistics ---
16 packets transmitted, 16 received, 0% packet loss, time 15575ms
rtt min/avg/max/mdev = 0.158/0.190/0.404/0.060 ms

# 反向连接不可以ping通
docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known


# 查看网络
PS C:\Users\Lenovo> docker network ls 
NETWORK ID     NAME      DRIVER    SCOPE
a7f4b01af50f   bridge    bridge    local
415a75655af9   host      host      local
6946f32282b4   none      null      local
PS C:\Users\Lenovo> docker network inspect a7f4b01af50f
[
    {
        "Name": "bridge",
        "Id": "a7f4b01af50fc4a9a99f9abfccbb04eb1536aaacba30e3731329d9a8b52100f0",
        "Created": "2025-02-08T05:00:00.765969212Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16", 
                    "Gateway": "172.17.0.1"  # docker0
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "23d09c537aa25a6b4cabf99ace995795e82105674ab562dc3a134d2c68101025": {
                "Name": "tomcat03",
                "EndpointID": "c5a58f7afe55e9d78d55467b8680b37c5f193e2e991c858fc65aacd60c721a0d",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "8734a5b207f3ca95fb57f0841b9396eca443f5ebdc8c6973418402af9fdf9f2d": {
                "Name": "tomcat02",
                "EndpointID": "35be13d81fbf7b63202d648a5f7ef1f8310eda538f214774b0de3d5f4ea683cf",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "c19d248ea5157098fd1e933c58216b767d46af90163a2315a68237450cefc024": {
                "Name": "tomcat01",
                "EndpointID": "20c58ac7fa0ce74c1ff5783fc64861d3aa1cc1313c4a6f8817c3644a4b3d2f8d",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

为什么Tomcat02可以ping通Tomcat03?

在这里插入图片描述

自定义网络

查看所有的docker网络

docker network ls
网络模式

bridge : 桥接docker(默认)

none:不配置网络

host:和宿主机共享网络

container:容器网络连通 !(用的少!局限很大)

自定义网络命令
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet




PS C:\Users\Lenovo> docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
d5212bca3cd3   bridge    bridge    local
415a75655af9   host      host      local
9c220d44b666   mynet     bridge    local
6946f32282b4   none      null      local
测试(tomcat)
# 由于我的tomcat镜像没有ping指令,我使用Dockerfile创建了自己的镜像
docker build -t mytomcat .
FROM tomcat
# 使用 LABEL 替代 MAINTAINER
LABEL maintainer="kkkwang2"
RUN apt-get update && apt-get install -y iputils-ping
# 1.编写自己的网络
PS C:\Users\Lenovo> docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 2.启动两个tomcat
PS C:\Users\Lenovo> docker run -d -P --name tomcat02 --net mynet mytomcat
e5bc00372ce2671c0a0f9ce4524e00d4f92ebb2ad19b92808ac44e6855e782c2
PS C:\Users\Lenovo> docker run -d -P --name tomcat03 --net mynet mytomcat
79f10552dbcafb33fc1b838067f8e7e3986e60a4d4580d7c4411a9eb51e3542b
# 2.查看自己写的网络
PS C:\Users\Lenovo> docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "9c220d44b666f6d63f6b3b0e1050e69f45d201db352dbcc07bda6f2fc2540966",
        "Created": "2025-02-08T11:15:49.791238875Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "79f10552dbcafb33fc1b838067f8e7e3986e60a4d4580d7c4411a9eb51e3542b": {
                "Name": "tomcat03",
                "EndpointID": "75585f857af080d1585e7659029bb32b812be7d286b4c925ac5b16839619fadd",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "e5bc00372ce2671c0a0f9ce4524e00d4f92ebb2ad19b92808ac44e6855e782c2": {
                "Name": "tomcat02",
                "EndpointID": "4fbec39ef7ad2552f9224502f5e88ef2655c581c03bac1e88db6fe9119cf86a0",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
# 4.测试连通
PS C:\Users\Lenovo> docker exec -it tomcat02 ping 192.168.0.3                                               PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.395 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.155 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.180 ms
^C
--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2115ms
rtt min/avg/max/mdev = 0.155/0.243/0.395/0.107 ms

PS C:\Users\Lenovo> docker exec -it tomcat03 ping tomcat02   
PING tomcat02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.246 ms
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.165 ms
^C
--- tomcat02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.165/0.205/0.246/0.040 ms

网络连通

docker run -d -P --name tomcat01 mytomcat
docker network connect mynet tomcat01 # 打通了mynet --- tomcat01



PS C:\Users\Lenovo\docker-home\dockerfile\mytomcat> docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.040 ms
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.040 ms
^C
--- tomcat02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1036ms
rtt min/avg/max/mdev = 0.040/0.040/0.040/0.000 ms

What's next:
    Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug tomcat01
    Learn more at https://docs.docker.com/go/debug-cli/

在这里插入图片描述

SpringBoot微服务打包Docker镜像

1.构建SpringBoot项目

2.打包应用
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.编写dockerfile

FROM java:openjdk-8u111-jdk-alpine
LABEL authors="kkkwang2"
COPY *.jar .\app.jar
CMD ["--server.port=8080"]

EXPOSE 8080
ENTRYPOINT ["java", "-jar", ".\app.jar"]

4.构建镜像

docker build -t helloworld .


[+] Building 1.3s (7/7) FINISHED                                                        docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                    0.0s
 => => transferring dockerfile: 206B                                                                    0.0s 
 => WARN: JSONArgsRecommended: JSON arguments recommended for ENTRYPOINT to prevent unintended behavio  0.0s 
 => [internal] load metadata for docker.io/library/java:openjdk-8u111-jdk-alpine                        0.0s 
 => [internal] load .dockerignore                                                                       0.1s 
 => => transferring context: 2B                                                                         0.0s 
 => [internal] load build context                                                                       0.7s 
 => => transferring context: 20.68MB                                                                    0.6s 
 => [1/2] FROM docker.io/library/java:openjdk-8u111-jdk-alpine                                          0.1s 
 => [2/2] COPY *.jar .app.jar                                                                           0.3s
 => exporting to image                                                                                  0.1s 
 => => exporting layers                                                                                 0.1s 
 => => writing image sha256:85f29eea389558daed4637e4e11f521404352d0c23ea4d2eec3c4c127e2ab6d2            0.0s 
 => => naming to docker.io/library/helloworld                                                           0.0s 

 1 warning found (use docker --debug to expand):
 - JSONArgsRecommended: JSON arguments recommended for ENTRYPOINT to prevent unintended behavior related to OS signals (line 7)

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/i177l2cycp1fabxomd1723clq   

在这里插入图片描述

注意:

1.本篇文章中的图片来自百度百科以及视频截图(侵删)!
2.在Windows中换行符以及文件路径写法与在Linux中不同
3.如有错误,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值