add:
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,424 @@
|
||||
# JWT Secret + ETCD Encryption Deployment Guide
|
||||
|
||||
完整的 JWT 认证系统部署指南,包括密钥管理、RBAC 权限控制和 ETCD 加密。
|
||||
|
||||
## 部署顺序
|
||||
|
||||
### 第1步:创建 Secret 和 RBAC(必需)
|
||||
|
||||
创建 JWT 秘钥和服务账户权限:
|
||||
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
|
||||
```
|
||||
|
||||
验证创建成功:
|
||||
|
||||
```bash
|
||||
# 检查 Secret
|
||||
kubectl get secret jwt-secret -n juwan
|
||||
kubectl get secret jwt-secret -n juwan -o yaml
|
||||
|
||||
# 检查 ServiceAccounts
|
||||
kubectl get sa user-rpc -n juwan
|
||||
kubectl get sa envoy-gateway -n juwan
|
||||
|
||||
# 检查 RBAC 权限
|
||||
kubectl get role jwt-secret-reader -n juwan
|
||||
kubectl get rolebinding -n juwan -l app=jwt-secret-reader
|
||||
```
|
||||
|
||||
### 第2步:更新 user-rpc 部署(依赖第1步)
|
||||
|
||||
已自动更新 `deploy/k8s/service/user/user-rpc.yaml`:
|
||||
|
||||
- ✅ 更新 `serviceAccountName` 从 `find-endpoints` → `user-rpc`
|
||||
- ✅ 添加环境变量 `JWT_SECRET_KEY` 从 Secret `jwt-secret` 读取
|
||||
|
||||
应用更新:
|
||||
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
|
||||
```
|
||||
|
||||
验证部署:
|
||||
|
||||
```bash
|
||||
# 检查 ServiceAccount 已正确绑定
|
||||
kubectl get deployment user-rpc -n juwan -o yaml | grep -A 5 serviceAccountName
|
||||
|
||||
# 查看 Pod 是否以 user-rpc ServiceAccount 身份运行
|
||||
kubectl get pod -n juwan -l app=user-rpc -o yaml | grep serviceAccount
|
||||
|
||||
# 验证环境变量已注入
|
||||
kubectl exec -it POD_NAME -n juwan -- env | grep JWT_SECRET_KEY
|
||||
```
|
||||
|
||||
### 第3步:更新 Envoy 网关部署(依赖第1步)
|
||||
|
||||
已自动更新 `deploy/k8s/envoy/envoy.yaml`:
|
||||
|
||||
- ✅ 添加 `serviceAccountName: envoy-gateway` 到 Deployment spec
|
||||
|
||||
应用更新:
|
||||
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/envoy/envoy.yaml
|
||||
```
|
||||
|
||||
验证部署:
|
||||
|
||||
```bash
|
||||
# 检查 ServiceAccount 已正确绑定
|
||||
kubectl get deployment envoy-gateway -n juwan -o yaml | grep -A 2 serviceAccountName
|
||||
|
||||
# 检查 Pod 状态
|
||||
kubectl get pod -n juwan -l app=envoy-gateway
|
||||
```
|
||||
|
||||
### 第4步:启用 ETCD 加密(强烈推荐用于生产环境)
|
||||
|
||||
这是一个集群级别的配置,需要在 Kubernetes 控制平面节点上执行。
|
||||
|
||||
**前提条件:**
|
||||
- 具有 Kubernetes 集群管理员权限
|
||||
- 可以访问控制平面节点
|
||||
- 备份 ETCD 数据库
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. **生成加密密钥**
|
||||
```bash
|
||||
head -c 32 /dev/urandom | base64
|
||||
```
|
||||
记录输出的 Base64 密钥。
|
||||
|
||||
2. **创建加密配置文件**
|
||||
|
||||
在控制平面节点上,创建 `/etc/kubernetes/encryption-config.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: <BASE64_ENCODED_32_BYTE_KEY>
|
||||
- identity: {}
|
||||
```
|
||||
|
||||
替换 `<BASE64_ENCODED_32_BYTE_KEY>` 为第1步生成的密钥。
|
||||
|
||||
3. **修改 kube-apiserver 配置**
|
||||
|
||||
在控制平面节点上,编辑 `/etc/kubernetes/manifests/kube-apiserver.yaml`:
|
||||
|
||||
**添加参数:**
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- name: kube-apiserver
|
||||
command:
|
||||
- kube-apiserver
|
||||
- --encryption-provider-config=/etc/kubernetes/encryption-config.yaml
|
||||
```
|
||||
|
||||
**添加卷挂载:**
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- name: kube-apiserver
|
||||
volumeMounts:
|
||||
- name: encryption-config
|
||||
mountPath: /etc/kubernetes
|
||||
readOnly: true
|
||||
|
||||
volumes:
|
||||
- name: encryption-config
|
||||
hostPath:
|
||||
path: /etc/kubernetes
|
||||
type: DirectoryOrCreate
|
||||
```
|
||||
|
||||
4. **重启 kube-apiserver**
|
||||
|
||||
修改清单后,kubelet 会自动重启 kube-apiserver。检查状态:
|
||||
|
||||
```bash
|
||||
# 在控制平面节点
|
||||
kubectl get pods -n kube-system | grep kube-apiserver
|
||||
|
||||
# 监控重启过程
|
||||
kubectl logs -n kube-system -l component=kube-apiserver -f
|
||||
```
|
||||
|
||||
5. **验证加密是否启用**
|
||||
|
||||
创建一个新 Secret 并检查它在 ETCD 中是否加密:
|
||||
|
||||
```bash
|
||||
# 创建测试 Secret
|
||||
kubectl create secret generic test-secret -n juwan --from-literal=key=value
|
||||
|
||||
# 从 control plane 节点检查 ETCD 数据
|
||||
# 如果数据不可读并包含加密标记,说明加密已启用
|
||||
```
|
||||
|
||||
6. **保存加密密钥**
|
||||
|
||||
⚠️ **关键:将加密密钥安全地保存在离线存储中**
|
||||
- 密钥丢失后,无法解密 ETCD 中的数据
|
||||
- 无法恢复任何 Secrets
|
||||
- 建议用密码管理工具(如 HashiCorp Vault)或 HSM 存储密钥
|
||||
|
||||
### 第5步:验证整个系统
|
||||
|
||||
完整的验证清单:
|
||||
|
||||
```bash
|
||||
# 检查所有 Secrets 已创建
|
||||
kubectl get secret -n juwan
|
||||
kubectl get secret jwt-secret -n juwan -o jsonpath='{.data.secret-key}' | base64 -d
|
||||
|
||||
# 检查 ServiceAccounts 已创建
|
||||
kubectl get sa -n juwan
|
||||
kubectl describe sa user-rpc -n juwan
|
||||
kubectl describe sa envoy-gateway -n juwan
|
||||
|
||||
# 检查 RBAC 权限
|
||||
kubectl get role -n juwan
|
||||
kubectl get rolebinding -n juwan
|
||||
kubectl describe role jwt-secret-reader -n juwan
|
||||
|
||||
# 测试权限:user-rpc 可以读 jwt-secret
|
||||
kubectl auth can-i get secrets --as=system:serviceaccount:juwan:user-rpc --resource-name=jwt-secret -n juwan
|
||||
|
||||
# 测试权限:envoy-gateway 可以读 jwt-secret
|
||||
kubectl auth can-i get secrets --as=system:serviceaccount:juwan:envoy-gateway --resource-name=jwt-secret -n juwan
|
||||
|
||||
# 测试权限:其他 ServiceAccount 无法读取
|
||||
kubectl auth can-i get secrets --as=system:serviceaccount:juwan:other-service -n juwan
|
||||
|
||||
# 检查 Deployments 已正确配置
|
||||
kubectl get deployment user-rpc -n juwan -o yaml | grep -A 2 serviceAccountName
|
||||
kubectl get deployment envoy-gateway -n juwan -o yaml | grep -A 2 serviceAccountName
|
||||
|
||||
# 检查 Pods 是否已启动并运行
|
||||
kubectl get pods -n juwan -l app=user-rpc
|
||||
kubectl get pods -n juwan -l app=envoy-gateway
|
||||
|
||||
# 查看 JWT Secret 是否已挂载到 Pod
|
||||
kubectl exec -it $(kubectl get pod -n juwan -l app=user-rpc -o name | head -1) -n juwan -- env | grep JWT_SECRET_KEY
|
||||
```
|
||||
|
||||
## 监控和日志
|
||||
|
||||
### 查看 Pod 日志
|
||||
|
||||
```bash
|
||||
# user-rpc 日志
|
||||
kubectl logs -n juwan -l app=user-rpc -f --all-containers=true
|
||||
|
||||
# Envoy 日志
|
||||
kubectl logs -n juwan -l app=envoy-gateway -f
|
||||
```
|
||||
|
||||
### 检查 Pod 事件
|
||||
|
||||
```bash
|
||||
# 查看 Pod 创建和启动事件
|
||||
kubectl describe pod -n juwan -l app=user-rpc
|
||||
kubectl describe pod -n juwan -l app=envoy-gateway
|
||||
```
|
||||
|
||||
### 权限问题排查
|
||||
|
||||
如果 Pod 无法读取 Secret:
|
||||
|
||||
```bash
|
||||
# 检查 Pod 使用的 ServiceAccount
|
||||
kubectl get pod POD_NAME -n juwan -o yaml | grep serviceAccountName
|
||||
|
||||
# 检查 RBAC 绑定
|
||||
kubectl get rolebinding -n juwan -o wide
|
||||
|
||||
# 检查 Role 权限定义
|
||||
kubectl get role jwt-secret-reader -n juwan -o yaml
|
||||
|
||||
# 尝试用 Pod 的身份读取 Secret(需要 kubectl-user-impersonate 或类似工具)
|
||||
kubectl get secret jwt-secret --as=system:serviceaccount:juwan:user-rpc -n juwan
|
||||
```
|
||||
|
||||
## 安全最佳实践
|
||||
|
||||
### 1. 密钥轮换
|
||||
|
||||
周期性更换 JWT 秘钥(建议每季度):
|
||||
|
||||
```bash
|
||||
# 1. 生成新密钥
|
||||
NEW_KEY=$(head -c 32 /dev/urandom | base64)
|
||||
|
||||
# 2. 更新 Secret
|
||||
kubectl create secret generic jwt-secret \
|
||||
--from-literal=secret-key=$NEW_KEY \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
# 3. 重启 Pods 以加载新密钥(滚动更新)
|
||||
kubectl rollout restart deployment/user-rpc -n juwan
|
||||
kubectl rollout restart deployment/envoy-gateway -n juwan
|
||||
|
||||
# 4. 验证新 Pods 已启动并运行
|
||||
kubectl rollout status deployment/user-rpc -n juwan
|
||||
kubectl rollout status deployment/envoy-gateway -n juwan
|
||||
|
||||
# 5. 已颁发的旧令牌将变为无效
|
||||
# 需要用户重新登录获取新令牌
|
||||
```
|
||||
|
||||
### 2. 审计和监控
|
||||
|
||||
在生产环境中启用 Kubernetes 审计日志来跟踪 Secret 访问:
|
||||
|
||||
```yaml
|
||||
# kube-apiserver 审计策略示例
|
||||
apiVersion: audit.k8s.io/v1
|
||||
kind: Policy
|
||||
rules:
|
||||
# 记录 secret 资源的访问
|
||||
- level: RequestResponse
|
||||
verbs: ["get", "list", "watch"]
|
||||
resources: ["secrets"]
|
||||
# 记录所有认证失败
|
||||
- level: RequestResponse
|
||||
omitStages:
|
||||
- RequestReceived
|
||||
userGroups: ["system:unauthenticated"]
|
||||
- level: Metadata
|
||||
omitStages:
|
||||
- RequestReceived
|
||||
```
|
||||
|
||||
### 3. 网络策略
|
||||
|
||||
使用 NetworkPolicy 限制 Pods 之间的通信:
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: jwt-secret-access
|
||||
namespace: juwan
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: jwt-secret-reader
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: user-rpc
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: envoy-gateway
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 443 # API Server
|
||||
```
|
||||
|
||||
## 灾难恢复
|
||||
|
||||
### 备份 Secret 和 RBAC 配置
|
||||
|
||||
```bash
|
||||
# 备份 JWT Secret
|
||||
kubectl get secret jwt-secret -n juwan -o yaml > jwt-secret-backup.yaml
|
||||
|
||||
# 备份 RBAC 配置
|
||||
kubectl get role jwt-secret-reader -n juwan -o yaml > jwt-role-backup.yaml
|
||||
kubectl get rolebinding -n juwan -l app=jwt-secret-reader -o yaml > jwt-rolebinding-backup.yaml
|
||||
|
||||
# 加密备份文件
|
||||
gpg --symmetric jwt-secret-backup.yaml
|
||||
```
|
||||
|
||||
### 恢复步骤
|
||||
|
||||
如果 Secret 被意外删除:
|
||||
|
||||
```bash
|
||||
# 从备份恢复
|
||||
kubectl apply -f jwt-secret-backup.yaml
|
||||
|
||||
# 重启 Pods 以重新加载 Secret
|
||||
kubectl rollout restart deployment/user-rpc -n juwan
|
||||
kubectl rollout restart deployment/envoy-gateway -n juwan
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: Pod 无法启动,显示 "failed to pull secret"
|
||||
|
||||
A: 检查:
|
||||
1. Secret 是否存在:`kubectl get secret jwt-secret -n juwan`
|
||||
2. ServiceAccount 是否绑定了 RBAC:`kubectl describe rolebinding -n juwan`
|
||||
3. Secret 名称和命名空间是否正确
|
||||
|
||||
### Q: 加密后如何验证 ETCD 中的数据已加密?
|
||||
|
||||
A: 从 control plane 节点:
|
||||
```bash
|
||||
# 直接读取 ETCD(如果配置了加密,数据应该不可读)
|
||||
sudo strings /var/lib/etcd/member/snap/db | grep -i secret
|
||||
```
|
||||
|
||||
### Q: 能否更改加密密钥而不重新创建 ETCD?
|
||||
|
||||
A: 可以,但流程复杂:
|
||||
1. 更新 encryption-config.yaml 中的新密钥
|
||||
2. 将新密钥添加到提供程序列表(保持旧密钥)
|
||||
3. 重启 kube-apiserver
|
||||
4. 触发重新加密:`kubectl get all --all-namespaces -o json | kubectl apply -f -`
|
||||
|
||||
### Q: 如何在 Minikube 中启用 ETCD 加密?
|
||||
|
||||
A: 参考 `ENCRYPTION.md` 中的 Minikube 特定说明部分。
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `jwt-secret.yaml` - Secret 和 RBAC 配置
|
||||
- `ENCRYPTION.md` - ETCD 加密详细文档
|
||||
- `README.md` - 快速参考指南
|
||||
- `/deploy/k8s/service/user/user-rpc.yaml` - user-rpc Deployment 配置
|
||||
- `/deploy/k8s/envoy/envoy.yaml` - Envoy 网关 Deployment 配置
|
||||
|
||||
## 下一步
|
||||
|
||||
部署完成后:
|
||||
|
||||
1. **集成 JWT 验证到 RPC Handlers**
|
||||
- 实现 gRPC unary interceptor
|
||||
- 验证令牌有效性
|
||||
- 处理令牌刷新逻辑
|
||||
|
||||
2. **集成 JWT 验证到 Envoy**
|
||||
- 扩展 Lua filter 进行令牌验证
|
||||
- 返回 401(无效令牌)或 200(有效令牌)
|
||||
|
||||
3. **端到端测试**
|
||||
- 创建用户和登录
|
||||
- 生成和验证 JWT
|
||||
- 测试令牌刷新和撤销
|
||||
- 验证 ETCD 加密
|
||||
|
||||
4. **生产部署**
|
||||
- 启用审计日志
|
||||
- 配置密钥轮换计划
|
||||
- 建立备份和恢复流程
|
||||
- 监控 Secret 访问
|
||||
@@ -0,0 +1,129 @@
|
||||
# ETCD Encryption Configuration for Kubernetes
|
||||
|
||||
To enable static encryption at rest for Kubernetes secrets in ETCD, you need to configure the API Server with an EncryptionConfiguration.
|
||||
|
||||
## 1. Generate an Encryption Key
|
||||
|
||||
```bash
|
||||
# Generate a 32-byte base64-encoded key
|
||||
head -c 32 /dev/urandom | base64
|
||||
# Example output: sxFdbKYquCe3EbRWVV+pFe2lS8K8hbiv3V8ExQZ0fD4=
|
||||
```
|
||||
|
||||
## 2. Create EncryptionConfiguration File
|
||||
|
||||
Create `/etc/kubernetes/encryption-config.yaml` on the control plane node:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: sxFdbKYquCe3EbRWVV+pFe2lS8K8hbiv3V8ExQZ0fD4=
|
||||
- identity: {}
|
||||
```
|
||||
|
||||
## 3. Update kube-apiserver Static Pod Manifest
|
||||
|
||||
Edit `/etc/kubernetes/manifests/kube-apiserver.yaml` on the control plane node:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- name: kube-apiserver
|
||||
command:
|
||||
- kube-apiserver
|
||||
# ... existing flags ...
|
||||
- --encryption-provider-config=/etc/kubernetes/encryption-config.yaml
|
||||
volumeMounts:
|
||||
- name: encryption-config
|
||||
mountPath: /etc/kubernetes
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: encryption-config
|
||||
hostPath:
|
||||
path: /etc/kubernetes
|
||||
type: DirectoryOrCreate
|
||||
```
|
||||
|
||||
## 4. Verify Encryption is Working
|
||||
|
||||
```bash
|
||||
# After restarting the API server, create a secret and verify it's encrypted
|
||||
kubectl create secret generic test-secret --from-literal=key=value -n juwan
|
||||
|
||||
# Check if the secret is encrypted in etcd
|
||||
kubectl get secret test-secret -o yaml
|
||||
|
||||
# You can also check raw etcd data (requires etcd access):
|
||||
# etcdctl --endpoints=https://127.0.0.1:2379 get /kubernetes.io/secrets/juwan/test-secret
|
||||
# The data should be encrypted (not human-readable)
|
||||
```
|
||||
|
||||
## 5. Important Notes
|
||||
|
||||
- **Backup your encryption key** in a secure location
|
||||
- **Never commit encryption keys** to version control
|
||||
- If you lose the key, all encrypted secrets will be unrecoverable
|
||||
- After enabling encryption, existing unencrypted secrets will not be automatically encrypted
|
||||
- To encrypt existing secrets, you can use: `kubectl delete secret <name> && kubectl create secret ...`
|
||||
- Or use: `kubectl patch secret <name> -p '{}' --type=merge` (triggers re-encryption)
|
||||
|
||||
## 6. RBAC Configuration for JWT Secret
|
||||
|
||||
The `jwt-secret.yaml` includes RBAC rules that:
|
||||
- Create a `jwt-secret` Secret in the `juwan` namespace
|
||||
- Create ServiceAccounts for `user-rpc` and `envoy-gateway`
|
||||
- Create a Role `jwt-secret-reader` that allows reading only the `jwt-secret` Secret
|
||||
- Bind this Role to both ServiceAccounts via RoleBindings
|
||||
|
||||
This ensures:
|
||||
- Only `user-rpc` and `envoy-gateway` Pods can read the JWT secret
|
||||
- Other services and users cannot access the JWT secret
|
||||
- Least privilege access principle is enforced
|
||||
|
||||
## 7. Update Deployment to Use ServiceAccount
|
||||
|
||||
Make sure your Deployment references the ServiceAccount:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: user-rpc
|
||||
namespace: juwan
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: user-rpc # This is important!
|
||||
containers:
|
||||
- name: user-rpc
|
||||
env:
|
||||
- name: JWT_SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: jwt-secret
|
||||
key: secret-key
|
||||
```
|
||||
|
||||
## 8. For Minikube Users
|
||||
|
||||
If using Minikube, you can enable encryption with:
|
||||
|
||||
```bash
|
||||
minikube config set apiserver.encryption-provider-config /path/to/encryption-config.yaml
|
||||
minikube start
|
||||
```
|
||||
|
||||
Or manually edit the kube-apiserver manifest after starting Minikube:
|
||||
|
||||
```bash
|
||||
minikube ssh
|
||||
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
|
||||
# Add the flags and volume mounts as shown above
|
||||
```
|
||||
@@ -0,0 +1,415 @@
|
||||
# 部署流程图和时间线
|
||||
|
||||
## 部署架构流程图
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ JWT 认证系统部署流程 │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Phase 1: 前置检查 (5分钟) │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ✓ Kubernetes 集群版本 >= 1.24 │
|
||||
│ ✓ kubectl 已配置,可访问集群 │
|
||||
│ ✓ juwan namespace 已存在 │
|
||||
│ ✓ redis-operator CRD 已安装 │
|
||||
│ ✓ 集群管理员权限(用于 ETCD 加密) │
|
||||
│ │
|
||||
│ 命令检查: │
|
||||
│ $ kubectl cluster-info │
|
||||
│ $ kubectl get ns juwan │
|
||||
│ $ kubectl get crd redisclusters.redis.redis.opstreelabs.in │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Phase 2: 创建 Secret 和 RBAC (5分钟) ⚡ 必需 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 执行: │
|
||||
│ $ kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml │
|
||||
│ │
|
||||
│ 创建的资源: │
|
||||
│ ✓ Secret: jwt-secret (包含 JWT 秘钥) │
|
||||
│ ✓ ServiceAccount: user-rpc │
|
||||
│ ✓ ServiceAccount: envoy-gateway │
|
||||
│ ✓ Role: jwt-secret-reader (只读权限) │
|
||||
│ ✓ RoleBinding: jwt-secret-reader-user-rpc │
|
||||
│ ✓ RoleBinding: jwt-secret-reader-envoy-gateway │
|
||||
│ │
|
||||
│ 验证: │
|
||||
│ $ kubectl get secret jwt-secret -n juwan │
|
||||
│ $ kubectl get sa -n juwan | grep -E "user-rpc|envoy" │
|
||||
│ $ kubectl get role -n juwan │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Phase 3: 更新 Deployments (10分钟) ⚡ 必需 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Step 3a: 更新 user-rpc Deployment │
|
||||
│ 执行: │
|
||||
│ $ kubectl apply -f deploy/k8s/service/user/user-rpc.yaml │
|
||||
│ │
|
||||
│ 变更: │
|
||||
│ - serviceAccountName: user-rpc (绑定权限) │
|
||||
│ - env.JWT_SECRET_KEY (从 Secret 挂载) │
|
||||
│ - 保持 Redis Cluster 配置 │
|
||||
│ │
|
||||
│ 等待 Pods 启动: │
|
||||
│ $ kubectl rollout status deployment/user-rpc -n juwan │
|
||||
│ │
|
||||
│ --- │
|
||||
│ │
|
||||
│ Step 3b: 更新 Envoy Gateway Deployment │
|
||||
│ 执行: │
|
||||
│ $ kubectl apply -f deploy/k8s/envoy/envoy.yaml │
|
||||
│ │
|
||||
│ 变更: │
|
||||
│ - serviceAccountName: envoy-gateway (绑定权限) │
|
||||
│ - 保持 CSRF Lua 防护配置 │
|
||||
│ │
|
||||
│ 等待 Pods 启动: │
|
||||
│ $ kubectl rollout status deployment/envoy-gateway -n juwan │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Phase 4: 验证部署 (15分钟) ⚡ 必需 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 检查清单: │
|
||||
│ │
|
||||
│ 1️⃣ Secret 和权限验证 │
|
||||
│ $ kubectl get secret jwt-secret -n juwan │
|
||||
│ $ kubectl get role jwt-secret-reader -n juwan │
|
||||
│ $ kubectl get rolebinding -n juwan | grep jwt-secret │
|
||||
│ │
|
||||
│ 2️⃣ 权限测试 │
|
||||
│ $ kubectl auth can-i get secrets \ │
|
||||
│ --as=system:serviceaccount:juwan:user-rpc \ │
|
||||
│ --resource-name=jwt-secret -n juwan │
|
||||
│ 预期: yes │
|
||||
│ │
|
||||
│ 3️⃣ Pods 运行状态 │
|
||||
│ $ kubectl get pods -n juwan -l app=user-rpc │
|
||||
│ $ kubectl get pods -n juwan -l app=envoy-gateway │
|
||||
│ 预期: 3 个 user-rpc Pods + 1 个 envoy-gateway Pod 都在 Running │
|
||||
│ │
|
||||
│ 4️⃣ 环境变量验证 │
|
||||
│ $ kubectl exec -it <user-rpc-pod> -n juwan -- env | grep JWT │
|
||||
│ 预期: JWT_SECRET_KEY=... │
|
||||
│ │
|
||||
│ 5️⃣ Redis 连接验证 │
|
||||
│ $ kubectl run redis-cli --image=redis:latest --rm -it \ │
|
||||
│ -- redis-cli -h user-redis.juwan:6379 PING │
|
||||
│ 预期: PONG │
|
||||
│ │
|
||||
│ 详见: VERIFICATION.md 第1-8部分 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
├─────────── 生产环境额外步骤 ──────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────────────────┐ ┌─────────────────────────────────────┐
|
||||
│ Phase 5a: 应用集成 │ │ Phase 5b: 启用 ETCD 加密 (30分钟) │
|
||||
│ (2-3 小时) ⚠️ 推荐 │ │ ⚠️ 生产推荐,需集群管理员权限 │
|
||||
├──────────────────────────┤ ├─────────────────────────────────────┤
|
||||
│ │ │ │
|
||||
│ 实施内容: │ │ 前提条件: │
|
||||
│ ✓ gRPC Interceptor │ │ ✓ Control Plane 节点访问权限 │
|
||||
│ ✓ Login/Logout Handler │ │ ✓ ETCD 备份已创建 │
|
||||
│ ✓ JWT Middleware │ │ ✓ 加密密钥已生成 │
|
||||
│ ✓ Token Refresh Logic │ │ │
|
||||
│ ✓ Error Handling │ │ 步骤: │
|
||||
│ ✓ Unit Tests │ │ 1. 生成 32 字节密钥 │
|
||||
│ │ │ $ head -c 32 /dev/urandom | base64
|
||||
│ 参考: │ │ │
|
||||
│ INTEGRATION.md │ │ 2. 创建加密配置文件 │
|
||||
│ │ │ /etc/kubernetes/encryption-config.yaml
|
||||
│ 时间估计: │ │ │
|
||||
│ - gRPC 拦截器: 30分钟 │ │ 3. 修改 kube-apiserver manifest │
|
||||
│ - Handlers: 60分钟 │ │ 添加密钥路径和卷挂载 │
|
||||
│ - Middleware: 30分钟 │ │ │
|
||||
│ - 测试: 60分钟 │ │ 4. 重启 kube-apiserver │
|
||||
│ │ │ kubelet 自动重启 │
|
||||
│ │ │ │
|
||||
│ │ │ 5. 验证加密已启用 │
|
||||
│ │ │ kubectl create secret generic ... │
|
||||
│ │ │ 检查 ETCD 中的数据是否加密 │
|
||||
│ │ │ │
|
||||
│ │ │ 详见: ENCRYPTION.md (8个部分) │
|
||||
│ │ │ 验证: VERIFICATION.md 第9部分 │
|
||||
│ │ │ │
|
||||
└──────────────────────────┘ └─────────────────────────────────────┘
|
||||
│ │
|
||||
└───────────────────┬─────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────┐
|
||||
│ Phase 6: 完成 ✅ │
|
||||
├──────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 最终检查: │
|
||||
│ ✓ 所有 Pods 运行正常 │
|
||||
│ ✓ RBAC 权限已验证 │
|
||||
│ ✓ JWT 功能已集成 │
|
||||
│ ✓ 日志和监控已配置 │
|
||||
│ ✓ (可选) ETCD 加密已启用 │
|
||||
│ │
|
||||
│ 生产推荐: │
|
||||
│ ✓ 启用审计日志 │
|
||||
│ ✓ 配置密钥轮换计划(季度) │
|
||||
│ ✓ 备份密钥到安全位置 │
|
||||
│ ✓ 配置告警和监控 │
|
||||
│ │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 时间估计和路径
|
||||
|
||||
```
|
||||
推荐部署路径
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
🚀 最快路径 (30 分钟) - 开发环境
|
||||
────────────────────────────────────────────────────────────────
|
||||
Phase 1: 前置检查 ⏱️ 5 分钟
|
||||
Phase 2: 创建 Secret 和 RBAC ⏱️ 5 分钟
|
||||
Phase 3: 更新 Deployments ⏱️ 10 分钟
|
||||
Phase 4: 验证部署 ⏱️ 10 分钟
|
||||
────────────────────────────────────────────────────────────────
|
||||
总计: 30 分钟
|
||||
|
||||
|
||||
📊 默认路径 (75 分钟) - 测试环境
|
||||
────────────────────────────────────────────────────────────────
|
||||
Phase 1-4: 如上 ⏱️ 30 分钟
|
||||
Phase 5a: 应用集成(简单版) ⏱️ 45 分钟
|
||||
────────────────────────────────────────────────────────────────
|
||||
总计: 75 分钟
|
||||
|
||||
|
||||
🏆 完整路径 (3.5-4 小时) - 生产环境
|
||||
────────────────────────────────────────────────────────────────
|
||||
Phase 1-4: 如上 ⏱️ 30 分钟
|
||||
Phase 5a: 应用集成(完整版) ⏱️ 2-3 小时
|
||||
Phase 5b: ETCD 加密配置 ⏱️ 30 分钟
|
||||
────────────────────────────────────────────────────────────────
|
||||
总计: 3.5-4 小时
|
||||
|
||||
|
||||
📚 学习路径 (6-8 小时) - 从零开始理解
|
||||
────────────────────────────────────────────────────────────────
|
||||
文档阅读 (SUMMARY + DEPLOYMENT + INTEGRATION) ⏱️ 1-2 小时
|
||||
完整路径部署 ⏱️ 3.5-4 小时
|
||||
验证和测试 ⏱️ 1-2 小时
|
||||
────────────────────────────────────────────────────────────────
|
||||
总计: 6-8 小时
|
||||
```
|
||||
|
||||
## 并行和串行步骤
|
||||
|
||||
```
|
||||
可以并行执行的任务
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
┌─────────────────────────────────┐
|
||||
│ 应用集成 (Phase 5a) │ ────┐
|
||||
├─────────────────────────────────┤ │ 可选,独立
|
||||
│ • gRPC interceptor │ │ 进行
|
||||
│ • REST middleware │ │
|
||||
│ • Handler 实现 │ │
|
||||
│ • 单元测试 │ │
|
||||
└─────────────────────────────────┘ │
|
||||
├─ 与 Phase 2-4 并行
|
||||
│
|
||||
┌─────────────────────────────────┐ │
|
||||
│ ETCD 加密 (Phase 5b) │ ────┘
|
||||
├─────────────────────────────────┤ │ 需要集群管理员
|
||||
│ • 生成密钥(可单独进行) │ │ 权限,在
|
||||
│ • 创建配置文件 │ │ Control Plane
|
||||
│ • 修改 kube-apiserver │ │ 节点执行
|
||||
│ • 重启 API server │ │
|
||||
└─────────────────────────────────┘────┘
|
||||
|
||||
|
||||
必须串行执行的步骤
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
Phase 1 → Phase 2 → Phase 3 → Phase 4 → (Phase 5a + Phase 5b)
|
||||
|
||||
↓ ↓ ↓ ↓
|
||||
前置检查 创建资源 部署应用 验证完整 可选扩展功能
|
||||
|
||||
• Phase 2 必须在 Phase 1 之后(需要 namespace)
|
||||
• Phase 3 必须在 Phase 2 之后(需要 RoleBinding)
|
||||
• Phase 4 必须在 Phase 3 之后(需要 Pods 启动)
|
||||
• Phase 5a/5b 可在 Phase 4 完成后并行进行
|
||||
```
|
||||
|
||||
## 关键时间点
|
||||
|
||||
```
|
||||
事件时间线
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
T+0 Phase 1: 验证前置条件
|
||||
└─ 预计 5 分钟
|
||||
|
||||
T+5 Phase 2: kubectl apply jwt-secret.yaml
|
||||
└─ 预计 1 分钟执行,5 分钟验证
|
||||
|
||||
T+11 Phase 3a: kubectl apply user-rpc.yaml
|
||||
└─ 3 个 Pods 启动(滚动更新)
|
||||
└─ 预计 ~3 分钟(取决于镜像拉取)
|
||||
|
||||
T+14 Phase 3b: kubectl apply envoy.yaml
|
||||
└─ 1 个 Pod 启动
|
||||
└─ 预计 ~2 分钟
|
||||
|
||||
T+16 Phase 4: 执行完整验证检查
|
||||
└─ 12 个验证部分,共 ~15 分钟
|
||||
|
||||
T+31 ✅ 基础部署完成
|
||||
|
||||
T+31 (可选) Phase 5a: 应用代码集成
|
||||
到 └─ 2-3 小时编码和测试
|
||||
T+211
|
||||
|
||||
T+31 (可选) Phase 5b: ETCD 加密
|
||||
到 └─ 30 分钟配置
|
||||
T+61
|
||||
|
||||
T+211 或 T+61 🎉 全部完成
|
||||
(取决于是否执行 Phase 5)
|
||||
```
|
||||
|
||||
## 推荐的部署顺序
|
||||
|
||||
### 对于 DevOps/SRE
|
||||
|
||||
```
|
||||
优先级顺序:
|
||||
|
||||
1️⃣ Phase 1-4 (核心部署) [必需]
|
||||
└─ 时间: 30 分钟
|
||||
|
||||
2️⃣ Phase 5b (ETCD 加密) [生产强烈推荐]
|
||||
└─ 时间: 30 分钟
|
||||
└─ 开始时间: T+16 之前 (与 Phase 4 并行)
|
||||
|
||||
3️⃣ 密钥备份和恢复计划 [重要]
|
||||
└─ 时间: 15 分钟
|
||||
└─ 参考: DEPLOYMENT.md 灾难恢复
|
||||
|
||||
4️⃣ Phase 5a 支持 [当开发完成时]
|
||||
└─ 协助开发团队集成 JWT
|
||||
└─ 参考: INTEGRATION.md
|
||||
```
|
||||
|
||||
### 对于应用开发者
|
||||
|
||||
```
|
||||
优先级顺序:
|
||||
|
||||
1️⃣ 了解系统架构 [了解背景]
|
||||
└─ 文档: SUMMARY.md
|
||||
└─ 时间: 10 分钟
|
||||
|
||||
2️⃣ Phase 5a: 代码集成 [并行进行]
|
||||
└─ 参考: INTEGRATION.md
|
||||
└─ 时间: 2-3 小时
|
||||
|
||||
3️⃣ 单元测试 [在开发中]
|
||||
└─ 参考: INTEGRATION.md 第 9 部分
|
||||
└─ 时间: 1 小时
|
||||
|
||||
4️⃣ 集成测试 [与运维协调]
|
||||
└─ 测试完整流程
|
||||
└─ 时间: 1-2 小时
|
||||
```
|
||||
|
||||
## 回滚应急步骤
|
||||
|
||||
如果部署失败,可以快速回滚:
|
||||
|
||||
```
|
||||
紧急回滚
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
如果 Phase 2 (Secret) 失败:
|
||||
→ kubectl delete secret jwt-secret -n juwan
|
||||
→ kubectl delete sa user-rpc envoy-gateway -n juwan
|
||||
→ kubectl delete role jwt-secret-reader -n juwan
|
||||
→ 修正配置后重新应用
|
||||
|
||||
如果 Phase 3 (Deployment) 失败:
|
||||
→ kubectl rollout undo deployment/user-rpc -n juwan
|
||||
→ kubectl rollout undo deployment/envoy-gateway -n juwan
|
||||
→ 或删除部署并使用稳定的旧版本重新部署
|
||||
|
||||
如果 Phase 5b (ETCD 加密) 失败:
|
||||
→ 从 kube-apiserver 清单中移除加密参数
|
||||
→ 重启 kube-apiserver
|
||||
→ 删除 /etc/kubernetes/encryption-config.yaml
|
||||
→ 从最近的 ETCD 备份恢复(如果需要)
|
||||
|
||||
注意: 备份是关键!每次重大操作前都应备份。
|
||||
```
|
||||
|
||||
## 部署检查点 (Go/No-Go)
|
||||
|
||||
```
|
||||
关键检查点
|
||||
═════════════════════════════════════════════════════════════════
|
||||
|
||||
✅ Checkpoint 1 (Phase 2 后)
|
||||
- Secret 已创建
|
||||
- ServiceAccounts 已创建
|
||||
- Go → 继续 Phase 3
|
||||
- No-Go → 检查 kubectl 权限
|
||||
|
||||
✅ Checkpoint 2 (Phase 3 后)
|
||||
- Pods 已启动 (Running)
|
||||
- No PodSchedulingFailure
|
||||
- Go → 继续 Phase 4
|
||||
- No-Go → 检查资源限制和镜像拉取
|
||||
|
||||
✅ Checkpoint 3 (Phase 4 权限测试)
|
||||
- user-rpc 可以读 jwt-secret
|
||||
- envoy-gateway 可以读 jwt-secret
|
||||
- 其他 SA 无法读取
|
||||
- Go → 继续 Phase 5
|
||||
- No-Go → 检查 RBAC 配置
|
||||
|
||||
✅ Checkpoint 4 (Phase 4 Redis 连接)
|
||||
- Redis Cluster 健康 (3/3 nodes)
|
||||
- PING 返回 PONG
|
||||
- Go → 继续应用集成
|
||||
- No-Go → 检查 Redis Pods 和网络
|
||||
|
||||
✅ Checkpoint 5 (Phase 5b - ETCD 加密)
|
||||
- 新创建的 Secret 在 ETCD 中已加密
|
||||
- Go → 生产就绪
|
||||
- No-Go → 检查 kube-apiserver 配置参数
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用这个流程图
|
||||
|
||||
1. **首次部署** → 从 "推荐部署路径" 选择合适的版本
|
||||
2. **卡在某一步** → 查看对应的 Phase 描述和命令
|
||||
3. **估算时间** → 查看 "时间估计和路径" 部分
|
||||
4. **需要回滚** → 参考 "回滚应急步骤"
|
||||
5. **检查进度** → 使用 "部署检查点"
|
||||
|
||||
详细的部署步骤见:[DEPLOYMENT.md](./DEPLOYMENT.md)
|
||||
@@ -0,0 +1,399 @@
|
||||
# JWT + ETCD 加密系统文档索引
|
||||
|
||||
## 📚 文档完整导航
|
||||
|
||||
### 快速入门 (5-15分钟)
|
||||
|
||||
**推荐路径:** 从上到下顺序阅读
|
||||
|
||||
1. **[SUMMARY.md](./SUMMARY.md)** ⭐ 从这里开始
|
||||
- 📋 项目概览和架构图
|
||||
- 🎯 核心特性一览
|
||||
- ✅ 生产就绪检查清单
|
||||
- 🚀 下一步行动计划
|
||||
|
||||
2. **[README.md](./README.md)**
|
||||
- 🏃 4个快速部署步骤
|
||||
- 🔐 安全考虑事项
|
||||
- 🔄 密钥轮换程序
|
||||
- 🆘 故障排查
|
||||
|
||||
3. **[QUICK_REFERENCE.md](./QUICK_REFERENCE.md)**
|
||||
- ⚡ 一页速查表
|
||||
- 📝 常见命令复制粘贴
|
||||
- 🗺️ 文档地图
|
||||
- 🎓 关键参数速知
|
||||
|
||||
### 部署实施 (30-60分钟)
|
||||
|
||||
4. **[DEPLOYMENT.md](./DEPLOYMENT.md)** - 最详细的部署指南
|
||||
- 📦 第1步:创建 Secret 和 RBAC(必需)
|
||||
- 🔄 第2步:更新 user-rpc Deployment
|
||||
- 🌐 第3步:更新 Envoy Gateway Deployment
|
||||
- 🔐 第4步:启用 ETCD 加密(生产推荐)
|
||||
- ✔️ 第5步:验证整个系统
|
||||
- 📊 监控和日志配置
|
||||
- 🛠️ 安全最佳实践
|
||||
- 🆘 故障排查指南
|
||||
- 💾 灾难恢复流程
|
||||
|
||||
### 验证和监控 (20-30分钟)
|
||||
|
||||
5. **[VERIFICATION.md](./VERIFICATION.md)** - 完整验证清单
|
||||
|
||||
**12个验证部分:**
|
||||
|
||||
| 部分 | 用途 | 时间 |
|
||||
|-----|------|------|
|
||||
| 第1部分 | Secret/RBAC 基础验证 | 2分钟 |
|
||||
| 第2部分 | 权限测试(allow/deny) | 3分钟 |
|
||||
| 第3部分 | Deployment 配置检查 | 2分钟 |
|
||||
| 第4部分 | Redis 连接测试 | 2分钟 |
|
||||
| 第5部分 | 应用启动日志 | 3分钟 |
|
||||
| 第6部分 | 网络和服务发现 | 3分钟 |
|
||||
| 第7部分 | Prometheus 指标 | 3分钟 |
|
||||
| 第8部分 | Loki 日志聚合 | 2分钟 |
|
||||
| 第9部分 | ETCD 加密验证 | 5分钟 |
|
||||
| 第10部分 | JWT 功能测试 | 10分钟 |
|
||||
| 第11部分 | 故障排查诊断 | 5分钟 |
|
||||
| 第12部分 | 清理和总结 | 2分钟 |
|
||||
|
||||
### 高级话题
|
||||
|
||||
6. **[ENCRYPTION.md](./ENCRYPTION.md)** - ETCD 加密完整指南
|
||||
- 🔑 第1部分:密钥生成
|
||||
- 📋 第2部分:配置格式
|
||||
- 🔧 第3部分:kube-apiserver 修改
|
||||
- ✅第4部分:验证加密
|
||||
- ⚠️ 第5部分:关键警告(数据不可恢复)
|
||||
- 🔐 第6部分:RBAC 解释
|
||||
- 📦 第7部分:Deployment 示例
|
||||
- 🍎 第8部分:Minikube 特定说明
|
||||
|
||||
7. **[INTEGRATION.md](../api/INTEGRATION.md)** - 代码集成指南
|
||||
- 🔗 第1部分:gRPC Unary Interceptor
|
||||
- 🔗 第2部分:gRPC Stream Interceptor
|
||||
- 👤 第3部分:登录 Handler 实现
|
||||
- 🔐 第4部分:受保护 Handler 中的声明提取
|
||||
- 🔄 第5部分:令牌刷新端点
|
||||
- 🚪 第6部分:登出处理
|
||||
- 🛣️ 第7部分:REST Routes 配置
|
||||
- 🔎 第8部分:错误处理最佳实践
|
||||
- 🧪 第9部分:单元测试示例
|
||||
|
||||
---
|
||||
|
||||
## 📁 文件结构详解
|
||||
|
||||
```
|
||||
deploy/k8s/
|
||||
├── secrets/
|
||||
│ ├── jwt-secret.yaml ✅ Kubernetes 清单文件
|
||||
│ │ ├── Secret: jwt-secret (JWT 秘钥数据)
|
||||
│ │ ├── ServiceAccount: user-rpc
|
||||
│ │ ├── ServiceAccount: envoy-gateway
|
||||
│ │ ├── Role: jwt-secret-reader
|
||||
│ │ ├── RoleBinding: jwt-secret-reader-user-rpc
|
||||
│ │ └── RoleBinding: jwt-secret-reader-envoy-gateway
|
||||
│ │
|
||||
│ ├── README.md 📖 快速参考指南(5分钟入门)
|
||||
│ ├── SUMMARY.md 📊 系统概览(10分钟了解全貌)
|
||||
│ ├── QUICK_REFERENCE.md ⚡ 速查表(查找命令和参数)
|
||||
│ ├── DEPLOYMENT.md 📦 详细部署指南(60分钟完整部署)
|
||||
│ ├── ENCRYPTION.md 🔐 ETCD 加密指南(Control Plane 配置)
|
||||
│ ├── VERIFICATION.md ✅ 验证清单(部署后验证)
|
||||
│ └── INDEX.md 🗺️ 本文件(文档导航)
|
||||
│
|
||||
└── envoy/
|
||||
│ └── envoy.yaml ✅ Envoy 网关配置
|
||||
│ └── 已更新: serviceAccountName: envoy-gateway
|
||||
│
|
||||
service/user/
|
||||
├── user-api.yaml ✅ user-api Service
|
||||
├── user-rpc.yaml ✅ user-rpc Deployment(已更新)
|
||||
│ ├── serviceAccountName: user-rpc (已更新)
|
||||
│ ├── JWT_SECRET_KEY env var (已更新)
|
||||
│ └── Redis Cluster configuration
|
||||
└── ...
|
||||
|
||||
app/users/
|
||||
├── api/
|
||||
│ └── INTEGRATION.md 📝 REST/gRPC 集成指南
|
||||
│
|
||||
└── rpc/
|
||||
├── internal/utils/jwt.go ✅ JwtManager 实现(已存在)
|
||||
├── internal/config/config.go ✅ JWT 配置(已存在)
|
||||
├── internal/svc/
|
||||
│ └── serviceContext.go ✅ 依赖注入(已存在)
|
||||
└── etc/pb.yaml ✅ 运行时配置(已存在)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 按场景查找文档
|
||||
|
||||
### 场景 1:我想快速了解这个系统是什么
|
||||
|
||||
**推荐阅读顺序:**
|
||||
1. [SUMMARY.md](./SUMMARY.md) - 项目概览(5分钟)
|
||||
2. [SUMMARY.md](./SUMMARY.md) 中的架构图和特性说明
|
||||
|
||||
**关键信息:**
|
||||
- JWT 令牌系统 + Redis 存储 + RBAC 权限 + ETCD 加密
|
||||
- 支持 7 天有效期、30 天可刷新
|
||||
- Envoy 网关 CSRF 防护
|
||||
|
||||
---
|
||||
|
||||
### 场景 2:我想立即部署到 Kubernetes
|
||||
|
||||
**推荐阅读顺序:**
|
||||
1. [README.md](./README.md) - 快速参考(2分钟)
|
||||
2. [QUICK_REFERENCE.md](./QUICK_REFERENCE.md) - 复制粘贴命令(3分钟)
|
||||
3. 运行部署命令(5分钟)
|
||||
4. [VERIFICATION.md](./VERIFICATION.md) 第1-7部分 - 验证(10分钟)
|
||||
|
||||
**快速命令:**
|
||||
```bash
|
||||
# Copy from QUICK_REFERENCE.md "部署命令" 部分
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
|
||||
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
|
||||
kubectl apply -f deploy/k8s/envoy/envoy.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 场景 3:部署后验证一切正常
|
||||
|
||||
**推荐阅读:**
|
||||
- [VERIFICATION.md](./VERIFICATION.md) - 12部分完整验证清单
|
||||
- 逐部分执行验证命令
|
||||
|
||||
**预计时间:** 30-40分钟
|
||||
|
||||
**验证触发点:**
|
||||
- ✅ Secrets 和 RBAC 已创建
|
||||
- ✅ Pods 已启动运行
|
||||
- ✅ 权限验证通过
|
||||
- ✅ Redis 连接成功
|
||||
|
||||
---
|
||||
|
||||
### 场景 4:启用 ETCD 加密(生产推荐)
|
||||
|
||||
**推荐阅读顺序:**
|
||||
1. [ENCRYPTION.md](./ENCRYPTION.md) - 完整加密指南
|
||||
2. 按照 8 个步骤逐一执行
|
||||
3. [VERIFICATION.md](./VERIFICATION.md) 第9部分 - 加密验证
|
||||
|
||||
**需要的权限:**
|
||||
- Control Plane 节点的 root/sudo 权限
|
||||
- Kubernetes 集群管理员权限
|
||||
|
||||
**预计时间:** 15-20分钟
|
||||
|
||||
---
|
||||
|
||||
### 场景 5:集成 JWT 到我的应用代码中
|
||||
|
||||
**推荐阅读顺序:**
|
||||
1. [INTEGRATION.md](../api/INTEGRATION.md) 第1-2部分 - gRPC 拦截器
|
||||
2. 第3-4部分 - 登录和受保护 Handlers
|
||||
3. 第7-8部分 - REST API 中间件
|
||||
4. 第9部分 - 单元测试
|
||||
|
||||
**需要实现:**
|
||||
- ✅ gRPC Unary/Stream Interceptors
|
||||
- ✅ 登录/登出端点
|
||||
- ✅ JWT Middleware for REST
|
||||
- ✅ 错误处理
|
||||
|
||||
**预计时间:** 2-3 小时
|
||||
|
||||
---
|
||||
|
||||
### 场景 6:部署后遇到问题
|
||||
|
||||
**根据错误类型选择:**
|
||||
|
||||
| 错误类型 | 查看文档 |
|
||||
|---------|--------|
|
||||
| Pod 无法启动 | [VERIFICATION.md](./VERIFICATION.md) 第11部分 |
|
||||
| 权限被拒绝 | [VERIFICATION.md](./VERIFICATION.md) 第2部分 + [README.md](./README.md) 故障排查 |
|
||||
| Redis 连接失败 | [VERIFICATION.md](./VERIFICATION.md) 第4部分 |
|
||||
| ETCD 加密失败 | [ENCRYPTION.md](./ENCRYPTION.md) 第5-6部分 |
|
||||
| 配置不清楚 | [QUICK_REFERENCE.md](./QUICK_REFERENCE.md) 配置文件位置 |
|
||||
|
||||
---
|
||||
|
||||
### 场景 7:定期维护任务
|
||||
|
||||
#### 任务:轮换 JWT 秘钥
|
||||
|
||||
**阅读:** [DEPLOYMENT.md](./DEPLOYMENT.md) 安全最佳实践 > 密钥轮换
|
||||
**或:** [QUICK_REFERENCE.md](./QUICK_REFERENCE.md) 密钥轮换步骤
|
||||
|
||||
**频率:** 季度(3个月)
|
||||
|
||||
#### 任务:轮换 ETCD 加密密钥
|
||||
|
||||
**阅读:** [ENCRYPTION.md](./ENCRYPTION.md) 第5部分
|
||||
**或:** [QUICK_REFERENCE.md](./QUICK_REFERENCE.md) ETCD 加密系统
|
||||
|
||||
**频率:** 年度(12个月)
|
||||
|
||||
#### 任务:备份密钥
|
||||
|
||||
**阅读:** [DEPLOYMENT.md](./DEPLOYMENT.md) 灾难恢复
|
||||
**或:** [ENCRYPTION.md](./ENCRYPTION.md) 关键警告
|
||||
|
||||
**频率:** 立即 + 每次轮换后
|
||||
|
||||
---
|
||||
|
||||
## 📊 文档深度对比
|
||||
|
||||
| 文档 | 深度 | 丰富度 | 代码 | 适合角色 |
|
||||
|-----|------|--------|------|---------|
|
||||
| README | 浅 | 概览 | - | PM/初学者 |
|
||||
| SUMMARY | 浅 | 概览 | - | 决策者 |
|
||||
| QUICK_REFERENCE | 中 | 速查 | 命令 | DevOps/SRE |
|
||||
| DEPLOYMENT | 深 | 详细 | 示例 | DevOps/运维 |
|
||||
| VERIFICATION | 深 | 详细 | 脚本 | QA/DevOps |
|
||||
| ENCRYPTION | 非常深 | 极详细 | YAML | 安全/运维 |
|
||||
| INTEGRATION | 非常深 | 代码级 | 完整 | 开发者 |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 学习路径建议
|
||||
|
||||
### 对于 DevOps/SRE
|
||||
|
||||
1. SUMMARY.md (5 分钟)
|
||||
2. DEPLOYMENT.md (30 分钟)
|
||||
3. VERIFICATION.md (30 分钟)
|
||||
4. ENCRYPTION.md (20 分钟)
|
||||
5. 实践部署 (60 分钟)
|
||||
|
||||
**总计:** ~3 小时
|
||||
|
||||
### 对于应用开发者
|
||||
|
||||
1. SUMMARY.md > "集成点" 部分 (5 分钟)
|
||||
2. INTEGRATION.md (60 分钟)
|
||||
3. QUICK_REFERENCE.md > "JWT Manager API" (10 分钟)
|
||||
4. 代码实现 (2-3 小时)
|
||||
5. 单元测试 (INTEGRATION.md 第9部分)
|
||||
|
||||
**总计:** ~4 小时
|
||||
|
||||
### 对于安全/合规人员
|
||||
|
||||
1. SUMMARY.md (5 分钟)
|
||||
2. ENCRYPTION.md (30 分钟)
|
||||
3. DEPLOYMENT.md > 安全最佳实践 (15 分钟)
|
||||
4. VERIFICATION.md 第9部分 (10 分钟)
|
||||
|
||||
**总计:** ~1 小时
|
||||
|
||||
### 对于项目经理
|
||||
|
||||
1. SUMMARY.md (5 分钟)
|
||||
2. DEPLOYMENT.md > "部署状态示意图" (5 分钟)
|
||||
3. DEPLOYMENT.md > "快速部署" (2 分钟)
|
||||
|
||||
**总计:** ~15 分钟
|
||||
|
||||
---
|
||||
|
||||
## 🎓 学习成果预期
|
||||
|
||||
### 完成后,您将能够:
|
||||
|
||||
✅ 在 Kubernetes 中部署 JWT 认证系统
|
||||
✅ 配置 RBAC 权限控制
|
||||
✅ 启用 ETCD 加密保护敏感数据
|
||||
✅ 在 Go-zero 应用中集成 JWT
|
||||
✅ 实现令牌刷新和撤销
|
||||
✅ 诊断和排查常见问题
|
||||
✅ 执行密钥轮换和灾难恢复
|
||||
|
||||
---
|
||||
|
||||
## 🆘 求助指南
|
||||
|
||||
### 第一步:找到相关文档
|
||||
- 浏览本索引找到相关章节
|
||||
- 或用 Ctrl+F 搜索关键词
|
||||
|
||||
### 第二步:查看文档中的相关部分
|
||||
- DEPLOYMENT.md 的相关章节
|
||||
- 或 VERIFICATION.md 的故障排查部分
|
||||
|
||||
### 第三步:运行诊断命令
|
||||
- QUICK_REFERENCE.md 的 "故障排查" 部分
|
||||
- 或 VERIFICATION.md 的 "故障排查" 部分
|
||||
|
||||
### 第四步:检查日志
|
||||
```bash
|
||||
kubectl logs -n juwan -l app=user-rpc -f
|
||||
kubectl logs -n juwan -l app=envoy-gateway -f
|
||||
```
|
||||
|
||||
### 第五步:查看详细文档
|
||||
如果上述步骤未能解决,查看对应的详细文档:
|
||||
- 配置问题 → DEPLOYMENT.md
|
||||
- 权限问题 → VERIFICATION.md 第2/11部分
|
||||
- 集成问题 → INTEGRATION.md
|
||||
- 加密问题 → ENCRYPTION.md
|
||||
|
||||
---
|
||||
|
||||
## 📞 文档反馈
|
||||
|
||||
如果您发现:
|
||||
- ❌ 文档不清楚
|
||||
- ❌ 命令不工作
|
||||
- ❌ 信息缺失或过时
|
||||
- ❌ 错别字或格式问题
|
||||
|
||||
请在相应的 `.md` 文件中标记,或提交更新建议。
|
||||
|
||||
---
|
||||
|
||||
## 📌 关键概念快速链接
|
||||
|
||||
| 概念 | 详见 |
|
||||
|-----|------|
|
||||
| JWT 令牌生命周期 | SUMMARY.md "关键特性" |
|
||||
| Redis 双键结构 | SUMMARY.md "关键特性" |
|
||||
| RBAC 权限隔离 | SUMMARY.md "关键特性" |
|
||||
| CSRF 防护 | SUMMARY.md "关键特性" |
|
||||
| ETCD 加密 | ENCRYPTION.md |
|
||||
| 错误处理 | INTEGRATION.md 第8部分 |
|
||||
| 密钥轮换 | DEPLOYMENT.md "安全最佳实践" |
|
||||
| 灾难恢复 | DEPLOYMENT.md "灾难恢复" |
|
||||
|
||||
---
|
||||
|
||||
## ✨ 文档特性
|
||||
|
||||
✅ **模块化** - 每个文档独立,但相互链接
|
||||
✅ **分层** - 从快速概览到深度细节
|
||||
✅ **实践导向** - 包含实际命令和代码示例
|
||||
✅ **完整性** - 覆盖部署、验证、维护、故障排查
|
||||
✅ **易查找** - 目录、索引、速查表
|
||||
|
||||
---
|
||||
|
||||
**开始阅读:** 👉 [SUMMARY.md](./SUMMARY.md)
|
||||
|
||||
或根据您的角色选择:
|
||||
|
||||
| 角色 | 开始文档 | 预计时间 |
|
||||
|-----|--------|--------|
|
||||
| DevOps/运维 | [DEPLOYMENT.md](./DEPLOYMENT.md) | 1-2 小时 |
|
||||
| 应用开发 | [INTEGRATION.md](../api/INTEGRATION.md) | 2-3 小时 |
|
||||
| 安全审查 | [ENCRYPTION.md](./ENCRYPTION.md) | 30 分钟 |
|
||||
| 项目经理 | [SUMMARY.md](./SUMMARY.md) | 15 分钟 |
|
||||
| 新手 | [README.md](./README.md) → [SUMMARY.md](./SUMMARY.md) | 15-20 分钟 |
|
||||
@@ -0,0 +1,350 @@
|
||||
# JWT + ETCD 加密系统 - 快速参考卡片
|
||||
|
||||
## 一页速查表
|
||||
|
||||
### 部署命令
|
||||
|
||||
```bash
|
||||
# 创建 Secret 和 RBAC
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
|
||||
|
||||
# 更新 Deployments
|
||||
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
|
||||
kubectl apply -f deploy/k8s/envoy/envoy.yaml
|
||||
|
||||
# 验证部署
|
||||
kubectl get secret jwt-secret -n juwan
|
||||
kubectl get sa user-rpc envoy-gateway -n juwan
|
||||
kubectl get role jwt-secret-reader -n juwan
|
||||
kubectl get pods -n juwan -l app=user-rpc
|
||||
kubectl get pods -n juwan -l app=envoy-gateway
|
||||
```
|
||||
|
||||
### 权限验证
|
||||
|
||||
```bash
|
||||
# user-rpc 可以读 jwt-secret
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:user-rpc \
|
||||
--resource-name=jwt-secret -n juwan
|
||||
# 预期: yes
|
||||
|
||||
# 其他 SA 无法读 jwt-secret
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:default \
|
||||
--resource-name=jwt-secret -n juwan
|
||||
# 预期: no
|
||||
```
|
||||
|
||||
### 日志查看
|
||||
|
||||
```bash
|
||||
# user-rpc 日志
|
||||
kubectl logs -n juwan -l app=user-rpc -f
|
||||
|
||||
# Envoy 日志
|
||||
kubectl logs -n juwan -l app=envoy-gateway -f
|
||||
|
||||
# 特定 Pod 日志
|
||||
kubectl logs -n juwan <pod-name> --all-containers=true -f
|
||||
```
|
||||
|
||||
### 环境变量验证
|
||||
|
||||
```bash
|
||||
# 检查 JWT_SECRET_KEY 已注入
|
||||
kubectl exec -it $(kubectl get pod -n juwan -l app=user-rpc -o name | head -1) \
|
||||
-n juwan -- env | grep JWT_SECRET_KEY
|
||||
```
|
||||
|
||||
### Redis 验证
|
||||
|
||||
```bash
|
||||
# 连接到 Redis Cluster
|
||||
kubectl run redis-cli --image=redis:latest --rm -it --restart=Never -- \
|
||||
redis-cli -h user-redis.juwan:6379 -c CLUSTER INFO
|
||||
|
||||
# 测试键操作
|
||||
kubectl run redis-cli --image=redis:latest --rm -it --restart=Never -- \
|
||||
redis-cli -h user-redis.juwan:6379 -c GET jwt:user:test-user-id
|
||||
```
|
||||
|
||||
### ETCD 加密配置
|
||||
|
||||
```bash
|
||||
# 1. 在 Control Plane 节点生成密钥
|
||||
head -c 32 /dev/urandom | base64
|
||||
|
||||
# 2. 编辑 kube-apiserver 清单
|
||||
sudo nano /etc/kubernetes/manifests/kube-apiserver.yaml
|
||||
|
||||
# 添加参数:
|
||||
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml
|
||||
|
||||
# 3. 创建加密配置文件
|
||||
cat <<EOF | sudo tee /etc/kubernetes/encryption-config.yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: <BASE64_KEY>
|
||||
- identity: {}
|
||||
EOF
|
||||
|
||||
# 4. 验证加密
|
||||
kubectl create secret generic test-encryption -n juwan --from-literal=key=value
|
||||
sudo ETCDCTL_API=3 etcdctl --cert=/etc/kubernetes/pki/etcd/server.crt \
|
||||
--key=/etc/kubernetes/pki/etcd/server.key \
|
||||
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
|
||||
--endpoints=127.0.0.1:2379 \
|
||||
get /registry/secrets/juwan/test-encryption | od -A x -t x1z
|
||||
```
|
||||
|
||||
### 故障排查
|
||||
|
||||
```bash
|
||||
# Pod 无法启动?查看事件
|
||||
kubectl describe pod <pod-name> -n juwan
|
||||
|
||||
# 权限被拒绝?检查 RBAC
|
||||
kubectl get rolebinding -n juwan -o wide
|
||||
kubectl describe rolebinding jwt-secret-reader-user-rpc -n juwan
|
||||
|
||||
# 无法挂载 Secret?检查 Secret 存在性
|
||||
kubectl get secret jwt-secret -n juwan -o yaml
|
||||
|
||||
# Redis 连接错误?测试连通性
|
||||
kubectl exec -it <user-rpc-pod> -n juwan -- \
|
||||
redis-cli -h user-redis.juwan:6379 PING
|
||||
```
|
||||
|
||||
## JWT Manager API 速查
|
||||
|
||||
### JwtManager 方法
|
||||
|
||||
```go
|
||||
// 生成新令牌
|
||||
token, err := svcCtx.JwtManager.New(ctx, userID, email, name)
|
||||
|
||||
// 验证令牌
|
||||
claims, err := svcCtx.JwtManager.Valid(ctx, token)
|
||||
|
||||
// 刷新令牌(如果过期但 Redis 仍有数据)
|
||||
newToken, err := svcCtx.JwtManager.Renew(ctx, token)
|
||||
|
||||
// 提取声明(不验证签名)
|
||||
claims, err := svcCtx.JwtManager.Extract(ctx, token)
|
||||
|
||||
// 检查令牌是否存在于 Redis
|
||||
exists, err := svcCtx.JwtManager.Exists(ctx, token)
|
||||
|
||||
// 撤销令牌(登出)
|
||||
err := svcCtx.JwtManager.Revoke(ctx, userID, token)
|
||||
|
||||
// 获取用户当前令牌
|
||||
token, err := svcCtx.JwtManager.GetUserToken(ctx, userID)
|
||||
|
||||
// 将声明转换为载荷
|
||||
payload := svcCtx.JwtManager.ClaimsToPayload(claims)
|
||||
```
|
||||
|
||||
## 配置文件位置
|
||||
|
||||
| 配置 | 位置 | 关键参数 |
|
||||
|-----|------|--------|
|
||||
| JWT Secret | `deploy/k8s/secrets/jwt-secret.yaml` | `secret-key` |
|
||||
| user-rpc 配置 | `app/users/rpc/etc/pb.yaml` | `JWT.SecretKey`, `REDIS_HOST` |
|
||||
| Envoy 配置 | `deploy/k8s/envoy/envoy.yaml` | CSRF 验证 Lua 代码 |
|
||||
| ETCD 加密 | `/etc/kubernetes/encryption-config.yaml`(Control Plane) | `secret` (32字节密钥) |
|
||||
|
||||
## 关键参数速查
|
||||
|
||||
```yaml
|
||||
# JWT 令牌有效期
|
||||
Token Exp: 7 days
|
||||
|
||||
# Redis 存储 TTL
|
||||
Redis TTL: 30 days
|
||||
|
||||
# 可刷新时间窗口
|
||||
Refresh Window: 30 days - 7 days = 23 days
|
||||
|
||||
# CSRF Token 位置
|
||||
Cookie: csrf_token=...
|
||||
Header: X-CSRF-Token: ...
|
||||
|
||||
# ETCD 加密算法
|
||||
Algorithm: AES-CBC
|
||||
Key Size: 256 bits (32 bytes)
|
||||
Encoding: Base64
|
||||
|
||||
# Secret 挂载方式
|
||||
Method: volumeMount (read-only)
|
||||
或
|
||||
Method: valueFrom.secretKeyRef
|
||||
```
|
||||
|
||||
## 常见问题速查
|
||||
|
||||
| 问题 | 排查命令 | 解决方案 |
|
||||
|-----|--------|--------|
|
||||
| Pod 无法启动 | `kubectl describe pod` | 检查 Secret/RBAC |
|
||||
| 权限被拒绝 | `kubectl auth can-i get secrets` | 验证 RBAC 绑定 |
|
||||
| Redis 连接失败 | `redis-cli PING` | 检查 Redis Pods |
|
||||
| JWT 验证失败 | 查看 Pod 日志 | 检查 Redis 中的令牌 |
|
||||
| CSRF 验证失败 | 查看 Envoy 日志 | 检查 Cookie/Header 匹配 |
|
||||
| ETCD 加密失败 | `kubectl get secret` | 检查 kube-apiserver 启动参数 |
|
||||
|
||||
## 部署检查清单 (5分钟版)
|
||||
|
||||
```bash
|
||||
# 第1步: 部署 Secret (10秒)
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml && sleep 5
|
||||
|
||||
# 第2步: 验证 Secret (10秒)
|
||||
kubectl get secret jwt-secret -n juwan && echo "✓ Secret 已创建"
|
||||
|
||||
# 第3步: 验证 RBAC (10秒)
|
||||
kubectl get role jwt-secret-reader -n juwan && echo "✓ RBAC 已配置"
|
||||
|
||||
# 第4步: 更新 Deployments (20秒)
|
||||
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
|
||||
kubectl apply -f deploy/k8s/envoy/envoy.yaml
|
||||
|
||||
# 第5步: 等待 Pods 启动 (30秒)
|
||||
kubectl rollout status deployment/user-rpc -n juwan
|
||||
kubectl rollout status deployment/envoy-gateway -n juwan
|
||||
|
||||
# 第6步: 快速功能测试 (2分钟)
|
||||
# 创建一个令牌并验证可读取
|
||||
REDIS_POD=$(kubectl get pod -n juwan -l redis=user-redis -o name | head -1)
|
||||
kubectl exec -it $REDIS_POD -n juwan -- redis-cli KEYS "jwt:*"
|
||||
```
|
||||
|
||||
## 密钥轮换步骤
|
||||
|
||||
```bash
|
||||
# 1. 生成新密钥
|
||||
NEW_KEY=$(head -c 32 /dev/urandom | base64)
|
||||
|
||||
# 2. 更新 Secret
|
||||
kubectl create secret generic jwt-secret \
|
||||
--from-literal=secret-key=$NEW_KEY \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
# 3. 重启 Pods(自动挂载新 Secret)
|
||||
kubectl rollout restart deployment/user-rpc -n juwan
|
||||
kubectl rollout restart deployment/envoy-gateway -n juwan
|
||||
|
||||
# 4. 等待 Pods 启动
|
||||
kubectl rollout status deployment/user-rpc -n juwan
|
||||
kubectl rollout status deployment/envoy-gateway -n juwan
|
||||
|
||||
# 5. 旧令牌现在需要刷新或重新登录
|
||||
```
|
||||
|
||||
## 文档地图
|
||||
|
||||
```
|
||||
deploy/k8s/secrets/
|
||||
├── jwt-secret.yaml ← Secrets + RBAC 配置
|
||||
├── README.md ← 开始阅读(快速指南)
|
||||
├── SUMMARY.md ← 本文件(系统概览)
|
||||
├── DEPLOYMENT.md ← 详细部署步骤(12步)
|
||||
├── ENCRYPTION.md ← ETCD 加密详细指南
|
||||
├── VERIFICATION.md ← 完整验证清单(12部分)
|
||||
└── QUICK_REFERENCE.md ← 本快速参考卡片
|
||||
|
||||
app/users/api/
|
||||
└── INTEGRATION.md ← JWT 代码集成指南
|
||||
|
||||
app/users/rpc/
|
||||
├── internal/utils/jwt.go ← JwtManager 实现
|
||||
├── internal/config/config.go ← JWT 配置
|
||||
├── internal/svc/serviceContext.go ← 依赖注入
|
||||
└── etc/pb.yaml ← 运行时配置
|
||||
```
|
||||
|
||||
## 关键时间点
|
||||
|
||||
| 阶段 | 时间 | 操作 |
|
||||
|-----|------|------|
|
||||
| 令牌签发 | T0 | 生成 JWT,过期时间 = T0 + 7天 |
|
||||
| | | 在 Redis 存储,TTL = 30天 |
|
||||
| Token 过期 | T0 + 7天 | JWT 验证失败 |
|
||||
| 令牌刷新 | T0 + 7天到T0 + 30天 | 如果 Redis 仍有数据,生成新令牌 |
|
||||
| 完全失效 | T0 + 30天 | Redis 删除,无法再刷新 |
|
||||
| 重新登录 | T0 + 30天+ | 用户需要重新登录 |
|
||||
|
||||
## 性能提示
|
||||
|
||||
```bash
|
||||
# 高并发下优化 Redis 连接
|
||||
# 在 pb.yaml 中调整:
|
||||
CacheConf:
|
||||
- Host: "user-redis.juwan:6379"
|
||||
Type: "cluster"
|
||||
MaxConnections: 100
|
||||
ConnectionPoolSize: 50
|
||||
|
||||
# 监控 JWT 验证吞吐量
|
||||
# 在 Prometheus 查询:
|
||||
rate(jwt_validations_total[5m])
|
||||
rate(jwt_refresh_total[5m])
|
||||
```
|
||||
|
||||
## 安全提示
|
||||
|
||||
✅ **必做**
|
||||
- [ ] 定期轮换 JWT 秘钥(季度)
|
||||
- [ ] 定期轮换 ETCD 加密密钥(年度)
|
||||
- [ ] 备份加密密钥到安全位置
|
||||
- [ ] 启用审计日志
|
||||
- [ ] 监控异常的令牌验证失败
|
||||
|
||||
❌ **禁止**
|
||||
- [ ] 不要在日志中输出 JWT 秘钥
|
||||
- [ ] 不要在代码库中存储密钥
|
||||
- [ ] 不要发送明文密钥到 Slack/Email
|
||||
- [ ] 不要在多个环境间共享密钥
|
||||
|
||||
## 版本信息
|
||||
|
||||
```
|
||||
Kubernetes: 1.24+
|
||||
Go-zero: v1.10.0+
|
||||
Redis: 7.0+
|
||||
ETCD: 3.5+
|
||||
Envoy: v1.32.2+
|
||||
```
|
||||
|
||||
## 支持和反馈
|
||||
|
||||
遇到问题?按优先级检查:
|
||||
|
||||
1. **运行验证脚本**
|
||||
```bash
|
||||
chmod +x deploy/k8s/secrets/verify-jwt-setup.sh
|
||||
./deploy/k8s/secrets/verify-jwt-setup.sh
|
||||
```
|
||||
|
||||
2. **查看日志**
|
||||
```bash
|
||||
kubectl logs -n juwan -l app=user-rpc -f
|
||||
```
|
||||
|
||||
3. **阅读 VERIFICATION.md**
|
||||
- 第1-5部分: 基础配置
|
||||
- 第6-8部分: 网络和监控
|
||||
- 第9部分: ETCD 加密
|
||||
- 第11部分: 故障排查
|
||||
|
||||
4. **详细指南**
|
||||
- DEPLOYMENT.md - 完整步骤
|
||||
- INTEGRATION.md - 代码集成
|
||||
- ENCRYPTION.md - 加密配置
|
||||
@@ -0,0 +1,148 @@
|
||||
# JWT Secret Management
|
||||
|
||||
This directory contains secure configuration for JWT secret key management.
|
||||
|
||||
## Files
|
||||
|
||||
- `jwt-secret.yaml`: Kubernetes Secret + ServiceAccount + RBAC rules
|
||||
- `ENCRYPTION.md`: Guide for enabling ETCD static encryption at rest
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Create the Secret and RBAC
|
||||
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
|
||||
```
|
||||
|
||||
This will create:
|
||||
- Secret `jwt-secret` in namespace `juwan` containing the JWT secret key
|
||||
- ServiceAccount `user-rpc` in namespace `juwan`
|
||||
- ServiceAccount `envoy-gateway` in namespace `juwan`
|
||||
- Role `jwt-secret-reader` that allows reading only `jwt-secret`
|
||||
- RoleBindings to grant both ServiceAccounts read permission on the secret
|
||||
|
||||
### 2. Update user-rpc Deployment
|
||||
|
||||
Update `deploy/k8s/service/user/user-rpc.yaml` to:
|
||||
|
||||
1. Set the serviceAccountName:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: user-rpc
|
||||
```
|
||||
|
||||
2. Add environment variable to load JWT secret:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: user-rpc
|
||||
env:
|
||||
- name: JWT_SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: jwt-secret
|
||||
key: secret-key
|
||||
```
|
||||
|
||||
### 3. Update envoy-gateway Deployment
|
||||
|
||||
Update `deploy/k8s/envoy/envoy.yaml` to:
|
||||
|
||||
1. Set the serviceAccountName:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: envoy-gateway
|
||||
```
|
||||
|
||||
2. Add environment variable or mount Secret:
|
||||
```yaml
|
||||
volumeMounts:
|
||||
- name: jwt-secret
|
||||
mountPath: /etc/jwt
|
||||
readOnly: true
|
||||
|
||||
volumes:
|
||||
- name: jwt-secret
|
||||
secret:
|
||||
secretName: jwt-secret
|
||||
defaultMode: 0400
|
||||
```
|
||||
|
||||
Then reference it in the Envoy config:
|
||||
```yaml
|
||||
data:
|
||||
envoy.yaml: |
|
||||
# Read JWT secret from /etc/jwt/secret-key
|
||||
```
|
||||
|
||||
### 4. Enable ETCD Encryption
|
||||
|
||||
Follow the guide in `ENCRYPTION.md` to enable static encryption at rest for all secrets in ETCD.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Least Privilege
|
||||
|
||||
- Only `user-rpc` and `envoy-gateway` can read the JWT secret
|
||||
- No other services or users have access
|
||||
- The Role allows reading **only** the `jwt-secret`, not other secrets
|
||||
|
||||
### Encryption at Rest
|
||||
|
||||
- With ETCD encryption enabled, the secret is encrypted when stored on disk
|
||||
- Even if someone gains access to the ETCD database files, they cannot read the secret without the encryption key
|
||||
|
||||
### Secret Rotation
|
||||
|
||||
To rotate the JWT secret key:
|
||||
|
||||
1. Generate a new key
|
||||
2. Update the Secret:
|
||||
```bash
|
||||
kubectl create secret generic jwt-secret --from-literal=secret-key=NEW_KEY --dry-run=client -o yaml | kubectl apply -f -
|
||||
```
|
||||
3. Pod mounts/env vars will be updated automatically within a few minutes
|
||||
4. Old tokens will become invalid (you may need to log users out)
|
||||
|
||||
## Production Checklist
|
||||
|
||||
- [ ] ETCD encryption enabled (see ENCRYPTION.md)
|
||||
- [ ] JWT secret key changed from default
|
||||
- [ ] Both user-rpc and envoy-gateway Deployments use correct serviceAccountName
|
||||
- [ ] Both Deployments load the secret via environment variable or volume mount
|
||||
- [ ] Regular secret rotation policy implemented
|
||||
- [ ] Secret backup stored in secure location (encrypted)
|
||||
- [ ] RBAC audit logging enabled to track secret access
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Cannot read jwt-secret
|
||||
Check if the Pod is using the correct ServiceAccount:
|
||||
```bash
|
||||
kubectl get deployment user-rpc -o yaml | grep serviceAccountName
|
||||
```
|
||||
|
||||
### Secret not being mounted
|
||||
Verify the Secret exists:
|
||||
```bash
|
||||
kubectl get secret jwt-secret -n juwan
|
||||
```
|
||||
|
||||
Check Pod logs for mounting errors:
|
||||
```bash
|
||||
kubectl logs -l app=user-rpc -n juwan
|
||||
```
|
||||
|
||||
### Permission denied error
|
||||
Verify RBAC binding:
|
||||
```bash
|
||||
kubectl get rolebinding -n juwan
|
||||
kubectl get role jwt-secret-reader -n juwan
|
||||
```
|
||||
@@ -0,0 +1,366 @@
|
||||
# JWT 认证系统 + ETCD 加密 - 完整部署总结
|
||||
|
||||
## 项目概览
|
||||
|
||||
这个项目为微服务提供了一个完整的 JWT 认证系统,包括:
|
||||
|
||||
1. **JWT 令牌管理** - 令牌生成、验证、刷新和撤销
|
||||
2. **Redis Cluster 存储** - 令牌交换缓存(30天TTL)和用户会话管理
|
||||
3. **RBAC 权限控制** - 限制只有 user-rpc 和 envoy-gateway 服务可以访问 JWT 秘钥
|
||||
4. **ETCD 加密** - 在 Kubernetes 集群中对所有 Secrets 进行加密
|
||||
5. **网关保护** - Envoy 网关处理 CSRF 防护和请求路由
|
||||
|
||||
## 创建的文件清单
|
||||
|
||||
### 部署配置文件
|
||||
|
||||
#### `/deploy/k8s/secrets/`
|
||||
|
||||
| 文件 | 说明 | 关键内容 |
|
||||
|-----|------|--------|
|
||||
| `jwt-secret.yaml` | Secret + RBAC 配置 | 包含JWT秘钥、ServiceAccounts、Role、RoleBindings |
|
||||
| `README.md` | 快速参考指南 | Secret 创建和 Deployment 更新说明 |
|
||||
| `DEPLOYMENT.md` | 详细部署步骤 | 12个部署步骤,包括ETCD加密配置 |
|
||||
| `ENCRYPTION.md` | ETCD加密完整指南 | 密钥生成、配置修改、验证流程 |
|
||||
| `VERIFICATION.md` | 验证清单 | 12个部分的完整验证脚本和检查项 |
|
||||
|
||||
### 应用代码更新
|
||||
|
||||
| 文件路径 | 修改内容 |
|
||||
|---------|--------|
|
||||
| `/app/users/rpc/internal/utils/jwt.go` | JwtManager 实现(已存在) |
|
||||
| `/app/users/rpc/internal/config/config.go` | JwtConfig 结构体(已存在) |
|
||||
| `/app/users/rpc/internal/svc/serviceContext.go` | Redis Cluster + JwtManager 依赖注入(已存在) |
|
||||
| `/app/users/rpc/etc/pb.yaml` | JWT 和 Redis Cluster 配置(已存在) |
|
||||
| `/deploy/k8s/service/user/user-rpc.yaml` | ✅ **已更新** - 添加 serviceAccountName + JWT_SECRET_KEY 环境变量 |
|
||||
| `/deploy/k8s/envoy/envoy.yaml` | ✅ **已更新** - 添加 serviceAccountName: envoy-gateway |
|
||||
| `/app/users/api/INTEGRATION.md` | 🆕 **新建** - JWT 集成指南(interceptors, handlers, middleware) |
|
||||
|
||||
## 部署状态示意图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Kubernetes Cluster │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ juwan Namespace │ │
|
||||
│ ├─────────────────────────────────────────────────────────────┤ │
|
||||
│ │ │ │
|
||||
│ │ ┌────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ Secret: jwt-secret │ │ │
|
||||
│ │ │ ├─ secret-key: <encrypted in ETCD> │ │ │
|
||||
│ │ │ └─ Protected by RBAC Role + RoleBindings │ │ │
|
||||
│ │ └────────────────────────────────────────────────────┘ │ │
|
||||
│ │ △ │ │
|
||||
│ │ │ (mounted via serviceAccountName) │ │
|
||||
│ │ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌──────────────────────┐ │ │
|
||||
│ │ │ user-rpc │ │ envoy-gateway │ │ │
|
||||
│ │ │ Deployment │ │ Deployment │ │ │
|
||||
│ │ ├─────────────────┤ ├──────────────────────┤ │ │
|
||||
│ │ │ SA: user-rpc │ │ SA: envoy-gateway │ │ │
|
||||
│ │ │ Replicas: 3 │ │ Replicas: 1 │ │ │
|
||||
│ │ │ Port: 9001(RPC) │ │ Port: 8080(HTTP) │ │ │
|
||||
│ │ │ 4001(Met) │ │ │ │ │
|
||||
│ │ └─────────────────┘ └──────────────────────┘ │ │
|
||||
│ │ │ JWT Manager │ CSRF Filter │ │
|
||||
│ │ │ (HS256 signing) │ (X-CSRF-Token) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ ┌──────▼──────────────────────────▼─────┐ │ │
|
||||
│ │ │ user-redis (RedisCluster) │ │ │
|
||||
│ │ │ 3-node cluster │ │ │
|
||||
│ │ │ - Token exchange cache (30d TTL) │ │ │
|
||||
│ │ │ - User session management │ │ │
|
||||
│ │ └────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Control Plane (kube-apiserver) │ │
|
||||
│ │ • ETCD 加密: AES-CBC 32-byte key │ │
|
||||
│ │ • Secrets 自动加密存储 │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 核心配置参数
|
||||
|
||||
### JWT 配置
|
||||
|
||||
```yaml
|
||||
JWT:
|
||||
SecretKey: "your-secret-jwt-key-change-this-in-production"
|
||||
Issuer: "your-app-name"
|
||||
# Token 有效期: 7 天
|
||||
# Redis TTL: 30 天(支持令牌刷新)
|
||||
```
|
||||
|
||||
### Redis Cluster
|
||||
|
||||
```yaml
|
||||
RedisCluster:
|
||||
ClusterSize: 3 🔴 主服务器 + 2 🔵 从服务器
|
||||
Address: "user-redis.juwan:6379"
|
||||
HighAvailability: 自动故障转移
|
||||
```
|
||||
|
||||
### RBAC 权限
|
||||
|
||||
```yaml
|
||||
Role: jwt-secret-reader
|
||||
Resources: [secrets]
|
||||
ResourceNames: [jwt-secret]
|
||||
Verbs: [get] # 只读,无列表/创建/删除
|
||||
Subjects:
|
||||
- user-rpc (ServiceAccount)
|
||||
- envoy-gateway (ServiceAccount)
|
||||
```
|
||||
|
||||
## 部署流程
|
||||
|
||||
### 快速部署(5分钟)
|
||||
|
||||
```bash
|
||||
# 第1步:创建 Secret 和 RBAC
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
|
||||
|
||||
# 第2步:更新 Deployments
|
||||
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
|
||||
kubectl apply -f deploy/k8s/envoy/envoy.yaml
|
||||
|
||||
# 第3步:验证
|
||||
./verify-jwt-setup.sh
|
||||
```
|
||||
|
||||
### ETCD 加密部署(需要集群管理员权限)
|
||||
|
||||
```bash
|
||||
# 在 Control Plane 节点执行
|
||||
1. 生成 32 字节密钥
|
||||
2. 创建 /etc/kubernetes/encryption-config.yaml
|
||||
3. 修改 /etc/kubernetes/manifests/kube-apiserver.yaml
|
||||
4. 重启 kube-apiserver
|
||||
5. 验证加密已启用
|
||||
```
|
||||
|
||||
详见:`deploy/k8s/secrets/ENCRYPTION.md`
|
||||
|
||||
## 关键特性
|
||||
|
||||
### 1. JWT 令牌生命周期
|
||||
|
||||
```
|
||||
登录 → 生成 JWT
|
||||
├─ 有效期: 7 天(exp claim)
|
||||
└─ 存储到 Redis: 30 天(TTL)
|
||||
|
||||
Token 过期(7天+)
|
||||
├─ JWT 签名验证失败
|
||||
└─ 检查 Redis 是否仍有数据
|
||||
├─ 有 → 生成新 Token(刷新)✅
|
||||
└─ 无 → 令牌已过期,需要重新登录 ❌
|
||||
```
|
||||
|
||||
### 2. Redis 双键结构
|
||||
|
||||
```
|
||||
jwt:user:{userId} → {token}
|
||||
用途: 快速查询用户当前令牌
|
||||
TTL: 30 天
|
||||
|
||||
jwt:token:{token} → {payload}
|
||||
用途: 令牌验证和刷新
|
||||
TTL: 30 天
|
||||
```
|
||||
|
||||
### 3. CSRF 防护(Envoy 网关)
|
||||
|
||||
```
|
||||
安全方法 (GET/HEAD/OPTIONS)
|
||||
→ 自动生成 csrf_token
|
||||
→ 返回 Set-Cookie: csrf_token=...
|
||||
|
||||
不安全方法 (POST/PUT/DELETE/PATCH)
|
||||
→ 检查 Cookie csrf_token
|
||||
→ 检查 X-CSRF-Token 头
|
||||
→ 两者必须相等,否则 403
|
||||
```
|
||||
|
||||
### 4. 权限隔离
|
||||
|
||||
```
|
||||
Only user-rpc + envoy-gateway 可以:
|
||||
✅ 读 jwt-secret
|
||||
|
||||
Other services 无法:
|
||||
❌ 列出 secrets
|
||||
❌ 获取 jwt-secret(RBAC 拒绝)
|
||||
❌ 删除 secrets
|
||||
```
|
||||
|
||||
### 5. ETCD 加密
|
||||
|
||||
```
|
||||
未加密:
|
||||
etcdctl get /registry/seca/...
|
||||
→ secret-key: "plaintext-value"
|
||||
|
||||
已加密 (AES-CBC):
|
||||
etcdctl get /registry/secrets/...
|
||||
→ 二进制数据,无法读取
|
||||
```
|
||||
|
||||
## 集成点
|
||||
|
||||
### 1. RPC Handler(需要实现)
|
||||
|
||||
```go
|
||||
// 在 gRPC server 中注册拦截器
|
||||
s := grpc.NewServer(
|
||||
grpc.UnaryInterceptor(interceptor.JwtUnaryInterceptor(ctx)),
|
||||
)
|
||||
|
||||
// 拦截器会:
|
||||
// 1. 提取 Authorization 头中的 Token
|
||||
// 2. 调用 JwtManager.Valid()
|
||||
// 3. 如果过期,尝试 JwtManager.Renew()
|
||||
// 4. 将声明注入 context
|
||||
```
|
||||
|
||||
参考:`app/users/api/INTEGRATION.md` 第1-2章
|
||||
|
||||
### 2. REST Endpoint(需要实现)
|
||||
|
||||
```go
|
||||
// 创建 JWT Middleware
|
||||
protected := middleware.JwtMiddleware(svcCtx)
|
||||
|
||||
// 应用到受保护的路由
|
||||
router.HandleFunc("GET /api/v1/users/me",
|
||||
protected(user.GetUserInfoHandler(svcCtx)))
|
||||
|
||||
// Middleware 会验证 Authorization: Bearer {token}
|
||||
```
|
||||
|
||||
参考:`app/users/api/INTEGRATION.md` 第3-4章
|
||||
|
||||
### 3. 登录/登出流程(需要实现)
|
||||
|
||||
```
|
||||
登录:
|
||||
1. 验证用户凭证(DB 查询)
|
||||
2. JwtManager.New() → 生成令牌
|
||||
3. 返回令牌给客户端
|
||||
|
||||
登出:
|
||||
1. 从上下文提取 userId
|
||||
2. JwtManager.Revoke() → 删除 Redis 中的令牌
|
||||
3. 用户需要重新登录获取新令牌
|
||||
```
|
||||
|
||||
参考:`app/users/api/INTEGRATION.md` 第5-6章
|
||||
|
||||
## 文档导航
|
||||
|
||||
| 场景 | 推荐阅读 |
|
||||
|-----|--------|
|
||||
| 第一次部署 | `README.md` → `DEPLOYMENT.md` |
|
||||
| 部署遇到问题 | `VERIFICATION.md` + `DEPLOYMENT.md` 故障排查部分 |
|
||||
| 代码集成 | `app/users/api/INTEGRATION.md` |
|
||||
| ETCD 加密配置 | `ENCRYPTION.md` |
|
||||
| ETCD 加密验证 | `VERIFICATION.md` 第9部分 |
|
||||
| 安全最佳实践 | `DEPLOYMENT.md` 安全最佳实践部分 |
|
||||
| 灾难恢复 | `DEPLOYMENT.md` 灾难恢复部分 |
|
||||
|
||||
## 生产就绪检查清单
|
||||
|
||||
- [ ] 所有 Pods 都在 Running 状态
|
||||
- [ ] JWT Secret 已创建并正确挂载
|
||||
- [ ] RBAC 权限验证通过
|
||||
- [ ] Redis Cluster 健康(3/3 节点)
|
||||
- [ ] ETCD 加密已启用(如需要)
|
||||
- [ ] 监控和日志聚合正常工作
|
||||
- [ ] 密钥轮换计划已制定
|
||||
- [ ] 备份和恢复流程已文档化
|
||||
- [ ] 安全审计日志已启用
|
||||
- [ ] 端到端测试已通过
|
||||
|
||||
## 下一步行动
|
||||
|
||||
### 短期(本周)
|
||||
|
||||
1. **部署 Secret 和 RBAC**
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
|
||||
```
|
||||
|
||||
2. **更新 Deployments**
|
||||
```bash
|
||||
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
|
||||
kubectl apply -f deploy/k8s/envoy/envoy.yaml
|
||||
```
|
||||
|
||||
3. **验证部署**
|
||||
```bash
|
||||
./verify-jwt-setup.sh
|
||||
```
|
||||
|
||||
### 中期(本月)
|
||||
|
||||
1. **实现 JWT 集成**
|
||||
- 创建 gRPC 拦截器
|
||||
- 实现登录/登出端点
|
||||
- 添加 JWT 中间件到 REST API
|
||||
|
||||
2. **端到端测试**
|
||||
- 测试令牌生成和验证
|
||||
- 测试令牌刷新
|
||||
- 测试 CSRF 防护
|
||||
|
||||
### 长期(本季度)
|
||||
|
||||
1. **启用 ETCD 加密**
|
||||
- 按照 `ENCRYPTION.md` 配置
|
||||
- 验证所有 Secrets 都已加密
|
||||
|
||||
2. **生产部署**
|
||||
- 启用审计日志
|
||||
- 配置监控和告警
|
||||
- 制定密钥轮换政策
|
||||
|
||||
## 支持
|
||||
|
||||
如遇到问题:
|
||||
|
||||
1. **检查日志**
|
||||
```bash
|
||||
kubectl logs -n juwan -l app=user-rpc -f
|
||||
kubectl logs -n juwan -l app=envoy-gateway -f
|
||||
```
|
||||
|
||||
2. **运行验证脚本**
|
||||
```bash
|
||||
chmod +x deploy/k8s/secrets/verify-jwt-setup.sh
|
||||
./deploy/k8s/secrets/verify-jwt-setup.sh
|
||||
```
|
||||
|
||||
3. **查看详细文档**
|
||||
- 部署问题 → `DEPLOYMENT.md`
|
||||
- 代码集成 → `INTEGRATION.md`
|
||||
- ETCD 加密 → `ENCRYPTION.md`
|
||||
- 诊断 → `VERIFICATION.md`
|
||||
|
||||
## 总结
|
||||
|
||||
这个系统为微服务提供了:
|
||||
|
||||
✅ **安全的身份验证** - JWT 令牌 + HS256 签名
|
||||
✅ **灵活的令牌管理** - 7天有效期,30天可刷新
|
||||
✅ **高可用性** - Redis Cluster 自动故障转移
|
||||
✅ **权限隔离** - RBAC 限制密钥访问
|
||||
✅ **数据加密** - ETCD 加密保护敏感信息
|
||||
✅ **请求保护** - Envoy CSRF 双令牌验证
|
||||
|
||||
现在可以部署并集成到应用中了!
|
||||
@@ -0,0 +1,507 @@
|
||||
# 完整部署验证清单
|
||||
|
||||
完成所有部署后使用此清单验证系统是否正确配置和运行。
|
||||
|
||||
## 第一部分:基础设施验证
|
||||
|
||||
### Secret 和 RBAC 创建
|
||||
|
||||
```bash
|
||||
# 检查 Secret 已创建
|
||||
kubectl get secret -n juwan | grep jwt-secret
|
||||
# 预期输出: jwt-secret Created
|
||||
|
||||
# 查看 Secret 详情(不显示敏感数据)
|
||||
kubectl describe secret jwt-secret -n juwan
|
||||
# 应该看到:
|
||||
# Name: jwt-secret
|
||||
# Namespace: juwan
|
||||
# Type: Opaque
|
||||
# Data
|
||||
# ====
|
||||
# secret-key: <encrypted>
|
||||
|
||||
# 验证 Secret 内容已正确加载
|
||||
kubectl get secret jwt-secret -n juwan -o jsonpath='{.data.secret-key}' | base64 -d | wc -c
|
||||
# 预期输出: 应该是 32 个字符(32 字节密钥的 Base64 解码)
|
||||
```
|
||||
|
||||
### ServiceAccount 验证
|
||||
|
||||
```bash
|
||||
# 检查 user-rpc ServiceAccount
|
||||
kubectl get sa user-rpc -n juwan
|
||||
kubectl describe sa user-rpc -n juwan
|
||||
# 应该显示正确的 Secrets 挂载
|
||||
|
||||
# 检查 envoy-gateway ServiceAccount
|
||||
kubectl get sa envoy-gateway -n juwan
|
||||
kubectl describe sa envoy-gateway -n juwan
|
||||
```
|
||||
|
||||
### RBAC 权限验证
|
||||
|
||||
```bash
|
||||
# 检查 Role 定义
|
||||
kubectl get role -n juwan -l app=jwt-secret-reader
|
||||
kubectl describe role jwt-secret-reader -n juwan
|
||||
# 应该显示:
|
||||
# PolicyRule:
|
||||
# Resources Non-Resource URLs Resource Names Verbs
|
||||
# --------- ----------------- -------------- -----
|
||||
# secrets [] [jwt-secret] [get]
|
||||
|
||||
# 检查 RoleBindings
|
||||
kubectl get rolebinding -n juwan | grep jwt-secret-reader
|
||||
# 应该显示两个绑定: jwt-secret-reader-user-rpc 和 jwt-secret-reader-envoy-gateway
|
||||
|
||||
# 验证每个 RoleBinding
|
||||
kubectl describe rolebinding jwt-secret-reader-user-rpc -n juwan
|
||||
kubectl describe rolebinding jwt-secret-reader-envoy-gateway -n juwan
|
||||
```
|
||||
|
||||
## 第二部分:权限测试
|
||||
|
||||
### 权限允许测试
|
||||
|
||||
```bash
|
||||
# 测试 user-rpc 可以读 jwt-secret
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:user-rpc \
|
||||
--resource-name=jwt-secret \
|
||||
-n juwan
|
||||
# 预期输出: yes
|
||||
|
||||
# 测试 envoy-gateway 可以读 jwt-secret
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:envoy-gateway \
|
||||
--resource-name=jwt-secret \
|
||||
-n juwan
|
||||
# 预期输出: yes
|
||||
|
||||
# 测试 user-rpc 无法读其他 Secrets
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:user-rpc \
|
||||
-n juwan
|
||||
# 预期输出: no
|
||||
|
||||
# 测试其他 ServiceAccount 无法读 jwt-secret
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:default \
|
||||
--resource-name=jwt-secret \
|
||||
-n juwan
|
||||
# 预期输出: no
|
||||
```
|
||||
|
||||
## 第三部分:Deployment 配置验证
|
||||
|
||||
### user-rpc Deployment 验证
|
||||
|
||||
```bash
|
||||
# 检查 ServiceAccountName 是否正确设置
|
||||
kubectl get deployment user-rpc -n juwan -o jsonpath='{.spec.template.spec.serviceAccountName}'
|
||||
# 预期输出: user-rpc
|
||||
|
||||
# 检查是否包含所有必需的环境变量
|
||||
kubectl get deployment user-rpc -n juwan -o yaml | grep -A 20 "env:"
|
||||
# 应该包括:
|
||||
# - name: JWT_SECRET_KEY
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: jwt-secret
|
||||
# key: secret-key
|
||||
|
||||
# 检查 Pod 是否正在运行
|
||||
kubectl get pods -n juwan -l app=user-rpc
|
||||
# 应该显示至少 3 个 Running 的 Pod
|
||||
|
||||
# 验证 Pod 已加载 Secret(在 Pod 中执行)
|
||||
kubectl exec -it $(kubectl get pod -n juwan -l app=user-rpc -o name | head -1) -n juwan -- env | grep -i jwt
|
||||
# 应该输出环境变量,例如:
|
||||
# JWT_SECRET_KEY=your-secret-jwt-key-change-this-in-production
|
||||
```
|
||||
|
||||
### Envoy Gateway Deployment 验证
|
||||
|
||||
```bash
|
||||
# 检查 ServiceAccountName 是否正确设置
|
||||
kubectl get deployment envoy-gateway -n juwan -o jsonpath='{.spec.template.spec.serviceAccountName}'
|
||||
# 预期输出: envoy-gateway
|
||||
|
||||
# 检查 Pod 是否正在运行
|
||||
kubectl get pods -n juwan -l app=envoy-gateway
|
||||
# 应该显示 Running 的 Pod
|
||||
|
||||
# 检查 Envoy 日志
|
||||
kubectl logs -n juwan -l app=envoy-gateway
|
||||
# 应该看到启动日志,没有权限相关错误
|
||||
```
|
||||
|
||||
## 第四部分:Redis 连接验证
|
||||
|
||||
### Redis Cluster 验证
|
||||
|
||||
```bash
|
||||
# 检查 RedisCluster CRD 状态
|
||||
kubectl get rediscluster -n juwan
|
||||
# 应该显示 user-redis,Status 应该是 Healthy
|
||||
|
||||
# 详细查看 RedisCluster 状态
|
||||
kubectl describe rediscluster user-redis -n juwan
|
||||
# 应该显示:
|
||||
# Status:
|
||||
# Cluster Status: Healthy
|
||||
# Nodes Ready: 3/3
|
||||
# Master: 1
|
||||
# Replicas: 2
|
||||
|
||||
# 检查 Redis Pods
|
||||
kubectl get pods -n juwan | grep redis
|
||||
# 应该显示 3 个 Redis Pod,都在 Running 状态
|
||||
|
||||
# 测试 Redis 连接
|
||||
kubectl run redis-cli --image=redis:latest --rm -it --restart=Never -- \
|
||||
redis-cli -h user-redis.juwan -c CLUSTER INFO
|
||||
# 应该看到集群信息,cluster_state:ok 表示集群健康
|
||||
```
|
||||
|
||||
## 第五部分:应用启动日志检查
|
||||
|
||||
### user-rpc 启动日志
|
||||
|
||||
```bash
|
||||
# 查看 user-rpc Pods 的启动日志
|
||||
kubectl logs -n juwan -l app=user-rpc --all-containers=true
|
||||
|
||||
# 应该包含类似以下消息:
|
||||
# - "Starting gRPC server on 0.0.0.0:9001"
|
||||
# - "Redis Cluster connected successfully" 或 JWT Manager 初始化成功
|
||||
# - "Listening on metrics port 4001"
|
||||
|
||||
# 如果有错误,查看详细日志
|
||||
kubectl logs -n juwan -l app=user-rpc -f --all-containers=true
|
||||
```
|
||||
|
||||
### Envoy 启动日志
|
||||
|
||||
```bash
|
||||
# 查看 Envoy 启动日志
|
||||
kubectl logs -n juwan -l app=envoy-gateway
|
||||
|
||||
# 应该包含:
|
||||
# - "[info] Configuration: /etc/envoy/envoy.yaml"
|
||||
# - "[info] listener listening on 0.0.0.0:8080"
|
||||
# - 没有权限相关错误
|
||||
```
|
||||
|
||||
## 第六部分:网络和服务发现验证
|
||||
|
||||
### Service 验证
|
||||
|
||||
```bash
|
||||
# 检查 user-rpc-svc
|
||||
kubectl get svc user-rpc-svc -n juwan
|
||||
# 应该显示 ClusterIP 和两个端口 (9001/rpc 和 4001/metrics)
|
||||
|
||||
# 检查 Envoy Gateway Service
|
||||
kubectl get svc envoy-gateway -n juwan
|
||||
# 应该显示 ClusterIP 和端口 80
|
||||
|
||||
# 检查 Redis Service
|
||||
kubectl get svc -n juwan | grep redis
|
||||
# 应该显示 user-redis(ClusterIP)服务
|
||||
```
|
||||
|
||||
### DNS 解析验证
|
||||
|
||||
```bash
|
||||
# 测试服务名称解析
|
||||
kubectl run -it --rm debug --image=busybox --restart=Never -- \
|
||||
nslookup user-rpc-svc.juwan.svc.cluster.local
|
||||
# 应该返回 ClusterIP 地址
|
||||
|
||||
kubectl run -it --rm debug --image=busybox --restart=Never -- \
|
||||
nslookup user-redis.juwan.svc.cluster.local
|
||||
# 应该返回 ClusterIP 地址
|
||||
```
|
||||
|
||||
## 第七部分:监控和指标验证
|
||||
|
||||
### Prometheus 指标收集
|
||||
|
||||
```bash
|
||||
# 检查 Prometheus 是否在收集指标
|
||||
kubectl port-forward -n monitoring svc/prometheus 9090:9090 &
|
||||
|
||||
# 打开浏览器访问 http://localhost:9090
|
||||
# 查看 Status > Targets
|
||||
# 应该看到 user-rpc-svc:4001 目标显示为 UP
|
||||
|
||||
# 查询一个指标
|
||||
curl 'http://localhost:9090/api/v1/query?query=up{job="kubernetes-pods"}'
|
||||
# 应该返回 user-rpc 的指标数据
|
||||
|
||||
# 关闭端口转发
|
||||
kill %1
|
||||
```
|
||||
|
||||
### 测试源代码级指标端点
|
||||
|
||||
```bash
|
||||
# 从 user-rpc Pod 直接访问指标端点
|
||||
kubectl port-forward -n juwan svc/user-rpc-svc 4001:4001 &
|
||||
|
||||
# 测试指标端点
|
||||
curl http://localhost:4001/metrics
|
||||
|
||||
# 应该看到 Prometheus 格式的指标,例如:
|
||||
# # HELP go_goroutines Number of goroutines that currently exist.
|
||||
# # TYPE go_goroutines gauge
|
||||
# go_goroutines 25
|
||||
|
||||
# 关闭端口转发
|
||||
kill %1
|
||||
```
|
||||
|
||||
## 第八部分:日志聚合验证(Loki)
|
||||
|
||||
```bash
|
||||
# 检查 Loki 是否正确接收日志
|
||||
kubectl port-forward -n monitoring svc/loki 3100:3100 &
|
||||
|
||||
# 查询日志
|
||||
curl 'http://localhost:3100/loki/api/v1/query_range?query={job="kubernetes-pods"}&start=0&end=9999999999'
|
||||
|
||||
# 应该返回最近的日志条目
|
||||
|
||||
# 检查特定应用的日志
|
||||
curl 'http://localhost:3100/loki/api/v1/query_range?query={app="user-rpc"}&start=0&end=9999999999'
|
||||
|
||||
kill %1
|
||||
```
|
||||
|
||||
## 第九部分:ETCD 加密验证
|
||||
|
||||
如果已启用 ETCD 加密,执行以下验证:
|
||||
|
||||
```bash
|
||||
# 从 control plane 节点
|
||||
ssh <control-plane-node>
|
||||
|
||||
# 检查 ETCD 配置
|
||||
sudo cat /etc/kubernetes/encryption-config.yaml | head -20
|
||||
|
||||
# 验证 kube-apiserver 正在使用加密配置
|
||||
sudo ps aux | grep kube-apiserver | grep encryption-provider
|
||||
|
||||
# 创建新 Secret 进行测试
|
||||
kubectl create secret generic test-encryption -n juwan --from-literal=key=value
|
||||
|
||||
# 检查 ETCD 中的数据是否加密
|
||||
# 注意:如果加密正确,数据应该不可读
|
||||
sudo ETCDCTL_API=3 etcdctl \
|
||||
--cert=/etc/kubernetes/pki/etcd/server.crt \
|
||||
--key=/etc/kubernetes/pki/etcd/server.key \
|
||||
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
|
||||
--endpoints=127.0.0.1:2379 \
|
||||
get /registry/secrets/juwan/test-encryption
|
||||
|
||||
# 输出应该是二进制数据,不可读(表示已加密)
|
||||
# 或者使用十六进制 dump
|
||||
sudo ETCDCTL_API=3 etcdctl \
|
||||
--cert=/etc/kubernetes/pki/etcd/server.crt \
|
||||
--key=/etc/kubernetes/pki/etcd/server.key \
|
||||
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
|
||||
--endpoints=127.0.0.1:2379 \
|
||||
get /registry/secrets/juwan/test-encryption | od -A x -t x1z -v
|
||||
```
|
||||
|
||||
## 第十部分:功能测试
|
||||
|
||||
### JWT 令牌生成和验证测试
|
||||
|
||||
如果已实现 JWT handlers,测试完整流程:
|
||||
|
||||
```bash
|
||||
# 1. 前向 user-api 服务
|
||||
kubectl port-forward -n juwan svc/user-api-svc 8888:8888 &
|
||||
|
||||
# 2. 调用登录端点获取令牌
|
||||
TOKEN=$(curl -X POST http://localhost:8888/api/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"user@example.com","password":"password"}' \
|
||||
| jq -r '.token')
|
||||
|
||||
echo "Token: $TOKEN"
|
||||
|
||||
# 3. 使用令牌访问受保护的端点
|
||||
curl -H "Authorization: Bearer $TOKEN" http://localhost:8888/api/v1/users/me
|
||||
|
||||
# 4. 测试令牌刷新
|
||||
curl -X POST http://localhost:8888/api/v1/auth/refresh \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"token\":\"$TOKEN\"}"
|
||||
|
||||
# 5. 测试无效令牌
|
||||
curl -H "Authorization: Bearer invalid-token" http://localhost:8888/api/v1/users/me
|
||||
# 应该返回 401 Unauthorized
|
||||
|
||||
kill %1
|
||||
```
|
||||
|
||||
### CSRF 保护测试
|
||||
|
||||
```bash
|
||||
# 1. 前向 Envoy Gateway
|
||||
kubectl port-forward -n juwan svc/envoy-gateway 8080:80 &
|
||||
|
||||
# 2. 获取 CSRF 令牌(安全方法)
|
||||
curl -i http://localhost:8080/
|
||||
|
||||
# 查看响应头中的 Set-Cookie,应该包含 csrf_token
|
||||
|
||||
# 3. 提取 CSRF 令牌
|
||||
CSRF_TOKEN=$(curl -i http://localhost:8080/ 2>/dev/null | grep -i csrf_token | sed 's/.*csrf_token=//;s/;.*//')
|
||||
|
||||
# 4. 使用 CSRF 令牌进行 POST 请求
|
||||
curl -X POST http://localhost:8080/api/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: csrf_token=$CSRF_TOKEN" \
|
||||
-H "X-CSRF-Token: $CSRF_TOKEN" \
|
||||
-d '{"email":"user@example.com","password":"password"}'
|
||||
|
||||
# 5. 测试无效 CSRF 令牌(应该返回 403)
|
||||
curl -X POST http://localhost:8080/api/v1/auth/login \
|
||||
-H "Cookie: csrf_token=valid_token" \
|
||||
-H "X-CSRF-Token: invalid_token" \
|
||||
-d '{"email":"user@example.com","password":"password"}'
|
||||
# 应该返回 403 Forbidden
|
||||
|
||||
kill %1
|
||||
```
|
||||
|
||||
## 第十一部分:故障排查
|
||||
|
||||
如果任何验证失败,运行以下诊断:
|
||||
|
||||
### Pod 无法启动
|
||||
|
||||
```bash
|
||||
# 显示 Pod 事件
|
||||
kubectl describe pod <pod-name> -n juwan
|
||||
|
||||
# 查看完整日志(包括初始化容器)
|
||||
kubectl logs <pod-name> -n juwan --all-containers=true --previous
|
||||
|
||||
# 检查 Pod 资源限制是否导致 OOMKilled
|
||||
kubectl get event -n juwan --sort-by='.lastTimestamp'
|
||||
```
|
||||
|
||||
### 权限被拒绝错误
|
||||
|
||||
```bash
|
||||
# 验证 ServiceAccount 是否正确
|
||||
kubectl get pod <pod-name> -n juwan -o jsonpath='{.spec.serviceAccountName}'
|
||||
|
||||
# 检查 RBAC 绑定
|
||||
kubectl get rolebinding -n juwan -o wide
|
||||
|
||||
# 手动测试权限
|
||||
kubectl auth can-i get secrets \
|
||||
--as=system:serviceaccount:juwan:user-rpc \
|
||||
-n juwan
|
||||
```
|
||||
|
||||
### Redis 连接错误
|
||||
|
||||
```bash
|
||||
# 检查 Redis Pods 状态
|
||||
kubectl get pods -n juwan -l redis=user-redis
|
||||
|
||||
# 查看 Redis 日志
|
||||
kubectl logs -n juwan -l redis=user-redis
|
||||
|
||||
# 测试 Redis 连接(从 user-rpc Pod)
|
||||
kubectl exec -it <user-rpc-pod> -n juwan -- \
|
||||
redis-cli -h user-redis.juwan:6379 PING
|
||||
# 应该返回 PONG
|
||||
```
|
||||
|
||||
### ETCD 加密问题
|
||||
|
||||
```bash
|
||||
# 验证加密配置
|
||||
kubectl get secret jwt-secret -n juwan -o json | jq '.data'
|
||||
|
||||
# 如果 ETCD 加密启用,直接读取 ETCD 的数据应该是二进制的
|
||||
# 如果看到明文,说明加密未启用或配置不正确
|
||||
```
|
||||
|
||||
## 第十二部分:清理测试资源
|
||||
|
||||
```bash
|
||||
# 删除测试 Secrets
|
||||
kubectl delete secret test-encryption test-secret -n juwan --ignore-not-found
|
||||
|
||||
# 清理前转发的端口
|
||||
lsof -i :9090 :3100 :8888 :8080 | grep LISTEN | awk '{print $2}' | xargs kill -9
|
||||
```
|
||||
|
||||
## 快速检查脚本
|
||||
|
||||
创建 `verify-jwt-setup.sh` 进行自动化验证:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
namespace="juwan"
|
||||
echo "=== JWT Setup Verification ==="
|
||||
|
||||
# 检查 Secret
|
||||
echo -n "✓ JWT Secret存在: "
|
||||
kubectl get secret jwt-secret -n $namespace &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
# 检查 ServiceAccounts
|
||||
echo -n "✓ user-rpc ServiceAccount: "
|
||||
kubectl get sa user-rpc -n $namespace &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
echo -n "✓ envoy-gateway ServiceAccount: "
|
||||
kubectl get sa envoy-gateway -n $namespace &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
# 检查 RBAC
|
||||
echo -n "✓ JWT RBAC Role: "
|
||||
kubectl get role jwt-secret-reader -n $namespace &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
# 检查 Deployments
|
||||
echo -n "✓ user-rpc Deployment: "
|
||||
kubectl get deployment user-rpc -n $namespace &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
echo -n "✓ envoy-gateway Deployment: "
|
||||
kubectl get deployment envoy-gateway -n $namespace &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
# 检查 Pods
|
||||
echo -n "✓ user-rpc Pods运行中: "
|
||||
[ $(kubectl get pods -n $namespace -l app=user-rpc --field-selector=status.phase=Running --no-headers | wc -l) -ge 1 ] && echo "✓" || echo "✗"
|
||||
|
||||
echo -n "✓ envoy-gateway 运行中: "
|
||||
kubectl get pods -n $namespace -l app=envoy-gateway --field-selector=status.phase=Running &>/dev/null && echo "✓" || echo "✗"
|
||||
|
||||
echo "=== Verification Complete ==="
|
||||
```
|
||||
|
||||
运行脚本:
|
||||
|
||||
```bash
|
||||
chmod +x verify-jwt-setup.sh
|
||||
./verify-jwt-setup.sh
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
所有检查项都通过后,JWT + ETCD 加密系统已准备就绪。下一步可以:
|
||||
|
||||
1. 集成 JWT 验证到 RPC handlers
|
||||
2. 实现令牌刷新端点
|
||||
3. 部署应用代码时启用 JWT 认证
|
||||
4. 监控令牌生成和验证指标
|
||||
5. 定期轮换加密密钥和 JWT 秘钥
|
||||
@@ -0,0 +1,60 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: jwt-secret
|
||||
namespace: juwan
|
||||
type: Opaque
|
||||
data:
|
||||
# base64 encoded: your-secret-jwt-key-change-this-in-production
|
||||
secret-key: eW91ci1zZWNyZXQtand0LWtleS1jaGFuZ2UtdGhpcy1pbi1wcm9kdWN0aW9u
|
||||
---
|
||||
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:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: ["jwt-secret"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user