normalize line endings to LF and add envoy dockerfile in deploy/dev

This commit is contained in:
wwweww
2026-04-06 05:26:41 +08:00
parent 7ec8b2a8f0
commit c7a33d4174
39 changed files with 12916 additions and 12246 deletions
+30 -30
View File
@@ -1,30 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFTCCAv2gAwIBAgIUXj+1vyqKDhTsubwSmcHY61+YvmQwDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAwwPYXBpLmp1d2FuLmxvY2FsMB4XDTI2MDIyMzExNTYxNloX
DTI3MDIyMzExNTYxNlowGjEYMBYGA1UEAwwPYXBpLmp1d2FuLmxvY2FsMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkn7Jw5f0awGFbGL3ZHEPJanZO9Yk
JDUklLF3kABiXqawSFpM6pXfKMa4VHE6/MfpREQeX2lkvtBseOf/vhC4DLACui8g
yslUObv77xGSXmIwjFcXZzLPQ/gEs2lxikxeoI4Su9qpsUQNzUD10rvWMx0iea8Z
47Z4RI6fIlA5xC5N4VfUFQdE/VN670HdiTZ7YAFIg9F/ZJQMH+hPVNSLgY6J0RdU
3gqKAkAvmCQZyQKWG1eRqKauw4CIvk6d7N+nOzmwDb6clueFj7Kx4h4IAFHCQthn
eXrf21uBCVwVjs64ilnTVwFfklr79euYRHPmRqR5eswbIGpDEFOaf1smu4hrkK9s
tQ8YWey8TICymBaXr1hI+WjSVEQFN8xPoVQwiKJRdu7lIosDjbH8V/ooKGMhCHgl
5C995L3sKsMyCMkw90viYNy2jUuSNu2X3eK+QJip2D2smfSM2tBsFtiXyEk+WeyY
cRDlwB7+6vvVwCHqz0+4lr0HHBEky43m3NgUtZoulfRwv4znGXcMqvxVUm4pwoBf
lo7zVuXh+cXrEzzCksQiCBzBM115itb3la8RX8A4bRUs38XG6Bz+Qfr6RQspppV1
vNd5mUOyBYNeVfErf59PnFsdMI3kD0UgwpLkkGdSGdzDKykdt7vffNRpV8jOYuuO
LxH+2WlebCv1N90CAwEAAaNTMFEwHQYDVR0OBBYEFF80R0EZORGRXrZTVrAfaatK
eNi9MB8GA1UdIwQYMBaAFF80R0EZORGRXrZTVrAfaatKeNi9MA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHFZUflyNOCJqV+RghOAaVFDc7wqtZJ1
d2dpIs28kKd43Nd+xjSZLmSmVhcntQNwqC8AHIuJKKNDmM5BRnzls1ZO+OLc+YcC
kXzO2aBrNz8a0S0nYGzgR+CoTPvd61RGGHbqQNvZiroWsC4NaR+7NYPzsORNaN+1
p/xqZygOYLOcD5tP5iNlgBugD+nPEHL0cylE0XpoZ059MIITdlvsrdPgHhFn9Nvv
McPZp4nzpJvyUmVjkbT7ZbKIJFrOQ6qJ9U2y55F4xuHzvnaAsOGnGx1tyBHtvkA1
IIovrku4su3TmMsBs/6ikT8XSR20gcsDq3N2RcFtgU5LONsWvUL9CTp7P7lMlIfg
v1RelzXDE2mESlZEbzbFyVVGAoEPZA4t6kgBV4zObxxp4YmimqGWmVs3qQ/A6wbV
OO4rLYW7NZeJLLvsGOabVK+jyFCMyB3YOS6nZ9q48SaWCHlFTZveluP5n/8Y5LGc
ppjaZbsG2/apCqlown6jKT7hkP84eu3a+HyQ6ZXpCa6P9c9OZ8bVlP8dXi4mRuhU
lINwIKA0HbFAzwhyArMkLFWsw26ImusLZH1KUjHabzbfxnDgb9hwIlSGyPrcHcYY
lXTlThSXL0ERoqafQTE9tpPFXC+LCneytAKUgM2TZ1KhRlisA9Tb3i0X4y/yJba7
T2Eqz8rRnaIe
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFTCCAv2gAwIBAgIUXj+1vyqKDhTsubwSmcHY61+YvmQwDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAwwPYXBpLmp1d2FuLmxvY2FsMB4XDTI2MDIyMzExNTYxNloX
DTI3MDIyMzExNTYxNlowGjEYMBYGA1UEAwwPYXBpLmp1d2FuLmxvY2FsMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkn7Jw5f0awGFbGL3ZHEPJanZO9Yk
JDUklLF3kABiXqawSFpM6pXfKMa4VHE6/MfpREQeX2lkvtBseOf/vhC4DLACui8g
yslUObv77xGSXmIwjFcXZzLPQ/gEs2lxikxeoI4Su9qpsUQNzUD10rvWMx0iea8Z
47Z4RI6fIlA5xC5N4VfUFQdE/VN670HdiTZ7YAFIg9F/ZJQMH+hPVNSLgY6J0RdU
3gqKAkAvmCQZyQKWG1eRqKauw4CIvk6d7N+nOzmwDb6clueFj7Kx4h4IAFHCQthn
eXrf21uBCVwVjs64ilnTVwFfklr79euYRHPmRqR5eswbIGpDEFOaf1smu4hrkK9s
tQ8YWey8TICymBaXr1hI+WjSVEQFN8xPoVQwiKJRdu7lIosDjbH8V/ooKGMhCHgl
5C995L3sKsMyCMkw90viYNy2jUuSNu2X3eK+QJip2D2smfSM2tBsFtiXyEk+WeyY
cRDlwB7+6vvVwCHqz0+4lr0HHBEky43m3NgUtZoulfRwv4znGXcMqvxVUm4pwoBf
lo7zVuXh+cXrEzzCksQiCBzBM115itb3la8RX8A4bRUs38XG6Bz+Qfr6RQspppV1
vNd5mUOyBYNeVfErf59PnFsdMI3kD0UgwpLkkGdSGdzDKykdt7vffNRpV8jOYuuO
LxH+2WlebCv1N90CAwEAAaNTMFEwHQYDVR0OBBYEFF80R0EZORGRXrZTVrAfaatK
eNi9MB8GA1UdIwQYMBaAFF80R0EZORGRXrZTVrAfaatKeNi9MA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHFZUflyNOCJqV+RghOAaVFDc7wqtZJ1
d2dpIs28kKd43Nd+xjSZLmSmVhcntQNwqC8AHIuJKKNDmM5BRnzls1ZO+OLc+YcC
kXzO2aBrNz8a0S0nYGzgR+CoTPvd61RGGHbqQNvZiroWsC4NaR+7NYPzsORNaN+1
p/xqZygOYLOcD5tP5iNlgBugD+nPEHL0cylE0XpoZ059MIITdlvsrdPgHhFn9Nvv
McPZp4nzpJvyUmVjkbT7ZbKIJFrOQ6qJ9U2y55F4xuHzvnaAsOGnGx1tyBHtvkA1
IIovrku4su3TmMsBs/6ikT8XSR20gcsDq3N2RcFtgU5LONsWvUL9CTp7P7lMlIfg
v1RelzXDE2mESlZEbzbFyVVGAoEPZA4t6kgBV4zObxxp4YmimqGWmVs3qQ/A6wbV
OO4rLYW7NZeJLLvsGOabVK+jyFCMyB3YOS6nZ9q48SaWCHlFTZveluP5n/8Y5LGc
ppjaZbsG2/apCqlown6jKT7hkP84eu3a+HyQ6ZXpCa6P9c9OZ8bVlP8dXi4mRuhU
lINwIKA0HbFAzwhyArMkLFWsw26ImusLZH1KUjHabzbfxnDgb9hwIlSGyPrcHcYY
lXTlThSXL0ERoqafQTE9tpPFXC+LCneytAKUgM2TZ1KhRlisA9Tb3i0X4y/yJba7
T2Eqz8rRnaIe
-----END CERTIFICATE-----
+52 -52
View File
@@ -1,52 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
Izss0+mp4ijKEFQuCGCkxjFmxUEq
-----END PRIVATE KEY-----
-----BEGIN PRIVATE KEY-----
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
Izss0+mp4ijKEFQuCGCkxjFmxUEq
-----END PRIVATE KEY-----
+38 -27
View File
@@ -35,6 +35,15 @@ services:
timeout: 3s
retries: 10
rl-redis:
image: redis:${REDIS_VERSION:-8}
container_name: ${REDIS_CONTAINER_NAME:-rl-redis-dev-server}
profiles:
- infra
ports:
- "6380:6379"
restart: unless-stopped
kafka:
image: apache/kafka:4.0.1
container_name: juwan-kafka
@@ -77,40 +86,42 @@ services:
condition: service_started
envoy-gateway:
image: envoyproxy/envoy:v1.31-latest
container_name: juwan-envoy-gateway
restart: unless-stopped
command:
- /usr/local/bin/envoy
- -c
- /etc/envoy/envoy.yaml
- --log-level
- info
build:
context: ../deploy/dev/envoy
image: envoy-gateway:latest
container_name: ${ENVOY_GATEWAY_CONTAINER_NAME:-envoy-gateway-dev-server}
ports:
- "18080:8080"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml:ro
- "8080:8080"
- "9901:9901"
depends_on:
authz-adapter:
condition: service_started
users-api:
condition: service_started
player-api:
condition: service_started
game-api:
condition: service_started
shop-api:
condition: service_started
order-api:
condition: service_started
wallet-api:
condition: service_started
community-api:
condition: service_started
objectstory-api:
required: false
user-api:
condition: service_started
required: false
email-api:
condition: service_started
required: false
restart: unless-stopped
ratelimit:
image: ratelimit:latest
container_name: rl-service
restart: unless-stopped
environment:
- REDIS_SOCKET_TYPE=tcp
- REDIS_URL=rl-redis:6379
- USE_STATSD=false
- RUNTIME_ROOT=/data
- RUNTIME_SUBDIRECTORY=ratelimit
- RUNTIME_WATCH_ROOT=true # 热重载
- LOG_LEVEL=debug
volumes:
- ./rls/ratelimit.yaml:/data/ratelimit/config/ratelimit.yaml:ro
ports:
- "8081:8081"
- "6070:6070"
# ==================== RPC 层 ====================
user-rpc:
+626
View File
@@ -0,0 +1,626 @@
static_resources:
listeners:
- name: ingress_http
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
generate_request_id: true
use_remote_address: true
xff_num_trusted_hops: 1
route_config:
name: local_route
virtual_hosts:
- name: juwan_services
domains: [ "*" ]
routes:
- match:
path: /healthz
direct_response:
status: 200
body:
inline_string: ok
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
path: /api/v1/auth/login
route:
cluster: user_api_cluster
timeout: 30s
rate_limits:
- actions:
- generic_key:
descriptor_value: login
- remote_address: {}
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
path: /api/v1/auth/register
route:
cluster: user_api_cluster
timeout: 30s
rate_limits:
- actions:
- generic_key:
descriptor_value: register
- generic_key:
descriptor_key: "period"
descriptor_value: "minute"
- remote_address: {}
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
path: /api/v1/auth/forgot-password
route:
cluster: user_api_cluster
timeout: 30s
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
path: /api/v1/auth/reset-password
route:
cluster: user_api_cluster
timeout: 30s
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
path: /api/v1/auth/forgot-password/send
route:
cluster: email_api_cluster
timeout: 30s
rate_limits:
- actions:
- generic_key:
descriptor_value: forgot_password_send
- generic_key:
descriptor_key: "period"
descriptor_value: "minute"
- remote_address: {}
- actions:
- generic_key:
descriptor_value: forgot_password_send
- generic_key:
descriptor_key: "period"
descriptor_value: "hour"
- remote_address: {}
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
prefix: /api/users
route:
cluster: user_api_cluster
timeout: 30s
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
prefix: /api/v1/shop
route:
cluster: shop_api_cluster
timeout: 30s
- match:
prefix: /api/v1/player
route:
cluster: player_api_cluster
timeout: 30s
- match:
prefix: /api/v1/games
route:
cluster: game_api_cluster
timeout: 30s
- match:
prefix: /api/v1/games
headers:
- name: :method
exact_match: GET
route:
cluster: game_api_cluster
timeout: 30s
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
path: /api/v1/email/verification-code/send
route:
cluster: email_api_cluster
timeout: 30s
rate_limits:
- actions:
- generic_key:
descriptor_value: verify_code_send
- generic_key:
descriptor_key: "period"
descriptor_value: "minute"
- remote_address: {}
- actions:
- generic_key:
descriptor_value: verify_code_send
- generic_key:
descriptor_key: "period"
descriptor_value: "hour"
- remote_address: {}
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
prefix: /api/v1/wallet
route:
cluster: wallet_api_cluster
timeout: 30s
- match:
prefix: /api/v1/players
route:
cluster: player_api_cluster
timeout: 30s
- match:
prefix: /api/v1/orders
route:
cluster: order_api_cluster
timeout: 30s
- match:
prefix: /api/v1/email
route:
cluster: email_api_cluster
timeout: 30s
- match:
prefix: /api/v1/auth
route:
cluster: user_api_cluster
timeout: 30s
- match:
prefix: /api/v1/upload
route:
cluster: objectstory_api_cluster
timeout: 30s
- match:
prefix: /api/v1/files
route:
cluster: objectstory_api_cluster
timeout: 30s
typed_per_filter_config:
envoy.filters.http.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
- match:
prefix: /api/email
route:
cluster: email_api_cluster
timeout: 30s
- match:
prefix: /api/v1/game
route:
cluster: game_api_cluster
timeout: 30s
- match:
prefix: /api/v1
route:
cluster: user_api_cluster
timeout: 30s
- match:
prefix: /
direct_response:
status: 404
body:
inline_string: gateway route not found
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
log_format:
json_format:
start_time: "%START_TIME%"
method: "%REQ(:METHOD)%"
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
protocol: "%PROTOCOL%"
authority: "%REQ(:AUTHORITY)%"
user_agent: "%REQ(USER-AGENT)%"
request_id: "%REQ(X-REQUEST-ID)%"
response_code: "%RESPONSE_CODE%"
response_flags: "%RESPONSE_FLAGS%"
bytes_received: "%BYTES_RECEIVED%"
bytes_sent: "%BYTES_SENT%"
duration_ms: "%DURATION%"
upstream_cluster: "%UPSTREAM_CLUSTER%"
upstream_host: "%UPSTREAM_HOST%"
upstream_service_time_ms: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
route_name: "%ROUTE_NAME%"
http_filters:
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local TOKEN_HEADER = "xsrf-token"
local TOKEN_COOKIE = "__Host-XSRF-TOKEN"
local GUARD_COOKIE = "__Host-XSRF-GUARD"
local seeded = false
local function seed_random()
if seeded then
return
end
seeded = true
math.randomseed(os.time())
end
local function split_cookie(header)
local out = {}
if not header then
return out
end
for pair in string.gmatch(header, "([^;]+)") do
local key, value = string.match(pair, "^%s*([^=]+)=?(.*)$")
if key ~= nil and value ~= nil then
out[string.lower(key)] = value
end
end
return out
end
local function is_safe_method(method)
return method == "GET" or method == "HEAD" or method == "OPTIONS"
end
local function build_token(request_id)
seed_random()
local rnd = tostring(math.random(100000, 999999))
local rid = request_id or "rid"
return tostring(os.time()) .. "-" .. rid .. "-" .. rnd
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
local method = headers:get(":method")
local cookie_header = headers:get("cookie")
local cookies = split_cookie(cookie_header)
local token_cookie = cookies[string.lower(TOKEN_COOKIE)]
local guard_cookie = cookies[string.lower(GUARD_COOKIE)]
request_handle:streamInfo():dynamicMetadata():set("csrf", "need_set_token_cookie", token_cookie == nil or token_cookie == "")
request_handle:streamInfo():dynamicMetadata():set("csrf", "need_set_guard_cookie", guard_cookie == nil or guard_cookie == "")
if token_cookie == nil or token_cookie == "" then
token_cookie = build_token(headers:get("x-request-id"))
request_handle:streamInfo():dynamicMetadata():set("csrf", "token_value", token_cookie)
else
request_handle:streamInfo():dynamicMetadata():set("csrf", "token_value", token_cookie)
end
if guard_cookie == nil or guard_cookie == "" then
guard_cookie = build_token(headers:get("x-request-id"))
request_handle:streamInfo():dynamicMetadata():set("csrf", "guard_value", guard_cookie)
else
request_handle:streamInfo():dynamicMetadata():set("csrf", "guard_value", guard_cookie)
end
if is_safe_method(method) then
return
end
local token_header = headers:get(TOKEN_HEADER)
if token_header == nil or token_header == "" then
request_handle:respond(
{[":status"] = "403", ["content-type"] = "application/json"},
'{"code":403,"message":"missing XSRF-TOKEN header"}'
)
return
end
if token_cookie == nil or token_cookie == "" or guard_cookie == nil or guard_cookie == "" then
request_handle:respond(
{[":status"] = "403", ["content-type"] = "application/json"},
'{"code":403,"message":"missing csrf cookies"}'
)
return
end
if token_header ~= token_cookie then
request_handle:respond(
{[":status"] = "403", ["content-type"] = "application/json"},
'{"code":403,"message":"xsrf token mismatch"}'
)
return
end
end
function envoy_on_response(response_handle)
local metadata = response_handle:streamInfo():dynamicMetadata():get("csrf")
if metadata == nil then
return
end
local token_value = metadata["token_value"]
local guard_value = metadata["guard_value"]
if metadata["need_set_token_cookie"] == true and token_value ~= nil and token_value ~= "" then
response_handle:headers():add(
"set-cookie",
TOKEN_COOKIE .. "=" .. token_value .. "; Path=/; Max-Age=7200; SameSite=Strict; Secure"
)
end
if metadata["need_set_guard_cookie"] == true and guard_value ~= nil and guard_value ~= "" then
response_handle:headers():add(
"set-cookie",
GUARD_COOKIE .. "=" .. guard_value .. "; Path=/; Max-Age=7200; SameSite=Strict; Secure; HttpOnly"
)
end
end
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
juwan_user_jwt:
issuer: juwan-user-rpc
from_cookies:
- JToken
local_jwks:
inline_string: '{"keys":[{"kty":"oct","k":"TUdVeU1XRTNaRGhqTVRRNVpEZzFNV1ZpT1dVME1HTTNPVEUyTldWa1lUQmxPVEU1WldSa1pEVTFZall6T0dKak9XUmlOek0wTlRjNE5ESXlNamxrWlE","alg":"HS256","use":"sig","kid":"juwan-hs256-1"}]}'
forward: false
claim_to_headers:
- header_name: x-auth-user-id
claim_name: UserId
- header_name: x-auth-is-admin
claim_name: IsAdmin
rules:
- match:
path: /healthz
- match:
prefix: /api/v1
headers:
- name: :method
exact_match: OPTIONS
- match:
path: /api/v1/auth/login
- match:
path: /api/v1/auth/register
- match:
path: /api/v1/auth/forgot-password
- match:
path: /api/v1/auth/reset-password
- match:
path: /api/v1/auth/forgot-password/send
- match:
path: /api/v1/email/verification-code/send
- match:
prefix: /api/v1
requires:
provider_name: juwan_user_jwt
- match:
prefix: /api/users
requires:
provider_name: juwan_user_jwt
- match:
prefix: /api/email
requires:
provider_name: juwan_user_jwt
- name: envoy.filters.http.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
transport_api_version: V3
failure_mode_allow: false
with_request_body:
max_request_bytes: 8192
allow_partial_message: true
grpc_service:
envoy_grpc:
cluster_name: authz_adapter_cluster
timeout: 0.5s
# RLS 全局过滤器
- name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: api
failure_mode_deny: false
rate_limited_as_resource_exhausted: true
enable_x_ratelimit_headers: DRAFT_VERSION_03
rate_limit_service:
transport_api_version: V3
grpc_service:
envoy_grpc:
cluster_name: ratelimit_cluster
timeout: 0.2s
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: user_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: user_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: user-api
port_value: 8888
- name: email_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: email_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: email-api
port_value: 8888
- name: shop_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: shop_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: shop-api
port_value: 8888
- name: game_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: game_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: game-api
port_value: 8888
- name: objectstory_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: objectstory_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: objectstory-api
port_value: 8888
- name: wallet_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: wallet_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: wallet-api
port_value: 8888
- name: order_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: order_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: order-api
port_value: 8888
- name: player_api_cluster
connect_timeout: 2s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: player_api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: player-api
port_value: 8888
- name: authz_adapter_cluster
connect_timeout: 0.5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options: { }
load_assignment:
cluster_name: authz_adapter_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: authz-adapter
port_value: 9002
# RLS 集群
- name: ratelimit_cluster
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: ratelimit_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: ratelimit # RLS 地址
port_value: 8081 # RLS gRPC 端口
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 9901
+33
View File
@@ -0,0 +1,33 @@
domain: api
descriptors:
- key: generic_key
value: login
descriptors:
- key: remote_address
rate_limit:
unit: MINUTE
requests_per_unit: 10
- key: generic_key
value: register
descriptors:
- key: remote_address
rate_limit:
unit: MINUTE
requests_per_unit: 5
- key: generic_key
value: forgot_password_send
descriptors:
- key: remote_address
rate_limit:
unit: MINUTE
requests_per_unit: 3
- key: generic_key
value: verify_code_send
descriptors:
- key: remote_address
rate_limit:
unit: MINUTE
requests_per_unit: 3
+4 -4
View File
@@ -1,4 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
+82 -82
View File
@@ -1,82 +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
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 -90
View File
@@ -1,90 +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
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 -138
View File
@@ -1,138 +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
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
+149 -149
View File
@@ -1,149 +1,149 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: promtail
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: promtail
rules:
- apiGroups: [""]
resources:
- nodes
- pods
- pods/log
- services
- endpoints
- 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_label_app_kubernetes_io_name]
target_label: app
regex: (.+)
- action: replace
source_labels: [__meta_kubernetes_pod_label_app]
target_label: app
regex: (.+)
- 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, __meta_kubernetes_pod_container_name]
separator: /
target_label: __path__
replacement: /var/log/pods/*$1/*.log
- job_name: kubernetes-pods-static
pipeline_stages:
- regex:
source: filename
expression: /var/log/pods/(?P<namespace>[^_]+)_(?P<pod>[^_]+)_[^/]+/(?P<container>[^/]+)/[0-9]+\.log
- regex:
source: pod
expression: ^(?P<app>.+?)(?:-[a-f0-9]{8,10}-[a-z0-9]{5}|-[0-9]+)?$
- labels:
namespace:
pod:
container:
app:
static_configs:
- targets:
- localhost
labels:
job: kubernetes-pods
__path__: /var/log/pods/*/*/*.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
securityContext:
runAsUser: 0
runAsGroup: 0
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
- name: dockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: config
configMap:
name: promtail-config
- name: positions
emptyDir: {}
- name: varlog
hostPath:
path: /var/log
- name: dockercontainers
hostPath:
path: /var/lib/docker/containers
apiVersion: v1
kind: ServiceAccount
metadata:
name: promtail
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: promtail
rules:
- apiGroups: [""]
resources:
- nodes
- pods
- pods/log
- services
- endpoints
- 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_label_app_kubernetes_io_name]
target_label: app
regex: (.+)
- action: replace
source_labels: [__meta_kubernetes_pod_label_app]
target_label: app
regex: (.+)
- 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, __meta_kubernetes_pod_container_name]
separator: /
target_label: __path__
replacement: /var/log/pods/*$1/*.log
- job_name: kubernetes-pods-static
pipeline_stages:
- regex:
source: filename
expression: /var/log/pods/(?P<namespace>[^_]+)_(?P<pod>[^_]+)_[^/]+/(?P<container>[^/]+)/[0-9]+\.log
- regex:
source: pod
expression: ^(?P<app>.+?)(?:-[a-f0-9]{8,10}-[a-z0-9]{5}|-[0-9]+)?$
- labels:
namespace:
pod:
container:
app:
static_configs:
- targets:
- localhost
labels:
job: kubernetes-pods
__path__: /var/log/pods/*/*/*.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
securityContext:
runAsUser: 0
runAsGroup: 0
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
- name: dockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: config
configMap:
name: promtail-config
- name: positions
emptyDir: {}
- name: varlog
hostPath:
path: /var/log
- name: dockercontainers
hostPath:
path: /var/lib/docker/containers
+67 -67
View File
@@ -1,67 +1,67 @@
apiVersion: v1
kind: Secret
metadata:
name: jwt-secret
namespace: juwan
type: Opaque
data:
secret-key: MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ==
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: user-rpc
namespace: juwan
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: envoy-gateway
namespace: juwan
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jwt-secret-reader
namespace: juwan
rules:
# JWT Secret 读取权限
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["jwt-secret"]
verbs: ["get"]
# 服务发现权限
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user-rpc-jwt-secret-reader
namespace: juwan
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jwt-secret-reader
subjects:
- kind: ServiceAccount
name: user-rpc
namespace: juwan
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: envoy-gateway-jwt-secret-reader
namespace: juwan
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jwt-secret-reader
subjects:
- kind: ServiceAccount
name: envoy-gateway
namespace: juwan
apiVersion: v1
kind: Secret
metadata:
name: jwt-secret
namespace: juwan
type: Opaque
data:
secret-key: MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ==
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: user-rpc
namespace: juwan
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: envoy-gateway
namespace: juwan
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jwt-secret-reader
namespace: juwan
rules:
# JWT Secret 读取权限
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["jwt-secret"]
verbs: ["get"]
# 服务发现权限
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user-rpc-jwt-secret-reader
namespace: juwan
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jwt-secret-reader
subjects:
- kind: ServiceAccount
name: user-rpc
namespace: juwan
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: envoy-gateway-jwt-secret-reader
namespace: juwan
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jwt-secret-reader
subjects:
- kind: ServiceAccount
name: envoy-gateway
namespace: juwan