第一部分 Docker快速入门

​ 在本章节我们将快速学习Docker常用的概念与命令.通过此章节,我们可以了解Docker的核心概念,并且能熟练运行容器,最后自己可以构建AspNetCore镜像并上传到镜像仓库

第一章 Docker介绍

1. 什么是Docker

image-20211230190156565

​ Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目, 它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权 协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会, 并成立推动 开放容器联盟(OCI)。 Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目已经超过 4 万 6 千个星标和一 万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。 Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作 系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。 Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极 大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

2. 为什么要使用Docker

​ 在传统应用程序中部署,我们会根据应用程序的类型.会选择特定的操作系统,并安装应用程序所需要的依赖,然后通过手动或者一些部署工具将程序部署到操作系统上,这个方式本没有什么问题,但是随着互联网时代的快速发展,我们的应用程序必须很快的上线,试错,抢占市场,这时候,就需要对我们的应用程序有更高的要求 有时还会因为一些环境依赖出现问题..在容器化时代,我们将不用在考虑这些繁琐的事情,真正实现 "一次打包,到处运行"容器化实际上一种开发方法, 简单的说就是,我们将应用程序打包成一个镜像,然后在 Linux/Windows 系统上,通过容器引擎,根据这个镜像迅速创建一个容器(类似虚拟机)并在容器里部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装、部署和升级,非常方便.

​ Docker就是虚拟化的一种轻量级替代技术。Docker的容器技术不依赖任何语言、框架或系统,可以将应用程序变成一种 标准化的、可移植的、自管理的组件,并脱离服务器硬件在任何主流系统中开发、调试和运行.另外基于Docker,我们可以将原本一台机器只能部署一个实例的应用程序,部署多个实例,并且没有系统限制.

Docker包含了两个版本

Docker CE: 社区版本,由社区维护和提供技术支持,为免费版本,适用于个人开发人员与小型团队.

Docker EE:企业版,为收费版本,由售后团队与技术团队提供技术支持,转为企业开发. 相对于CE版本 提供了一些额外的功能,最重要的是技术支持与安全保障.

通常情况,Docker CE版本已经足够满足我们的要求

3. Docker与虚拟机的区别

​ 下图展示了Docker与虚拟机的比较

image-20211230190226668

​ 虚拟机包括应用程序,必要的库或二进制文件以及完成的一套操作系统,虚拟机与宿主机进行物理隔离,并且无法通过内部应用程序操作宿主机。与容器相比需要更多的资源。容器包括应用程序以及所有依赖项,但是他们与宿主机共享资源,在宿主机上以一个独立的进程运行,并且容器内部程序可以操作宿主机,与虚拟机相比,只需要少量资源即可。

4. Docker的结构与特性

Docker程序使用Golang语言进行编写,采用C/S架构,包括了Docker ServerDocker Client.Docker本身是一个单机程序,通过一些接口和内核进行交互.由于Docker使用到了Linuxcgroups,namespaces等操作,所以只能安装到linux系统上,当然通过虚拟机技术,在Window和Mac系统上,我们也可以安装Docker.

​ Docker是一个C/S架构,它的Server端是Docker Daemon,在宿主机上以守护集成的方式运行.Docker Daemon需要随机启动.通常我们操作Docker就是通过Docker Client发送指令到Server端,Docker Daemon守护进程执行指令完毕,返回结果.

​ 下面我们以部署Nginx为例,工作流程大致如下

  1. Docker Client 发送指令到Docker Daemon
  2. Docker Daemon收到指令后,去镜像仓库搜索镜像
  3. Docker Daemon找到指定镜像后,进行下载.
  4. 下载完成后,进行部署镜像

image-20220110210318062

第二章 安装与配置

1. 注册Docker账号

​ 访问Docker官网https://hub.docker.com,根据相关提示进行注册即可,Docker拉取镜像不需要注册账号,但是为了后续我们将自己的镜像推送到Docker Hub所以需要注册一个账号

image-20220113171118217

2. Windows10安装Docker

​ 在安装之前,Windows 版 Docker 的环境有以下要求

​ Windows 10 Pro(专业版) / Enterprise(企业版) / Education(教育版)(1607 Anniversary Update、Build 14393 或者更新的版本)

