Азбука бяспекі ў Kubernetes: аўтэнтыфікацыя, аўтарызацыя, аўдыт
Рана ці позна ў эксплуатацыі любой сістэмы ўстае пытанне бяспекі: забеспячэнні аўтэнтыфікацыі, падзелы мае рацыю, аўдыту і іншых задач. Для Kubernetes ужо створана мноства рашэнняў, якія дазваляюць дамагчыся адпаведнасці стандартам нават у вельмі патрабавальных асяродках… Гэты ж матэрыял прысвечаны базавым аспектам бяспекі, рэалізаваным у рамках убудаваных механізмаў K8s. У першую чаргу ён будзе карысны тым, хто пачынае знаёміцца з Kubernetes, - як адпраўная кропка для вывучэння пытанняў, звязаных з бяспекай.
аўтэнтыфікацыя
У Kubernetes ёсць два тыпы карыстальнікаў:
Сэрвісныя акаўнты - Акаўнты, якія кіруюцца Kubernetes API;
Асноўнае адрозненне гэтых тыпаў у тым, што для Service Accounts існуюць спецыяльныя аб'екты ў Kubernetes API (яны так і называюцца - ServiceAccounts), якія прывязаны да прасторы імёнаў і набору аўтарызацыйных дадзеных, якія захоўваюцца ў кластары ў аб'ектах тыпу Secrets. Такія карыстальнікі (Service Accounts) прызначаны ў асноўным для кіравання правамі доступу да Kubernetes API працэсаў, якія працуюць у кластары Kubernetes.
Звычайныя ж Users не маюць запісаў у Kubernetes API: кіраванне імі павінна ажыццяўляцца вонкавымі механізмамі. Яны прызначаны для людзей або працэсаў, якія жывуць па-за кластарам.
Кожны запыт да API прывязаны альбо да Service Account, альбо да User, альбо лічыцца ананімным.
Аўтэнтыфікацыйныя дадзеныя карыстальніка ўключаюць у сябе:
Імя карыстальніка - імя карыстальніка (залежыць ад рэгістра!);
UID — машынна-чытаемы радок ідэнтыфікацыі карыстальніка, які «больш кансістэнтны і ўнікальны, чым імя карыстальніка»;
груп - спіс груп, да якіх належыць карыстальнік;
экстра - Дадатковыя палі, якія могуць быць выкарыстаны механізмам аўтарызацыі.
Kubernetes можа выкарыстоўваць вялікую колькасць механізмаў аўтэнтыфікацыі: сертыфікаты X509, Bearer-токены, які аўтэнтыфікуе проксі, HTTP Basic Auth. Пры дапамозе гэтых механізмаў можна рэалізаваць вялікую колькасць схем аўтарызацыі: ад статычнага файла з паролямі да OpenID OAuth2.
Больш за тое, дапускаецца выкарыстанне некалькіх схем аўтарызацыі адначасова. Па змаўчанні ў кластары выкарыстоўваюцца:
service account tokens - для Service Accounts;
X509 - для Users.
Пытанне пра кіраванне ServiceAccounts выходзіць за рамкі дадзенага артыкула, а жадаючым падрабязней азнаёміцца з гэтым пытаннем рэкамендую пачаць са старонкі афіцыйнай дакументацыі. Мы ж разгледзім падрабязней пытанне працы сертыфікатаў X509.
апрацоўку запыту на сертыфікат пры дапамозе ключоў CA кластара Kubernetes, атрыманне сертыфіката карыстальніка (для атрымання сертыфіката трэба выкарыстоўваць уліковы запіс, які мае доступ да ключа цэнтра сертыфікацыі кластара Kubernetes, які па змаўчанні знаходзіцца ў /etc/kubernetes/pki/ca.key):
Для палягчэння пераносу канфіга паміж уліковымі запісамі і серверамі карысна адрэдагаваць значэнні наступных ключоў:
certificate-authority
client-certificate
client-key
Для гэтага можна закадаваць паказаныя ў іх файлы пры дапамозе base64 і прапісаць іх у канфігу, дадаўшы ў назву ключоў суфікс. -data, г.зн. атрымаўшы certificate-authority-data і да т.п.
Сертыфікаты з kubeadm
З рэлізам Кубернетэс 1.15 праца з сертыфікатамі стала значна прасцей дзякуючы альфа-версіі яе падтрымкі ў утыліце kubeadm. Напрыклад, вось як зараз можа выглядаць генерацыя канфігурацыйнага файла з ключамі карыстача:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200
NB: Патрабаваны advertise address можна паглядзець у канфігу api-server, які па змаўчанні размешчаны ў /etc/kubernetes/manifests/kube-apiserver.yaml.
Выніковы канфіг будзе выведзены ў stdout. Яго трэба захаваць у ~/.kube/config ўліковага запісу карыстальніка ці ж у файл, пазначаны ў зменнай асяроддзі KUBECONFIG.
Капнуць глыбей
Для жадаючых больш старанна разабрацца ў апісаных пытаннях:
асобны артыкул па рабоце з сертыфікатамі ў афіцыйнай дакументацыі Kubernetes;
Аўтарызаваны ўліковы запіс па змаўчанні не мае правоў на дзеянні ў кластары. Для прадастаўлення дазволаў у Kubernetes рэалізаваны механізм аўтарызацыі.
Да версіі 1.6 у Kubernetes ужываўся тып аўтарызацыі, званы ABAC (Attribute-based access control). Падрабязнасці аб ім можна знайсці ў афіцыйнай дакументацыі. У наш час гэты падыход лічыцца састарэлым (legacy), аднак вы ўсё яшчэ можаце выкарыстоўваць яго адначасова з іншымі тыпамі аўтарызацыі.
Актуальны ж (і больш гнуткі) спосаб падзелу правоў доступу да кластара завецца РБАК (Кантроль доступу на аснове роляў). Ён быў аб'яўлены стабільным з версіі Кубернетэс 1.8. RBAC рэалізуе мадэль правоў, у якой забаронена ўсё, што не дазволена відавочна. Каб уключыць RBAC, трэба запусціць Kubernetes api-server з параметрам --authorization-mode=RBAC. Параметры выстаўляюцца ў маніфесце з канфігурацыяй api-server, якая па змаўчанні знаходзіцца па дарозе /etc/kubernetes/manifests/kube-apiserver.yaml, у секцыі command. Зрэшты, па змаўчанні RBAC і так уключаны, таму хутчэй за ўсё турбавацца аб гэтым не варта: пераканацца ў гэтым можна па значэнні authorization-mode (ва ўжо згаданым kube-apiserver.yaml). Дарэчы, сярод яго значэнняў могуць аказацца і іншыя тыпы аўтарызацыі.node, webhook, always allow), але іх разгляд пакінем за рамкамі матэрыялу.
Дарэчы, мы ўжо публікавалі артыкул з досыць падрабязным аповядам аб прынцыпах і асаблівасцях працы з RBAC, таму далей абмяжуюся кароткім пералікам асноў і прыкладаў.
Для кіравання доступам у Kubernetes праз RBAC выкарыстоўваюцца наступныя сутнасці API:
Role и ClusterRole - ролі, якія служаць для апісання правоў доступу:
Role дазваляе апісаць правы ў рамках прасторы імён;
ClusterRole - у рамках кластара, у тым ліку да кластар-спецыфічных аб'ектаў тыпу вузлоў, non-resources urls (г.зн. не звязаных з рэсурсамі Kubernetes - напрыклад, /version, /logs, /api*);
RoleBinding и ClusterRoleBinding - служыць для прывязкі Role и ClusterRole да карыстача, групы карыстальнікаў або ServiceAccount.
Сутнасці Role і RoleBinding з'яўляюцца абмежаванымі namespace'ам, г.зн. павінны знаходзіцца ў межах адной прасторы імёнаў. Аднак RoleBinding можа спасылацца на ClusterRole, што дазваляе стварыць набор тыпавых дазволаў і кіраваць доступам з іх дапамогай.
Ролі апісваюць правы пры дапамозе набораў правіл, якія змяшчаюць:
рэсурсы (рэсурсы: pod, namespace, deployment і да т.п.);
дзеясловы (Дзеясловы: set, update і да т.п.).
імёны рэсурсаў (resourceNames) - для выпадку, калі трэба даць доступ да нейкага вызначанага рэсурсу, а не да ўсіх рэсурсаў гэтага тыпу.
Больш падрабязны разбор аўтарызацыі ў Kubernetes можна знайсці на старонцы афіцыйнай дакументацыі. Замест гэтага (а дакладней - у дадатак да гэтага) прывяду прыклады, якія ілюструюць яе працу.
Прыклады сутнасцяў RBAC
простая Role, якая дазваляе атрымліваць спіс і статус pod'аў і сачыць за імі ў прасторы імёнаў target-namespace:
Прыклад ClusterRole, што дазваляе атрымліваць спіс і статус pod'аў і сачыць за імі ва ўсім кластары:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# секции "namespace" нет, так как ClusterRole задействует весь кластер
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Прыклад RoleBinding, што дазваляе карыстачу mynewuser "чытаць" pod'ы ў прасторы імёнаў my-namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: target-namespace
subjects:
- kind: User
name: mynewuser # имя пользователя зависимо от регистра!
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # здесь должно быть “Role” или “ClusterRole”
name: pod-reader # имя Role, что находится в том же namespace,
# или имя ClusterRole, использование которой
# хотим разрешить пользователю
apiGroup: rbac.authorization.k8s.io
Аўдыт падзей
Схематычна архітэктуру Kubernetes можна ўявіць наступным чынам:
Ключавы кампанент Kubernetes, які адказвае за апрацоўку запытаў, - api-server. Усе аперацыі над кластарам праходзяць праз яго. Падрабязней пра гэтыя ўнутраныя механізмы можна пачытаць у артыкуле «Што адбываецца ў Kubernetes пры запуску kubectl run?.
Аўдыт сістэмы - цікавая фіча ў Kubernetes, якая па змаўчанні выключана. Яна дазваляе лагіраваць усе звароты да Kubernetes API. Як лёгка здагадацца, праз гэты API вырабляюцца ўсе дзеянні, злучаныя з кантролем і зменай стану кластара. Добрае апісанне яе магчымасцяў можна (як звычайна) знайсці ў афіцыйнай дакументацыі K8s. Далей я пастараюся выказаць тэму больш простай мовай.
Такім чынам, каб уключыць аўдыт, нам трэба перадаць кантэйнеру ў api-server тры абавязковыя параметры, падрабязней пра якія расказана ніжэй:
Апроч гэтых трох неабходных параметраў, існуе мноства дадатковых налад, якія адносяцца да аўдыту: ад ратацыі логаў да апісанняў webhook. Прыклад параметраў ратацыі логаў:
Як ужо згадвалася, усе параметры выстаўляюцца ў маніфесце са канфігурацыяй api-server (па змаўчанні /etc/kubernetes/manifests/kube-apiserver.yaml), у секцыі command. Вернемся да 3 абавязковых параметраў і разбяром іх:
audit-policy-file - шлях да YAML-файла з апісаннем палітыкі (policy) аўдыту. Да яго зместу мы яшчэ вернемся, а пакуль заўважу, што файл павінен быць даступны для чытання працэсам api-server'а. Таму неабходна змантаваць яго ўнутр кантэйнера, для чаго можна дадаць наступны код у адпаведныя секцыі канфіга:
audit-log-format - Фармат лога аўдыту. Па змаўчанні гэта json, але даступны і састарэлы тэкставы фармат (legacy).
Палітыка аўдыту
Зараз аб згаданым файле з апісаннем палітыкі лагіравання. Першае паняцце audit policy - гэта level, узровень лагіравання. Яны бываюць наступнымі:
None - не лагіраваць;
Metadata - лагіраваць метададзеныя запыту: карыстальніка, час запыту, мэтавы рэсурс (pod, namespace і да т.п.), тып дзеяння (verb) і да т.п.;
Request - лагіраваць метададзеныя і цела запыту;
RequestResponse - Лагаваць метададзеныя, цела запыту і цела адказу.
Апошнія два ўзроўні (Request и RequestResponse) не лагіруюць запыты, якія не звярталіся да рэсурсаў (звароты да так званых non-resources urls).
Таксама ўсе запыты праходзяць праз некалькі стадый:
RequestReceived - этап, калі запыт атрыманы апрацоўшчыкам і яшчэ не перададзены далей па ланцужку апрацоўшчыкаў;
ResponseStarted - загалоўкі адказу адпраўленыя, але перад адпраўкай цела адказу. Генеруецца для працяглых запытаў (напрыклад, watch);
ResponseComplete - цела адказу адпраўлена, больш інфармацыі адпраўляцца не будзе;
Panic - падзеі генеруюцца, калі выяўлена няштатная сітуацыя.
Для пропуску якіх-небудзь стадый можна выкарыстоўваць omitStages.
У файле палітыкі мы можам апісаць некалькі секцый з рознымі ўзроўнямі лагіравання. Прымяняцца будзе першае прыдатнае правіла, знойдзенае ў апісанні policy.
Дэман kubelet адсочвае змену маніфесту з канфігурацыяй api-server і пры выяўленні такіх перазапускае кантэйнер з api-server. Але ёсць важная дэталь: змены ў файле policy будуць ім ігнаравацца. Пасля занясення змен у файл policy запатрабуецца перазапусціць api-server уручную. Паколькі api-server запушчаны як static pod, каманда kubectl delete не прывядзе да яго перазапуску. Прыйдзецца ўручную зрабіць docker stop на kube-master'ах, дзе зменена палітыка аўдыту:
Пры ўключэнні аўдыту важна памятаць, што на kube-apiserver павялічваецца нагрузка. У прыватнасці, павялічваецца спажыванне памяці для захоўвання кантэксту запытаў. Запіс у лог пачынаецца толькі пасля адпраўкі загалоўка адказу. Таксама нагрузка залежыць ад канфігурацыі палітыкі аўдыту.
Прыклады палітык
Разбяром структуру файлаў policy на прыкладах.
Вось просты файл policy, каб лагіраваць усё на ўзроўні Metadata:
У policy можна ўказваць пералік карыстальнікаў (Users и ServiceAccounts) і груп карыстальнікаў. Напрыклад, вось так мы будзем праігнараваць сістэмных карыстальнікаў, але лагіраваць усё астатняе на ўзроўні Request:
дзеясловы (Дзеясловы: get, update, delete і іншыя);
рэсурсы (рэсурсы, А менавіта: pod, configmaps і да т.п.) і групы рэсурсаў (apiGroups).
Звярніце ўвагу! Рэсурсы і групы рэсурсаў (групы API, г.зн. apiGroups), а таксама іх версіі, усталяваныя ў кластары, можна атрымаць пры дапамозе каманд:
Для аператыўнага рэагавання на падзеі аўдыту ёсць магчымасць апісаць webhook. Гэтае пытанне расчынена ў афіцыйнай дакументацыі, пакіну яго за рамкамі дадзенага артыкула.
Вынікі
У артыкуле дадзены агляд механізмаў базавага забеспячэння бяспекі ў кластарах Kubernetes, якія дазваляюць ствараць персаніфікаваныя ўліковыя запісы карыстальнікам, падзяляць іх правы, а таксама рэгістраваць іх дзеянні. Спадзяюся, ён спатрэбіцца тым, хто сутыкнуўся з такімі пытаннямі ў тэорыі ці ўжо на практыцы. Рэкамендую таксама азнаёміцца са спісам іншых матэрыялаў па тэме бяспекі ў Kubernetes, што прыведзены ў «PS», - магчыма, сярод іх вы знойдзеце патрэбныя падрабязнасці па актуальных для вас праблемах.