背景:
工作中发现k8s集群中命名空间B-test中的某服务的域名返回404,该请求链路为:
client ——> traefik(namespace:A-test) ——> ingress(namespace:B-test) ——> pod(namespace:B-test)
使用的traefik模板如下:
点击查看代码
---
# rbac配置: role
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-ingress-controller
namespace: A-test
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
---
# rbac配置: rolebinding
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-ingress-controller
namespace: A-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: test
---
# rbac配置: serviceaccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: A-test
---
# daemonset配置
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: A-test
labels:
k8s-app: traefik-ingress-lb
spec:
selector:
matchLabels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8080
hostPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --api
- --kubernetes
- --kubernetes.namespaces=A-test # 该配置为重点
- --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: A-test
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
现象:
无论如何修改ingress规则,通过域名访问均返回404,但通过后端服务的serviceName,clusterIP,PodIP均能正常返回页面
解决思路:
检查后发现该traefik ds配置使用的rbac为namespace级别(即role-rolebinding),若需访问跨namespace的后端pod需要新增对应rbac权限(在B-test命名空间中增加对应role和rolebinding),并在traefik参数--kubernetes.namespaces中添加后端pod所在的namespace
官方文档中关于该参数的描述如下:

翻译:对于命名空间限制,每个监视的命名空间都需要一个 RoleBinding 以及 Traefik 的 kubernetes.namespaces 参数的相应配置。
修改方式如下:
1. 添加应用所在的B-test命名空间下的traefik rbac权限配置,否则traefik将无权限获取到B-test命名空间下的ingress规则及service-endpoints对应关系
# 添加B-test命名空间下的rbac,并关联至A-test命名空间下的serviceaccount: traefik-ingress-controller
# cat rbac-traefik-B-test.yaml
---
# B-test下的role配置文件(权限集)
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-ingress-controller
namespace: B-test
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
---
# B-test下的rolebinding配置文件(sa与role的绑定关系)
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-ingress-controller
namespace: B-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: A-test # 该namespace为traefik的sa所在namespace,无需修改,即将A-test下的traefik sa与B-test下的role进行关联,使A-test中的traefik拥有查看B-test下的ing、ep、svc权限
# 生效rbac配置
kubectl create -f rbac-traefik-B-test.yaml
# 生效后可通过如下命令验证,可以查看到ingress规则即权限正常
kubectl get ing -n B-test --as=system:serviceaccount:A-test:traefik-ingress-controller
2. 修改traefik ds中的--kubernetes.namespaces参数
# 根据官方文档介绍,namespace级rbac配置的traefik需要在参数中根据所监视的namespace修改--kubernetes.namespaces参数
kubectl edit ds -n A-test traefik-ingress-controller
...omit...
args:
- --api
- --kubernetes
- --kubernetes.namespaces=A-test,B-test # 在原有基础上追加B-test命名空间
- --logLevel=INFO
...omit...
# 修改后保存退出即可
3. 验证发现通过A-test命名空间下的traefik访问B-test命名空间下的pod已恢复正常
最后:
1. 若同一套k8s物理集群内存在namespace隔离的多个项目环境,尽量使用namespace级rbac配置(role/rolebinding)并通过--kubernetes.namespaces参数对traefik进行namespace级的ingress路由规则限制,以免项目间ingress配置互相干扰。
2. 若同一套k8s物理集群内所有namespace均属于同一项目,则可以使用cluster级rbac配置(clusterrole/clusterrolebinding),且无需在traefik配置中指定--kubernetes.namespaces参数(即集群内所有namespace),官方给出的traefik模板即为cluster级rbac鉴权,可直接参考:
https://doc.traefik.io/traefik/v1.7/user-guide/kubernetes/
https://github.com/traefik/traefik/tree/v1.7.11/examples/k8s
posted on
浙公网安备 33010602011771号