​ 首先,需要确认在 Windows 10 操作系统中,Hyper-V 和容器特性已安装并且开启。

  1. 右键单击 Windows 开始按钮并选择"应用和功能"页面

  2. 单击"程序和功能"

  3. 单击"启用或关闭Windows功能"

    打开Hyper-v

    打开容器

  4. 当完成 Hyper-V 和容器特性的安装并重启机器之后,就可以安装 Windows 版 Docker 了。

  5. 访问 Docker 的下载(https://www.docker.com/products/docker-desktop)页面,并单击其中的 Download for Windows 按钮。

    image-202201011926103346. 下载完成后,双击进行安装即可。

    安装后,我们使用打开Docker Desktop,该程序如果能正常打开,即说明Docker已经正常运行中,左下角会显示docker的引擎状态,正常情况为绿色,

image-20220113190435919

至此说明Docker已经安装成.

​ 然后我们使用刚刚注册的账号进行登录,点击右上角的Sign in,然后输入用户名与密码即可

image-20220113171806447

3. CentOS8安装Docker

3.1 Hyper-V安装CentOS8

  1. Hyper-V的默认网络交换机是一个叫Default Switch,该交换机是没有连接网络的能力的, 所以我们需要一个具有能连接网络的交换机

image-20220115230848875

  1. 新建虚拟网络交换机,类型选择外部,然后创建虚拟交换机

image-20220115231048952

  1. 命名为外网,选择外部网络,然后选择具有联网的网卡,这里笔者选择的是WIFI网卡,然后保存.

image-20220115231243993

  1. 新建虚拟机
  1. 名称为centos8

image-20220116110041055

  1. 选择第一代

image-20220116110100226

  1. 启动内存2048MB

image-20220116110311179

  1. 配置网络,选择刚刚配置的外网

image-20220116110404692

  1. 下一步

image-20220116110439096

  1. 选择centos8的iso文件路径

image-20220116110515593

  1. 点击完成
  2. Hyper-V管理器中,右键选择刚刚创建的虚拟机,点击**连接*

image-20220116110721262

  1. 点击启动

image-20220116110741909

  1. 使用键盘方向键选中Install CentOS Linux 8,并回车

image-20220116110903687

  1. 选择中文,并继续

image-20220116111054122

  1. 配置项
  • 软件选择:服务器,此项不带有GUI

image-20220116111516236

  • 开启网络

    image-20220116111606232

    • 安装目标位置,选择完成即可

    image-20220116111726002

    • 点击开始安装

    image-20220116111759650

  1. 用户设置,设置根密码,也就是root账户密码

image-20220116111904871

  1. 安装完毕即可

3.2 CentOS 8安装Docker

​ 接下来,我在CentOS 8中,安装Docker

  1. 检查CentOS 8是否安装了podman容器管理荣俱,如果安装需要先移除.

image-20220116134008126

  1. 移除podman
yum -y erase podman buildah
1

image-20220116134231212

  1. 接下来按官方教程,进行安装即可,分别执行以下三条命令
yum install -y yum-utils  device-mapper-persistent-data  lvm2
1
yum-config-manager  --add-repo https://download.docker.com/linux/centos/docker-ce.repo
1
yum install -y docker-ce docker-ce-cli containerd.io
1
  1. 安装完Docker以后,配置随机启动
systemctl enable docker --now
1
  1. 使用docker info命令查看

image-20220116121150648

​ 至此,在CentOS 8中,已经成功安装Docker

4. 配置加速器

​ 由于Docker Hub服务器在国外,在拉取与推送镜像的时候,网速会不稳定,所以可以设置为国内的镜像源服务器,在之前有很多国内比较有名的镜像源,但是现在已经都用不了,这里推荐使用阿里云的镜像加速服务,个人使用免费

4.1 获取加速器地址

  1. 注册阿里云账号

  2. 产品与服务中,找到容器镜像服务,然后选择镜像工具->镜像加速器

    image-20220113173757728

4.2 Windows配置加速器

  1. 复制加速器地址,打开Docker DesktopSettings页面,选择Docker Engine选项,按照以下格式进行复制进去

image-20220113174137571

​ 点击Apply & Restart即可.

4.3 CentOS 8配置加速器

  1. 使用命令vi /etc/docker/daemon.json,并输入以下内容

image-20220116140612883

  1. 保存重启Docker即可
systemctl daemon-reload
systemctl restart docker
1
2

第三章 核心概念

1. 镜像

什么是镜像(image)

​ 比如一个恰当的例子,镜像就像是一个应用程序的安装文件,通过安装文件,我们可以一次又一次的安装该程序.那么我们通过镜像,就可以多次部署容器

​ 镜像是静态的,是一个特殊的文件系统,提供了容器运行时的程序,库,配置文件,资源,运行时等,还包含了一些特殊参数,比如,环境变量,用户等等

1.1 搜索镜像

​ 我们可以使用docker search 镜像名称命令,进行相关镜像搜索,下面我们搜索一个nginx镜像.

相关命令

docker search nginx

  1. 打开命令行,输入docker search nginx

image-20220109221857588

1.2 拉取镜像

​ 当搜索到我们想要的镜像后,接下来就是需要拉取镜像.拉取镜像使用docker pull 镜像名称命令,下面我们将上面搜索的第一行镜像,下载到电脑上.

相关命令

docker pull nginx

  1. 在控制台中输入docker pull nginx

image-20220109221905888

​ 该命令是下载最新版本的nginx,当然我们也可以使用该命令下载指定版本的nginx,主需要在nginx后面加上指定版本号即可,如docker pull nginx:1.21.5,即拉取nginx的1.21.5版本.如果想要查看历时版本,可以登录Docker Hubopen in new window进行查看

1.3 查看镜像

​ 想要查看本机已经下载的镜像

相关命令

docker images

image-20220109224408585

1.4 部署镜像

​ 部署镜像使用docker run这个命令,下面我们就将部署nginx镜像

相关命令

docker run --name nginx-text -p 8080:80 nginx:latest

  1. 打开控制台,并输入以下命令并回车.如果指定镜像在本机不存在,则会自动拉取该镜像

image-20220114143101804

  1. 访问 http://localhost:8008

image-20220109222511694

​ 正常显示nginx的页面,说明已经部署成功.我们来拆解一下这一条命令

  1. docker run: 是镜像部署命令
  2. --name nginx-test: 指定这个镜像部署成容器以后的名字为nginx-test,该参数为空的话,Docker会生成一个默认的名称
  3. -p 8080:80: 指定本机8080端口映射到容器的80端口
  4. nginx:latest: 指的是镜像的名称与标签
  5. -d: 指示容器在后台运行,如果不指定该参数,则为阻塞运行.即控制台退出后,该容器也会退出,下面我们演示一下去掉该参数的效果.在控制台输入命令docker run -p 8081:80 nginx:latest

image-20220114143200461

此时看到,该控制台的光标已经被阻塞,这时候我们访问http://localhost:8081,可以正常出现nginx的默认页

image-20220111172323792

然后,我们关闭该控制台.然后我们在访问http://localhost:8081,就会出现以下页面,提示:无法访问此页面了.

image-20220111172347705

这就是**-d**参数的作用了

​ 当然还有一些其他比较常用的参数比如:

  1. --restart=always 指定该容器退出的话自启动
  2. -e 注入环境变量 ,比如 -e ASPNETCORE_ENVIRONMENT=Production ,这样我们的应用程序内部的ASPNETCORE_ENVIRONMENT这个环境变量的值就是Production,当然也可以注入我们自定义的环境变量
  3. -v 挂载存储卷 ,就是将本地目录挂载到容器内部目录,这样容器就可以写数据到该目录,该参数在第五章详解

​ 以上为使用频率比较多的参数,docker run 还有其他参数,我们可以通过docker run --help命令查看

image-20220109225451780

1.5 删除镜像

​ 删除镜像使用docker rmi 镜像ID或者名称命令,下面我们将刚刚下载的nginx镜像删除.

相关命令

docker rmi nginx:latest

  1. 在命令行中输入以下命令

image-20220114143309475

​ 哎呀,出错了,这是怎么回事呢?因为刚刚我们已经使用该镜像部署了一个名为nginx-test容器,使用docker ps命令查看本机已经运行的容器

image-20220114143404091

​ 第一行,就是刚刚我们部署的nginx容器.已经部署的镜像Docker是不允许删除的.所以我们需要先将所有使用该镜像部署的容器停止,然后删除这些容器,最后在删除镜像.操作步骤如下

  1. 停止容器:使用docker stop 容器ID或者容器名称命令

image-20220114143425775

  1. 删除容器:docker rm 容器ID或者容器名称

image-20220114143442215

  1. 删除镜像:docker rmi nginx

image-20220114143608922

1.6 镜像标签

​ 在我们查看镜像的时候,都过看到有一列,名称TAG,那么这个TAG是什么意思呢?

image-20220114134740220

​ 利用标签我们对镜像进行重命名与版本管理,使用也很简单,命令是docker tag 原镜像名称 新镜像名称:标签,下面我将上图中镜像nginxfile进行重命名

image-20220114141947368

​ 可以看到,出现一个nginxfilenew的镜像,TAGv1.原有镜像还是存在的,原有镜像和新镜像的IMAGE ID是一样的.删除镜像则会有以下情况

无法使用docker rmi 镜像ID,会出现以下提示

image-20220114142453463

docker rmi 镜像名称:标签删除镜像

image-20220114142624449

1.7 导入导出

​ 现实环境中,有很多项目的运行环境是需要在内网运行,无法进行联网,这时候我们可以将制作好的镜像导出,然后携带到内网环境进行导入与部署

导出

​ 只需要使用命令docker save -o 镜像ID或者名称 路径/包名.tar,根据镜像的大小,导出时间可能会比较长

相关命令

docker save nginx -o C:\Users\Yan\Downloads\nginx_new.tar

image-20220111151740481

该目录存在导出镜像

image-20220111150740789

打开该文件,我们可以看到,该文件中包含了镜像的所有元数据信息.

image-20220111170933041

导入

​ 使用命令docker load -i 包名.tar,导入成功后,会显示相关镜像的信息

相关命令

** docker load -i C:\Users\Yan\Downloads\nginx_new.tar**

image-20220111151950090

导入成功后,我们就使用基于docker tag命令,打成我们需要的指定标签即可

2. 容器

什么是容器

​ 通过镜像运行起来的程序,可以理解为是一个容器,容器实质是一个进程,容器内部的应用程序运行属于自己的独立命名空间.拥有自己的文件系统,用户权限,网路配置等.是一个与外界隔离的环境.

2.1 启动停止

停止

​ 容器的停止我们可以使用docker stop 容器ID或者名称即可.该命令只是关闭了这个容器,并不是删除了这个容器,所以容器内部所产生的数据都还是存在的.

相关命令

docker stop ea98406c26a4

image-20220111134858924

启动

​ 启动一个停止的容器使用docker start 容器ID或者名称.

相关命令

docker start ea98406c26a4

image-20220111134921223

2.2 查看容器

​ 使用docker ps命令来查看本机正在运行的容器.

相关命令

docker ps

image-20220111115122803

​ 当然该命令后面也支持一些参数,常用的如docker ps -a 用来显示所有的容器,包括已经停止的

相关命令

docker ps -a

image-20220111115229646

其他参数可以使用docker ps --help来查看

​ 对于单个容器的详细信息,我们可以通过使用docker inspect 容器ID或者名称命令来查看容器的相关信息

PS C:\Users\Yan> docker inspect c0e4fe128f41
[
    {
        "Id": "c0e4fe128f411c4ad293e09562b55546c25d02d5d190f263f485d05ab964a2ef",
        "Created": "2022-01-04T13:34:16.000134Z",
        "Path": "dotnet",
        "Args": [
            "HelloWorld.dll"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 1372,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-01-13T11:03:08.048296Z",
            "FinishedAt": "2022-01-13T11:03:06.2776274Z"
        },
        "Image": "sha256:1bd6b7fcd2afcd7ff3ff5d2dfb921c9fc22d04c6e90e90f253624cc0b89c433f",
        "ResolvConfPath": "/var/lib/docker/containers/c0e4fe128f411c4ad293e09562b55546c25d02d5d190f263f485d05ab964a2ef/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/c0e4fe128f411c4ad293e09562b55546c25d02d5d190f263f485d05ab964a2ef/hostname",
        "HostsPath": "/var/lib/docker/containers/c0e4fe128f411c4ad293e09562b55546c25d02d5d190f263f485d05ab964a2ef/hosts",
        "LogPath": "/var/lib/docker/containers/c0e4fe128f411c4ad293e09562b55546c25d02d5d190f263f485d05ab964a2ef/c0e4fe128f411c4ad293e09562b55546c25d02d5d190f263f485d05ab964a2ef-json.log",
        "Name": "/sharp_khayyam",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {
                "80/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8080"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "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",
            "ConsoleSize": [
                24,
                121
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "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"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/5eb2d4bf32f9d1945fc73746e8cb2562b97c13796753af840fef94f20c62f523-init/diff:/var/lib/docker/overlay2/v84nhpyr9a77bacb3rqlmqnnk/diff:/var/lib/docker/overlay2/nv7gpifv5fg6zx5bv5bayptvm/diff:/var/lib/docker/overlay2/30cb1539d3a4dc75a839f8032c826ccf08b8948a996aa330a357379d3548a168/diff:/var/lib/docker/overlay2/4a8e91a72f6b3623c0e144e0696b43b180f0be45288ee1d789c780e855a3b9bd/diff:/var/lib/docker/overlay2/83503ad4531a40c883a8d9e33dd4d08253f08db63063b562943d88fb5d38f6f6/diff:/var/lib/docker/overlay2/eb139cbb458b4e435e4ef3ad6c6243619a114334a744bd103199a0a76946bcbb/diff:/var/lib/docker/overlay2/52bf9483e03fc6dc4d1b0037f4731b66552e4369e330ffc403d44c6a77061e57/diff",
                "MergedDir": "/var/lib/docker/overlay2/5eb2d4bf32f9d1945fc73746e8cb2562b97c13796753af840fef94f20c62f523/merged",
                "UpperDir": "/var/lib/docker/overlay2/5eb2d4bf32f9d1945fc73746e8cb2562b97c13796753af840fef94f20c62f523/diff",
                "WorkDir": "/var/lib/docker/overlay2/5eb2d4bf32f9d1945fc73746e8cb2562b97c13796753af840fef94f20c62f523/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "c0e4fe128f41",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "ASPNETCORE_URLS=http://+:80",
                "DOTNET_RUNNING_IN_CONTAINER=true"
            ],
            "Cmd": null,
            "Image": "helloworld:v1",
            "Volumes": null,
            "WorkingDir": "/App",
            "Entrypoint": [
                "dotnet",
                "HelloWorld.dll"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "20bc2792c13b2e08885b7697ece8333290817e47db70d9645861e02d00424e21",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8080"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/20bc2792c13b",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "8d9e4a97b71c1fea02f47b185c76174ddc8c257ab0b3445639f1edb333ebfde5",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.4",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "e20a24b365b706773ec43b4cb90a1ae2e17ae341ccff642dab0362ffdc9551e1",
                    "EndpointID": "8d9e4a97b71c1fea02f47b185c76174ddc8c257ab0b3445639f1edb333ebfde5",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.4",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:04",
                    "DriverOpts": null
                }
            }
        }
    }
]
PS C:\Users\Yan>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

