以下均为亲自实践并应用
概要
1、k8s sprintboot eureka高可用配置、部署、优化
2、k8s sprintboot 微服务高可用配置、部署、优化
3、springboot安装prometheus依赖并获取metric
4、helm安装prometheus operator、prometheus adapter(custom metric)
5、配置prometheus及adapter获取应用qps
6、配置k8s hpa(HorizontalPodAutoscaler)
7、配置grafana展示监控数据
效果展示
1、k8s sprintboot eureka高可用配置、部署、优化
简介:eureka做集群,需要eureka互相注册,为方便注册,使用statefulSet方式部署
eureka server配置:
eureka:
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 5000
client:
fetch-registry: true
register-with-eureka: true #互相注册
serviceUrl:
defaultZone: ${EUREKA_URL}
instance:
prefer-ip-address: true
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 10
eureka_url:将多实例地址均填写,方便配置
EUREKA_URL="http://eureka-0.eureka.default.svc.cluster.local:8761/eureka/,http://eureka-1.eureka.default.svc.cluster.local:8761/eureka/"
eureka statefulSet配置:
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: eureka
name: eureka
namespace: default
spec:
replicas: 2
serviceName: eureka
podManagementPolicy: "Parallel"
revisionHistoryLimit: 3
selector:
matchLabels:
app: eureka
template:
metadata:
labels:
app: eureka
annotations: #用于prometheus收集数据,需micrometer-registry-prometheus插件
prometheus.io/path: "/actuator/prometheus"
prometheus.io/port: "8761"
prometheus.io/scrape: "true"
spec:
containers:
- image: eureka:latest #镜像名
imagePullPolicy: IfNotPresent
name: eureka
envFrom:
- configMapRef:
name: app-configmap #环境变量
env:
- name: MEMORY
value: "800"
resources:
limits:
cpu: "0"
memory: 1000Mi
requests:
cpu: "0"
memory: 1000Mi
readinessProbe:
tcpSocket:
port: 8761
failureThreshold: 1
initialDelaySeconds: 20
livenessProbe:
tcpSocket:
port: 8761
failureThreshold: 1
initialDelaySeconds: 60
volumeMounts:
- mountPath: /logs
name: log-vol
volumes:
- name: log-vol
nfs:
path: /logs/eureka #多实例日志可统一在此次查看
server: 127.0.0.1 #nfs地址
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: registry-harbor
restartPolicy: Always
2、k8s sprintboot 微服务高可用配置、部署、优化
这边有思考点,client以什么地址注册eureka?
a、以deployment直接部署,默认情况会将容器名称注册到eureka,k8s不识别deployment方式容器名称域名,导致无法访问
b、使用statefulSet部署,通过pod名称注册,并且可以识别域名,以pod名称注册并使用,感觉完美,然而需要弹性扩缩容时候,pod缩容,注册信息不会立马从eureka server去除,有延迟,会导致请求到这个销毁的pod上,error!(如果不考虑hpa这方式ok)
c、使用service注册,通过endpoint分发请求,pod销毁后pod ip会里面从endpoint里去除,不会出现缩容时候请求到销毁pod上,扩容时候,服务没完全起来请求转发到此pod上会出现问题,不过可以通过健康检查解决
最终选择c方案:
client配置如下:
HOSTNAME即k8s service名称,注册时候会将service注册到eureka
#服务注册相关配置
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URL}
instance:
prefer-ip-address: true
instance-id: ${HOSTNAME}:${server.port}
ip-address: ${HOSTNAME}
deployment和service配置
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: client
name: client
namespace: default
spec:
replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
annotations:
prometheus.io/path: "/actuator/prometheus"
prometheus.io/port: "8024"
prometheus.io/scrape: "true"
spec:
containers:
- image: client:latest
imagePullPolicy: IfNotPresent
name: client
envFrom:
- configMapRef:
name: client-configmap
env:
- name: MEMORY
value: "1300"
- name: HOSTNAME
value: client
resources:
limits:
cpu: "0"
memory: 1500Mi
requests:
cpu: "0"
memory: 1500Mi
readinessProbe:
tcpSocket:
port: 8024
failureThreshold: 1
initialDelaySeconds: 60
livenessProbe:
tcpSocket:
port: 8024
failureThreshold: 1
initialDelaySeconds: 90
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: registry-harbor
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: client
namespace: default
labels:
app: client
spec:
ports:
- name: http-8024
port: 8024
protocol: TCP
targetPort: 8024
selector:
app: client
3、springboot安装prometheus依赖并获取metric
高可用部署完成后就需要弹性扩缩容, 需要获取qps数据,这里用的是prometheus,直接贴配置
增加pom依赖:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
增加配置文件:
management:
endpoints:
web:
exposure:
include: '*'
metrics:
tags:
application: ${spring.application.name}
主函数增加bean
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
MeterRegistryCustomizer<MeterRegistry> configurer(
@Value("${spring.application.name}") String applicationName) {
return (registry) -> registry.config().commonTags("application", applicationName);
}
}
配置完成后访问:http:localhost:8024/actuator/prometheus,返回数据如下(重点关注下http_server_requests_seconds_count,后面会用到)
# HELP jvm_memory_max_bytes The maximum amount of memory in bytes that can be used for memory management
# TYPE jvm_memory_max_bytes gauge
jvm_memory_max_bytes{application="portal-eureka",area="heap",id="Par Survivor Space",} 2.7918336E7
jvm_memory_max_bytes{application="portal-eureka",area="nonheap",id="Compressed Class Space",} 1.073741824E9
jvm_memory_max_bytes{application="portal-eureka",area="heap",id="Tenured Gen",} 5.59284224E8
jvm_memory_max_bytes{application="portal-eureka",area="nonheap",id="Metaspace",} -1.0
jvm_memory_max_bytes{application="portal-eureka",area="heap",id="Par Eden Space",} 2.23739904E8
jvm_memory_max_bytes{application="portal-eureka",area="nonheap",id="Code Cache",} 2.5165824E8
# HELP logback_events_total Number of error level events that made it to the logs
# TYPE logback_events_total counter
logback_events_total{application="portal-eureka",level="info",} 804.0
http_server_requests_seconds_count{application="portal-eureka",exception="None",method="POST",outcome="SUCCESS",status="204",uri="root",} 8.0
http_server_requests_seconds_sum{application="portal-eureka",exception="None",method="POST",outcome="SUCCESS",status="204",uri="root",} 0.29997471
http_server_requests_seconds_count{application="portal-eureka",exception="None",method="GET",outcome="SUCCESS",status="200",uri="/actuator/prometheus",} 114.0
...
4、helm安装prometheus operator、prometheus adapter(custom metric)
a、下载prometheus-operator
helm fetch stable/prometheus-operator --version 8.13.0
b、解压
tar -zxvf prometheus-operator-8.13.3.tgz
c、修改values.yaml文件,增加采集pod job(operator默认没有搜集kubernetes-pod的配置)
vim prometheus-operator/values.yaml
增加
additionalScrapeConfigs:
- job_name: 'kubernetes-pods'
honor_labels: false
kubernetes_sd_configs:
- role: pod
tls_config:
insecure_skip_verify: true
relabel_configs:
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (.+)
d、安装
helm install -n prometheus-operator prometheus-operator --namespace monitor
e、暴露端口
kubectl edit svc prometheus-operator-prometheus -nmonitor #增加externalIPs或者nodeport
f、安装stable/prometheus-adapter
helm fetch stable/prometheus-adapter --version 2.3.1
解压
tar -zxvf prometheus-adapter-2.3.1.tgz
修改prometheus server配置
vim prometheus-adapter/values.yaml #将prometheus.url替换为http://prometheus-operator-prometheus.monitor.svc
安装
helm install -n prometheus-adapter prometheus-adapter --namespace monitor
查看api
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1
5、配置prometheus及adapter获取应用qps
a、增加adapter规则
kubectl edit cm -nmonitor prometheus-adapter
增加规则,将http_server_requests_seconds_count以每5分钟为时间段计算为qps,metric名称为http_server_requests_seconds
- seriesQuery: '{namespace!="",__name__!~"^container_.*"}'
seriesFilters:
- isNot: .*_seconds_total
resources:
template: <<.Resource>>
name:
matches: ^(.*)_count$
as: ""
metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>)
b、重启adapter
kubectl -nmonitor delete pod prometheus-adapter-...
c、查看自定义metric qps
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_server_requests_seconds"
6、配置k8s hpa(HorizontalPodAutoscaler)
直接贴配置:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: client
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: client
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: http_server_requests_seconds
target:
type: AverageValue
averageValue: 50
kubectl get hpa #查看hpa是否获取到metric
7、配置grafana展示监控数据
展示应用qps sql(不包含/actuator/prometheus地址)
sum(rate(http_server_requests_seconds_count{job="kubernetes-pods",uri!="/actuator/prometheus" }[5m])) by (application)
dashboard模板地址:https://grafana.com/grafana/dashboards?dataSource=prometheus&direction=asc&orderBy=name&search=spring
推荐Spring Boot 2.1 Statistics模板,导入方法如下图,复制id或者json即可