Начало работы с агентом Open Policy (OPA)

облачный носитель Kubernetes Открытый исходный код
Начало работы с агентом Open Policy (OPA)

Всем привет, меня зовут Чжан Цзиньтао.

В этой статье я познакомлю вас с общим механизмом политики, который мне очень нравится, под названием OPA, полное название — Open Policy Agent.

Прежде чем мы подробно поговорим об OPA, давайте поговорим о том, зачем нужен механизм общей политики и какие проблемы решает OPA.

Какую проблему решает OPA

В реальной производственной среде управление политиками требуется во многих сценариях, таких как:

  • Политика необходима для управления тем, могут ли пользователи входить на сервер или выполнять некоторые операции;

  • Требуются политики для управления тем, какие проекты/компоненты могут быть развернуты;

  • Нужны политики для управления доступом к базе данных;

  • Нужны политики для контроля того, какие ресурсы можно развернуть в Kubernetes;

img

Однако для этих сценариев или программного обеспечения стратегия их настройки должна быть связана с программным обеспечением, которое не является унифицированным и универсальным. Это также будет запутанно в управлении и принесет много затрат на обслуживание.

Появление OPA может унифицировать политики, настроенные повсеместно, что значительно улучшитСнижение затрат на техническое обслуживание. И отделите стратегию от соответствующего программного обеспечения/сервиса, чтобы облегчить перенос/повторное использование.

img

Эволюция ОРА

Первоначально OPA был проектом, созданным Styra с открытым исходным кодом в 2016 году. В настоящее время основным продуктом компании является служба визуальной панели мониторинга, которая обеспечивает визуальный контроль политик и их выполнение.

OPA впервые вошла в CNCF и стала проектом уровня «песочницы» в 2018 г., а закончила CNCF в феврале 2021 г. Этот процесс относительно быстрый, также видно, что OPA является относительно активным и прикладным проектом. .

Что такое ОПА

Ранее мы сообщали, что Open Policy Agent (OPA) — это механизм политик общего назначения с открытым исходным кодом, который обеспечивает унифицированный контекстно-зависимый контроль политик во всем стеке.

OPA отделяет (отделяет) решения политики от бизнес-логики приложения,Глядя на суть через явление, политика представляет собой набор правил, в движок отправляются запросы, а движок принимает решения на основе правил.

img

Рисунок 3, пример разделения политик для OPA

OPA не отвечает за выполнение конкретных задач, оно отвечает только за принятие решений, запрос, который необходимо решить, передается в OPA в виде JSON, и после того, как OPA принимает решение, результат также будет возвращен в виде JSON.

Rego

Стратегия в OPA представлена ​​DSL (Domain Specific Language) компании Rego.