docker inspect命令以json的格式进行展示非常丰富的信息.通过**-f**参数我们可以提取部分自己想要的信息.如我们来查找一下容器的IP地址

image-20220113230316731

2.3 容器日志

​ 通常我们的应用程序会通过控制台输出很多日志信息,方便我们定位和查看相关信息,如果我们想看容器输出的日志,可是用docker logs 容器ID或者名称来查看

相关命令

docker logs ea984006c26a4

image-20220111134759197

2.4 更新容器

​ 对于已经正在运行的容器,我们通过docker update命令来更新某些信息,比如我们在部署镜像的时候,忘记了让容器自动启动,我们就可以使用命令docker update 容器ID --restart=always 来让容器自启动.当然docker update也不是任意指令都支持的,具体支持命令我们可以通过 **docker update --help **来查看

image-20220111113407720

我们来设置nginx容器自动启动.

相关命令

docker update 028a88755896 --restart=always

image-20220111140904894

我们也会常用使用这个命令限制容器使用的内存,比如我们限制该容器内存为256m,Swap无限制

docker update 028a88755896 --memory 256m --memory-swap -1

*注意:在某些java容器情况下,我们限制了容器使用内存,但是未限制容器内部的jvm的内存,则容器内部的程序有几率会OOM

2.5 进入容器

