步骤 | 操作 | 代码示例
----|-----|--------
1 | 在K8S集群中部署metrics服务器 | `kubectl create -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml`
该命令会从GitHub下载metrics服务器的YAML配置文件,并创建相应资源。
2 | 配置metrics-server | 创建一个包含metrics-server的配置文件metrics-config.yaml,并将其应用到集群中
```apiVersion: v1```
```kind: ConfigMap```
```metadata:```
``` name: metrics-server-config```
``` namespace: kube-system```
```data:```
``` metrics-config.yaml: |```
``` apiVersion: kubelet.config.k8s.io/v1beta1```
``` kind: KubeletConfiguration```
``` metricsResolution: 10s```
``` authentication```
``` anonymous:```
``` enabled: false```
``` cgroupDriver: cgroupfs```
``` cpuManagerPolicy: none```
``` evictionHard:```
``` memory.available: "100Mi"```
``` enableControllerAttachDetach: true```
``` kubeReserved```
``` cpu: 100m```
``` memory: 200Mi```
``` systemReserved```
``` cpu: 100m```
``` memory: 200Mi```
``` evictionSoft:```
``` memory.available: "200Mi"```
``` imageMinimumGCAge: 2m```
``` kubeReservedCgroup: "/"```
``` evictionPressureTransitionPeriod: 20s```
``` cpuManagerReconcilePeriod: 10s```
``` rotateCertificates: true```
``` kubeReservedCgroupName: kube-reserved```
``` kubeReservedCgroupParent: ""```
``` nodeLease```
``` durationSeconds: 7```
``` renewDeadlineSeconds: 5```
``` renewIntervalSeconds: 2```
``` topologyManager```
``` policy: "best-effort"```
``` evictionSoftGracePeriod:```
``` memory.available: "300Mi"```
``` kubeletCgroups:```
``` cpu: "/system.slice"```
``` cpuacct: "/system.slice"```
``` failSwapOn: true```
``` kubeAPIBurst: 100```
``` enforceNodeAllocatable:```
``` pods: false```
``` evictionMaxPodGracePeriod: 30```
``` resourceContainer: "/kubeletconfig"```
``` evictionPressureTransitionPeriodCheck: 0```
``` serializeImagePulls: false```
``` configureCBR0: false```
``` evictionHardGracePeriod:```
``` memory.available: "100Mi"```
``` runtimeRequestTimeout: 10m```
``` readOnlyPort: 0```
``` logFile: /var/log/pods kubelet.log```
``` reservedSystemCPUs: /system.slice```
``` enableControllerAttachDetachPlugins: true```
``` enforceCPUCFSQuota: false```
``` evictionPressureTransitionPeriodAnnotation: eviction.alpha.kubernetes.io/memory-threshold```
``` kubeAPIThrottleBurst: 200```
``` registerNode: true```
``` kubeAPIThrottleEnable: true```
``` kubeletPreferredAddressTypes:```
``` - "Hostname"```
``` - "InternalDNS"```
``` - "InternalIP"```
``` resources:```
``` requests:```
``` cpu: 100m```
``` memory: 200Mi```
``` limits:```
``` cpu: 100m```
``` memory: 200Mi```
``` topologyManagerScope: container```
``` evictionSoftGracePeriodRatio:```
``` memory.available: 0.2```
``` imageGCHighThresholdPercent: 85```
``` generic```
``` mountpath: /var/lib/docker-overlays```
``` kubeReservedCgroupDriver: cgroupfs```
``` protectKernelDefaults: true```
``` systemReservedCgroupName: system-reserved```
``` systemReservedCgroup: ""```
``` kubeletFinalizeOnStop: true```
``` systemReservedCgroupParent: ""```
``` scanner```
``` name: local```
``` enabled: false```
``` hairpinMode: promiscuous-bridge```
``` kubeReservedSystemCPUs: /system.slice```
``` maxOpenFiles: 1000000```
``` systemReservedSystemCPUs: /system.slice```
``` topologManagerPolicyPlugins:```
``` - "topology.kubernetes.io/zone"```
``` - "topology.kubernetes.io/region"```
``` - "*"`
``` experimentalKernelMemcgNotification: false```
``` taints: null```
``` podCIDR: ""```
``` kubeAPIDGracePeriod: 10s```
``` kubeAPIQPS: 50```
``` readOnlyPortFile: /var/lib/kubelet/readonly_kubelet_port```
``` serializeImagePullsDefault: false```
``` kubeAPIQPSBurst: 100```
``` evictionMaxPodGracePeriodSeconds: 30```
``` resolvConf: "/etc/resolv.conf"```
``` experimentalAllocatableIgnoreEvictionSoft: false```
``` kubeCrossNodeContainerMounts: false```
``` kubeReservedCgroupsPerPod: kube-reserved```
``` enableSystemProbe: true```
``` protectKernelDefaultsReadOnly: false```
``` evictionPressureTransitionPeriodDuration: 20s```
``` systemReservedReservationMemory: 200Mi```
``` enableCRI: true```
``` kubeletCgroupManager: systemd```
``` imageGCHighThresholdPercentAnnotation: "imagegc.kubernetes.io/high-threshold-percent"```
``` evictionSoftTransitionPeriod: 10s```
``` experimentalAllowedUnsafeSysctls: null```
``` protectedKernelDefaultsReadOnly: false```
``` enablePodOverhead: true```
``` kubeReservedCgroupsPerNamespace: false```
``` imagePullProgressDeadline: 1m```
``` imageMinimumGCAgeAnnotation: "imagegc.kubernetes.io/minimum-aged"```
``` evictionMaxPodGracePeriodRatio: 2```
``` kubeReservedSystemCPUsPerNode: 0```
``` resolvConfReadOnly: false```
``` kubeletHostname: ""```
``` experimentalAllowedUnsafeSysctlsAnnotation: "kubernetes.io/allowed-unsafe-sysctls"```
``` systemReservedCgroupsPerPod: system-reserved```
``` kubeletVersion: "v1.21.1-0+kubernetes+1"```
``` hairpinModeInterface: enp0s8```
``` failSwapOnDefaults: true```
``` pidsLimit: 0```
``` kubeleHAUpgradeEnable: true```
``` systemReservedReservationCPU: 100m```
``` systemReservedSystemCPUsPerNode: 0```
``` experimentalAllowedUnsafeSysctlsDefaults: null```
``` kubeletSystemReservedCPU: 100m```
``` kubeletSystemReservedMemory: 200Mi```
``` experimentalKernelMemcgNotificationDefaults: false```
``` topologyManagerPolicySeparator: "/"```
``` evictionHardGracePeriodDuration: 30s```
``` experimentalKernelMemcgNotificationAnnotation: "experimental.kubernetes.io/memcgNotifyOnRelease"```
``` rotateCertificatesDefaults: true```
``` kubeAPIServer:```
``` containers:```
``` - image: kube-apiserver-amd64:1.21```
``` name: kube-apiserver```
``` resources: null```
``` volumeMounts:```
``` - mountPath: /var/run/secrets/kubernetes.io/serviceaccount```
``` name: "kube-api-access-elk-es-cluster"```
``` readOnly: true```
``` securityContext:```
``` privileged: false```
``` terminationMessagePath: /dev/termination-log```
``` volumes:```
``` - name: "kube-api-access-elk-es-cluster"```
``` secret:```
``` secretName: kube-api-access-elk-es-cluster```
``````
```kind: ConfigMap```
```metadata:```
``` labels:```
``` app: metrics-server```
``` name: metrics-server```
``` namespace: kube-system```
```data:```
``` metrics-config.yaml: |```
``` apiVersion: apiregistration.k8s.io/v1```
``` kind: APIService```
``` metadata:```
``` name: v1beta1.metrics.k8s.io```
``` spec:```
``` group: metrics.k8s.io```
``` groupPriorityMinimum: 100```
``` insecureSkipTLSVerify: true```
``` service:```
``` name: metrics-server```
``` namespace: kube-system```
``` version: v1beta1```
``` versionPriority: 100```
``` ---```
``` apiVersion: rbac.authorization.k8s.io/v1```
``` kind: ClusterRole```
``` metadata:```
``` name: system:metrics-server```
``` rules:```
``` - apiGroups:```
``` - ""```
``` resources:```
``` - pods```
``` - nodes```
``` - nodes/stats```
``` - namespaces```
``` - namespace```
``` - endpoints```
``` verbs:```
``` - get```
``` - list```
``` - watch```
``` - apiGroups:```
``` - "extenders.kubevirt.io"```
``` resources:```
``` - vmstats```
``` - virtvolumestats```
``` - vmetrics```
``` verbs:```
``` - get```
``` - list```
``` - watch```
``` ---```
``` apiVersion: rbac.authorization.k8s.io/v1```
``` kind: ClusterRoleBinding```
``` metadata:```
``` name: system:metrics-server```
``` roleRef:```
``` apiGroup: rbac.authorization.k8s.io```
``` kind: ClusterRole```
``` name: system:metrics-server```
``` subjects:```
``` - kind: ServiceAccount```
``` name: metrics-server```
``` namespace: kube-system```
3 | 验证metrics-server是否正常运行 | `kubectl top nodes`
该命令可以查看节点的资源使用情况,如果输出结果正常,证明metrics-server已经正常运行。
4 | 在自己的应用程序中使用metrics | 导入相应的库,并在应用程序中添加代码来采集和暴露metrics数据。
```import io.prometheus.client.Counter;```
```import io.prometheus.client.Gauge;```
```import io.prometheus.client.exporter.HTTPServer;```
```import io.prometheus.client.exporter.MetricsServlet;```
```import io.prometheus.client.hotspot.DefaultExports;```
```...```
```public class MyApp {```
``` private static final Counter requestsTotal = Counter.build()```
``` .name("myapp_requests_total")```
``` .help("Total number of requests.")```
``` .register();```
``````
``` public void handleRequest() {```
``` requestsTotal.inc();```
``` // handle the request```
``` }```
}
```...```
```public class Main {```
``` public static void main(String[] args) throws IOException {```
``` // 注册默认的hotspot监控指标```
``` DefaultExports.initialize();```
``````
``` // 创建一个HTTPServer来公开/metrics```
``` HTTPServer server = new HTTPServer(8080);```
``````
``` // 在HTTPServer中添加MetricsServlet```
``` server.getContext("/metrics").addServlet(new MetricsServlet(), "/");```
``````
``` // 启动应用程序并处理请求```
``` MyApp app = new MyApp();```
``` app.handleRequest();```
``` ...```
``` }```
}
```
5 | 查看应用程序暴露出的metrics数据 | 在浏览器中访问`http://localhost:8080/metrics`(假设应用程序运行在本地8080端口),即可查看应用程序暴露出的metrics数据。
以上就是基于metrics的K8S集群实现的步骤和相应的代码示例。通过这些步骤和代码示例,我们可以在K8S集群中部署和配置metrics-server,并在自己的应用程序中使用metrics来采集和暴露数据,从而实现基于metrics的监控和调优。