如何在Kubernetes中仅对API A、B实现认证与授权?
在Kubernetes中为指定API(A、B)配置认证与授权的实现方案
针对你需要仅为API A、B配置认证授权,API C无需限制的需求,以下是几种基于Kubernetes的实用实现方案:
方案一:基于Ingress-Nginx的认证授权(适合外部访问场景)
如果你的API主要通过Ingress暴露给外部访问,这是最直接的方案:
- 部署Ingress-Nginx Controller:确保集群中已安装Ingress-Nginx控制器(可通过官方Helm Chart部署)。
- 创建认证凭证(以HTTP Basic Auth为例):
- 生成密码文件:
htpasswd -c auth your-username,输入密码完成创建。 - 将密码文件存入Kubernetes Secret:
kubectl create secret generic basic-auth --from-file=auth。
- 生成密码文件:
- 为API A、B配置带认证的Ingress:
为API A和B创建Ingress资源,通过Nginx注解启用认证:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: protected-api-ingress annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth nginx.ingress.kubernetes.io/auth-realm: "请输入认证凭证" spec: rules: - host: your-domain.com http: paths: - path: /api/a pathType: Prefix backend: service: name: api-a-service port: { number: 80 } - path: /api/b pathType: Prefix backend: service: name: api-b-service port: { number: 80 } - 为API C配置无认证的Ingress:
直接创建普通Ingress,不添加任何认证注解:
进阶:如果需要JWT等更复杂的认证,可使用apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: public-api-c-ingress spec: rules: - host: your-domain.com http: paths: - path: /api/c pathType: Prefix backend: service: name: api-c-service port: { number: 80 }nginx.ingress.kubernetes.io/auth-url注解,指向自定义的JWT验证服务,由该服务完成认证逻辑后,Ingress再转发请求到API A/B。
方案二:基于Istio服务网格的细粒度控制(适合内外混合访问场景)
如果你的服务需要内部调用控制+外部访问认证,Istio可以提供更细粒度的流量管控:
- 部署Istio:安装Istio控制平面,并为所有API Pod注入Sidecar代理。
- 配置认证规则(JWT为例):
创建RequestAuthentication资源,仅对API A、B生效,验证请求中的JWT Token:apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: api-a-b-jwt-auth namespace: your-namespace spec: selector: matchLabels: app: api-a # 可复制该资源修改标签为api-b,分别配置 jwtRules: - issuer: "your-token-issuer" jwksUri: "http://jwks-service.your-namespace.svc.cluster.local/jwks.json" - 配置授权规则:
为API A、B创建AuthorizationPolicy,拒绝未认证的请求;为API C创建允许所有请求的规则:# API A的授权规则:拒绝未认证请求 apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: api-a-authz namespace: your-namespace spec: selector: matchLabels: app: api-a action: DENY rules: - from: - source: notRequestPrincipals: ["*"]# API C的授权规则:允许所有请求 apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: api-c-allow-all namespace: your-namespace spec: selector: matchLabels: app: api-c action: ALLOW rules: - {}
方案三:Sidecar代理注入(自定义认证逻辑场景)
如果需要高度自定义的认证授权逻辑,可以为API A、B的Pod注入认证Sidecar:
- 编写认证Sidecar:开发一个轻量代理服务,负责拦截进入API的请求,验证凭证(如JWT、API Key),验证通过后转发到主容器的API服务。
- 为API A、B配置带Sidecar的Pod:
在API A、B的Deployment中添加Sidecar容器,API C的Deployment保持无Sidecar:
所有访问API A的请求先经过apiVersion: apps/v1 kind: Deployment metadata: name: api-a-deployment spec: replicas: 3 selector: matchLabels: app: api-a template: metadata: labels: app: api-a spec: containers: - name: api-a-main image: your-api-a-image:latest ports: - containerPort: 8080 - name: auth-proxy image: your-auth-proxy-image:latest ports: - containerPort: 80 env: - name: UPSTREAM_URL value: "http://localhost:8080" - name: VALIDATION_ENDPOINT value: "http://auth-service.your-namespace.svc.cluster.local/validate"auth-proxy容器验证,通过后转发到主容器;API C直接处理外部请求。
方案四:Kubernetes原生ServiceAccount(仅内部服务调用场景)
如果仅需限制内部K8s服务对API A、B的访问,可使用Kubernetes的ServiceAccount+NetworkPolicy:
- 创建授权的ServiceAccount:
kubectl create serviceaccount authorized-api-client - 配置NetworkPolicy限制访问:
为API A、B创建NetworkPolicy,仅允许指定ServiceAccount的Pod访问;API C允许所有Pod访问:# API A的NetworkPolicy apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: api-a-access-control namespace: your-namespace spec: podSelector: matchLabels: app: api-a ingress: - from: - podSelector: matchLabels: serviceAccount: authorized-api-client - API内部验证Token:API A、B的服务需要解析请求中的ServiceAccount Token(通过
Authorization: Bearer <token>头),验证调用方的身份合法性。
内容的提问来源于stack exchange,提问作者Aissam Chia
相关产品推荐
相关产品推荐