​ 在某些情况下,我们想要查看容器内部的信息,比如配置信息,日志记录,执行脚本等等,此时我们就可以使用docker exec -it 容器ID或者名称 bash或者sh命令.

相关命令

docker exec -it 028a88755896 bash

image-20220111140400992

​ 该命令的意思就是在运行的容器中执行bash或者sh命令.所以也就是变相的进入到了容器内部.至于是bash还是sh取决于我们所使用的镜像.这时,我们就可以使用相关shell命令,但这里有个前提,您要使用的shell命令需要在该镜像中存在.如果在构建竟像时没有包含该指令,则无法使用.

image-20220111140708590

​ 我们使用vi命令来查看nginx的默认页面,这时提示bash: vi: command not found,那是因为使用的镜像在构建时没有将vi包含进去.其余参数的意义如下

-i 即使没有附加也保持STDIN(标准输入输出) 打开

-t 分配一个伪终端

2.6 停止容器

​ 使用命令docker stop 容器ID或者名称来停止容器.该操作,只是停止容器运行,并不会删除容器,容器内部所产生的的数据依然存在,

image-20220111140754530

2.7 删除容器

​ 使用命令docker rm 容器ID或者名称来删除容器,该操作,会删除指定容器和容器内部已经删除的数据.想要保留产生的数据,我们会在第四章 数据存储来讲解

