本文是学习《每天五分钟玩转Docker容器技术》的总结。是基础知识学习,熟悉docker容器技术,为了更好的研究docker相关漏洞。

容器知识图谱

容器生态系统

容器的基本架构

  • Docker客户端:Client
  • Docker服务器:Docker daemon
  • Docker镜像:Image
  • Docker仓库:Registry
  • Docker容器:Container

image

通过docker我们可以方便地在Host上构建和运行容器。最常用的Docker客户端是docker命令。用户也可以通过REST API与服务器通信。

常用的命令

命令分类 命令 功能说明 常用示例
容器生命周期管理 docker run​​ 创建并启动容器 docker run -d -p 80:80 --name mynginx nginx(后台启动 nginx,映射 80 端口)
docker start [容器名/ID] 启动已停止的容器 docker start mynginx
docker stop [容器名/ID] 停止运行中的容器(优雅关闭) docker stop mynginx
docker restart [容器名/ID] 重启容器 docker restart mynginx
docker rm [容器名/ID] 删除容器(需先停止,-f 强制删除运行中容器) docker rm -f mynginx
容器查看 docker ps 查看运行中的容器 docker ps -a(查看所有容器,包括已停止)
docker inspect [容器名/ID]​​ 查看容器详细信息(配置、网络等) docker inspect mynginx
docker logs [容器名/ID]​​ 查看容器日志(-f 实时跟踪,–tail 100 查看最后 100 行) docker logs -f mynginx
容器操作 docker exec -it [容器名/ID] [命令]​​ 进入运行中的容器并执行命令(-it 交互模式) docker exec -it mynginx /bin/bash(进入 bash 终端)
docker cp [本地路径] [容器名/ID]:[容器路径] 从本地复制文件到容器 docker cp ./test.txt mynginx:/tmp/
docker cp [容器名/ID]:[容器路径] [本地路径] 从容器复制文件到本地 docker cp mynginx:/tmp/test.txt ./
docker top [容器名/ID]​​ 查看容器内运行的进程 docker top mynginx
镜像管理 docker images 查看本地镜像 docker images -a(包括中间镜像)
docker pull [镜像名:标签] 从仓库拉取镜像 docker pull mysql:8.0
docker push [镜像名:标签] 推送镜像到仓库(需先登录) docker push myrepo/myimage:v1
docker rmi [镜像名/ID] 删除本地镜像(-f 强制删除,需先删除依赖容器) docker rmi -f nginx
docker build -t [镜像名:标签] [Dockerfile路径] 基于 Dockerfile 构建镜像 docker build -t myapp:v1 .(当前目录的 Dockerfile)
镜像信息 docker image inspect [镜像名/ID]​​ 查看镜像详细信息 docker image inspect nginx
docker history [镜像名/ID]​​ 查看镜像构建历史(各层操作) docker history nginx
仓库管理 docker login [仓库地址] 登录 Docker 仓库(默认 Docker Hub) docker login(登录 Docker Hub)
docker logout [仓库地址] 退出仓库登录 docker logout
docker search [关键词] 搜索仓库中的镜像 docker search python
数据卷管理 docker volume create [卷名] 创建数据卷(持久化存储) docker volume create myvol
docker volume ls 查看所有数据卷 docker volume ls
docker volume inspect [卷名] 查看数据卷详细信息 docker inspect myvol
docker volume rm [卷名] 删除数据卷 docker volume rm myvol
网络管理 docker network ls 查看 Docker 网络 docker network ls
docker network create [网络名] 创建自定义网络(默认 bridge 模式) docker network create mynet
docker network connect [网络名] [容器名/ID] 将容器连接到指定网络 docker network connect mynet mynginx
docker network disconnect [网络名] [容器名/ID] 断开容器与网络的连接 docker network disconnect mynet mynginx
系统信息 docker info 查看 Docker 系统信息(版本、镜像数、容器数等) docker info
docker version 查看 Docker 客户端和服务端版本 docker version

image

REST API 需要Docker daemon配置开启端口,很多未授权漏洞就是这个原因:

1
2
3
4
5
6
7
8
9
10
#Linux 系统 编辑 /etc/docker/daemon.json
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

