diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 6ce080b3..76cb378e 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -41,6 +41,9 @@ spec: - --provider-config=/etc/kruise-game/config.toml image: controller:latest name: manager + ports: + - name: https + containerPort: 8080 securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/config/prometheus/grafana.json b/config/prometheus/grafana.json new file mode 100644 index 00000000..63e92626 --- /dev/null +++ b/config/prometheus/grafana.json @@ -0,0 +1,1635 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 7157434, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 20, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "sum(okg_gameservers_state_count)", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 3, + "y": 0 + }, + "id": 26, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_state_count{state=\"Ready\"})", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "Ready GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 6, + "y": 0 + }, + "id": 22, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_opsState_count{opsState=\"Maintaining\"})", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "Maintaining GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 9, + "y": 0 + }, + "id": 24, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_opsState_count{opsState=\"WaitToBeDeleted\"})", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "WaitToBeDeleted GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameservers_state_count{state!=\"\"}) by (state)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{state}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServer State (now)", + "type": "piechart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameservers_opsState_count) by (opsState)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{opsState}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServer OpsState (now)", + "type": "piechart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 0, + "y": 5 + }, + "id": 32, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_state_count{state=\"Deleting\"})", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "Deleting GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 3, + "y": 5 + }, + "id": 28, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_state_count{state=\"Updating\"})", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "Updating GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 6, + "y": 5 + }, + "id": 34, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_state_count{state=\"NotReady\"})", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "NotReady GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 9, + "y": 5 + }, + "id": 30, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "expr": "max(okg_gameservers_total)", + "fields": [ + { + "jsonPath": "" + } + ], + "method": "GET", + "queryParams": "", + "refId": "A", + "urlPath": "" + } + ], + "title": "Existed GameServers", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.0.8", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(okg_gameservers_state_count{state!=\"\"}) by (state)", + "fields": [ + { + "jsonPath": "" + } + ], + "instant": false, + "interval": "", + "legendFormat": "{{state}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServer State (Time series)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 18, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameservers_opsState_count) by (opsState)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{opsState}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServer OpsState (Time series)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 36, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameserver_deletion_priority{gsNs=~\"$namespace\",gsName=~\"$gsName\"}) by (gsNs,gsName)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{gsNs}}/{{gsName}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServer Deletion Priority", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 38, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameserver_update_priority{gsNs=~\"$namespace\",gsName=~\"$gsName\"}) by (gsNs,gsName)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{gsNs}}/{{gsName}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "GameServer Update Priority", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 26 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(okg_gameserversets_replicas_count{gsStatus=\"current\",gssNs=~\"$namespace\",gssName=~\"$gssName\"}) by (gssNs,gssName)", + "fields": [ + { + "jsonPath": "" + } + ], + "instant": false, + "interval": "", + "legendFormat": "{{gssNs}}/{{gssName}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "The Number of Current Gs in GameServerSet", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 26 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameserversets_replicas_count{gsStatus=\"available\",gssNs=~\"$namespace\",gssName=~\"$gssName\"}) by (gssNs,gssName)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{gssNs}}/{{gssName}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "The Number of Available Gs in GameServerSet", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 34 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameserversets_replicas_count{gsStatus=\"maintaining\",gssNs=~\"$namespace\",gssName=~\"$gssName\"}) by (gssNs,gssName)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{gssNs}}/{{gssName}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "The Number of Maintaining Gs in GameServerSet", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 34 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "editorMode": "code", + "expr": "max(okg_gameserversets_replicas_count{gsStatus=\"waitToBeDeleted\",gssNs=~\"$namespace\",gssName=~\"$gssName\"}) by (gssNs,gssName)", + "fields": [ + { + "jsonPath": "" + } + ], + "legendFormat": "{{gssNs}}/{{gssName}}", + "method": "GET", + "queryParams": "", + "range": true, + "refId": "A", + "urlPath": "" + } + ], + "title": "The Number of WaitToBeDeleted Gs in GameServerSet", + "type": "timeseries" + } + ], + "schemaVersion": 36, + "showAgsLink": "cn", + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": "", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "definition": "label_values(okg_gameserversets_replicas_count, gssNs)", + "hide": 0, + "includeAll": true, + "multi": false, + "name": "namespace", + "options": [], + "query": { + "query": "label_values(okg_gameserversets_replicas_count, gssNs)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": "", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "definition": "label_values(okg_gameserversets_replicas_count, gssName) ", + "hide": 0, + "includeAll": true, + "multi": false, + "name": "gssName", + "options": [], + "query": { + "query": "label_values(okg_gameserversets_replicas_count, gssName) ", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "prometheus", + "uid": "ok9xcsIVk" + }, + "definition": "label_values(okg_gameserver_deletion_priority, gsName) ", + "hide": 0, + "includeAll": true, + "multi": false, + "name": "gsName", + "options": [], + "query": { + "query": "label_values(okg_gameserver_deletion_priority, gsName) ", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "OKG Metrics Statics", + "uid": "pOPwQUPVz", + "version": 20, + "weekStart": "" +} \ No newline at end of file diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml index d19136ae..9b8047b7 100644 --- a/config/prometheus/monitor.yaml +++ b/config/prometheus/monitor.yaml @@ -11,10 +11,6 @@ spec: endpoints: - path: /metrics port: https - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - insecureSkipVerify: true selector: matchLabels: control-plane: controller-manager diff --git a/docs/en/user_manuals/gameserver_monitor.md b/docs/en/user_manuals/gameserver_monitor.md new file mode 100644 index 00000000..8e60495e --- /dev/null +++ b/docs/en/user_manuals/gameserver_monitor.md @@ -0,0 +1,34 @@ +## Metrics available + +OKG by default exposes game server related Prometheus metrics, including: + +| Name | Description | Type | +| --- |------------------------------------------------|---------| +| GameServersStateCount | Number of game servers in different states | gauge | +| GameServersOpsStateCount | Number of game servers in different ops states | gauge | +| GameServersTotal | Total number of game servers that have existed | counter | +| GameServerSetsReplicasCount | Number of replicas for each GameServerSet | gauge | +| GameServerDeletionPriority | Deletion priority for game servers | gauge | +| GameServerUpdatePriority | Update priority for game servers | gauge | + + +## Monitoring Dashboard + +### Dashboard Import +1. Import ./config/prometheus/grafana.json to Grafana +2. Choose data source +3. Replace UID and complete the import + +### Dashboard Introduction +The imported dashboard is shown below: + +

+ +

+ +From top to bottom, it includes: + +- First row: number of GameServers in each current state, and a pie chart showing the proportion of GameServers in each current state +- Second row: line chart showing the number of GameServers in each state over time +- Third row: line chart showing the changes in deletion and update priorities for GameServers (can be filtered by namespace and gsName in the top-left corner) +- Fourth and fifth rows: line charts showing the number of GameServers in different states for each GameServerSet (can be filtered by namespace and gssName in the top-left corner) \ No newline at end of file diff --git a/docs/images/gra-dash.png b/docs/images/gra-dash.png new file mode 100644 index 00000000..369c1a83 Binary files /dev/null and b/docs/images/gra-dash.png differ diff --git "a/docs/\344\270\255\346\226\207/\347\224\250\346\210\267\346\211\213\345\206\214/\346\270\270\346\210\217\346\234\215\347\233\221\346\216\247.md" "b/docs/\344\270\255\346\226\207/\347\224\250\346\210\267\346\211\213\345\206\214/\346\270\270\346\210\217\346\234\215\347\233\221\346\216\247.md" new file mode 100644 index 00000000..387fa39b --- /dev/null +++ "b/docs/\344\270\255\346\226\207/\347\224\250\346\210\267\346\211\213\345\206\214/\346\270\270\346\210\217\346\234\215\347\233\221\346\216\247.md" @@ -0,0 +1,36 @@ +## 可用指标 + +OKG 默认透出游戏服相关 prometheus metrics,其中指标包括: + +| 名称 | 描述 | 类型 | +| --- |----------------------|---------| +| GameServersStateCount | 不同state状态下的游戏服数量 | gauge | +| GameServersOpsStateCount | 不同opsState状态下的游戏服数量 | gauge | +| GameServersTotal | 存在过的游戏服总数 | counter | +| GameServerSetsReplicasCount | 每个GameServerSet的副本数量 | gauge | +| GameServerDeletionPriority | 游戏服删除优先级 | gauge | +| GameServerUpdatePriority | 游戏服更新优先级 | gauge | + +## 监控仪表盘 + +### 仪表盘导入 + +1. 将 ./config/prometheus/grafana.json 导入至Grafana中 +2. 选择数据源 +3. 替换UID并完成导入 + +### 仪表盘说明 + +完成导入后的仪表盘如下所示: + +

+ +

+ +从上至下,依次包含 + +- 第一行:当前游戏服各个状态的数量、当前游戏服各个状态的比例饼图 +- 第二行:游戏服各个状态数量变化折线图 +- 第三行:游戏服删除优先级、更新优先级变化折线图(可根据左上角namespace与gsName筛选游戏服) +- 第四、五行:游戏服集合中不同状态的游戏服数量变化折线图(可根据左上角namespace与gssName筛选游戏服集合) + diff --git a/main.go b/main.go index 3b7f1aec..0495414d 100644 --- a/main.go +++ b/main.go @@ -22,8 +22,11 @@ import ( kruiseV1beta1 "github.com/openkruise/kruise-api/apps/v1beta1" "github.com/openkruise/kruise-game/cloudprovider" cpmanager "github.com/openkruise/kruise-game/cloudprovider/manager" + kruisegameclientset "github.com/openkruise/kruise-game/pkg/client/clientset/versioned" + kruisegamevisions "github.com/openkruise/kruise-game/pkg/client/informers/externalversions" controller "github.com/openkruise/kruise-game/pkg/controllers" "github.com/openkruise/kruise-game/pkg/externalscaler" + "github.com/openkruise/kruise-game/pkg/metrics" "github.com/openkruise/kruise-game/pkg/webhook" "google.golang.org/grpc" "net" @@ -102,7 +105,8 @@ func main() { } } - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + restConfig := ctrl.GetConfigOrDie() + mgr, err := ctrl.NewManager(restConfig, ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, Port: 9443, @@ -169,6 +173,20 @@ func main() { } }() + kruisegameInformerFactory := kruisegamevisions.NewSharedInformerFactory(kruisegameclientset.NewForConfigOrDie(restConfig), 30*time.Second) + metricsController, err := metrics.NewController(kruisegameInformerFactory) + if err != nil { + setupLog.Error(err, "unable to create metrics controller") + os.Exit(1) + } + kruisegameInformerFactory.Start(signal.Done()) + go func() { + if metricsController.Run(signal) != nil { + setupLog.Error(err, "unable to setup metrics controller") + os.Exit(1) + } + }() + externalScaler := externalscaler.NewExternalScaler(mgr.GetClient()) go func() { grpcServer := grpc.NewServer() diff --git a/pkg/metrics/controller.go b/pkg/metrics/controller.go new file mode 100644 index 00000000..203aca8b --- /dev/null +++ b/pkg/metrics/controller.go @@ -0,0 +1,184 @@ +/* +Copyright 2023 The Kruise Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "context" + "errors" + gamekruisev1alpha1 "github.com/openkruise/kruise-game/apis/v1alpha1" + kruisegamevisions "github.com/openkruise/kruise-game/pkg/client/informers/externalversions" + kruisegamelister "github.com/openkruise/kruise-game/pkg/client/listers/apis/v1alpha1" + "k8s.io/client-go/tools/cache" + "k8s.io/klog/v2" + "sync" +) + +type Controller struct { + gameServerLister kruisegamelister.GameServerLister + gameServerSetLister kruisegamelister.GameServerSetLister + gameServerSynced cache.InformerSynced + gameServerSetSynced cache.InformerSynced + stateLock sync.Mutex + opsStateLock sync.Mutex + gameServerStateLastChange map[string]float64 + gameServerOpsStateLastChange map[string]float64 +} + +func NewController(kruisegameInformerFactory kruisegamevisions.SharedInformerFactory) (*Controller, error) { + gameServer := kruisegameInformerFactory.Game().V1alpha1().GameServers() + gsInformer := gameServer.Informer() + + gameServerSet := kruisegameInformerFactory.Game().V1alpha1().GameServerSets() + gssInformer := gameServerSet.Informer() + + c := &Controller{ + gameServerLister: gameServer.Lister(), + gameServerSetLister: gameServerSet.Lister(), + gameServerSynced: gsInformer.HasSynced, + gameServerSetSynced: gssInformer.HasSynced, + stateLock: sync.Mutex{}, + opsStateLock: sync.Mutex{}, + gameServerStateLastChange: make(map[string]float64), + gameServerOpsStateLastChange: make(map[string]float64), + } + + gsInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: c.recordGsWhenAdd, + UpdateFunc: c.recordGsWhenUpdate, + DeleteFunc: c.recordGsWhenDelete, + }) + + gssInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: func(oldObj, newObj interface{}) { + c.recordGssWhenChange(newObj) + }, + DeleteFunc: c.recordGssWhenDelete, + }) + + return c, nil +} + +func (c *Controller) recordGsWhenAdd(obj interface{}) { + gs, ok := obj.(*gamekruisev1alpha1.GameServer) + if !ok { + return + } + + GameServersTotal.WithLabelValues().Inc() + + state := string(gs.Status.CurrentState) + opsState := string(gs.Spec.OpsState) + GameServersStateCount.WithLabelValues(state).Inc() + GameServersOpsStateCount.WithLabelValues(opsState).Inc() + + dp := 0 + up := 0 + if gs.Status.DeletionPriority != nil { + dp = gs.Status.DeletionPriority.IntValue() + } + if gs.Status.UpdatePriority != nil { + up = gs.Status.UpdatePriority.IntValue() + } + GameServerDeletionPriority.WithLabelValues(gs.Name, gs.Namespace).Set(float64(dp)) + GameServerUpdatePriority.WithLabelValues(gs.Name, gs.Namespace).Set(float64(up)) +} + +func (c *Controller) recordGsWhenUpdate(oldObj, newObj interface{}) { + oldGs, ok := oldObj.(*gamekruisev1alpha1.GameServer) + if !ok { + return + } + + newGs, ok := newObj.(*gamekruisev1alpha1.GameServer) + if !ok { + return + } + + oldState := string(oldGs.Status.CurrentState) + oldOpsState := string(oldGs.Spec.OpsState) + newState := string(newGs.Status.CurrentState) + newOpsState := string(newGs.Spec.OpsState) + if oldState != newState { + GameServersStateCount.WithLabelValues(newState).Inc() + GameServersStateCount.WithLabelValues(oldState).Dec() + } + if oldOpsState != newOpsState { + GameServersOpsStateCount.WithLabelValues(newOpsState).Inc() + GameServersOpsStateCount.WithLabelValues(oldOpsState).Dec() + } + + newDp := 0 + newUp := 0 + if newGs.Status.DeletionPriority != oldGs.Status.DeletionPriority { + newDp = newGs.Status.DeletionPriority.IntValue() + } + if newGs.Status.UpdatePriority != oldGs.Status.UpdatePriority { + newUp = newGs.Status.UpdatePriority.IntValue() + } + GameServerDeletionPriority.WithLabelValues(newGs.Name, newGs.Namespace).Set(float64(newDp)) + GameServerUpdatePriority.WithLabelValues(newGs.Name, newGs.Namespace).Set(float64(newUp)) +} + +func (c *Controller) recordGsWhenDelete(obj interface{}) { + gs, ok := obj.(*gamekruisev1alpha1.GameServer) + if !ok { + return + } + + state := string(gs.Status.CurrentState) + opsState := string(gs.Spec.OpsState) + + GameServersStateCount.WithLabelValues(state).Dec() + GameServersOpsStateCount.WithLabelValues(opsState).Dec() + GameServerDeletionPriority.DeleteLabelValues(gs.Name, gs.Namespace) + GameServerUpdatePriority.DeleteLabelValues(gs.Name, gs.Namespace) +} + +func (c *Controller) recordGssWhenChange(obj interface{}) { + gss, ok := obj.(*gamekruisev1alpha1.GameServerSet) + if !ok { + return + } + + GameServerSetsReplicasCount.WithLabelValues(gss.Name, gss.Namespace, "current").Set(float64(gss.Status.CurrentReplicas)) + GameServerSetsReplicasCount.WithLabelValues(gss.Name, gss.Namespace, "ready").Set(float64(gss.Status.ReadyReplicas)) + GameServerSetsReplicasCount.WithLabelValues(gss.Name, gss.Namespace, "available").Set(float64(gss.Status.AvailableReplicas)) + GameServerSetsReplicasCount.WithLabelValues(gss.Name, gss.Namespace, "maintaining").Set(float64(*gss.Status.MaintainingReplicas)) + GameServerSetsReplicasCount.WithLabelValues(gss.Name, gss.Namespace, "waitToBeDeleted").Set(float64(*gss.Status.WaitToBeDeletedReplicas)) +} + +func (c *Controller) recordGssWhenDelete(obj interface{}) { + gss, ok := obj.(*gamekruisev1alpha1.GameServerSet) + if !ok { + return + } + + GameServerSetsReplicasCount.DeleteLabelValues(gss.Name, gss.Namespace, "current") + GameServerSetsReplicasCount.DeleteLabelValues(gss.Name, gss.Namespace, "ready") + GameServerSetsReplicasCount.DeleteLabelValues(gss.Name, gss.Namespace, "available") + GameServerSetsReplicasCount.DeleteLabelValues(gss.Name, gss.Namespace, "maintaining") + GameServerSetsReplicasCount.DeleteLabelValues(gss.Name, gss.Namespace, "waitToBeDeleted") +} + +func (c *Controller) Run(ctx context.Context) error { + klog.Info("Wait for metrics controller cache sync") + if !cache.WaitForCacheSync(ctx.Done(), c.gameServerSynced, c.gameServerSetSynced) { + return errors.New("failed to wait for caches to sync") + } + <-ctx.Done() + return nil +} diff --git a/pkg/metrics/prometheus_metrics.go b/pkg/metrics/prometheus_metrics.go new file mode 100644 index 00000000..745a171c --- /dev/null +++ b/pkg/metrics/prometheus_metrics.go @@ -0,0 +1,76 @@ +/* +Copyright 2023 The Kruise Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +func init() { + metrics.Registry.MustRegister(GameServersStateCount) + metrics.Registry.MustRegister(GameServersOpsStateCount) + metrics.Registry.MustRegister(GameServersTotal) + metrics.Registry.MustRegister(GameServerSetsReplicasCount) + metrics.Registry.MustRegister(GameServerDeletionPriority) + metrics.Registry.MustRegister(GameServerUpdatePriority) +} + +var ( + GameServersStateCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "okg_gameservers_state_count", + Help: "The number of gameservers per state", + }, + []string{"state"}, + ) + GameServersOpsStateCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "okg_gameservers_opsState_count", + Help: "The number of gameservers per opsState", + }, + []string{"opsState"}, + ) + GameServersTotal = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "okg_gameservers_total", + Help: "The total of gameservers", + }, + []string{}, + ) + GameServerSetsReplicasCount = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "okg_gameserversets_replicas_count", + Help: "The number of replicas per gameserverset)", + }, + []string{"gssName", "gssNs", "gsStatus"}, + ) + GameServerDeletionPriority = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "okg_gameserver_deletion_priority", + Help: "The deletionPriority of gameserver.)", + }, + []string{"gsName", "gsNs"}, + ) + GameServerUpdatePriority = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "okg_gameserver_update_priority", + Help: "The updatePriority of gameserver.)", + }, + []string{"gsName", "gsNs"}, + ) +)