相关命令

docker rm 43e405881f01

image-20220111114935801

2.8 导入导出

导出

​ 假如我们自己的程序正在以容器的方式运行,在容器内部写了很多的数据或者文件,这时候我们想要将整个容器进行导出,可以使用docker export 镜像ID或者名称 -o 路径\包名.tar进行导出

相关命令

docker export a137b9505320 -o C:\Users\Yan\Downloads\nginx_new.tar

​ 我们将一个正在运行的nginx容器进行导出

image-20220113180411495

可以看到导出成功

image-20220111203202640

打开该文件看一下目录,可以看到Docker将容器运行时全部复制了下来

image-20220111203133038

导入

​ 使用docker import 路径\包名.tar 新镜像名称即可导入

相关命令

docker import C:\Users\Yan\Downloads\nginx_new.tar nginx_new

image-20220111203428887

导入成功

image-20220111203449073

接下来,我们部署一下这个镜像,执行命令**docker run -d -p 8081:80 nginx_new **,会发现出现以下错误,这是为什么呢?

image-20220111205258543

以这种方式导入的镜像,部署的时候会有些麻烦,由于在export导出的时候,会丢失该镜像的所有信息包括元数据,所以部署需要额外指定执行命令

image-20220111204632960

我们访问http://localhost:8081,可以正常访问nginx服务

image-20220111204806003

​ 细心的同学可以看到,我们在docker run指令最后,加入了nginx的启动命令.没错,因为该种方式导出导入会引起镜像的元数据丢失,docker无法感知需要执行的命令,所以,在命令最后,我们手动指定命令,告诉docker需要执行的命令是nginx -g "daemon off;"

​ 所以当我们对镜像导出导入的时候,应该寻找该镜像内部的启动程序,如果是AspNetCore,那自然就是dotnet run xx.dll

2.9 容器监控

2.9.1 单个容器

​ 我们可以通过docker stats 容器ID或者名称来查看指定容器占用的系统资源,如CPU,内存,网络磁盘等

相关命令

docker stats c0e4fe128f41

image-20220114154712281

2.9.2 所有容器

​ 直接使用docker stats,则会看到所有容器的资源使用状况,

image-20220116213103439

2.9.3 Cadvisor

​ Cadvisor可以对节点机器上的资源及容器进行实时监控和性能数据采集,包括CPU使用情况、内存使用情况、网络吞吐量及文件系统使用情况,并且提供了Web控制台.Cadvisor使用Go语言开发,利用Linux的cgroups获取容器的资源使用信息,在Kubernetes中集成在Kubelet里作为默认启动项,官方标配。

​ Cadvisor使用也非常简单,直接使用以下命令即可

docker run  --volume=/:/rootfs:ro  --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080 --detach=true --name=cadvisor google/cadvisor
1

然后我们访问http://localhost:8080即可

image-20220116213748027

2.10 资源限制

​ 默认情况下,docker并没有限制容器的内存和CPU,当一台主机上运行多个容器时,底层是共享CPU,内存,硬盘,网络这些资源的,如果不对容器进行资源限制,那么容器之间则会相互影响,可能会导致主机资源耗尽,服务不可用

docker作为容器的管理者,提供了对于CPU,内存,磁盘三个方面的控制

3. 仓库

Registry

​ 仓库(Repository)是集中存放镜像的地方,是一个管理镜像的服务,我们构建完的镜像,可以上传到相应的镜像仓库,然后通过网络进行下载分发等.就拿IPhone手机做类比,仓库就是App Store.Docker就是IPhone的操作系统IOS,而镜像就是应用商店里的应用程序

​ 在实际应用中,运维同学创建好镜像仓库,由开发同学制作镜像,然后上传到镜像仓库.Docker Daemon守护进程在从镜像仓库拉取镜像,

​ 镜像仓库分为公共仓库私有仓库

3.1 公有仓库

​ 目前 Docker 官方维护了一个公有仓库 Docker Hubopen in new window。由于我们之前已经在Docker Hub注册了一个账号,所以我们可以将我们自己制作的镜像上传到公有仓库中,

如果是在Linux系统下,我们需要使用以下步骤进行登录

  1. 在命令行中输入docker login
  2. 在输入用户名与密码即可

image-20220113202148757

​ 公有仓库是公开的,仓库里的镜像,所有人都可以进行拉取,对于企业首选私有镜像仓库

3.2 私有仓库

3.2.1 Docker Registry

​ Docker官方提供了docker-registry镜像,我们可以直接拉取部署该镜像,这是最简单的方式

image-20220111212823144

然后部署这个镜像,使用命令docker run -d -p 5000:5000 registry

image-20220111213244598

已经成功运行,接下来我们使用docker logs来看一下容器的日志

image-20220111213258387

​ 由于该镜像没有Web控制台,所以如果要用到企业内部,还需要很多配套设置,比较麻烦,所以此方案不在多述.

3.2.2 Harbor

​ Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,可以用来构建企业内部自有的镜像服务器.它具有以下特点

  1. 开源
  2. 策略和角色访问,切支持LDAP/AD集成
  3. 确保镜像被扫描并且没有漏洞
  4. CNCF(云原生计算基金会)
  5. 完整的Web控制面板

image-20220109223041401

​ 对于Harbor的安装可以访问官方Harbor (goharbor.io)open in new window虽然自建镜像仓库虽然具有比较高的安全性,但是还需要投入硬件服务器存储等,对于使用量比较大的团队,可能还需要对镜像仓库做高可用配置,还有专业的运维同学负责维护,综合成本不算低,所以中小型团队可以直接使用国内各大云服务商提供的免费镜像仓库服务

3.2.3 云服务商

​ 国内很多云服务商都会提供免费的镜像仓库,让大家免费试用,这里推荐使用阿里云的镜像服务.个人版使用免费

3.3 推送镜像

​ 接下来,我们将学习如何推送镜像到镜像仓库,推送镜像使用docker push命令.

如果是推送Docker Hub命令格式如下

docker push Docker账号/镜像名称:tag

如果是推送至私有仓库,命令格式如下

docker push 地址/命名空间/镜像名称:tag

3.3.1 推送公用仓库

​ 我们将2.8章节导入的nginx_new镜像上传到Docker Hub.

​ 推送公有仓库的命令格式为docker push 账号/镜像名称:tag

  1. 对镜像打tag.a121984376为笔者的Docker账号

image-20220113204937618

  1. 推送镜像

image-20220113205119669

3.3.2 推送阿里云私有仓库

​ 推送私有仓库主要有以下几步:

  1. 确认阿里云镜像服务地址,在阿里云->控制台->容器镜像服务首页可以看到

image-20220113205658634

  1. 在阿里云镜像服务创建命名空间

image-20220113210745250

  1. 对要导入的镜像打上tag,推送命令规则registry.cn-hangzhou.aliyuncs.com/命名空间/镜像名称:tag

image-20220113210944225

  1. 登录公网

image-20220113205758078

  1. 推送镜像

image-20220113211041006

  1. 通过阿里云控制台查看推送的镜像

image-20220113211216636

4. 制作自己的镜像

4.1 HelloWorld By AspNetCore

​ 通过前三掌,我们已经知道了镜像,容器,仓库三个核心的概念,下面我们使用Asp.NetCore来制作一个经典的HelloWorld镜像然后上传到私有仓库

4.1.1 制作镜像
  1. 基于**.NET Core 3.1**,创建Hello World项目

image-20220104212120241

  1. 更改启动路径打开Properties文件夹里的launchSettings.json,移除IIS Express节点,本步骤不是必须,更改后如下

    image-20220104211533515

  2. 更改Controller

image-20220104211658768

  1. 添加Dockerfile,右键项目-添加Dockerfile文本文件,注意没有扩展名,添加以下命令

image-20220104213830549

  1. 右键Dockerfile属性,选择始终复制

image-20220104212242678

  1. 重新生成项目,并打开生成后的文件夹

image-20220104212732565

  1. 再此目录打开命令行,并执行以下命令

image-20220104213045691

  1. 使用docker images命令查看刚刚只做的镜像,可以看到刚刚只做的helloword的镜像.

image-20220104213124039

  1. 接下来,就让我们运行该容器.在命令行输入以下命令,注意8080问您本机端口,该端口可以是其他任意端口,但是不能被其他应用程序占用

image-20220104213426386

  1. 检查容器是否正常,在命令行中,使用以下命令.可以看到容器已经正常运行着

image-20220104213634427

  1. 访问本地地址**localhost:8080/helloworldopen in new window**,可以看到,已经正常相应

image-20220104213713335

4.1.2 推送镜像

​ 我们制作的镜像已经成功被部署了,接下来我们将这个镜像推送到Docker Hub官方镜像仓库.

  1. 使用**docker tag **命令,对进行重命名

image-20220113203347233

  1. 使用docker push命令推送金象

image-20220113203551078

​ 经过以上两步,我们从制作镜像部署镜像再到推送镜像,都已经成功了!距离AspNetCore云原生更进一步了!

4.2 Dockerfile

第一种写法

​ 在前面制作镜像的时候,我们使用了命令docker build -t helloworld:v1 . 我们来拆解一下这行命令

  • docker build: 构建镜像命令
  • **-t:**镜像名称与TAG
  • **. 😗*指的是当前目录

所以就是在当前目录中构建镜像,名为:helloworld:v1,在构建竟像时Docker会自动在指定的目录中,寻找Dockerfile文件,并按照文件中的定义步骤来构建.

​ 我们来具体解释一下上面实战中其中Dockerfile的作用,注意所有首单词需要大写

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
EXPOSE 80
COPY . /App
WORKDIR /App
ENTRYPOINT ["dotnet", "HelloWorld.dll"]

1
2
3
4
5
6
  • FROM: 指定基础镜像
  • EXPOSE: 镜像暴露的端口
  • COPY: 将宿主机的文件复制到镜像的指定目录
  • WORKDIR: 当前工作目录
  • ENTRYPOINT: 启动命令

​ 还有些其他常用参数

  • RUN: 要执行的命令
  • ENV: 指定环境变量
  • USER: 指定容器内部以那个用户运行进程
  • MAINTAINER: 维护者
  • CMD: 启动命令

其中启动命令既有ENTRYPOINT也有CMD,这两种命令几乎是重复的,单独使用一个可以实现大多数的用例

另一种写法

