Kubernetes pods/exec
Kubernetes pods/exec #
pods/exec
— удобный способ выполнять команды внутри контейнера для отладки и администрирования. Но
вот вам сходу задача: как вы считаете, насколько безопасна вот такая роль в Kubernetes, которую можно выдать
любому пользователю, предположив абсурдную ситуацию, что ресурс Secret в кластере не используется?

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: test-role
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["get"]
Если вы ответили «безопасная», то вы не одиноки — и вы предоставили бы доступ к pods/exec
любому
пользователю в кластере, конечно если бы создали сверху ClusterRolebinding.
Оглавление
- Что изменилось
- Влияние на kubectl и RBAC
- Проверка на Minikube
- Демонстрация (kubectl 1.33.3 vs 1.29.0)
- Итоги и рекомендации
Что изменилось
На самом деле — ничего. Проблеме уже больше 7 лет, но о ней мало кто знает. Проблема заключается в том, что в головах умных мужей укоренилась мысль, что доступ к pods/exec
можно дать вот таким простым правилом:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: test-role
rules:
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
В принципе вы были бы правы, но, как показала практика — не только =)
Первое упоминание о проблеме мне помогли найти ребята из ever_secure:
kubernetes RBAC role verbs to exec to pod
I had to add the verb "get" to my pods/exec section as well since the client library I'm using is doing an http GET to negotiate a websocket first. Using kubectl it sends an http POST and requires the "create" verb in that case. It may be worth updating this example to include the "get" verb.
То есть, уже 7 лет назад был тревожный звоночек: kubectl exec
может работать не только через POST, но и через GET.
Это окончательно подтвердилось после перехода kubectl
на WebSocket в версии 1.31, где теперь kubectl exec
использует GET для установления соединения, а не POST по умолчанию.
Источник: Streaming Transitions from SPDY to WebSockets
Влияние на kubectl и RBAC
Чтобы понять, почему теперь нужен get
, надо разобраться, как HTTP-методы отображаются в Kubernetes verbs:
HTTP-метод | Kubernetes verb |
---|---|
GET | get |
POST | create |
PUT | update |
DELETE | delete |
Некоторые клиенты используют GET для установки WebSocket-соединения с pods/exec, а не POST, как kubectl. Поэтому для работы exec может потребоваться не только create, но и get в RBAC.