← [Раздел](README.md) · [Главная](../README.md)

# Lab 03 — Kubernetes RBAC и NetworkPolicy

## Цель

В локальном кластере создать namespace с **ограниченным RBAC** (разработчик не может читать secrets) и **NetworkPolicy** (запрет исходящего трафика кроме DNS), проверить deny/allow поведение.

## Предварительно

- `kubectl`, `kind` (или minikube).
- ~1 ГБ RAM свободно.

## Время

~60 минут.

## Шаг 1 — Кластер

```bash
kind create cluster --name lab03
kubectl cluster-info
```

## Шаг 2 — Namespace и приложение

```bash
kubectl create namespace learn-shop
kubectl create deployment api --image=nginx:alpine -n learn-shop
kubectl expose deployment api --port=80 -n learn-shop
kubectl get all -n learn-shop
```

## Шаг 3 — ServiceAccount для «разработчика»

`sa-developer.yaml`:

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: developer
  namespace: learn-shop
```

```bash
kubectl apply -f sa-developer.yaml
```

## Шаг 4 — Role без доступа к secrets

`role-developer.yaml`:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer-limited
  namespace: learn-shop
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "services", "configmaps"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch"]
```

`rolebinding-developer.yaml`:

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-limited-binding
  namespace: learn-shop
subjects:
  - kind: ServiceAccount
    name: developer
    namespace: learn-shop
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: developer-limited
```

```bash
kubectl apply -f role-developer.yaml -f rolebinding-developer.yaml
```

## Шаг 5 — Учебный secret

```bash
kubectl create secret generic db-creds \
  --from-literal=password=CHANGEME-DEMO-ONLY \
  -n learn-shop
```

## Шаг 6 — Проверка RBAC

```bash
# Должно работать: список pods
kubectl auth can-i list pods -n learn-shop --as=system:serviceaccount:learn-shop:developer

# Должно быть no: чтение secrets
kubectl auth can-i get secrets -n learn-shop --as=system:serviceaccount:learn-shop:developer
```

Ожидаемый вывод: `yes` и `no`.

Попытка от имени SA (через impersonation):

```bash
kubectl get secret db-creds -n learn-shop \
  --as=system:serviceaccount:learn-shop:developer
```

Должна быть ошибка `Forbidden`.

## Шаг 7 — NetworkPolicy deny-all egress

`netpol-default-deny.yaml`:

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: learn-shop
spec:
  podSelector: {}
  policyTypes:
    - Egress
```

`netpol-allow-dns.yaml`:

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: learn-shop
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
```

```bash
kubectl label namespace kube-system kubernetes.io/metadata.name=kube-system --overwrite
kubectl apply -f netpol-default-deny.yaml -f netpol-allow-dns.yaml
```

> **Примечание:** в kind CNI по умолчанию поддерживает NetworkPolicy (kindnet). Если egress-тест не блокируется — проверьте версию kind и документацию CNI.

## Шаг 8 — Тест сети из pod

```bash
kubectl run nettest --rm -it --image=busybox:1.36 -n learn-shop -- sh
```

Внутри shell:

```sh
nslookup kubernetes.default
wget -qO- --timeout=3 http://example.com || echo "wget failed as expected"
```

DNS может работать; HTTP наружу — должен **таймаутиться** при корректной политике.

Выйдите: `exit`.

## Шаг 9 — Документирование

Заполните мини-отчёт:

| Контроль | Реализация | Результат проверки |
|----------|------------|-------------------|
| Least privilege RBAC | Role `developer-limited` | `can-i get secrets` = no |
| Egress restriction | default-deny + DNS | wget example.com fail |

## Очистка

```bash
kind delete cluster --name lab03
```

## Критерии успеха

- [ ] SA developer не читает secrets.
- [ ] NetworkPolicy применены без ошибки.
- [ ] Выполнен тест из pod.

## Самопроверка

1. Разница Role и ClusterRole?
2. Зачем отдельная политика на DNS?
3. Кто в prod должен иметь доступ к `get secrets`?
4. Как NetworkPolicy связана с ISO контролем сегментации сети?

## Дальше

[Lab 04 — tabletop инцидента](lab-04-incident-tabletop.md)
