AICon上海|与字节、阿里、腾讯等企业共同探索Agent 时代的落地应用 了解详情
写点什么

在 Amazon EKS 上使用 Open Policy Agent

  • 2019-10-08
  • 本文字数:5839 字

    阅读完需:约 19 分钟

在 Amazon EKS 上使用 Open Policy Agent

Open Policy Agent (OPA) 是云原生计算基金会 (CNCF) 的一个沙盒项目,可帮助您针对几乎所有内容实施自动化策略,其工作原理与 AWS Identity and Access Management (IAM) 类似。借助 OPA,您可以使用一种基于 datalog 的名为 rego 的语言编写非常精简的策略。然后,您可以将这些策略部署到 rego 文件中的 Open Policy Agent Admission Controller,并让其验证或修改向 Kubernetes API 服务器发送的请求。这就是说,您可以编写一个有两行代码的策略,并让此策略对请求中的属性实施验证,例如可以检查 imagePullPolicy 是否设置为 Always,或者 Deployment 是否总是拥有至少 2 个 replica,或者映像是否来源于白名单存储库中的注册表。下文将介绍如何将 OPA 部署到 Amazon Elastic Container Service for Kubernetes (EKS) 集群中并实施检查,仅允许存在来自您自己的 Amazon Elastic Container Registry (ECR) 或 EKS ECR 存储库的映像。

开始使用

在开始之前,我们需要设置一个 Amazon EKS 集群。我们将在集群配置文件机制中使用 eksctl。首先,必须下载以下工具:



部署集群


export AWS_REGION=us-east-2export ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
复制代码


在导出区域后,我们可以按如下所示创建 ClusterConfig:


cat >cluster.yaml <<EOFapiVersion: eksctl.io/v1alpha4kind: ClusterConfigmetadata:  name: opa  region: ${AWS_REGION}
nodeGroups: - name: ng-1 desiredCapacity: 2 allowSSH: trueEOF
复制代码


在创建该文件后,我们将使用 eksctl create cluster 命令创建集群:


eksctl create cluster -f cluster.yaml
复制代码


完成此操作大约需要 15 分钟时间,之后,我们便可获得可供使用的 Amazon EKS 集群。与此同时,我们可以开始为满足 Open Policy Agent 需求做准备。首先,我们将为 Admission Controller 生成自签名证书颁发机构,以便所有通信均可通过 TLS 完成。


创建资源


openssl genrsa -out ca.key 2048openssl req -x509 -new -nodes -key ca.key -days 100000 -out ca.crt -subj "/CN=admission_ca"
复制代码


创建 CA 后,我们需要为 OPA 创建 TLS 密钥和证书:


cat >server.conf <<EOF[req]req_extensions = v3_reqdistinguished_name = req_distinguished_name[req_distinguished_name][ v3_req ]basicConstraints = CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEnciphermentextendedKeyUsage = clientAuth, serverAuthEOF
复制代码


创建 server.conf 后,我们可以再次使用 openssl 生成密钥和证书:


openssl genrsa -out server.key 2048openssl req -new -key server.key -out server.csr -subj "/CN=opa.opa.svc" -config server.confopenssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 100000 -extensions v3_req -extfile server.conf
复制代码


接下来,我们将创建 Open Policy Agent Admission Controller 清单:


cat >admission-controller.yaml <<EOF---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: opa-viewerroleRef:  kind: ClusterRole  name: view  apiGroup: rbac.authorization.k8s.iosubjects:- kind: Group  name: system:serviceaccounts:opa  apiGroup: rbac.authorization.k8s.io---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:  namespace: opa  name: configmap-modifierrules:- apiGroups: [""]  resources: ["configmaps"]  verbs: ["update", "patch"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  namespace: opa  name: opa-configmap-modifierroleRef:  kind: Role  name: configmap-modifier  apiGroup: rbac.authorization.k8s.iosubjects:- kind: Group  name: system:serviceaccounts:opa  apiGroup: rbac.authorization.k8s.io---kind: ServiceapiVersion: v1metadata:  name: opa  namespace: opaspec:  selector:    app: opa  ports:  - name: https    protocol: TCP    port: 443    targetPort: 443---apiVersion: extensions/v1beta1kind: Deploymentmetadata:  labels:    app: opa  namespace: opa  name: opaspec:  replicas: 1  selector:    matchLabels:      app: opa  template:    metadata:      labels:        app: opa      name: opa    spec:      containers:        - name: opa          image: openpolicyagent/opa:0.10.5          args:            - "run"            - "--server"            - "--tls-cert-file=/certs/tls.crt"            - "--tls-private-key-file=/certs/tls.key"            - "--addr=0.0.0.0:443"            - "--addr=http://127.0.0.1:8181"          volumeMounts:            - readOnly: true              mountPath: /certs              name: opa-server        - name: kube-mgmt          image: openpolicyagent/kube-mgmt:0.6          args:            - "--replicate-cluster=v1/namespaces"            - "--replicate=extensions/v1beta1/ingresses"      volumes:        - name: opa-server          secret:            secretName: opa-server---kind: ConfigMapapiVersion: v1metadata:  name: opa-default-system-main  namespace: opadata:  main: |    package system
import data.kubernetes.admission
main = { "apiVersion": "admission.k8s.io/v1beta1", "kind": "AdmissionReview", "response": response, }
default response = {"allowed": true}
response = { "allowed": false, "status": { "reason": reason, }, } { reason = concat(", ", admission.deny) reason != "" }EOF
复制代码


然后,我们将创建 ValidatingWebhookConfiguration,它将指示 Kubernetes 发送 CREATE、UPDATE Pod 事件,以让我们的策略对这些事件进行验证:


cat > webhook-configuration.yaml <<EOFkind: ValidatingWebhookConfigurationapiVersion: admissionregistration.k8s.io/v1beta1metadata:  name: opa-validating-webhookwebhooks:  - name: validating-webhook.openpolicyagent.org    rules:      - operations: ["CREATE", "UPDATE"]        apiGroups: ["*"]        apiVersions: ["v1"]        resources: ["Pod"]    clientConfig:      caBundle: $(cat ca.crt | base64 | tr -d '\n')      service:        namespace: opa        name: opaEOF
复制代码


然后,我们将创建第一个策略。我们要创建的策略将验证每个 Pod 的映像是否来自白名单中的注册表。我们策略中的前两个条目分别为我们自己账户的 Amazon ECR 和 Amazon EKS 特定的 ECR。


cat > image_source.rego <<EOFpackage kubernetes.admission
deny[msg] { input.request.kind.kind = "Pod" input.request.operation = "CREATE" image = input.request.object.spec.containers[_].image name = input.request.object.metadata.name not registry_whitelisted(image,whitelisted_registries) msg = sprintf("pod %q has invalid registry %q", [name, image])}
whitelisted_registries = {registry | registries = [ "602401143452.dkr.ecr.${AWS_REGION}.amazonaws.com", "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" ] registry = registries[_]}
registry_whitelisted(str, patterns) { registry_matches(str, patterns[_])}
registry_matches(str, pattern) { contains(str, pattern)}EOF
复制代码


最后,我们将创建用来测试策略的 nginx test Pod 清单:


cat > nginx.yaml <<EOFkind: PodapiVersion: v1metadata:  name: nginx  labels:    app: nginx  namespace: defaultspec:  containers:  - image: nginx    name: nginxEOF
复制代码


在创建集群之后,我们便可部署所有资源并对其进行测试。


部署资源


首先,我们将创建 opa 命名空间,并在当前环境中对其进行设置。这样,可以更轻松地跟踪我们正在执行的所有操作:


kubectl create namespace opakubectl config set-context --namespace opa --current
复制代码


接下来,我们将部署之前创建的所有清单,先从使用我们的服务器密钥和证书的 TLS 密钥开始:


kubectl create secret tls opa-server --cert=server.crt --key=server.key
复制代码


然后,我们将部署 Admission Controller:


kubectl apply -f admission-controller.yaml
复制代码


如果您要在多租户或不受信任的环境中运行集群,建议您通读此处的 TLS 和身份验证方案。


在部署 AdmissionController 之后,我们可以部署已创建的 ValidatingWebhookConfiguration。这会指示 Kubernetes API 服务器将所有 Pod CREATE 和 UPDATE 事件发送至 OPA 服务进行验证。


kubectl apply -f webhook-configuration.yaml


最后需要进行的配置是部署我们的自定义策略,限制 Pod 通过不受信任的注册表进行部署:


kubectl create configmap image-source --from-file=image_source.rego


注意:与我们正在使用的其他 kubectl 命令不同,此命令属于命令性配置。这有时会使您的 ConfigMap 很难保持同步,尤其是在使用 Gitops 之类的部署策略时,难度更大。如果您想使用 apply,则需创建 ConfigMap 清单,并将您的策略复制到 data 属性中。


在创建策略之后,我们便可进行测试,看看它是否已正确编译,以及 Open Policy Agent 是否已成功对 rego 脚本进行了初始化。要执行此操作,请使用 kubectl get configmap image-source -o yaml:


$ kubectl get configmap image-source -o jsonpath="{.metadata.annotations}"map[openpolicyagent.org/policy-status (http://openpolicyagent.org/policy-status):{"status":"ok"}]
复制代码


在资源部署完毕并已在 Open Policy Agent 中进行初始化之后,我们便可运行 nginx Pod 测试。


测试策略


$ kubectl apply -f nginx.yamlError from server (pod "nginx" has invalid registry "nginx"): error when creating "nginx.yaml": admission webhook "validating-webhook.openpolicyagent.org" denied the request: pod "nginx" has invalid registry "nginx"
复制代码



现在,让我们使用自己的注册表标记 nginx 映像,推送该映像,并尝试通过我们自己的注册表进行部署。首先,我们需要创建一个存储库:


aws ecr create-repository —repository-name nginx
复制代码


然后,我们将从 API 中获得存储库名称,以便标记我们的 nginx 实例:


export REPOSITORY=$(aws ecr describe-repositories --repository-name nginx --query "repositories[0].repositoryUri" --output text)
复制代码


现在,我们会将 Docker Hub 公有 nginx 提取到本地,以便重新对其进行标记:


docker pull nginx
复制代码


然后,我们可以使用存储库名称重新标记 latest,并将映像推送至您自己的 Amazon ECR。首先,我们登录 Amazon ECR:


aws ecr get-login —no-include-email | bash -
复制代码


然后,将 latest 标签推送至 Amazon ECR:


docker push ${REPOSITORY}:latest
复制代码


接下来,我们可以重新创建 nginx 清单文件,并将其推送至 Amazon EKS 集群:


cat > private-nginx.yaml <<EOFkind: PodapiVersion: v1metadata:  name: nginx  labels:    app: nginx  namespace: defaultspec:  containers:  - image: ${REPOSITORY}:latest    name: nginxEOF
复制代码


最后,我们将 nginx Pod 部署到集群:


$ kubectl apply -f private-nginx.yamlpod/nginx created
复制代码



清理


如果您想删除已创建的集群,可以先删除集群中创建的所有资源,然后使用 eksctl 再次删除 Amazon EKS 集群:


kubectl delete -f private-nginx.yamlkubectl delete namespace opaeksctl delete cluster -f cluster.yaml
复制代码


更多示例


以下是一些很好的示例,其中展示了人们目前是如何将 Open Policy Agent 与 Kubernetes 集群结合使用,来帮助管理其自定义策略的:


现在,有谁在结合使用 @OpenPolicyAgent 与 @kubernetesio? 有没有有趣的策略?

我刚刚为 Amazon EKS 编写了一个策略,用来检查映像是来自 EKS 注册表还是您自己的账户的 ECR。

你们都用它来做什么?

– Chris Hein (@christopherhein) 2019 年 3 月 1 日


网关守卫实际效果视频 – https://t.co/brjywlDmen

– Lachlan Evenson (@LachlanEvenson) 2019 年 3 月 1 日

我编写了一些有关联合身份的有趣策略,其中它只允许基于标签部署到欧洲或全球的集群,另一个策略则用于检查第三方“jira”(模拟),它只允许在 P1 票证打开时访问生产名称空间

– Andy Repton (@SethKarlo) 2019 年 3 月 2 日

我们将它用于多种用途,但主要的是确保人们不向错误的 ingress 类添加 ingress,不向 Internet 披露他们不应披露的内容

– briggsl (@briggsl) 2019 年 3 月 2 日


@OpenPolicyAgent 是我们 @kubernetesio 服务堆栈中的一个新的核心组件。

我的同事 @sbueringer 为此撰写了两篇博文:https://t.co/LFkfJ8ElEshttps://t.co/ZxsQtZ2Z1Y


– Mario Constanti (@bavarian_bidi) 2019 年 3 月 2 日

小结

借助 Open Policy Agent,您不必再通过编写自定义代码来处理组织或团队的自定义策略。现在,您可以像我们在本文中所做的那样部署自定义 ValidatingAdmissionControllers 或 MutatingAdmissionControllers(为您的 Kubernetes 资源提供正常的默认值),或设置适当的标签。您会拥有几乎无穷无尽的控件。要了解有关 Open Policy Agent 的更多信息,请查看 Open Policy Agent 文档,并加入 Open Policy Agent 社区。


阅读 Chris 撰写的更多博文。


作者介绍:


Chris Hein


Chris Hein 是一位资深的开发者,倡导 Amazon Web Services 的 Kubernetes/EKS。加入 Amazon 之前,Chris 曾就职于众多规模不等的公司,如 GoPro、Sproutling 和 Mattel。有关 Chris 的更多信息,请访问 https://aws.amazon.com/blogs/opensource/author/heichris/,并通过 @christopherhein 关注他


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/using-open-policy-agent-on-amazon-eks/


2019-10-08 14:10886
用户头像

发布了 1858 篇内容, 共 132.0 次阅读, 收获喜欢 81 次。

关注

评论

发布
暂无评论
发现更多内容

使用 ClusterResourceSet 为 Cluster API 集群自动安装 CNI 插件

Se7en

非正式全面解析 NebulaGraph 中 Session 管理

NebulaGraph

图数据库 会话管理 session管理

Python图像处理丨详解图像去雾处理方法

华为云开发者联盟

Python 人工智能 华为云 12 月 PK 榜

案例分享:硬件敏捷

ShineScrum

Scrum 敏捷开发 TDD 硬件敏捷

MVP、原型、概念验证,傻傻分不清楚?

敏捷开发

开发 MVP 原型

uniapp 在微信小程序中图片宽度显示问题

ModStart

华为云助推武水集团项目成功入选住建部“智慧水务”典型案例!

华为云开发者联盟

云计算 后端 华为云 12 月 PK 榜

软件测试|HTTPS 的通信

霍格沃兹测试开发学社

【Java技术专题】「原理专题」深入分析Java中finalize方法的作用和底层原理

码界西柚

Java JVM Finalizer 12月月更

如何通过Java应用程序将Word转为Excel

在下毛毛雨

Java Excel word 文档 转换

数字化时代,校园生活还可以这样过

华为云开发者联盟

数据库 后端 华为云 12 月 PK 榜

架构实战营 模块三作业 外包学生管理系统架构设计

西山薄凉

「架构实战营」

参与Getaverse早期建设,成为节点验证者!!

Geek_Web3

#区块链# did #Web3

Triple 协议支持 Java 异常回传的设计与实现

Apache Dubbo

Java 开源 微服务 gRPC dubbo

容器安全的三大挑战

SEAL安全

容器安全 12 月 PK 榜

信息安全等级测评师证书有效期是多久?谁能告诉一下?

行云管家

等保

活动预约报名系统怎么做?快来借鉴「苍山徒步之家」的经验做法

天天预约

微信小程序 SaaS 数据统计 预约工具 活动报名

上云节省 35%计算资源,420 个运维人天:运满满实时计算实践和思考

Apache Flink

大数据 flink 实时计算

说透IO多路复用模型

京东科技开发者

开发 系统 epoll poll Lunix

时序引擎架构和实例演练

KaiwuDB

浅谈权限系统在多利熊业务应用

百度Geek说

百度 权限系统 12 月 PK 榜 多利熊

多模态交互在数智化营销服中的技术实践

中关村科金

人工智能 算法 全栈 数字化转型 多模态

智能低代码平台,驱动企业数字化转型

元年技术洞察

低代码 数字化转型

龙蜥开发者说:众人拾柴火焰高!聊一聊我在社区的所思所想 | 第 14期

OpenAnolis小助手

开发者 开源社区 龙蜥开发者说 LoongArch 架构 红旗软件

2022-12-28:有n个黑白棋子,它们的一面是黑色,一面是白色, 它们被排成一行,位置0~n-1上。一开始所有的棋子都是黑色向上, 一共有q次操作,每次操作将位置标号在区间[L,R]内的所有棋子翻

福大大架构师每日一题

golang 算法 福大大

软件测试面试 | 一面试就紧张,怎么办?

霍格沃兹测试开发学社

软件测试简历书写 | 简历中应该如何描述才能体现出软技能的实力 ?

测试人

软件测试 自动化测试 简历 软技能 测试开发

PHP 中类自动加载相关文件分析

ModStart

2023年内蒙古等保测评公司有哪些?五家还是6家?

行云管家

等保 等保测评 内蒙古

Gitea 的邮件通知

HoneyMoose

Java高手速成│Java程序怎样和数据库对话

TiAmo

JDBC 数据库· 12月月更

在 Amazon EKS 上使用 Open Policy Agent_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章