dotnet-monitor可以在Kubernetes中作为Sidecar运行,Sidecar是一个容器,它与应用程序在同一个Pod中运行,利用Sidecar模式使我们可以诊断及监控应用程序。
如下图所示,这是我们最终要实现的目标,通过可视化界面查看应用程序的指标信息。
应用服务
创建dotnetmonitor.yaml
文件,如下所示。
apiVersion: apps/v1
kind: Deployment
metadata:name: dotnet-monitor-example
spec:replicas: 3selector:matchLabels:app: dotnet-monitor-exampletemplate:metadata:annotations:prometheus.io/scrape: 'true'prometheus.io/port: "52325"labels:app: dotnet-monitor-examplespec:containers:- name: serverimage: mcr.microsoft.com/dotnet/core/samples:aspnetappports:- containerPort: 80volumeMounts:- mountPath: /tmpname: tmp- name: sidecarimage: mcr.microsoft.com/dotnet/monitorports:- containerPort: 52323resources:requests:cpu: 50mmemory: 32Milimits:cpu: 250mmemory: 256Miargs: ["--no-auth"]env:- name: DOTNETMONITOR_Urlsvalue: "http://+:52323"volumeMounts:- name: tmpmountPath: /tmpvolumes:- name: tmpemptyDir: {}
Sidecar和应用程序共享tmp
目录,同时将目录映射到emptyDir
类型的 Volume中。接下来,创建dotnetmonitor-service.yaml,为应用程序和Sidecar开放端口。
apiVersion: v1
kind: Service
metadata:name: dotnetmonitorlabels:app: dotnetmonitor
spec:type: NodePortports:- name: sidecarprotocol: TCPport: 52323nodePort: 31623- name: appprotocol: TCPport: 80nodePort: 31624selector:app: dotnet-monitor-example
Prometheus配置
创建prometheus-config.yaml
文件,通过ConfigMaps管理Prometheus的配置文件,并写入如下内容。
apiVersion: v1
kind: ConfigMap
metadata:name: prometheus-config
data:prometheus.yaml: |global:scrape_interval: 2s evaluation_interval: 2sscrape_configs:- job_name: 'prometheus'static_configs:- targets: ['localhost:9090']- job_name: default/dotnet-monitor-example/0honor_timestamps: truescrape_interval: 10sscrape_timeout: 10smetrics_path: /metricsscheme: httpfollow_redirects: truerelabel_configs:# 使用 Label "__meta_kubernetes_pod_container_name" 的值- source_labels: [__meta_kubernetes_pod_container_name]separator: ;# 正则表达式,用于匹配源标签值使用的regex: sidecar# replacement指定的替换后的标签(target_label)对应的数值replacement: $1# keep就是保留符合正则表达式targets,并显示出来action: keep - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]action: keepregex: true- source_labels: [__meta_kubernetes_pod_name]action: replacetarget_label: podkubernetes_sd_configs:- role: endpointsfollow_redirects: truenamespaces:names:- default
在Prometheus中如果采用静态服务发现(static_configs)模式注册,那么HPA(HorizontalPodAutoscaler,Pod水平自动伸缩)的变动会导致服务很难快速的注册,如果频繁更改配置文件,那么也是得不偿失的,所以,在此处选择kubernetes服务发现(kubernetes_sd_configs)模式,除此之外Prometheus还支持其他方式的服务发现。
static_configs: 静态服务发现
dns_sd_configs: DNS 服务发现
file_sd_configs: 文件服务发现
kubernetes_sd_configs: Kubernetes 服务发现
gce_sd_configs: GCE 服务发现
ec2_sd_configs: EC2 服务发现
openstack_sd_configs: OpenStack 服务发现
azure_sd_configs: Azure 服务发现
现在,意味着我们会在Kubernetes中的会保留__meta_kubernetes_pod_container_name
值为sidecar的,同时也需要满足__meta_kubernetes_pod_annotation_prometheus_io_scrape
属性为true的Pod。
接下来,创建prometheus-rbac-setup.yaml
文件,为了使Prometheus可以访问到Kubernetes API,我们需要对Prometheus进行访问授权,在Kubernetes中通过基于角色的访问控制模型(Role-Based Access Control),用于访问Kubernetes的资源。首先我们定义角色(ClusterRole)并设置相应的访问权限;为Prometheus创建账号(ServiceAccount);最后将账号与角色进行绑定(ClusterRoleBinding)。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: prometheus
rules:
- apiGroups: [""]resources:- nodes- nodes/proxy- services- endpoints- podsverbs: ["get", "list", "watch"]
- apiGroups:- extensionsresources:- ingressesverbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:name: prometheusnamespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: prometheus
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: prometheus
subjects:
- kind: ServiceAccountname: prometheusnamespace: default
创建prometheus-deployment.yaml文件。
apiVersion: apps/v1
kind: Deployment
metadata:labels:name: prometheusname: prometheus
spec:replicas: 1selector:matchLabels:app: prometheus template:metadata:labels:app: prometheusspec:serviceAccountName: prometheuscontainers:- name: prometheusimage: prom/prometheus:latestcommand:- "/bin/prometheus"args:- "--config.file=/etc/prometheus/prometheus.yml"ports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: "/etc/prometheus"name: prometheus-configvolumes:- name: prometheus-configconfigMap:name: prometheus-config
创建prometheus-service.yaml文件。
apiVersion: v1
kind: Service
metadata:name: prometheuslabels:name: prometheus
spec:type: NodePortports:- name: prometheusprotocol: TCPport: 9090targetPort: 9090nodePort: 32732selector:app: prometheus
如下所示,展示了Prometheus仪表盘
Grafana
Grafana的内容不做展开了,当然你可以直接查看或使用我的dashboard文件。
https://github.com/hueifeng/dotnet-monitor-on-k8s
参考
部署Prometheus
https://dotnetos.org/blog/2021-11-22-dotnet-monitor-grafana/