如何将Emissary Ingress与OPA集成

译文
云计算 云原生
本文将介绍如何将Emissary Ingress与OPA集成以进行外部授权。

​译者 | 李睿

审校 | 孙淑娟

API网关在公开微服务时,起着至关重要的作用。它们是网络中的一个附加跃点,传入请求必须通过该跃点才能与服务通信。API网关在收到来自客户端的请求之后会执行路由、组合、协议转换和用户策略实施,然后将其反向代理到适当的底层API。由于API网关能够执行上述任务,它们还可以配置为将传入的客户端请求发送到外部第三方授权(authz)服务器。然后,传入请求的命运取决于这一外部身份验证服务器对网关的响应。这正是开放策略代理(OPA)发挥作用的地方。  

有许多开源的Kubernetes原生API网关,例如Contour、Kong Gateway、Traefik、Gloo等。以下深入了解一下Emissary Ingress。  

什么是Emissary Ingress?  

Emissary Ingress早期被称为Ambassar API网关;它是一个开源的Kubernetes原生API网关,目前是云原生应用计算基金会(CNCF)孵化项目。与许多其他Kubernetes网关一样,Emissary也被构建为与Envoy代理一起使用。它部署为完整的无状态架构,并支持多个插件,例如传统的SSO身份验证协议(例如OAuth、OpenIDConnect)、速率限制、日志记录和跟踪服务。Emissary在AuthService资源中利用其ExtAuth协议来配置传入请求的身份验证和授权。ExtAuth支持两种协议:gRPC和HTTP。对于gRPC接口,外部服务必须实现Envoy的external_auth.proto。  

OPA  

Open Policy Agent(OPA)是一个众所周知的通用策略引擎,并已成为跨堆栈的策略执行器,无论是API网关、服务网格、Kubernetes、微服务、CI/CD还是IAC。OPA将决策制定与策略执行分离,这样每当软件需要对传入请求做出决定时,它都会查询OPA。OPA-Envoy使用实现Envoy外部授权API的gRPC服务器扩展OPA,从而使其自身与Emissary的外部authz服务器兼容。

将Emissary Ingress与OPA集成  

上图展示了Emissary和OPA集成的高层架构。当来自客户端的传入请求到达Emissary时,它会向OPA发送授权请求,其中包含输入JSON。OPA根据提供给它的Rego策略评估这个JSON并响应Emissary;如果来自OPA的这个结果JSON允许为真,那么只有客户端请求被进一步路由到API,否则请求被Emissary拒绝并且永远不会到达API。将安装Emissary Ingress并将其与OPA集成以进行外部授权。  

(1)入门  

首先,需要启动一个Minikube集群。如果没有Minikube,可以从这里安装它。  

minikube start

通过Helm将Emissary Ingress安装到minikube。  

# Add the Repo:
helm repo add datawire https://app.getambassador.io
helm repo update
# Create Namespace and Install:
kubectl create namespace emissary && \
kubectl apply -f https://app.getambassador.io/yaml/emissary/2.2.2/emissary-crds.yaml
kubectl wait --timeout=90s --for=condition=available deployment emissary-apiext -n emissary-system
helm install emissary-ingress --namespace emissary datawire/emissary-ingress && \
kubectl -n emissary wait --for condition=available --timeout=90s deploy -lapp.kubernetes.io/instance=emissary-ingress

或者参考Emissary Ingress文档通过Kubernetes YAMLs安装它。

(2)为演示应用程序配置路由  

不同的网关有自己的一组用于公开服务的配置。在Emissary中,需要通过映射和侦听器配置路由。

映射资源只是告诉Emissary将传入请求重定向到哪个服务。它像Ingress一样高度可配置。将创建一个简单的映射资源,它将所有传入请求重定向到演示应用程序的服务,即demo-svc。  

cat <<EOF | kubectl apply -f -
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: demo-app-mapping
spec:
hostname: "*"
prefix: /
service: demo-svc
EOF

侦听器资源指示Emissary在网络上侦听传入请求。在这里,将创建一个侦听器来侦听端口8080和HTTP协议,并与所有命名空间中的主机关联。

cat <<EOF | kubectl apply -f -
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
name: demo-app-listener-8080
namespace: emissary
spec:
port: 8080
protocol: HTTP
securityModel: XFP
hostBinding:
namespace:
from: ALL
EOF

(3)安装echo应用程序  

安装一个简单的echo服务器作为演示应用程序。  

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: http-svc
image: gcr.io/google_containers/echoserver:1.8
ports:
- containerPort: 8080
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
name: demo-svc
labels:
app: demo-app
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: demo-app
EOF

通过不同的路径与演示应用程序通信。

minikube service emissary-ingress -n emissary

注意:上述公开方法可能不适用于macOS用户。他们可以使用一个忙框,并将其配置为命中Emissary本地端点。

使用目标端口80复制专用URL。URL必须为IP 192.168.49.2,后跟一个节点端口,如http://192.168.49.2:30329。将NodePort值导出为$NodePort环境变量,并将curl导出为路径处的值,如下所示:

curl http://192.168.49.2:$NODEPORT/public
curl http://192.168.49.2:$NODEPORT/secured

OPA尚未添加到设置中,并且上述curl请求直接发送到API,而无需任何策略强制。

(4)如何安装和配置OPA?

OPA将通过configmap读取提供给它的策略。创建以下configmap,其中包含一个策略,该策略只允许通过GET方法接收所有传入请求。

cat <<EOF | kubectl apply -n emissary -f  -
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-policy
data:
policy.rego: |-
package envoy.authz
default allow = false
allow {
input.attributes.request.http.method == "GET"
}
EOF

通过将OPA部署为独立部署或作为emissary-ingress的sidecar,可以将OPA配置为外部授权服务器。在这里,将其添加为sidecar。将以下YAML保存为opa-patch.yaml。  

spec:
template:
spec:
containers:
- name: opa
image: openpolicyagent/opa:latest-envoy
ports:
- containerPort: 9191
args:
- "run"
- "--server"
- "--addr=0.0.0.0:8181"
- "--set=plugins.envoy_ext_authz_grpc.addr=0.0.0.0:9191"
- "--set=plugins.envoy_ext_authz_grpc.query=data.envoy.authz.allow"
- "--set=decision_logs.console=true"
- "--ignore=.*"
- "/policy/policy.rego"
volumeMounts:
- mountPath: /policy
name: demo-policy
readOnly: true
volumes:
- name: demo-policy
configMap:
          name: demo-policy

修补 emissary-ingress 部署并等待所有 emissary-ingress pod 重新启动。

kubectl patch deployment emissary-ingress -n emissary --patch-file opa-patch.yaml

等到所有的emissary-ingresspod进入带有OPA sidecar的运行状态。  

创建以下AuthService。AuthService是一种资源,它配置Emissary与外部服务进行通信,以获取传入请求的Authn和Authz。将其配置为与localhost上的OPA通信,因为OPA被部署为sidecar。

cat <<EOF | kubectl apply -f -
apiVersion: getambassador.io/v3alpha1
kind: AuthService
metadata:
name: opa-ext-authservice
namespace: emissary
labels:
product: aes
app: opa-ext-auth
spec:
proto: grpc
auth_service: localhost:9191
timeout_ms: 5000
tls: "false"
allow_request_body: true
protocol_version: v2
include_body:
max_bytes: 8192
allow_partial: true
status_on_error:
code: 504
failure_mode_allow: false
EOF

现在尝试curl;由于该策略接受来自GET方法的请求并且对路径没有限制,因此两个请求都将获得200个OK响应。

curl -i http://192.168.49.2:$NODEPORT/public
curl -i http://192.168.49.2:$NODEPORT/private

现在编辑策略以仅接受来自路径 /public 的传入请求,而对任何其他路径的请求都将被拒绝。

cat <<EOF | kubectl apply -n emissary -f  -
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-policy
data:
policy.rego: |-
package envoy.authz
default allow = false
allow {
input.attributes.request.http.method == "GET"
input.attributes.request.http.path == "/public"
}
EOF

现在重新启动使者入口部署以使策略更改生效。

kubectl rollout restart deployment emissary-ingress -n emissary

等到所有的Emissary-Ingresspod在重启后进入Running状态。  

现在在路径/public处执行curl请求;它将被接受,但在路径/privat,e它将被OPA拒绝并返回403响应,因此请求不会到达演示API。  

curl-ihttp://192.168.49.2:$NODEPORT/public  
curl-ihttp://192.168.49.2:$NODEPORT/private

关于从客户端到公开API的传入请求的决策可以解耦到OPA作为Emissary Ingress设置中的外部授权服务器。OPA可以作为即插即用策略执行器添加到Emissary和任何其他支持Envoy外部授权API的网关。

原文标题:How Do You Integrate Emissary Ingress With OPA​,作者:Tayyab Jamadar

责任编辑:华轩 来源: 51CTO
相关推荐

2020-09-07 19:34:48

边缘计算核心系统Edge

2013-05-31 09:03:47

SkypeLync集成

2022-03-24 07:44:41

OPA安全策略Rego

2021-03-15 13:05:13

LinuxNautilusGit

2022-10-08 00:35:48

gRPCGuice服务器

2020-03-10 22:01:54

物联网安全物联网IOT

2011-09-02 14:05:57

云计算解决方案虚拟化

2022-04-23 10:55:51

存储AI/ML对象锁定

2018-06-23 13:55:15

Apache SparPython数据

2009-08-26 18:05:25

ViewState持久

2022-03-10 15:57:03

物联网工业4.0大数据

2020-06-04 07:48:08

Istio服务注册API Server

2022-09-02 13:43:33

零信任首席信息安全官

2023-12-29 07:04:28

Go项目Docker编写

2019-03-12 09:46:33

程序Windows 10启动

2011-05-04 09:32:16

2018-06-12 15:07:57

IT

2011-05-18 14:51:43

2023-02-17 12:07:45

ChatGPTPython

2011-11-08 15:15:40

路由器复位
点赞
收藏

51CTO技术栈公众号