Contents
- 1 Шаги
- 1.1 1. Включите рекомендуемые контроллеры доступа Kubernetes.
- 1.2 2. Создайте новое пространство имен для развертывания OPA.
- 1.3 3. Создайте учетные данные TLS для OPA
- 1.4 4. Определите политику OPA
- 1.5 5. Создайте и опубликуйте пакет OPA
- 1.6 6. Разверните OPA в качестве контроллера доступа
- 1.7 7. Применение политики ограничения имен хостов
- 1.8 8. Применение политики запрета конфликтов имен хостов
- 2 Заворачивать
Шаги
1. Включите рекомендуемые контроллеры доступа Kubernetes.
Чтобы внедрить правила управления допуском, которые проверяют ресурсы Kubernetes во время операций создания, обновления и удаления, необходимо включить ValidatingAdmissionWebhook при запуске сервера API Kubernetes. Контроллер допуска ValidatingAdmissionWebhook включен в рекомендуемый набор контроллеров допуска, чтобы включить
Запустить миникуб:
minikube start
Убедитесь, что входной аддон minikube включен:
minikube addons enable ingress
2. Создайте новое пространство имен для развертывания OPA.
kubectl create namespace opa
Настройте kubectl
использование этого пространства имен:
kubectl config set-context opa-tutorial --user minikube --cluster minikube --namespace opa
kubectl config use-context opa-tutorial
3. Создайте учетные данные TLS для OPA
Связь между Kubernetes и OPA должна быть защищена с помощью TLS. Чтобы настроить TLS, используйте openssl
для создания центра сертификации (CA) и пары сертификат/ключ для OPA:
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -sha256 -key ca.key -days 100000 -out ca.crt -subj "/CN=admission_ca"
Сгенерируйте ключ TLS и сертификат для OPA:
cat >server.conf <<EOF
[ req ]
prompt = no
req_extensions = v3_ext
distinguished_name = dn
[ dn ]
CN = opa.opa.svc
[ v3_ext ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = DNS:opa.opa.svc,DNS:opa.opa.svc.cluster,DNS:opa.opa.svc.cluster.local
EOF
openssl genrsa -out server.key 2048
openssl req -new -key server.key -sha256 -out server.csr -extensions v3_ext -config server.conf
openssl x509 -req -in server.csr -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 100000 -extensions v3_ext -extfile server.conf
Примечание. Значение Common Name и Subject Alternative Name, которые вы даете openssl, ДОЛЖНЫ совпадать с именем службы OPA, созданной ниже.
Создайте секрет для хранения учетных данных TLS для OPA:
kubectl create secret tls opa-server --cert=server.crt --key=server.key --namespace opa
4. Определите политику OPA
Давайте определим пару политик для проверки контроля доступа. Сначала создайте новую папку для хранения наших политик:
mkdir policies && cd policies
Политика 1: Ограничение имен хостов
Создайте политику, ограничивающую имена хостов, которые может использовать вход. Будут разрешены только имена хостов, соответствующие указанным регулярным выражениям.
ingress-allowlist.rego :
5. Создайте и опубликуйте пакет OPA
Создайте пакет OPA, содержащий политики, определенные на предыдущем шаге. В нашей настройке OPA будет загружать политики из службы пакетов, а kube-mgmt
контейнер будет загружать ресурсы Kubernetes в OPA. Поскольку мы загружаем политику и данные в OPA из нескольких источников, нам необходимо ограничить пакет до подмножества политики OPA и кэша данных, определив манифест. Более подробную информацию об этом можно найти здесь . Выполните следующие команды в policies
папке, созданной на предыдущем шаге.
cat > .manifest <<EOF
{
"roots": ["kubernetes/admission", "system"]
}
EOF
opa build -b .
Теперь мы будем обслуживать пакет OPA с помощью Nginx.
docker run --rm --name bundle-server -d -p 8888:80 -v ${PWD}:/usr/share/nginx/html:ro nginx:latest
6. Разверните OPA в качестве контроллера доступа
Затем используйте файл ниже, чтобы развернуть OPA в качестве контроллера доступа.
admission-controller.yaml
:
# Grant OPA/kube-mgmt read-only access to resources. This lets kube-mgmt
# replicate resources into OPA so they can be used in policies.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: opa-viewer
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:opa
apiGroup: rbac.authorization.k8s.io
---
# Define role for OPA/kube-mgmt to update configmaps with policy status.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opa
name: configmap-modifier
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["update", "patch"]
---
# Grant OPA/kube-mgmt role defined above.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opa
name: opa-configmap-modifier
roleRef:
kind: Role
name: configmap-modifier
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
name: system:serviceaccounts:opa
apiGroup: rbac.authorization.k8s.io
---
kind: Service
apiVersion: v1
metadata:
name: opa
namespace: opa
spec:
selector:
app: opa
ports:
- name: https
protocol: TCP
port: 443
targetPort: 8443
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: opa
namespace: opa
name: opa
spec:
replicas: 1
selector:
matchLabels:
app: opa
template:
metadata:
labels:
app: opa
name: opa
spec:
containers:
# WARNING: OPA is NOT running with an authorization policy configured. This
# means that clients can read and write policies in OPA. If you are
# deploying OPA in an insecure environment, be sure to configure
# authentication and authorization on the daemon. See the Security page for
# details: https://www.openpolicyagent.org/docs/security.html.
- name: opa
image: openpolicyagent/opa:0.43.0-rootless
args:
- "run"
- "--server"
- "--tls-cert-file=/certs/tls.crt"
- "--tls-private-key-file=/certs/tls.key"
- "--addr=0.0.0.0:8443"
- "--addr=http://127.0.0.1:8181"
- "--set=services.default.url=http://host.minikube.internal:8888"
- "--set=bundles.default.resource=bundle.tar.gz"
- "--log-format=json-pretty"
- "--set=status.console=true"
- "--set=decision_logs.console=true"
volumeMounts:
- readOnly: true
mountPath: /certs
name: opa-server
readinessProbe:
httpGet:
path: /health?plugins&bundle
scheme: HTTPS
port: 8443
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
scheme: HTTPS
port: 8443
initialDelaySeconds: 3
periodSeconds: 5
- name: kube-mgmt
image: openpolicyagent/kube-mgmt:2.0.1
args:
- "--replicate-cluster=v1/namespaces"
- "--replicate=networking.k8s.io/v1/ingresses"
volumes:
- name: opa-server
secret:
secretName: opa-server
⚠️ При использовании
kind
для запуска локального кластера Kubernetes URL-адрес службы пакета должен бытьhttp://host.docker.internal:8888
.
kubectl apply -f admission-controller.yaml
При запуске OPA kube-mgmt
контейнер загрузит объекты Kubernetes Namespace и Ingress в OPA. Вы можете настроить sidecar для загрузки любых объектов Kubernetes в OPA. Sidecar устанавливает часы на сервере API Kubernetes, чтобы OPA имел доступ к постоянно согласованному кешу объектов Kubernetes.
Затем сгенерируйте манифест, который будет использоваться для регистрации OPA в качестве контроллера допуска. Этот веб-перехватчик будет игнорировать любое пространство имен с меткой openpolicyagent.org/webhook=ignore
.
cat > webhook-configuration.yaml <<EOF
kind: ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
metadata:
name: opa-validating-webhook
webhooks:
- name: validating-webhook.openpolicyagent.org
namespaceSelector:
matchExpressions:
- key: openpolicyagent.org/webhook
operator: NotIn
values:
- ignore
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["*"]
clientConfig:
caBundle: $(cat ca.crt | base64 | tr -d '\n')
service:
namespace: opa
name: opa
admissionReviewVersions: ["v1"]
sideEffects: None
EOF
Сгенерированный файл конфигурации включает представление сертификата ЦС, созданного на шаге 3 , в кодировке base64 , чтобы можно было установить соединения TLS между сервером API Kubernetes и OPA.
Следующая метка kube-system
и opa
пространство имен, чтобы OPA не контролировал ресурсы в этих пространствах имен.
kubectl label ns kube-system openpolicyagent.org/webhook=ignore
kubectl label ns opa openpolicyagent.org/webhook=ignore
Наконец, зарегистрируйте OPA в качестве контроллера доступа:
kubectl apply -f webhook-configuration.yaml
Вы можете следить за журналами OPA, чтобы увидеть запросы веб-перехватчиков, выдаваемые сервером API Kubernetes:
# ctrl-c to exit
kubectl logs -l app=opa -c opa -f
7. Применение политики ограничения имен хостов
Теперь давайте применим политику Restrict Hostnames , создав два новых пространства имен.
qa-namespace.yaml :
apiVersion: v1
kind: Namespace
metadata:
annotations:
ingress-allowlist: "*.qa.acmecorp.com,*.internal.acmecorp.com"
name: qa
производственное пространство имен.yaml :
apiVersion: v1
kind: Namespace
metadata:
annotations:
ingress-allowlist: "*.acmecorp.com"
name: production
kubectl create -f qa-namespace.yaml
kubectl create -f production-namespace.yaml
Затем определите два объекта Ingress. Один из объектов Ingress будет разрешен, а другой будет отклонен.
вход-ok.yaml :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-ok
spec:
rules:
- host: signin.acmecorp.com
http:
paths:
- pathType: ImplementationSpecific
path: /
backend:
service:
name: nginx
port:
number: 80
вход-плохой.yaml :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-bad
spec:
rules:
- host: acmecorp.com
http:
paths:
- pathType: ImplementationSpecific
path: /
backend:
service:
name: nginx
port:
number: 80
Наконец, попробуйте создать оба объекта Ingress:
kubectl create -f ingress-ok.yaml -n production
kubectl create -f ingress-bad.yaml -n qa
Второй Ingress отклонен, так как его имя хоста не соответствует белому списку в qa
пространстве имен.
Он сообщит об ошибке следующим образом:
Error from server: error when creating "ingress-bad.yaml": admission webhook "validating-webhook.openpolicyagent.org"
denied the request: invalid ingress host "acmecorp.com"
8. Применение политики запрета конфликтов имен хостов
Протестируйте политику « Запретить конфликты имен хостов», убедившись, что вы не можете создать Ingress в другом пространстве имен с тем же именем хоста, что и созданное ранее.
промежуточное пространство имен.yaml :
apiVersion: v1
kind: Namespace
metadata:
annotations:
ingress-allowlist: "*.acmecorp.com"
name: staging
kubectl create -f staging-namespace.yaml
kubectl create -f ingress-ok.yaml -n staging
Приведенная выше команда сообщит об ошибке следующим образом:
Error from server (BadRequest): error when creating "ingress-ok.yaml": admission webhook
"validate.nginx.ingress.kubernetes.io" denied the request: host "signin.acmecorp.com" and
path "/" is already defined in ingress production/ingress-ok
Заворачивать
Поздравляем с окончанием урока!
В этом руководстве показано, как можно использовать OPA для обеспечения принятия решений по управлению доступом в кластерах Kubernetes без изменения или перекомпиляции каких-либо компонентов Kubernetes. Кроме того, с помощью функции OPA Bundle политики можно периодически загружать .
Эта статья является переводом с сайта kubernetes-tutorial