在当下的云计算时代,我们经常会听到“租户”、“多租户”。“租户”是多租户架构技术中的概念,这种技术是用来处理多个组织共用同一个系统或者组件时的数据隔离性。在 Kubernetes 中的最简单的多租户是根据命名空间( Namespace)进行划分的,众多的命名空间将资源/工作负载进行了隔离。
![[single-ingress-controller.png]]
作为 Kubernetes 资源之一的 Ingress 也不例外,用户可以在不同的命名空间下创建Ingress
资源来控制进入集群的流量。即使Ingress
资源实现了多租户,但作为组件的Ingress Controller
依然是共用的,没有做到真正的隔离。
因此就有了多租户 Ingress Controller 的诉求:每个命名空间下都有独立的 Ingress Controller,命名空间之间做到组件的隔离,达到了互不影响目的。
原理
Flomesh 提出了 NamespacedIngress 的概念,通过控制器在指定的命名空间下部署 Ingress Controller。每个 Ingress Controller 只处理各自命名空间下 Ingress
资源标识的流量。
比如下面的 YAML 中定义了监控在端口 100
上的 Ingress Controller,同时还会为其创建 LoadBalancer
类型的 Service
,监听在 100
端口。
apiVersion: flomesh.io/v1alpha1
kind: NamespacedIngress
metadata:
name: namespaced-ingress-100
namespace: test-100
spec:
serviceType: LoadBalancer
ports:
- name: http
port: 100
protocol: TCP
复制代码
![[multi-tenant-ingress-controller.png]]
Demo
安装 Flomesh Ingress Controller
Flomesh 提供了标准的 Helm chart,可以通过 Helm CLI 进行安装。
helm repo add fsm https://flomesh-io.github.io/fsm
helm repo update
helm install fsm fsm/fsm --namespace flomesh --create-namespace --set fsm.ingress.namespaced=true
复制代码
确认所有 pod 都启动并正常运行。
kubectl get po -n flomesh
NAME READY STATUS RESTARTS AGE
fsm-manager-6857f96858-sjksm 1/1 Running 0 55s
fsm-repo-59bbbfdc5f-w7vg6 1/1 Running 0 55s
fsm-bootstrap-8576c5ff4f-7qr7k 1/1 Running 0 55s
fsm-cluster-connector-local-8f8fb87f6-h7z9j 1/1 Running 0 32s
复制代码
创建示例应用
# 创建命名空间
kubectl create ns httpbin
# 部署应用
kubectl apply -f https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/main/manifests/samples/httpbin/httpbin.yaml -n httpbin
复制代码
创建独立的 Ingress Controller
接来下就是为命名空间 httpbin
创建独立的 Ingress Controller。
kubectl apply -f - <<EOF
apiVersion: flomesh.io/v1alpha1
kind: NamespacedIngress
metadata:
name: namespaced-ingress-httpbin
namespace: httpbin
spec:
serviceType: LoadBalancer
http:
port:
name: http
port: 81
nodePort: 30081
resources:
limits:
cpu: 500m
memory: 200Mi
requests:
cpu: 100m
memory: 20Mi
EOF
复制代码
执行完上面的命令之后,在命名空间 httpbin
下会看到有 Ingress Controller 成功运行。
kubectl get po -n httpbin -l app=fsm-ingress-pipy
NAME READY STATUS RESTARTS AGE
fsm-ingress-pipy-httpbin-5594ffcfcc-zl5gl 1/1 Running 0 58s
复制代码
此时,该命名空间下还有对应的 Service
。
kubectl get svc -n httpbin -l app.kubernetes.io/component=controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
fsm-ingress-pipy-httpbin LoadBalancer 10.43.62.120 192.168.1.11 81:30081/TCP 2m49s
复制代码
有了 Ingress Controller 之后,就是创建 Ingress
资源了。
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpbin
namespace: httpbin
spec:
ingressClassName: pipy
rules:
- host: httpbin.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpbin
port:
number: 14001
EOF
复制代码
测试
前面检查 Ingress Controller 的时候,可以看到其外部 IP 地址为 192.168.1.11
,端口为 81
。
curl -sI http://192.168.1.11:81/get -H "Host: httpbin.org"
HTTP/1.1 200 OK
server: gunicorn/19.9.0
date: Wed, 07 Sep 2022 12:02:04 GMT
content-type: application/json
content-length: 239
access-control-allow-origin: *
access-control-allow-credentials: true
connection: keep-alive
复制代码
总结
多租户的 Ingress Controller 在云环境中,尤其是复杂组织的系统中非常使用,做到了配置和组件的双重隔离。本篇演示的是简单应用的 controller 隔离,对于服务网格的环境下使用方法相同,有兴趣的同学可以尝试一下。
评论