Windows/macOS:
通过 Docker Desktop 配置:
进入 Settings → Docker Engine,在 JSON 配置中添加上述 hosts 字段,点击 Apply & Restart。

客户端连接:docker -H 192.168.56.102 info
1
2
3
4
5
6
//安全配置
1、TLS 证书认证,客户端使用证书认证访问API(网上随便都有教程不写了)
2、最小权限原则:仅开放必要的 API 端口(2376),并限制来源 IP(通过防火墙)。
3、定期轮换证书:TLS 证书设置较短有效期(如 90 天),定期更新。
4、日志审计:开启 Docker 和反向代理(如果有)的访问日志,监控异常请求。
5、使用网络隔离:将 Docker API 部署在私有网络,避免直接暴露公网。

Docker镜像

Dockerfile是镜像的描述文件,定义了如何构建Docker镜像。

1
2
3
4
FROM debian
RUN apt-get install emacs
RUN apt-get install apache2
CMD ["/bin/bash"]

新镜像是从base镜像(内核和host一样)一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。分层结构最大的一个好处就是:共享资源

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#构建镜像
docker build -t [镜像名:标签] [Dockerfile路径]
docker commit [选项] <容器ID或名称> <新镜像名[:标签]> //现有容器打包成镜像

#dockerfile语法
FROM #指定base镜像。
MAINTAINER #设置镜像的作者,可以是任意字符串。
COPY #将文件从build context复制到镜像。COPY src dest
ADD #与COPY类似,不同的是,如果src是归档文件(tar、zip、tgz、xz等)文件会被自动解压到dest。
ENV #设置环境变量,环境变量可被后面的指令使用。
EXPOSE #指定容器中的进程会监听某个端口,Docker可以将该端口暴露出来。
VOLUME #将文件或目录声明为volume。
WORKDIR #为后面的RUN、CMD、ENTRYPOINT、ADD或COPY指令设置镜像中的当前工作目录。
RUN #在容器中运行指定的命令。
CMD #容器启动时运行指定的命令。Dockerfile中可以有多个CMD指令,但只有最后一个生效。CMD可以被dockerrun之后的参数替换。
ENTRYPOINT #设置容器启动时运行的命令。Dockerfile中可以有多个ENTRYPOINT指令,但只有最后一个生效。CMD或docker run之后的参数会被当作参数传递给ENTRYPOINT。

Docker容器

镜像启动的实例。

资源限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#内存限额 -m 或 --memory
docker run -m 200M --menmory-swap=300M ubantu
#CPU限额 -c 或 --cpu-shares
docker run --name A -c 1024 ubantu

#Block IO带宽限额 限制容器写 /dev/sda的速率为30 MB/s
docker run -it --device-write-bps /dev/sda:30MB ubantu

--device-read-bps:限制读某个设备的bps。
--device-write-bps:限制写某个设备的bps。
--device-read-iops:限制读某个设备的iops。
--device-write-iops:限制写某个设备的iops。

bps是byte per second,每秒读写的数据量。
iops是io per second,每秒IO的次数。

容器的底层技术

cgroup实现资源限额,namespace实现资源隔离。

cgroup

cgroup全称Control Group。Linux操作系统通过cgroup可以设置进程使用CPU、内存和IO资源的限额。上面的 --cpu-shares、-m、–device-write-bps 实际上就是在配置cgroup。可以在宿主机或者容器内 /sys/fs/cgroup中找到它。有一个漏洞CVE-2022-0492(cgroup逃逸), 这里不展开写。

image

namespace

在每个容器中,我们都可以看到文件系统、网卡等资源,这些资源看上去是容器自己的。拿网卡来说,每个容器都会认为自己有一块独立的网卡,即使host上只有一块物理网卡。Linux实现这种方式的技术是namespace。namespace管理着host中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace实现了容器间资源的隔离。

