本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2021年11月09日 统计字数: 15042字 阅读时间: 31分钟阅读 本文链接: https://soulteary.com/2021/11/09/private-cloud-environment-installed-in-a-notebook-storage-part-2.html ----- # 装在笔记本里的私有云环境:网络存储篇(中) 本篇是系列中的第四篇内容,我们继续聊聊如何把一个简化过的私有云环境部署在笔记本里,以满足低成本、低功耗、低延时的实验环境。 在前三篇文章中,我们聊过了基础虚拟化相关的[前置准备](https://soulteary.com/2021/10/28/private-cloud-environment-installed-in-a-notebook-preparation.html)、以及为了避免在搭建过程中盲人摸象,而准备的[监控服务](https://soulteary.com/2021/10/30/private-cloud-environment-installed-in-a-notebook-monitor.html),还有上一篇[基础存储服务](https://soulteary.com/2021/11/04/private-cloud-environment-installed-in-a-notebook-storage-part-1.html)的搭建。接下来我们来进行一些基础的监控配置以及监控服务完善,让存储服务能够相对稳定的运行在我们的“视野之内”。 ## 写在前面 在前文中,我们[提到了](https://soulteary.com/2021/10/30/private-cloud-environment-installed-in-a-notebook-monitor.html#%E5%BC%80%E6%BA%90%E7%9B%91%E6%8E%A7%E4%BA%A7%E5%93%81%E6%99%AE%E7%BD%97%E7%B1%B3%E4%BF%AE%E6%96%AF)包括 Prometheus 在内的监控服务的工作模式主要有“推”和“拉”两种。为了能够使用推送模式,我们部署了 [“推送网关:Push-Gateway”](https://soulteary.com/2021/10/30/private-cloud-environment-installed-in-a-notebook-monitor.html#%E6%8E%A8%E9%80%81%E7%BD%91%E5%85%B3push-gateway),但是“拉”模式就是开箱即用的吗? 除了一些云原生的应用外,默认应用多数并不包含能够让 Prometheus 能够开箱即用的,能够让 Prometheus 进行数据拉取的,包含应用性能指标数据的接口。 对于这些应用,为了能够让监控服务和它们能够进行持续的“数据交互”,我们得在需要监控的应用侧搭建一些数据上报服务,提供这个“数据开放”的能力。这些服务一般被称作“exporter”,它会根据应用的实际情况,采取使用应用 API 、文件监控、应用数据读取等方式将应用当前的运行状态汇总,在 Prometheus 进行数据抓取的时候进行提供,这些提供的数据一般被称作 “metrics”。 那么,我们就来挨着聊聊前文中提到的几个服务的监控集成,恰好它们的监控配置都比较典型。本文中提到的应用配置,同样已经上传到了 [GitHub](https://github.com/soulteary/Home-Network-Note/tree/master/example) 中,有需要的同学可以自取。 ## MinIO 的监控集成 第一个要聊的应用,是典型的云原生应用,它自带了能够让 Prometheus 开箱即用的接口。但是,考虑到应用性能以及运营数据的隐私要求,这个接口默认并不是默认开启的。 ### 开启 MinIO 的性能指标接口 为了能够让 Prometheus 对 MinIO 进行监控,我们需要先将它的性能指标接口通过配置变量的方式开启,编辑上文提到的 `docker-compose.yml` 文件,添加一个新的环境变量: ```php environment: - MINIO_PROMETHEUS_AUTH_TYPE=public ``` 这里对于这个配置可选数值还有 `jwt`,不过并不推荐,因为我们系列最终会使用 Traefik 进行统一鉴权管理,没有必要再加一层。如果你对另外一个模式感兴趣,可以[自行了解](https://github.com/minio/minio/blob/master/docs/metrics/prometheus/README.md)。 更新完配置后,我们使用 `docker-compose down && docker-compose up -d` 重启应用,MinIO 的监控接口便准备就绪啦,我们可以使用下面的地址进行访问性测试: ```bash curl http://s3.storage.lab.com/minio/v2/metrics/cluster ``` 如果顺利的话,你将会看到类似下面的内容: ```bash # HELP minio_bucket_objects_size_distribution Distribution of object sizes in the bucket, includes label for the bucket name. # TYPE minio_bucket_objects_size_distribution gauge minio_bucket_objects_size_distribution{bucket="public",range="BETWEEN_1024_B_AND_1_MB",server="127.0.0.1:9000"} 1 minio_bucket_objects_size_distribution{bucket="public",range="BETWEEN_10_MB_AND_64_MB",server="127.0.0.1:9000"} 0 minio_bucket_objects_size_distribution{bucket="public",range="BETWEEN_128_MB_AND_512_MB",server="127.0.0.1:9000"} 0 minio_bucket_objects_size_distribution{bucket="public",range="BETWEEN_1_MB_AND_10_MB",server="127.0.0.1:9000"} 0 minio_bucket_objects_size_distribution{bucket="public",range="BETWEEN_64_MB_AND_128_MB",server="127.0.0.1:9000"} 0 minio_bucket_objects_size_distribution{bucket="public",range="GREATER_THAN_512_MB",server="127.0.0.1:9000"} 0 minio_bucket_objects_size_distribution{bucket="public",range="LESS_THAN_1024_B",server="127.0.0.1:9000"} 0 # HELP minio_bucket_replication_received_bytes Total number of bytes replicated to this bucket from another source bucket. # TYPE minio_bucket_replication_received_bytes gauge minio_bucket_replication_received_bytes{bucket="public",server="127.0.0.1:9000"} 0 # HELP minio_bucket_usage_object_total Total number of objects ... ``` (上面打印出来的的内容,就是我们前文中提到的 Prometheus 实际工作时,进行定时抓取的性能指标数据。) ### 配置 Prometheus 抓取 MinIO 性能指标数据 在上报数据就绪后,我们来配置 Prometheus 的抓取配置,让这个数据能够持续的写入 Prometheus 的时序数据库中。 在监控篇中,我们提到了 Prometheus 的[部署和配置](https://soulteary.com/2021/10/30/private-cloud-environment-installed-in-a-notebook-monitor.html#%E4%B8%BB%E5%BA%94%E7%94%A8%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%BA%93prometheus),其中主要的抓取配置都保存在了 `config/prometheus.yml`,所以我们需要继续修改这个配置,让它能够抓取 MinIO。 ```yaml - job_name: minio scrape_interval: 10s metrics_path: /minio/v2/metrics/cluster scheme: http static_configs: - targets: ['s3.storage.lab.com'] ``` 更新完毕配置后,同样使用 `docker-compose down && docker-compose up -d` 重启 prometheus,然后在浏览器中访问:`http://monitor.lab.com:9090/targets`,在列表中就能看到 MinIO 已经被正确的作为新的数据源使用啦。 ![在 Prometheus 看到的 MinIO 数据源](https://attachment.soulteary.com/2021/11/09/minio-prom.jpg) ### 为 MinIO 配置 Grafana 监控面板 为了直观的观测 MinIO 的运行状况,我们可以继续在 Grafana 中为 MinIO 配置一个监控面板。MinIO 官方已经将一个比较通用的模版上传到了 Grafana 模版市场,我们可以直接进行使用。 ![MinIO 官方提供的 Grafana 面板](https://attachment.soulteary.com/2021/11/09/minio-grafana-dash-id.jpg) 参考监控篇中的“[Grafana 控制面板导入](https://soulteary.com/2021/10/30/private-cloud-environment-installed-in-a-notebook-monitor.html#%E5%8F%AF%E8%A7%86%E5%8C%96%E9%9D%A2%E6%9D%BFgrafana)”方式,将编号“13502”的面板导入 Grafana 中,就可以看到下面的监控面板界面了。 ![默认的 MinIO 监控面板](https://attachment.soulteary.com/2021/11/09/minio-grafana-default.jpg) 可以看到上面的界面中出现了非常多的 “N/A”,这是因为 Grafana 并不知道我们要使用哪一个上报的应用数据进行展示,在界面的左上角筛选并使用“minio”(上一小节在 Prometheus 抓取配置中配置的内容)之后,我们就能够看到正确的监控界面了。 ![数据来源筛选后的 MinIO 监控面板](https://attachment.soulteary.com/2021/11/09/minio-grafana-dashboard.jpg) 接着来聊聊另外一种普通应用的监控配置方式。 ## Syncthing 的监控集成 和 MinIO 不同的是,Syncthing 原生虽然支持通过 API 进行应用运行数据查询,但是它并不符合 Prometheus 的监控数据格式要求,所以我们需要为它搭建一个监控指标接口服务( exporter )进行数据暴露,以及配置 Prometheus 对它进行数据抓取。 ### 配置 Syncthing 性能指标服务 关于 Syncthing Exporter 的运行细节,可以围观 [GitHub 的仓库](https://github.com/f100024/syncthing_exporter)。为了更好的执行性能,我将这个项目的容器镜像进行了重新构建,并上传到了 [https://github.com/soulteary/syncthing\_exporter](https://github.com/soulteary/syncthing_exporter)。镜像已经推送到了 DockerHub,所以,你可以通过下面的方式获取这个更小的容器镜像(压缩后仅有12M): ```bash docker pull soulteary/syncthing-exporter ``` 访问 `https://syncthing.storage.lab.com` ,点击顶部导航栏右侧的操作按钮,选择“高级”配置菜单,在弹出的对话框里获取我们接下来要使用的“API KEY”。 ![获取 Syncthing API KEY](https://attachment.soulteary.com/2021/11/09/syncthing-api-token.jpg) 接着,编辑上篇文章中[提到的 Syncthing](https://soulteary.com/2021/11/04/private-cloud-environment-installed-in-a-notebook-storage-part-1.html#%E6%90%AD%E5%BB%BA%E5%90%8C%E6%AD%A5%E5%BA%94%E7%94%A8syncthing) 环境变量配置文件 `.env`,在文件尾部添加下面的内容,并使用刚刚获取的 API 替换下面的“`DOCKER_EXPORTER_API_TOKEN`”中的内容: ```bash # == exporter DOCKER_EXPORTER_IMAGE_NAME=soulteary/syncthing-exporter DOCKER_EXPORTER_API_TOKEN=YOUR_API_TOKEN DOCKER_EXPORTER_HOSTNAME=syncthing-exporter-on-storage DOCKER_EXPORTER_DOMAIN=syncthing-exporter.storage.lab.com ``` 然后,编写 Exporter 的容器配置 `docker-compose.exporter.yml`: ```yaml version: "3" services: syncthing-exporter: image: ${DOCKER_EXPORTER_IMAGE_NAME} container_name: DOCKER_EXPORTER_HOSTNAME expose: - 9093 restart: always environment: SYNCTHING_URI: "http://${DOCKER_SYNCTHING_HOSTNAME}:8384/" SYNCTHING_TOKEN: ${DOCKER_EXPORTER_API_TOKEN} labels: - "traefik.enable=true" - "traefik.docker.network=traefik" - "traefik.http.routers.sync-exporter-http.entrypoints=http" - "traefik.http.routers.sync-exporter-http.rule=Host(`${DOCKER_EXPORTER_DOMAIN}`)" - "traefik.http.routers.sync-exporter-http.service=sync-exporter-backend" - "traefik.http.routers.sync-exporter-https.entrypoints=https" - "traefik.http.routers.sync-exporter-https.tls=true" - "traefik.http.routers.sync-exporter-https.rule=Host(`${DOCKER_EXPORTER_DOMAIN}`)" - "traefik.http.routers.sync-exporter-https.service=sync-exporter-backend" - "traefik.http.services.sync-exporter-backend.loadbalancer.server.scheme=http" - "traefik.http.services.sync-exporter-backend.loadbalancer.server.port=9093" networks: - traefik logging: driver: "json-file" options: max-size: "1m" networks: traefik: external: true ``` 使用 `docker-compose -f docker-compose.exporter.yml up -d` 启动应用。如果你使用 `docker logs` 查看这个新创建的容器,会看到类似下面的日志: ```bash level=info ts=2021-11-09T13:11:20.621Z caller=main.go:94 msg="Starting syncthing_exporter" version="(version=0.3.2, branch=main, revision=84736272309b3b08d6b6feb08cc7d41f13b4cd5e)" level=info ts=2021-11-09T13:11:20.621Z caller=main.go:95 msg="Build context" build_context="(go=go1.17.3, user=local, date=09 Nov 2021 10:20:09 UTC)" level=info ts=2021-11-09T13:11:20.621Z caller=main.go:108 msg="Listening on" address=:9093 ``` 同样使用命令查看服务的可访问性: ```bash curl http://syncthing-exporter.storage.lab.com/metrics ``` 会看到和前文中类似的日志数据: ```bash # HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 2.2292e-05 go_gc_duration_seconds{quantile="0.25"} 2.2292e-05 go_gc_duration_seconds{quantile="0.5"} 2.2292e-05 go_gc_duration_seconds{quantile="0.75"} 2.2292e-05 go_gc_duration_seconds{quantile="1"} 2.2292e-05 go_gc_duration_seconds_sum 2.2292e-05 go_gc_duration_seconds_count 1 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 11 # HELP go_info Information about the Go environment. # TYPE go_info gauge go_info{version="go1.17.3"} 1 # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. # TYPE go_memstats_alloc_bytes gauge go_memstats_alloc_bytes 3.236424e+06 # HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed. # TYPE go_memstats_alloc_bytes_total counter go_memstats_alloc_bytes_total 4.851856e+06 # HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table. # TYPE go_memstats_buck_hash_sys_bytes gauge ... ``` ### 配置 Prometheus 抓取 Syncthing 性能指标数据 在上报数据就绪后,我们继续来配置 Prometheus 的数据抓取配置,让这个数据能够同样持续的写入 Prometheus 的数据库。继续编辑 `config/prometheus.yml` 配置文件: ```yaml - job_name: syncthing scrape_interval: 10s metrics_path: /metrics scheme: http static_configs: - targets: ['syncthing-exporter.storage.lab.com'] ``` 更新完上面的配置后,使用 `docker-compose down && docker-compose up -d` 重启 prometheus,然后在浏览器中访问:`http://monitor.lab.com:9090/targets`,列表中便会出现 Syncthing 的数据源了。 ![在 Prometheus 看到的 Syncthing 数据源](https://attachment.soulteary.com/2021/11/09/syncthing-prom.jpg) ### 为 Syncthing 配置 Grafana 监控面板 Syncthing 在 Grafana 官方面板市场中并没有配置被上传,我将 Syncthing 开源项目配套的面板配置进行了修改,并上传至了 [GitHub](https://github.com/soulteary/Home-Network-Note/blob/master/example/storage/syncthing/grafana.json)。 将这个 JSON 配置中的所有内容复制,然后使用 Grafana 导入配置的方式,在导入配置的文本框中粘贴进去上面的内容,Syncthing 的监控面板就搞定了。 ![配置完成的 Syncthing 监控面板](https://attachment.soulteary.com/2021/11/09/syncthing-grafana-dashboard.jpg) ## NextCloud 的搭建以及监控配置 上篇文章中想偷个懒,直接使用了之前为国际学术顶会使用的 [NextCloud 方案](https://soulteary.com/2020/08/09/use-docker-to-build-a-stable-and-reliable-private-network-disk.html)。但是有同学提出“我只有少量用户(比如自己)使用 NextCloud,能否不使用独立的数据库,使用轻量的 SQLite ,节约一些系统资源”。 答案是可以的, NextCloud 默认支持使用 SQLite 进行数据存储,在注意定期备份数据的前提下,作为自用的方案问题不大。 ### NextCloud 单人使用简单配置 为了让同学们能偷个懒,这里先补充一个 NextCloud 的简单配置,完整配置已上传至 [GitHub](https://github.com/soulteary/Home-Network-Note/tree/master/example/storage/nextcloud): ```yaml version: "3.6" services: nextcloud: image: ${DOCKER_NEXTCLOUD_IMAGE_NAME} container_name: ${DOCKER_NEXTCLOUD_HOSTNAME} restart: always expose: - 80 volumes: # Linux 环境下使用 # - /etc/localtime:/etc/localtime:ro # - /etc/timezone:/etc/timezone:ro - ./data:/var/www/html:rw extra_hosts: - "${DOCKER_NEXTCLOUD_DOMAIN}:127.0.0.1" networks: - traefik labels: - "traefik.enable=true" - "traefik.docker.network=traefik" - "traefik.http.routers.www-nextcloud.entrypoints=http" - "traefik.http.routers.www-nextcloud.rule=Host(`${DOCKER_NEXTCLOUD_DOMAIN}`)" - "traefik.http.routers.ssl-nextcloud.entrypoints=https" - "traefik.http.routers.ssl-nextcloud.tls=true" - "traefik.http.routers.ssl-nextcloud.rule=Host(`${DOCKER_NEXTCLOUD_DOMAIN}`)" - "traefik.http.services.www-nextcloud-backend.loadbalancer.server.scheme=http" - "traefik.http.services.www-nextcloud-backend.loadbalancer.server.port=80" logging: driver: "json-file" options: max-size: "1m" networks: traefik: external: true ``` 以及这个配置需要使用的 `.env` 环境变量: ```yaml # == nextcloud DOCKER_NEXTCLOUD_IMAGE_NAME=nextcloud:22.2.0 DOCKER_NEXTCLOUD_HOSTNAME=nextcloud.storage.lab.com DOCKER_NEXTCLOUD_DOMAIN=nextcloud.storage.lab.com ``` 使用 `docker-compose up -d` 启动服务,然后在浏览器中打开我们配置好的域名 `nextcloud.storage.lab.com` 就能够开始 NextCloud 的配置安装了。完成安装(初始化)之后,就能够看到久违的欢迎界面啦。 ![NextCloud 欢迎界面](https://attachment.soulteary.com/2021/11/09/nextcloud-welcome.jpg) ### 配置 NextCloud 的性能指标服务 在 NextCloud 服务就绪之后,因为 NextCloud 和 Syncthing 一样,本身并不直接支持使用 Prometheus 进行数据采集。所以,我们同样需要为它创建一个 Exporter 服务。先在 NextCloud 使用的环境变量 `.env` 文件中,继续添加需要使用的配置(使用你自己的应用账号和密码替换下面配置中的内容): ```bash # == exporter DOCKER_EXPORTER_IMAGE_NAME=xperimental/nextcloud-exporter DOCKER_EXPORTER_USER=soulteary DOCKER_EXPORTER_PASS=soulteary DOCKER_EXPORTER_DOMAIN=nextcloud-exporter.storage.lab.com ``` 接着,编写 Exporter 需要使用到的容器配置: ```yaml version: "3.6" services: nextcloud-exporter: image: ${DOCKER_EXPORTER_IMAGE_NAME} restart: always environment: NEXTCLOUD_SERVER: http://${DOCKER_NEXTCLOUD_DOMAIN} NEXTCLOUD_USERNAME: ${DOCKER_EXPORTER_USER} NEXTCLOUD_PASSWORD: ${DOCKER_EXPORTER_PASS} NEXTCLOUD_TIMEOUT: 5s expose: - 9205 networks: - traefik labels: - "traefik.enable=true" - "traefik.docker.network=traefik" - "traefik.http.routers.http-nextcloud-exporter.entrypoints=http" - "traefik.http.routers.http-nextcloud-exporter.rule=Host(`${DOCKER_EXPORTER_DOMAIN}`)" - "traefik.http.routers.nextcloud-exporter.entrypoints=https" - "traefik.http.routers.nextcloud-exporter.tls=true" - "traefik.http.routers.nextcloud-exporter.rule=Host(`${DOCKER_EXPORTER_DOMAIN}`)" - "traefik.http.services.nextcloud-exporter-backend.loadbalancer.server.scheme=http" - "traefik.http.services.nextcloud-exporter-backend.loadbalancer.server.port=9205" logging: driver: "json-file" options: max-size: "1m" networks: traefik: external: true ``` 然后,使用 `docker-compose -f docker-compose.exporter.yml up -d` 启动服务。 我们同样使用命令检查一下服务的可用性: ```bash curl http://nextcloud-exporter.storage.lab.com/metrics ``` 不出意外,会看到“熟悉”的日志: ```bash # HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 0.000185922 go_gc_duration_seconds{quantile="0.25"} 0.000185922 go_gc_duration_seconds{quantile="0.5"} 0.000224615 go_gc_duration_seconds{quantile="0.75"} 0.000224615 go_gc_duration_seconds{quantile="1"} 0.000224615 go_gc_duration_seconds_sum 0.000410537 go_gc_duration_seconds_count 2 # HELP go_goroutines Number of goroutines that currently exist. # TYPE go_goroutines gauge go_goroutines 9 # HELP go_info Information about the Go environment. # TYPE go_info gauge go_info{version="go1.15.3"} 1 # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. # TYPE go_memstats_alloc_bytes gauge go_memstats_alloc_bytes 3.402328e+06 # HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed. # TYPE go_memstats_alloc_bytes_total counter go_memstats_alloc_bytes_total 7.031024e+06 # HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table. # TYPE go_memstats_buck_hash_sys_bytes gauge go_memstats_buck_hash_sys_bytes 1.446245e+06 # HELP go_memstats_frees_total Total number of frees. # TYPE go_memstats_frees_total counter go_memstats_frees_total 31048 ... ``` ### 配置 Prometheus 抓取 NextCloud 性能指标数据 第三次重复操作,应该轻车熟路了吧 : D。继续编辑 `config/prometheus.yml` 配置文件: ```yaml - job_name: nextcloud scrape_interval: 10s metrics_path: /metrics scheme: http static_configs: - targets: ['nextcloud-exporter.storage.lab.com'] ``` 使用 `docker-compose down && docker-compose up -d` 重启 Prometheus,然后在浏览器中访问:`http://monitor.lab.com:9090/targets`,确认列表中包含新配置的 NextCloud 的数据源。 ![在 Prometheus 看到的 NextCloud 数据源](https://attachment.soulteary.com/2021/11/09/nextcloud-prom.jpg) ### 为 NextCloud 配置 Grafana 监控面板 NextCloud Exporter 的开源项目贡献者提供了一个现成的面板,所以相比较 Syncthing 而言,配置监控面板的操作会简单不少。 ![NextCloud 开源网友提供的 Grafana 面板](https://attachment.soulteary.com/2021/11/09/nextcloud-grafana-dash-id.jpg) 还是参考监控篇中的“[Grafana 控制面板导入](https://soulteary.com/2021/10/30/private-cloud-environment-installed-in-a-notebook-monitor.html#%E5%8F%AF%E8%A7%86%E5%8C%96%E9%9D%A2%E6%9D%BFgrafana)”方式,将编号“9632”的面板导入 Grafana 中,我们就可以看到类似下面的面板界面啦。 ![NextCloud 监控面板](https://attachment.soulteary.com/2021/11/09/nextcloud-grafana-dashboard.jpg) ## 最后 在写“装在笔记本里的私有云环境”这个系列的内容时,稍不注意文章字数(包含代码)就会超过各种平台允许最大字数,所以不得已将本篇文章进行了分拆。 迄今为止,我们已经几乎完成了全部存储服务的搭建,以及监控配置,下一篇文章中,我将会继续展开聊聊“数据备份”以及上篇文章中提到的典型的网络存储应用的搭建和使用。 --EOF