Rego поддерживается Datalog (Итак, Wikipedia.org/wiki/data…Вдохновленный , и расширенная поддержка Datalog для модели структурированного документа, удобно обрабатывать данные в JSON.

Rego позволяет политикам сосредоточиться на запросе, который возвращает контент, а не на том, как выполнить запрос. В то же время OPA также имеет встроенную оптимизацию при выполнении правил, и пользователи могут использовать ее по умолчанию.

Rego позволяет нам инкапсулировать и повторно использовать логику с помощью правил (если-то), которые могут быть полными или частичными.

Каждое правило состоит из заголовка и тела. В Rego заголовок правила считается истинным, если тело правила оценивается как истинное для некоторой переменной. Его значение можно запросить, обратившись к любому правилу, загруженному в OPA, по его абсолютному пути. Путь к правилу всегда: data.. (все значения, сгенерированные правилом, можно запросить через глобальную переменную данных. Например, в примере нижеdata.example.rules.any_public_networks

  • Полное правило представляет собой оператор if-then, который присваивает единственное значение переменной.

img

Рисунок 4. Пример полного правила Rego

  • Частью правила является оператор if-then, который генерирует набор значений и присваивает этот набор переменной.

img

Рисунок 5, Пример частичных правил Rego

  • Logic или для определения нескольких правил с одинаковым именем в Rego. (Когда несколько выражений объединяются в запросе, это означает логическое И)

img

Рисунок 6, пример схемы правил Rego или полных правил и частичных правил.

Использование ОРА

Использование OPA относительно простое, давайте посмотрим.

Установить ОРА

двоичный режим

Мы можем загрузить его двоичные файлы непосредственно со страницы выпуска OPA для использования.

➜  ~ wget -q -O ~/bin/opa https://github.com/open-policy-agent/opa/releases/download/v0.35.0/opa_linux_amd64_static 
➜  ~ chmod +x ~/bin/opa
➜  ~ opa version
Version: 0.35.0
Build Commit: a54537a
Build Timestamp: 2021-12-01T02:11:47Z
Build Hostname: 9e4cf671a460
Go Version: go1.17.3
WebAssembly: unavailable

контейнер

Мы можем использовать его официальное зеркало

➜  ~ docker run --rm  openpolicyagent/opa:0.35.0 version    
Version: 0.35.0
Build Commit: a54537a
Build Timestamp: 2021-12-01T02:10:31Z
Build Hostname: 4ee9b086e5de
Go Version: go1.17.3
WebAssembly: available

взаимодействие OPA

opa eval

Самая простая командаopa eval, конечно, помимо использования для выполнения политики, его также можно использовать для вычислений выражений.

img

Рисунок 7, помощь с opa eval

➜  ~ opa eval "6+6"
{
  "result": [
    {
      "expressions": [
        {
          "value": 12,
          "text": "6+6",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}

opa run

opa runЗапустится интерактивная оболочка (REPL). Мы можем использовать REPL для тестирования стратегии и создания нового прототипа.

➜  ~ opa run
OPA 0.35.0 (commit a54537a, built at 2021-12-01T02:11:47Z)

Run 'help' to see a list of commands and check for updates.

> true
true
> ["Hello", "OPA"]
[
  "Hello",
  "OPA"
]
> pi := 3.14
Rule 'pi' defined in package repl. Type 'show' to see rules.
> show
package repl

pi := 3.14
> pi > 1
true

Мы также можем загружать политики непосредственно в него или запускать OPA как сервис и выполнять запросы по HTTP. По умолчанию монитор OPA прослушивает порт 8181.

➜  ~ opa run --server
{"addrs":[":8181"],"diagnostic-addrs":[],"level":"info","msg":"Initializing server.","time":"2021-12-07T01:12:47+08:00"}

Вы также можете увидеть простое окно запроса, открыв браузер

img

opa используется как библиотека для go

OPA можно встраивать в программы Go в виде библиотеки. Самый простой способ внедрить OPA в виде библиотеки — это импортироватьgithub.com/open-policy-agent/opa/regoМешок. пройти черезrego.NewФункции используются для создания объекта, который можно подготовить или оценить,PrepareForEval()для получения исполняемых запросов.

Вот простой пример:

  • Структура каталогов
➜  opa tree 
.
├── data
├── go.mod
├── go.sum
├── input.json
├── k8s-label.rego
└── main.go

1 directory, 5 files
  • файл политики

Файл политики здесь должен проверить, содержит ли ВХОД метку с именем домен и начинается ли метка сmoelove-начало.

package kubernetes.validating.existence

deny[msg] {
	not input.request.object.metadata.labels.domain
	msg := "Every resource must have a domain label"
}


deny[msg] {
	value := input.request.object.metadata.labels.domain
	not startswith(value, "moelove-")
	msg := sprintf("domain label must start with `moelove-`; found `%v`", [value])
}
  • INPUT-файл на примере AdmissionReview Kubernetes.
{
    "kind": "AdmissionReview",
    "request": {
        "kind": {
            "kind": "Pod",
            "version": "v1"
        },
        "object": {
            "metadata": {
                "name": "myapp",
                "labels": {
                    "domain": "opa"
                }
            },
            "spec": {
                "containers": [
                    {
                        "image": "alpine",
                        "name": "alpine"
                    }
                ]
            }
        }
    }
}
  • файл main.go
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"

	"github.com/open-policy-agent/opa/rego"
)

func main() {

	ctx := context.Background()

	// Construct a Rego object that can be prepared or evaluated.
	r := rego.New(
		rego.Query(os.Args[2]),
		rego.Load([]string{os.Args[1]}, nil))

	// Create a prepared query that can be evaluated.
	query, err := r.PrepareForEval(ctx)
	if err != nil {
		log.Fatal(err)
	}

	// Load the input document from stdin.
	var input interface{}
	dec := json.NewDecoder(os.Stdin)
	dec.UseNumber()
	if err := dec.Decode(&input); err != nil {
		log.Fatal(err)
	}

	rs, err := query.Eval(ctx, rego.EvalInput(input))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(rs)
}

Результат выполнения следующий:

➜  opa go run main.go k8s-label.rego "data" < input.json
[{[map[kubernetes:map[validating:map[existence:map[deny:[domain label must start with `moelove-`; found `opa`]]]]]] map[]}]

Суммировать

Вышеизложенное является общим введением в OPA.Существует много сценариев применения OPA.В следующих статьях мы расскажем о применении OPA в Kubernetes и применении OPA к конвейеру CI/CD. Быть в курсе.


Добро пожаловать, чтобы подписаться на мой публичный аккаунт статьи [MoeLove]TheMoeLove