Linux使用了6种namespace,分别对应6种资源:Mount、UTS、IPC、PID、Network和User。

  • Mount namespace让容器看上去拥有整个文件系统。

  • UTS namespace让容器有自己的hostname。

  • IPC namespace让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与host和其他容器的IPC混在一起。

  • PID namespace 让容器在host中以进程的形式运行。例如当前host中运行了两个容器。通过宿主机 ps axf 可以查看容器进程。所有容器的进程都挂在dockerd进程下,同时也可以看到容器自己的子进程。

  • Network namespace让容器拥有自己独立的网卡、IP、路由等资源。

  • User namespace让容器能够管理自己的用户,host不能看到容器中创建的用户。

Docker网络

单个host上的容器网络

none网络

none网络就是什么都没有的网络。挂在这个网络下的容器除了lo,没有其他任何网卡。

1
docker run -itd --network=none httpd

host网络

连接到host网络的容器共享Docker host的网络栈,容器的网络配置与host完全一样。

1
2
3
4
docker run -itd --network=host httpd
docker inspect 309d1004f38c

"NetworkMode": "host"

bridge网络

Docker安装时会创建一个命名为docker0的Linux bridge。如果不指定–network,创建的容器默认都会挂到docker0上。 brctl show可以看网卡

image

1
2
3
4
docker run -itd httpd
docker inspect da9b1b378e0f

"NetworkMode": "default"

image

user-defined网络

用户也可以根据业务需要创建user-defined网络。

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
docker network create --driver bridge my_net 1
docker network inspect1 my_net #查看

"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},


docker run -itd --network=my_net1 httpd

#设置网络
--subnet 172.22.16.0/24
--gateway 172.22.16.1


#使用 --ip 指定IP 只有使用 --subnet创建的网络才能指定静态IP。
docker network create --driver bridge my_net2 --subnet 172.22.16.0/24 --gateway 172.22.16.1
docker run -itd --network=my_net2 --ip 172.22.16.8 busybox

不同的网卡 host 的 iptables 默认DROP 无法连通。如果需要连通,则需添加目标网络网卡

1
docker network connect my_net2 httpd容器ID

容器间通信

容器之间可通过IP, Docker DNS Server joined 容器三种方式通信。两个容器要能通信,必须要有属于同一个网络的网卡。

  • IP

    具体做法是在容器创建时通过 --network指定相应的网络,或者通过docker network connect将现有容器加入到指定网络。

  • Docker DNS Server

    docker daemon实现了一个内嵌的DNS server,使容器可以直接通过"容器名"通信。方法很简单,只要在启动时用 --name为容器命名就可以了。

  • joined容器

    joined容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined容器之间可以通过127.0.0.1直接通信。

    1
    2
    3
    docker run -d -it --name=web1 httpd
    docker run -it --network=container:web1 busybox
    #两个容器使用相同的网卡

将容器与外部世界连接

通过NAT, docker实现了容器对外网的访问。

image

(1)busybox发送ping包:172.17.0.2 > www.bing.com

(2)docker0收到包,发现是发送到外网的,交给NAT处理。

(3)NAT将源地址换成enp0s3的IP:10.0.2.15 > www.bing.com

(4)ping包从enp0s3发送出去,到达www.bing.com

外部世界访问容器

docker可将容器对外提供服务的端口映射到host的某个端口,外网通过该端口访问容器。容器启动时通过-p参数映射端口。

1
2
docker run -d -p [host port]:[container port] httpd 
docker run -d -p 8080:80 httpd

每一个映射的端口,host都会启动一个docker-proxy进程来处理访问容器的流量。

image

(1)docker-proxy监听host的32773端口。

(2)当curl访问10.0.2.15:32773时,docker-proxy转发给容器172.17.0.2:80。

(3)httpd容器响应请求并返回结果。

跨多个host的网络

跨主机网络方案:docker原生的overlay和macvlan; 第三方方案:常用的包括flannel、weave和calico。这些方案与docker集成是通过libnetworkcontainer network model

libnetwork & CNM

