Учебное пособие. Входная проверка

by moiseevrus

Шаги

Чтобы внедрить правила управления допуском, которые проверяют ресурсы 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

 

You may also like

Leave a Comment