Kubernetes彻底改变了构建基础架构的方式,加快了部署速度,并使我们能够复制和扩展微服务架构。但是,Kubernetes在应用可见性和监控功能方面,却面临一系列新的挑战。
在这篇文章中,我通过回顾Sensu首席执行官Caleb Hailey在CNCF的讨论,如:一些现有的和流行的Kubernetes监控模式(例如Prometheus),以及为什么传统方法在云原生世界中的不足。除此之外,我还将介绍用于监控Kubernetes上的工作负载的当前最佳实践–sidecar模式。
容器:现状
长期以来,我们一直依靠微服务,实现在云中更快,更可靠地交付软件。容器化是微服务发展过程中自然而然的下一步,它与Kubernetes一起进行容器编排,迫使我们重新考虑如何部署和监控应用程序。
尽管Kubernetes是一个功能强大的平台,可用于在任何地方运行应用程序,但这种功能带来了更多的复杂性。
Kubernetes监控:挑战和数据来源
采用Kubernetes意味着要争夺各种各样的数据源。这些数据源都是抽象的,因此要了解系统的运行状况和性能,你需要访问堆栈中的监控数据。
Sensu首席技术官Sean Porter 之前在一篇文章中详细概述了数据源。简而言之,你需要能够从四个主要来源收集数据:
Kubernetes的动态特性,要求一种动态的监控方法–并可以应对大量的分布式应用程序和临时基础设施。
Kubernetes监控策略
监控策略概括如下:
- 远程轮询 -轮询设备并报告其健康状况的传统服务检查方法。
- 基于节点(每个主机的代理) -监控代理位于Kubernetes主机上,或者在Kubernetes集群内部以DaemonSet进行部署,以获得对系统资源信息的访问。
- Sidecar(每个Pod的代理) -用于监控Kubernetes系统及其正在运行的工作负载。
- 日志和APM-日志数据和应用程序性能的管理。
考虑到这些可观察性方法,让我们仔细研究监控Kubernetes的一种更传统的方法:使用Prometheus。
Kubernetes:Prometheus监控
有篇很不错的文章—Prometheus成为Kubernetes出色的基于遥测的监控伴侣的方法。
使用Prometheus监控有个好处,就是开发人员不用修改他们的deployment的yaml文件。
但是,如果你需要服务的功能运行状况检查,Prometheus则无法反映“是否健康?”。
更全面的监控方法:Sidecar模式
Kubernetes监控的 sidecar 模式是一种更具动态性的方法。Sidecar作为一种模式并不是Kubernetes的正式约定,但是随着Kubernetes的发展,Sidecar也越来越普及。
Kubernetes的Sidecar示例包括:
- 服务网格
- 使用作为sidecar运行的代理,来记录平台的日志
- 监控解决方案(例如Sensu),他们以sidecar方式运行代理,可以为每个服务一对一地配对监控代理。
当你使用sidecar模式时,你的Kubernetes pod将运行应用程序的容器与运行Sensu代理的容器保持在一起。这些容器共享相同的网络空间,因此你的应用程序可以与Sensu通信,它们就像在同一容器或主机中运行一样。
Sidecar具有和微服务在云原生环境中相同的优势,如:
- 模块化的
- 可组合
- 可重用
演示:Sidecar方式监控应用程序
在本教程中,我们将使用Kubectl在Kubernetes中部署应用程序(NGINX网站)。在演示的第二部分中,我们将展示如何监控已部署的应用程序。
如果你想再本地使用演示,则需要安装Kubernetes(可以通过Minikube工具在本地运行Kubernetes)并将Sensu部署到Kubernetes中。
完整示例: https://github.com/calebhailey/monitoring-k8s-workloads
在kubernetes中部署Sensu,请参考 https://github.com/sensu/sensu-kube-demo
首先,使用kubectl apply命令部署NGINX部署:
nginx-deployment.yaml
--- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - name: http protocol: TCP port: 8000 targetPort: 80 type: LoadBalancer --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx spec: replicas: 3 selector: matchLabels: app: nginx minReadySeconds: 10 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - protocol: TCP containerPort: 80
部署
$ kubectl create namespace webinar $ kubectl --namespace webinar apply -f kubernetes/nginx-deployment.yaml $ kubectl --namespace webinar get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx LoadBalancer 10.27.251.183 35.230.122.31 8000:30161/TCP 33d
NGINX容器默认在80端口上运行。我通过8000端口暴露了它。
现在,在浏览器中输入http://35.230.122.31:8000访问你的NGINX应用程序。
你已经在Kubernetes中部署了应用程序或服务,但是如何找出监控它的最佳方法。
让我们看看如何将Sensu Go代理作为 sidecar 添加到你的应用程序中。(这适用于所有Kubernetes控制器: deployments ,Statefulsets,DaemonSet等)。
nginx-deployment-with-sensu-sidecar.yaml
--- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - name: http protocol: TCP port: 8000 targetPort: 80 type: LoadBalancer --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx spec: replicas: 3 selector: matchLabels: app: nginx minReadySeconds: 10 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - protocol: TCP containerPort: 80 - name: sensu-agent image: sensu/sensu:5.11.1 command: ["/opt/sensu/bin/sensu-agent", "start", "--log-level=debug", "--insecure-skip-tls-verify", "--keepalive-interval=5", "--keepalive-timeout=10"] env: - name: SENSU_BACKEND_URL value: wss://sensu-backend-0.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-1.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-2.sensu.sensu-system.svc.cluster.local:8081 - name: SENSU_NAMESPACE value: webinar - name: SENSU_SUBSCRIPTIONS value: linux kubernetes nginx - name: SENSU_DEREGISTER value: "true" - name: SENSU_STATSD_EVENT_HANDLERS value: statsd
使用kubectl apply以下命令更新你的deployment:
$ kubectl --namespace webinar apply -f kubernetes/nginx-deployment-with-sensu-sidecar.yaml
访问Sensu面板,将看到Sensu自动注册Sidecar。(Sensu还会自动注销节点,因此你可以分辨出发生故障的节点与已取消配置的节点之间的区别。)
Kubernetes中deployment 的.spec.template.spec.containers:
- name: sensu-agent image: sensu/sensu:5.11.1 command: ["/opt/sensu/bin/sensu-agent", "start", "--log-level=debug", "--insecure-skip-tls-verify", "--keepalive-interval=5", "--keepalive-timeout=10"] env: - name: SENSU_BACKEND_URL value: wss://sensu-backend-0.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-1.sensu.sensu-system.svc.cluster.local:8081 wss://sensu-backend-2.sensu.sensu-system.svc.cluster.local:8081 - name: SENSU_NAMESPACE value: webinar - name: SENSU_SUBSCRIPTIONS value: linux kubernetes nginx - name: SENSU_DEREGISTER value: "true" - name: SENSU_STATSD_EVENT_HANDLERS value: statsd
现在已经有了此配置,你可以轻松扩展资源。
$ kubectl --namespace webinar scale deployment nginx --replicas 10
在配置监控检查之前,我们有必要了解下有关Sensu的体系结构以及服务如何通信的背景知识。
Sensu代理以pub-sub模型与Sensu后端进行通信,并且该代理仅要求出站网络访问,因此我们不必打开代理中或Pod上的端口即可访问它们。
代理在Sensu Go中具有TLS加密的Web套接字,它们与Sensu后端保持此连接,并内置支持高可用性。
当代理连接时,它会自我描述其角色。如果是 sidecar ,它说:“我在Kubernetes上,我是Docker容器,我的角色是nginx服务。” 代理通过订阅收集数据。Sensu支持各种插件,如:Nagios插件,本地StatsD套接字,Prometheus endpoints等等。
在本教程中,我们将使用Nagios check_http插件配置一个简单的检查。
首先,你需要提供Sensu配置,其中包括四个主要属性: resource type, API version, metadata, 和spec 。这些将在控制平面中注册,并与监控检查配置关联。
例如,这是Sensu中的监控检查,其中包含注册该检查所需的插件:
输出的格式为nagios_perfdata,并将其写入InfluxDB。
让我们配置监控检查:
$ sensuctl --namespace webinar create -f sensu/checks/check-nginx.yaml
你会看到该配置出现在Sensu仪表板中,可以在需要的地方对其进行编辑,并且该配置将在所有三个Kubernetes Pod上自动执行。
这是你的服务检查结果:
通过Sensu的监控事件管道,最终我们可以再面板上看到这些数据。
你可以在Sensu中配置InfluxDB处理程序,以将数据从其Nagios格式转换为InfluxDB格式,以便可以将其写入InfluxDB,并且可以开始在Granfana仪表板上查看指标。
以下是配置遥测管道(InfluxDB处理程序)的方法:
sensu/handlers/influxdb.yaml
--- type: Asset api_version: core/v2 metadata: name: monitoring-plugins-alpine spec: url: https://github.com/calebhailey/sensu-assets-monitoring-plugins/releases/download/2.2.0/monitoring-plugins-alpine_2.2.0_linux_amd64.tar.gz sha512: 81f7d411bd4ed4234dc54cd9218e808130a0a7db93d8ea998aa6ce74dc847bbd87ffa232c70bf4b066eb96ff3e6cb3ea0ddab1f593050b5c0bdb83f4eb36a6b2 filters: - entity.system.os == 'linux' - entity.system.arch == 'amd64' - entity.system.platform == 'alpine' --- type: Asset api_version: core/v2 metadata: name: monitoring-plugins-centos spec: url: https://github.com/calebhailey/sensu-assets-monitoring-plugins/releases/download/2.2.0/monitoring-plugins-centos_2.2.0_linux_amd64.tar.gz sha512: 0131ffea75099b2140b2d11da576c5b601d99eb7661a8105cadd884e5d953f215d23386a84ed871aabfe6a5751ce11443278be6ab510c8feab478b0365b329f0 filters: - entity.system.os == 'linux' - entity.system.arch == 'amd64' - entity.system.platform == 'centos' --- type: Asset api_version: core/v2 metadata: name: monitoring-plugins-debian spec: url: https://github.com/calebhailey/sensu-assets-monitoring-plugins/releases/download/2.2.0/monitoring-plugins-debian_2.2.0_linux_amd64.tar.gz sha512: 632366d0d55bd79762a71ef4e3209bcf6a499b6449ef6cb9471712e7799d3f6834ae7b3bafa1dfb00d4f358afed27971e7ed8b34d0424cdb31ec7a18aaf74b4f filters: - entity.system.os == 'linux' - entity.system.arch == 'amd64' - entity.system.platform == 'debian' --- type: CheckConfig api_version: core/v2 metadata: name: check-nginx spec: command: check_http -H 127.0.0.1 -N publish: true interval: 10 subscriptions: - nginx runtime_assets: - monitoring-plugins-alpine - monitoring-plugins-centos - monitoring-plugins-debian timeout: 10 output_metric_format: nagios_perfdata output_metric_handlers: - influxdb
部署
$ sensuctl --namespace webinar create -f sensu/handlers/influxdb.yaml
你可以在GitHub中重新查看这些配置。
最后
现在,你已经建立了一个简单的管道,该管道可以通过Sidecar模式从Kubernetes收集指标,并且能够将数据发送到Grafana进行可视化。
如果你想了解有关InfluxDB处理程序(或可与Sensu Go一起使用的任何其他处理程序,包括PagerDuty,ElasticSearch,Splunk等的处理程序)的更多信息,请访问Sensai社区的开源目录Bonsai。
译文链接: https://kubernetes.io/blog/2020/04/16/monitoring-kubernetes-sidecar-pattern/