libnetwork是docker容器网络库,最核心的内容是其定义的Container Network Model(CNM)

  • Sandbox(类似存储interface、路由表和DNS设置的表):Sandbox是容器的网络栈,包含容器的interface、路由表和DNS设置。LinuxNetwork Namespace是Sandbox的标准实现。Sandbox可以包含来自不同Network的Endpoint。
  • Endpoint(类似网卡):Endpoint的作用是将Sandbox接入Network。Endpoint的典型实现是veth pair,一个Endpoint只能属于一个网络,也只能属于一个Sandbox。
  • Network(类似交换机):Network包含一组Endpoint,同一Network的Endpoint可以直接通信。Network的实现可以是Linux Bridge、VLAN等。

libnetwork CNM定义了docker容器的网络模型,按照该模型开发出的driver就能与docker daemon协同工作,实现容器网络。

imageimage

overlay

容器跨主机通信,Docker提供了overlay driver,使用户可以创建基于VxLAN的overlay网络。VxLAN可将二层数据封装到UDP进行传输,VxLAN提供与VLAN相同的以太网二层服务,但是拥有更强的扩展性和灵活性。(就是新建了桥接网卡,容器可添加变为双网卡)

1
2
#创建 docker network create   -d 指定网络driver
docker network create -d overlay ov_net1

macvlan

macvlan本身是linux kernel模块,其功能是允许同一个物理网卡配置多个MAC地址,即多个interface,每个interface可以配置自己的IP。macvlan本质上是一种网卡虚拟化技术

1
2
3
4
docker network create -d macvlan --subnet=172.16.86.0/24 \
--gateway=172.16.86.1 -o parent=eth1 mac_net1

-o parent指定使用的网络interface。
  • docker没有为macvlan提供DNS服务,这点与overlay网络是不同的。无法ping bbox1,只能通过IP。
  • macvlan网络是local网络,为了保证跨主机能够通信,用户一般需要自己管理IP subnet。
  • docker不会为macvlan创建网关,这里的网关应该是真实存在的,否则容器无法路由。
1
2
docker run -itd --name bbox1 --ip=172.16.86.10 --network nac_net1 busybox
docker run -itd --name bbox2 --ip=172.16.86.11 --network nac_net1 busybox

macvlan不依赖Linux bridge, brctl show可以确认并没有创建新的bridge

image

用sub-interface实现多macvlan网络

macvlan会独占主机的网卡,也就是说一个网卡只能创建一个macvlan网络。macvlan不仅可以连接到interface(如enp0s9),也可以连接到sub-interface(如VLAN enp0s9.xxx)。

不同macvlan网络之间不能通信。但准确的说法应该是:不同macvlan网络不能在二层上通信。在三层上可以通过网关将macvlan连通。可以借助中间网关连通。可以是物理路由,可以是某台主机配置的sub-interface网关IP。开启ip forward,以及iptables来充当虚拟路由器。

如将Host 192.168.56.101配置成一个虚拟路由器,设置网关并转发VLAN10和VLAN20的流量。

image···

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//ip forward开启
sysctl -w net.ipv4.ip_forward=1

//在 /etc/network/interfaces中配置vlan sub-interface
auto eth2 iface eth2 inet manual
auto eth2.10 iface eth2.10 inet manual vlan-raw-device eth2
auto eth2.20 iface eth2.20 inet manual vlan-raw-device eth2
启用sub-interface:
ifup eth2.10 ifup eth2.20

//将网关IP配置到sub-interface:
ifconfig eth2.10 172.16.10.1 netmask 255.255.255.0 up
ifconfig eth2.20 172.16.20.1 netmask 255.255.255.0 up

//添加iptables规则,转发不同VLAN的数据包。
iptables -t nat -A POSTROUTING -o eth2.10 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2.20 -j MASQUERADE
iptables -A FORWARD -i eth2.10-o eth2.20 -m state --state RELATED, ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth2.20-o eth2.10 -m state --state RELATED, ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth2.10-o eth2.20 -j ACCEPT
iptables -A FORWARD -i eth2.20-o eth2.10 -j ACCEPT

第三方需要特别搭建,文章篇幅不拓展了

flannel

flannel是CoreOS开发的容器网络解决方案。flannel为每个host分配一个subnet,容器从此subnet中分配IP,这些IP可以在host间路由,容器间无须NAT和portmapping就可以跨主机通信。同时没有隔离能力。

