add: envoy redis

This commit is contained in:
wwweww
2026-02-23 15:54:33 +08:00
parent 26864d578e
commit 4898aecd3b
79 changed files with 9520 additions and 650 deletions
+157
View File
@@ -0,0 +1,157 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-config
namespace: juwan
data:
envoy.yaml: |
static_resources:
listeners:
- name: http_listener
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: gozero_services
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: user-api
http_filters:
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
math.randomseed(os.time())
local function is_safe(method)
return method == "GET" or method == "HEAD" or method == "OPTIONS"
end
local function parse_cookie(cookie_header)
if not cookie_header then
return nil
end
for cookie in string.gmatch(cookie_header, "([^;]+)") do
local k, v = cookie:match("^%s*([^=]+)=?(.*)$")
if k == "csrf_token" then
return v
end
end
return nil
end
local function random_token()
local t = {}
for i = 1, 32 do
t[i] = string.format("%x", math.random(0, 15))
end
return table.concat(t)
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
local method = headers:get(":method") or ""
local cookie = parse_cookie(headers:get("cookie"))
local csrf_header = headers:get("x-csrf-token")
if is_safe(method) then
if not cookie then
local token = random_token()
request_handle:streamInfo():dynamicMetadata():set("csrf", "token", token)
end
return
end
if not cookie or not csrf_header or cookie ~= csrf_header then
request_handle:respond({[":status"] = "403"}, "CSRF validation failed")
return
end
end
function envoy_on_response(response_handle)
local md = response_handle:streamInfo():dynamicMetadata():get("csrf") or {}
local token = md["token"]
if token then
response_handle:headers():add("set-cookie", "csrf_token=" .. token .. "; Path=/; SameSite=Strict")
end
end
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: user-api
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: user-api
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: user-api-svc.juwan.svc.cluster.local
port_value: 8888
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: envoy-gateway
namespace: juwan
labels:
app: envoy-gateway
spec:
replicas: 1
selector:
matchLabels:
app: envoy-gateway
template:
metadata:
labels:
app: envoy-gateway
spec:
containers:
- name: envoy
image: envoyproxy/envoy:v1.32.2
args:
- "-c"
- "/etc/envoy/envoy.yaml"
- "--log-level"
- "info"
ports:
- name: http
containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/envoy
volumes:
- name: config
configMap:
name: envoy-config
---
apiVersion: v1
kind: Service
metadata:
name: envoy-gateway
namespace: juwan
spec:
type: ClusterIP
selector:
app: envoy-gateway
ports:
- name: http
port: 80
targetPort: 8080
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
+82
View File
@@ -0,0 +1,82 @@
apiVersion: v1
kind: Secret
metadata:
name: grafana-admin
namespace: monitoring
type: Opaque
data:
admin-user: YWRtaW4=
admin-password: Y2hhbmdlLW1l
---
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-datasources
namespace: monitoring
data:
datasources.yaml: |
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
- name: Loki
type: loki
access: proxy
url: http://loki:3100
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:10.4.6
ports:
- name: http
containerPort: 3000
env:
- name: GF_SECURITY_ADMIN_USER
valueFrom:
secretKeyRef:
name: grafana-admin
key: admin-user
- name: GF_SECURITY_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-admin
key: admin-password
volumeMounts:
- name: datasources
mountPath: /etc/grafana/provisioning/datasources
volumes:
- name: datasources
configMap:
name: grafana-datasources
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: monitoring
spec:
type: ClusterIP
ports:
- name: http
port: 3000
targetPort: http
selector:
app: grafana
+90
View File
@@ -0,0 +1,90 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: loki-config
namespace: monitoring
data:
loki.yaml: |
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: boltdb-shipper
object_store: filesystem
schema: v12
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/cache
shared_store: filesystem
ruler:
alertmanager_url: http://localhost:9093
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: loki
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: loki
template:
metadata:
labels:
app: loki
spec:
containers:
- name: loki
image: grafana/loki:2.9.6
args:
- "-config.file=/etc/loki/loki.yaml"
ports:
- name: http
containerPort: 3100
volumeMounts:
- name: config
mountPath: /etc/loki
- name: data
mountPath: /loki
volumes:
- name: config
configMap:
name: loki-config
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: loki
namespace: monitoring
spec:
type: ClusterIP
ports:
- name: http
port: 3100
targetPort: http
selector:
app: loki
+138
View File
@@ -0,0 +1,138 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/metrics
- services
- endpoints
- pods
- namespaces
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "apps"]
resources:
- deployments
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
---
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: monitoring
data:
prometheus.yml: |
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "kubernetes-annotated-endpoints"
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: "true"
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+):(?:\d+);(\d+)
replacement: $1:$2
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: service
- source_labels: [__meta_kubernetes_endpoint_port_name]
action: replace
target_label: port
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
serviceAccountName: prometheus
containers:
- name: prometheus
image: prom/prometheus:v2.53.0
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=15d"
- "--web.enable-lifecycle"
ports:
- name: http
containerPort: 9090
volumeMounts:
- name: config
mountPath: /etc/prometheus
- name: data
mountPath: /prometheus
volumes:
- name: config
configMap:
name: prometheus-config
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: monitoring
spec:
type: ClusterIP
ports:
- name: http
port: 9090
targetPort: http
selector:
app: prometheus
+108
View File
@@ -0,0 +1,108 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: promtail
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: promtail
rules:
- apiGroups: [""]
resources:
- pods
- namespaces
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: promtail
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: promtail
subjects:
- kind: ServiceAccount
name: promtail
namespace: monitoring
---
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail-config
namespace: monitoring
data:
promtail.yaml: |
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /run/promtail/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: replace
source_labels: [__meta_kubernetes_pod_node_name]
target_label: node
- action: replace
source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- action: replace
source_labels: [__meta_kubernetes_pod_name]
target_label: pod
- action: replace
source_labels: [__meta_kubernetes_pod_container_name]
target_label: container
- action: replace
source_labels: [__meta_kubernetes_pod_uid]
target_label: __path__
replacement: /var/log/pods/*$1/*/*.log
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: promtail
namespace: monitoring
spec:
selector:
matchLabels:
app: promtail
template:
metadata:
labels:
app: promtail
spec:
serviceAccountName: promtail
tolerations:
- operator: "Exists"
containers:
- name: promtail
image: grafana/promtail:2.9.6
args:
- "-config.file=/etc/promtail/promtail.yaml"
volumeMounts:
- name: config
mountPath: /etc/promtail
- name: positions
mountPath: /run/promtail
- name: varlog
mountPath: /var/log
readOnly: true
volumes:
- name: config
configMap:
name: promtail-config
- name: positions
emptyDir: {}
- name: varlog
hostPath:
path: /var/log
@@ -17,7 +17,7 @@ spec:
app: user-rpc
spec:
serviceAccountName: find-endpoints
initContainers:
initContainers: # 等待数据库就绪的 Init Container 不影响资源使用但是影响调度策略(也可以忽略不计)
- name: wait-for-db
image: busybox:1.36
command:
@@ -31,12 +31,20 @@ spec:
image: user-rpc:v1
ports:
- containerPort: 9001
- containerPort: 4001
env:
- name: DB_URI
valueFrom:
secretKeyRef:
name: user-db-app
key: uri
- name: REDIS_HOST
value: "user-redis.juwan:6379"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: user-redis
key: password
readinessProbe:
tcpSocket:
port: 9001
@@ -68,10 +76,18 @@ kind: Service
metadata:
name: user-rpc-svc
namespace: juwan
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "4001"
prometheus.io/path: "/metrics"
spec:
ports:
- port: 9001
- name: rpc
port: 9001
targetPort: 9001
- name: metrics
port: 4001
targetPort: 4001
selector:
app: user-rpc
@@ -120,8 +136,40 @@ spec:
target:
type: Utilization
averageUtilization: 80
---
# Redis Cluster
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: RedisCluster
metadata:
name: user-redis
namespace: juwan
spec:
clusterSize: 3
kubernetesConfig:
image: quay.io/opstree/redis:v7.0.12
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
redisSecret:
name: user-redis
key: password
redisExporter:
enabled: true
image: quay.io/opstree/redis-exporter:latest
imagePullPolicy: Always
podSecurityContext:
runAsUser: 1000
fsGroup: 1000
storage:
size: 1Gi
---
# PostgreSQL 集群
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
@@ -129,11 +177,6 @@ metadata:
name: user-db
spec:
instances: 3
postInitSQLRefs:
configMapRefs:
- name: db-dx-init-script
key: init-extensions-sql
optional: false
backup:
barmanObjectStore:
destinationPath: s3://juwan-dev-pg-backups-zj/pg-data/
+3
View File
@@ -0,0 +1,3 @@
kubectl create secret generic user-redis \
--from-literal=password=$(openssl rand -base64 12) \
--namespace juwan