背景
Ingress 作为 Kubernetes 集群外部到集群内部应用的访问入口,对进入集群的流量实施管理。Kubernetes Ingress API 采用关注点分离的设计,其中 Ingress 的实现提供了由运维人员管理的入口功能基础设施;同时允许应用程序所有者通过规则来控制到后端请求的路由。
osm-edge 支持多种 Ingress 的实现来对入口流量进行管理,并提供 IngressBackend API 来配置后端服务接收来自可信入口的访问。这篇文章主要介绍 osm-edge 与 FSM 的集成来管理入口流量。
FSM 介绍
FSM 是 Flomesh 的另一款开源产品,用于 Kubernetes 南北向的流量管理。FSM 以可编程代理 Pipy 为核心,提供了 Ingress 管理器、Gateway API* 实现、负载均衡器以及跨集群的服务注册发现等功能。
与 FSM 集成
osm-edge 内部已经集成 FSM,可以在安装 osm-edge 时启用 FSM;也可在独立安装 FSM 与现有的 osm-edge 网格中。
前置条件
FSM 下载 osm-edge CLI:
system=$(uname -s | tr [:upper:] [:lower:])arch=$(dpkg --print-architecture)release=v1.1.1curl -L https://github.com/flomesh-io/osm-edge/releases/download/${release}/osm-edge-${release}-${system}-${arch}.tar.gz | tar -vxzf -./${system}-${arch}/osm versioncp ./${system}-${arch}/osm /usr/local/bin/
复制代码
集成式安装
export osm_namespace=osm-system export osm_mesh_name=osm
osm install --set fsm.enabled=true \ --mesh-name "$osm_mesh_name" \ --osm-namespace "$osm_namespace"
复制代码
独立安装
如果安装 osm-edge 未启用 FSM,可以使用独立安装的方式来安装。
helm repo add fsm https://charts.flomesh.io
export fsm_namespace=osm-system helm install fsm fsm/fsm --namespace "$fsm_namespace" --create-namespace
复制代码
确认所有的 pod 已启动并正常运行。
kubectl get pods -n osm-systemNAME READY STATUS RESTARTS AGErepo-8756f76fb-2f78g 1/1 Running 0 5m53smanager-866585bbd5-pbg7q 1/1 Running 0 5m53sosm-bootstrap-7c6689ff57-47ksk 1/1 Running 0 5m53sosm-controller-57888cfc7c-tnqxl 2/2 Running 0 5m52sosm-injector-5f77898899-45f65 1/1 Running 0 5m53sbootstrap-fd5894bcc-nr7hf 1/1 Running 0 5m53scluster-connector-local-68c7584c8b-qf7xm 1/1 Running 0 2m43singress-pipy-6fb8c8b794-pgthl 1/1 Running 0 5m53s
复制代码
配置
为了通过对访问后端流量的限制来对客户端授权,我们将配置 IngressBackend,这样只有来自 ingress-pipy-controller 端点的入口流量才可以路由到后端服务。为了发现 ingress-pipy-controller 端点,我们需要 osm-edge 控制器及监视相应的命名空间。但是为了保证 FSM 功能正常,不能为其注入 sidecar。
kubectl label namespace "$osm_namespace" openservicemesh.io/monitored-by="$osm_mesh_name"
复制代码
保存入口网关的外部 IP 地址和端口,后面会用其测试访问后端应用。
export ingress_host="$(kubectl -n "$osm_namespace" get service ingress-pipy-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')"export ingress_port="$(kubectl -n "$osm_namespace" get service ingress-pipy-controller -o jsonpath='{.spec.ports[?(@.name=="http")].port}')"echo $ingress_host:$ingress_port
复制代码
部署示例服务
下一步是部署示例 httpbin 服务。
# 创建命名空间kubectl create ns httpbinkubectl create ns httpbin
# 将命名空间加入到网格中osm namespace add httpbin
# 部署应用kubectl apply -f - <<EOFapiVersion: v1kind: ServiceAccountmetadata: name: httpbin namespace: httpbin---apiVersion: v1kind: Servicemetadata: name: httpbin namespace: httpbin labels: app: httpbin service: httpbinspec: ports: - name: http port: 14001 selector: app: httpbin---apiVersion: apps/v1kind: Deploymentmetadata: name: httpbin namespace: httpbinspec: replicas: 1 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: serviceAccountName: httpbin containers: - image: kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin command: ["gunicorn", "-b", "0.0.0.0:14001", "httpbin:app", "-k", "gevent"] ports: - containerPort: 14001EOF
复制代码
确认 pod 和 service 是否已创建,且应用成功运行。
kubectl get pods,services -n httpbinNAME READY STATUS RESTARTS AGEpod/httpbin-54cc8cf5d-7vclc 2/2 Running 0 14s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/httpbin ClusterIP 10.43.105.166 <none> 14001/TCP 14s
复制代码
配置入口规则
接下来我们要从集群外访问部署的 httpbin 服务,需要提供 ingress 的配置规则。
kubectl apply -f - <<EOFapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: httpbin namespace: httpbin annotations: pipy.ingress.kubernetes.io/rewrite-target-from: /httpbin pipy.ingress.kubernetes.io/rewrite-target-to: /spec: ingressClassName: pipy rules: - host: httpbin.org http: paths: - path: /httpbin pathType: Prefix backend: service: name: httpbin port: number: 14001EOF
复制代码
使用上面记录的 IP 地址和端口访问 httpbin 服务,将会收到如下 502 Bad Gateway 的错误响应。这是因为我们还未将 FSM 的 ingress 设置为可信入口。
curl -sI http://"$ingress_host":"$ingress_port"/httpbin/get -H "Host: httpbin.org"HTTP/1.1 502 Bad Gatewaycontent-length: 0connection: keep-alive
复制代码
执行下面的命令,将 FSM ingress 设置为可信入口。
kubectl apply -f - <<EOFkind: IngressBackendapiVersion: policy.openservicemesh.io/v1alpha1metadata: name: httpbin namespace: httpbinspec: backends: - name: httpbin port: number: 14001 # targetPort of httpbin service protocol: http sources: - kind: Service namespace: "$osm_namespace" name: ingress-pipy-controllerEOF
复制代码
再次尝试请求 httpbin 服务,这时便可以成功访问。
curl -sI http://"$ingress_host":"$ingress_port"/httpbin/get -H "Host: httpbin.org"HTTP/1.1 200 OKserver: gunicorn/19.9.0date: Thu, 18 Aug 2022 05:18:50 GMTcontent-type: application/jsoncontent-length: 241access-control-allow-origin: *access-control-allow-credentials: trueosm-stats-namespace: httpbinosm-stats-kind: Deploymentosm-stats-name: httpbinosm-stats-pod: httpbin-54cc8cf5d-7vclcconnection: keep-alive
复制代码
总结
FSM Ingress 对外暴露了 Kubernetes 集群内的应用访问入口,方便对入口流量进行管理。osm-edge 的 IngressBackend API 为则为网格内服务的对外暴露提供了又一道防线,避免数据的意外泄露。
评论