每个subnet都是从一个更大的IP池中划分的,flannel会在每个主机上运行一个叫flanneld的agent,其职责就是从池子中分配subnet。为了在各个主机间共享信息,flannel用etcd(与consul类似的key-value分布式数据库)存放网络配置、已分配的subnet、host的IP等信息。

weave

weave是Weaveworks开发的容器网络解决方案。weave创建的虚拟网络可以将部署在多个主机上的容器连接起来。对容器来说,weave就像一个巨大的以太网交换机,所有容器都被接入这个交换机,容器可以直接通信,无须NAT和端口映射。除此之外,weave的DNS模块使容器可以通过hostname访问。weave不依赖分布式数据库(例如etcd和consul)交换网络信息,每个主机上只需运行weave组件就能建立起跨主机容器网络。

默认配置下,weave使用一个大subnet(例如10.32.0.0/12),所有主机的容器都从这个地址空间中分配IP,因为同属一个subnet,容器可以直接通信。如果要实现网络隔离,可以通过环境变量WEAVE_CIDR为容器分配不同subnet的IP。

weave是一个私有的VxLAN网络,默认与外部网络隔离。连通需要(1)首先将主机加入到weave网络。(2)然后把主机当作访问weave网络的网关。

calico

Calico是一个纯三层的虚拟网络方案,Calico为每个容器分配一个IP,每个host都是router,把不同host的容器连接起来。与VxLAN不同的是,Calico不对数据包做额外封装,不需要NAT和端口映射,扩展性和性能都很好。Calico依赖etcd在不同主机间共享和交换信息,存储Calico网络状态。host192.168.56.101负责运行etcd。Calico网络中的每个主机都需要运行Calico组件,实现容器interface管理、动态路由、动态ACL、报告状态等。

不同的calico网络,默认不能通行。calico默认的policy规则是:容器只能与同一个calico网络中的容器通信。

Docker存储

Docker为容器提供了两种存放数据的资源:由storage driver管理的镜像层和容器层和Data Volume

Storage driver

storage driver实现了多层数据的堆叠并为用户提供一个单一的合并之后的统一视图。Docker支持多种storage driver,有AUFS、Device Mapper、Btrfs、OverlayFS、VFS和ZFS。

优先使用Linux发行版默认的storage driver。

Ubuntu默认driver用的是AUFS,底层文件系统是extfs

Redhat/CentOS的默认driver是Device Mapper, SUSE则是Btrfs

容器没有需要持久化的数据,随时可以从镜像直接创建。使用storage driver即可。

Data Volume

Data Volume本质上是Docker Host文件系统中的目录或文件,能够直接被mount到容器的文件系统中。

(1)Data Volume是目录或文件,而非没有格式化的磁盘(块设备)。

(2)容器可以读写volume中的数据。

(3)volume数据可以被永久地保存,使用它的容器销毁不影响它。

在具体的使用上,docker提供了两种类型的volume:bind mountdocker managed volume

bind mount

bind mount是将host上已存在的目录或文件mount到容器。即使容器没有了,bind mount也还在。bind mount时还可以指定数据的读写权限,默认是可读可写,可指定为只读

1
2
3
4
5
-v的格式为 <host path>:<container path>
docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

ro=Read-only 只有host有权修改数据,提高了安全性。
docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs:ro httpd

docker managed volume

docker managed volume与bind mount在使用上的最大区别是不需要指定mount源,随机在host生成。docker inspect 容器长ID 查看存储源位置。

1
docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd

数据共享

容器与host共享数据

对于bind mount是非常明确的:直接将要共享的目录mount到容器。

docker managed volume就要麻烦点。由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据复制到volume中。

1
2
docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
docker cp ~/htdocs/index.html 容器ID:/usr/local/apache2/htdocs

容器之间共享数据

将共享数据放在bind mount中,然后将其mount到多个容器。

1
2
docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

另一种在容器之间共享数据的方式是使用volume container。volume container是专门为其他容器提供volume的容器。它提供的卷可以是bind mount,也可以是docker managed volume。