​ 在上面的示例中,我们发现,对于项目的编译,我们使用了Visual Studio对项目进行了编译,那就意味着,我们需要宿主机上需要安装相关的dotnet sdk,才可以进行编译,如果在多语言的环境下,那就意味着宿主机需要事先安装每一个语言的sdk,所以这种方式不太方便,所以该Dockerfile则有另一种写法,我们来看一下

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY . /src
RUN dotnet publish  -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS final
EXPOSE 80

WORKDIR /app
COPY --from=build /app/publish .

ENTRYPOINT ["dotnet", "HelloWorld.dll"]	
1
2
3
4
5
6
7
8
9
10
11
12

我们分析一下这个Dockefile

第一步 FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build 指定了我们需要编译项目的sdk的镜像

然后使用WORKDIR命令指定工作目录在**/src**,然后使用COPY命令,将所有文件复制到**/src**目录

Dockerfile有两步,第一步,对项目进行编译,第二部指定runtime和启动的dll入口。

将项目的编译放置到了容器内部,这样就不会依赖宿主机的环境。

4.3 自定义Nginx镜像

​ 接下来,让我们自定义一个nginx镜像,nginx官方镜像里不包含ifconfig命令,那么我们就ifconfig命令构建镜像里

  1. Dockerfile
FROM centos
RUN yum install -y nginx
RUN yum install -y net-tools
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
1
2
3
4
5
  1. 构建镜像,名为:new_nginx执行 **docker build -t new_nginx . ** 命令,

image-20220117212617207

  1. 部署镜像docker run -d new_nginx,并进入容器内部使用ifconfig命令

image-20220117212724464

可以看到,容器中已经可以使用ifconfig命令了

第四章 数据卷

​ 默认情况下容器内所创建的文件和产生的数据都是保存在容器的可写层,容器一旦被删除,其内部所产生的数据也会一并被移除.为了解决这些问题,Docker引入了**数据卷(Volume)**机制.

​ 数据卷的设计目的就是数据的持久化,因为其生存周期独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷.

Docker提供了两种挂载数据卷的方法:

1. Bind mount

​ 这种方式是Docker早期提供的容器与宿主机共享数据的方式,该方式使用也比较简单.其使用方式就是将宿主机的目录映射到容器内部的目录,这样容器内部的程序就可以向这个目录写数据.

指令格式

docker run -v 宿主机绝对路径:容器内部绝对路径

​ 下面我们基于nginx镜像来演示一下

  1. 部署nginx镜像,并使用 -v 参数 挂载目录本地C:\Users\Yan\Downloads到容器内部根目录下的data目录

image-20220114172906406

  1. 进入容器内部,并进入到data目录,通过ls命令可以看到data目录已经存在

image-20220114172944879

  1. 进入到data目录,然后创建test.txt文件

image-20220114173019736

  1. 查看本地C:\Users\Yan\Downloads目录,此时发现,test.txt文件也同时被创建

image-20220114173122695

  1. 接下来,我停止并删除该容器

image-20220114173051171

  1. 再次查看本地C:\Users\Yan\Downloads目录,test.txt还存在.

image-20220114173135069

​ 所以基于这种方式,下次在启动容器的时候,直接将该目录映射进去就可以.这种方式的优点就是简单易用,缺点就是需要为每个容器挂载目录

第五章 网络模式

​ 安装Docker时,它会自动创建三个网络。您可以使用以下docker network ls命令列出这些网络

image-20220101202328620

​ 在部署镜像的时候使用参数**--network 模式名称即可指定.如docker run -d --network host nginx**

1. Bridge网络

​ Bridge模式是默认的网络模式,当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,用来连接宿主机和容器,此主机上的Docker容器都会连接到这个虚拟网桥上.

​ 处于这个模式的容器,都会有自己IP地址与端口资源.所以我们需要将宿主机的端口映射到容器的指定端口,方可进行通讯,在第三章 核心概念中我们的示例都是基于该模式

image-20220116123027345

2. Host网络

​ 在该网络模式Docker不会拥有独立的IP端口,而是共享宿主机的IP端口.

docker-host

​ 下面我来演示一下改模的效果.该模式在Windows会存在一些问题,由于使用的是虚拟机技术,所以Docker共享的是虚拟机的IP端口,并不是WindowsIP端口.所以为了更直观的演示效果,我们基于CentOS 8Docker来演示.

  1. 使用命令部署nginx镜像,使用参数**--network host指定网路为host**模式

    docker run -d --network host nginximage-20220116122304956

  2. 查看CentOS 8IP,可以看到IP地址是:192.168.68.217

    ifconfigimage-20220116122408129

  1. 我们在CentOS 8中,使用访问http://192.168.68.217,可以看到输出的正式nginx的默认页.

image-20220116122527675

​ 至此,这就是host网络模式的效果

3. None网络

​ 顾名思义,所有加入到这个网络模式中的container,都"不能”进行网络通信。貌似有点鸡肋,目前还没遇到使用该模式的场景

4. 查看网络

​ 我们可以通过docker network inspect 网络名称来查看网络的详细信息

我们查看一下host网络模式

docker network inspect host

image-20220118200542308

4. 自定义网络

​ 我们可以使用docker network create -d bridge --subnet=网段 网络名来创建一个自定义的网路

相关命令

docker network create -d bridge --subnet=10.0.0.0/24 customer_bridge

image-20220118203003407

我们使用nginx镜像来指定该网络,然后使用docker inpect命令查看IP地址

相关命令

docker run -d --network customer_bridge nginx

image-20220118205037954

5. 容器互联

1. IP