1
2
3
4
5
docker create vc_data \
-v ~/htdocs:/usr/local/apache2/htdocs \
-v /other/useful/tools httpd

docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

容器命名为vc_data,docker create命令,这是因为volume container的作用只是提供数据,它本身不需要处于运行状态。

  • bind mount,存放Web Server的静态文件。

  • docker managed volume,存放一些实用工具

  • 其他容器可以通过--volumes-from使用vc_data这个volume container

1
2
docker run --name web1 -d -p 80 --volumes-from vc_data httpd
docker run --name web2 -d -p 80 --volumes-from vc_data httpd

data-packed volume container 将数据完全放到volume container中,同时又能与其他容器共享。原理是将数据打包到镜像中,然后通过docker managed volume共享。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs

//build新镜像datapacked
docker build -t datapacked .


ADD将静态文件添加到容器目录 /usr/local/apache2/htdocs。
VOLUME的作用与 -v 等效,用来创建docker managed volume,mount point 为/usr/local/apache2/htdocs
因为这个目录就是ADD添加的目录,所以会将已有数据复制到volume中。


//build新镜像datapacked
docker create --name vc_data datapacked

因为在Dockerfile中已经使用了VOLUME指令,这里就不需要指定volume的mount point了,启动httpd容器并使用data-packed volume container。和volume container其实一样。

1
docker run --name web2 -d -p 80:80 --volumes-from vc_data httpd

容器监控

监控子命令:ps、top和stats,然后是几个功能更强的开源监控工具sysdig、Weave Scope、cAdvisor和Prometheus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//监控子命令
docker container ps
docker container top 容器ID //某个容器中运行了哪些进程
docker container stats //用于显示每个容器各种资源的使用情况

//sysdig
docker container run -it --rm --name=sysdig --privileged=true \ --
volume=/var/run/docker.sock:/host/var/run/docker.sock \ --
volume=/dev:/host/dev \ --volume=/proc:/host/proc:ro \ --
volume=/boot:/host/boot:ro \ --volume=/lib/modules:/host/lib/modules:ro
\ --volume=/usr:/host/usr:ro \ sysdig/sysdig

//Weave Scope
curl -L git.io/scope -o /usr/local/bin/scope
chmod a+x /usr/local/bin/scope
scope launch

//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:latest


Prometheus提供了监控数据搜集、存储、处理、可视化和告警一套完整的解决方案。

  1. Prometheus Server:负责从Exporter拉取和存储监控数据,并提供一套灵活的查询语言(PromQL)供用户使用。
  2. Exporter:负责收集目标对象(host、container等)的性能数据,并通过HTTP接口供Prometheus Server获取。
  3. 可视化组件:Grafana能够与Prometheus无缝集成,提供完美的数据展示能力。
  4. Alertmanager:用户可以定义基于监控数据的告警规则,规则会触发告警。一旦Alertmanager收到告警,会通过预定义的方式发出告警通知。支持的方式包括Email、PagerDuty、Webhook等。

image

日志管理

Docker logs

1
2
docker attach 容器ID  //只能记录attach执行后的日志 按Ctrl+p键,然后再按Ctrl+q键才能退出
docker logs -f 容器ID

ELK

ELK是三个软件的合称:Elasticsearch、Logstash、Kibana。 Logstash->Elasticsearch->Kibana

  1. Elasticsearch:一个近乎实时查询的全文搜索引擎。Elasticsearch的设计目标就是要能够处理和搜索巨量的日志数据。
  2. Logstash:读取原始日志,并对其进行分析和过滤,然后将其转发给其他组件(比如Elasticsearch)进行索引或存储。Logstash支持丰富的Input和Output类型,能够处理各种应用的日志。
  3. Kibana:一个基于JavaScript的Web图形界面程序,专门用于可视化Elasticsearch的数据。Kibana能够查询Elasticsearch并通过丰富的图表展示结果。用户可以创建Dashboard来监控系统的日志。
1
2
3
4
5
docker run -p 5601:5601-p 9200:9200-p 5044:5044-it --name elk sebp/elk

- 5601:Kibana web接口
- 9200:Elasticsearch JSON接口
- 5044:Logstash日志接收接口