​ 容器之间可以通过IP互相进行访问,在前面的章节中,我们自定了带有net-tools的nginx镜像,我们使用该镜像来做演示.使用该镜像,分别创建两个容器名为n1n2,然后我们进入n1中,ping n2

相关命令

docker run -d --name=n1 new_nginx

docker run -d --name=n2 new_nginx

image-20220118205807000

查看容器n2的IP地址

image-20220118205946312

进入到容器n1中,并使用ping命令

image-20220118210213307

可以看到网络正常

​ 在我们运行容器的时候,可是通过**--link参数来指定要连接的容器,这样容器就不需要通过IP来访问.我们使用Wordpress**来演示这功能

相关命令

  • 创建数据库容器

docker run -d --name db -e MYSQL_DATABSE=wordpress -e MYSQL_ROOT_PASSWORD=wordpress mysql:5.7

image-20220118223947965

  • 创建Wordpress容器

docker run -d --name blog --link db -p 8081:80 wordpress

image-20220118224006811

这时候我们访问http://localhost:8081 wordpress已经能正常访问

image-20220118224041255

所以使用**--link**参数,可以很方便的让容器互通,且不用关注IP是什么

第六章 docker-compose

1. 什么是docker-compose

Docker的理念是一个容器一个进程,可是现实中,我们的应用会有多个模块,可能会部署到多个容器中,最典型的,就是一个Web服务容器,一个数据库容器.这种情况,我们处理的方式就是:

docker start web

docker start db

如果需要停止,就会

docker stop web

docker stop db

​ 是不是觉得很麻烦?所以Docker就有了自己的容器编排工具Docker Compose.它允许用户在一个模板中,使用YAML文件格式,定义一组关联的应用容器,通过使用docker-compose up就可以把这一组服务以此创建和启动.

2. 安装docker-compose

​ 在Windows环境中,当我们安装完Docker以后,就已经有了docker-compose命令了

image-20220113170604522

CentOS 7-8中需要单独安装该组件.以CentOS 8为例

执行以下命令

curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose
1
2
3

image-20220117191046869

执行docker-compose version,说明已经安装成功

3. 部署WordPress

接下来,我们使用docker-compose来部署知名博客软件WordPress.

  1. 在本地目录创建docker-compose.yaml,该文件名称不能更改
version: '3'
services:
db:
image: mysql:5.7
volumes:
    - db_data:/var/lib/mysql
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: wordpress
    MYSQL_DATABASE: wordpress
    MYSQL_USER: wordpress
    MYSQL_PASSWORD: wordpress
wordpress:
  depends_on:
    - db
  image: wordpress
  ports:
    - "8000:80"
  restart: always
  environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
    WORDPRESS_DB_NAME: wordpress
volumes:
 db_data: {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

我们来解释一下这段yaml的意思,

  • **image:**镜像
  • **volumes:**挂载的数据卷
  • **restart:**自启动
  • **environment:**注入环境变量
  • **ports:**端口映射
  • depends_on: wordpress容器依赖db容器,也就是db容器需要先于wordpress容器启动

2 在该文件目录执行命令docker-compose up -d,该命令会在执行的目录自动寻找docker-compose.yaml文件

image-20220117200421473

如果镜像不存在,则会自动拉取改镜像,

  1. 访问http://localhost:8000,可以看到Wordpress已经正确的运行起来了

image-20220117200518192

  1. 使用docker-compose ls来查看已经运行的容器

image-20220117200741443

  1. 在该目录中使用docker-compose stop命令停止服务

image-20220117200938138

  1. 在该目录中使用docker-compose start命令启动服务

image-20220117201035596

  1. 在该目录中使用docker-compose down命令停止并删除服务

image-20220117200345052

第七章 监控

​ 在第三章 容器部分,我介绍了可以使用命令docker states来查看容器的使用情况,这种命令使用不方便,数据展示也不友好

[root@cd ~]# docker stats
CONTAINER ID   NAME                       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
148fbc23cab1   kong-database              0.11%     30.81MiB / 2.708GiB   1.11%     1.47kB / 0B       105MB / 205kB     6
f295b5b7d5e9   teamcity-agent-1           8.73%     341.8MiB / 2.708GiB   12.33%    10.9kB / 27.5kB   770MB / 49.2kB    57
c193e640484f   teamcity-server-instance   46.13%    1.191GiB / 2.708GiB   43.98%    1.08MB / 738kB    5.39GB / 5.71MB   153
CONTAINER ID   NAME                       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
148fbc23cab1   kong-database              0.11%     30.81MiB / 2.708GiB   1.11%     1.47kB / 0B       105MB / 205kB     6
f295b5b7d5e9   teamcity-agent-1           8.73%     341.8MiB / 2.708GiB   12.33%    10.9kB / 27.5kB   770MB / 49.2kB    57
1
2
3
4
5
6
7
8

下面介绍一款可视化监控容器的组件cadvisor

cadvisor为谷歌开源组件,可以手机当前主机上云运行的容器信息,还提供基础的查询界面,提供http接口,方便与其他组件进行交互,通常情况是cadvisor + influxdb + grafna搭配使用

下载镜像,注意该源

docker pull google/cadvisor
1

部署镜像

docker run -it -d -p 8080:8080 google/cadvisor
2d933e9a74219199e9546343b0cd786764a0efcc763882991dc0110d2984e06c
1
2

然后在浏览器访问http://127.0.0.1:8080

image-20220309210906486

该组件是没有任何认证授权的,所以要在内网使用.

Last Updated:
Contributors: 刘岩