
SÄ smÄningom uppstÄr sÀkerhetsfrÄgor i drift av alla system: att sÀkerstÀlla autentisering, rÀttighetsdelning, granskning och andra uppgifter. För Kubernetes har det redan skapats , som gör det möjligt att uppnÄ compliance med standarderna Àven i mycket krÀvande miljöer... Detta material Àr Àgnat Ät grundlÀggande aspekter av sÀkerhet som realiserats inom ramen för de inbyggda mekanismerna i K8s. FrÀmst kommer det vara anvÀndbart för dem som börjar bekanta sig med Kubernetes, - som en utgÄngspunkt för att studera frÄgor relaterade till sÀkerhet.
Autentisering
I Kubernetes finns det tvÄ typer av anvÀndare:
- Servicekonton â konton som hanteras av Kubernetes API;
- AnvĂ€ndare â "normala" anvĂ€ndare, som hanteras av externa, oberoende tjĂ€nster.
Den viktigaste skillnaden mellan dessa typer Àr att det finns speciella objekt i Kubernetes API för Servicekonton (de kallas just ServiceAccounts), som Àr kopplade till ett namnrymd och en uppsÀttning autentiseringsdata som lagras i klustret i objekt av typen Secrets. SÄdana anvÀndare (Service Accounts) Àr huvudsakligen avsedda för att hantera ÄtkomstrÀttigheter till Kubernetes API för processer som körs i Kubernetes-klustret.
Vanliga AnvÀndare har dÀremot inga poster i Kubernetes API: hantering av dem mÄste göras av externa mekanismer. De Àr avsedda för mÀnniskor eller processer som lever utanför klustret.
Varje begÀran till API:t Àr kopplad antingen till ett Service Account, eller till en AnvÀndare, eller betraktas som anonym.
AnvÀndarens autentiseringsuppgifter inkluderar:
- AnvĂ€ndarnamn â anvĂ€ndarnamn (beroende av versaler!);
- UID â en maskinlĂ€sbar identitetsstrĂ€ng som "Ă€r mer konsekvent och unik Ă€n anvĂ€ndarnamnet";
- Grupper â lista över grupper som anvĂ€ndaren tillhör;
- Extra â ytterligare fĂ€lt som kan anvĂ€ndas av auktoriseringmekanismen.
Kubernetes kan anvÀnda mÄnga olika autentiseringsmekanismer: X509-certifikat, Bearer-token, autentiserande proxy, HTTP Basic Auth. Genom dessa mekanismer kan mÄnga auktoriseringsscheman implementeras: frÄn en statisk fil med lösenord till OpenID OAuth2.
Dessutom tillÄts anvÀndning av flera auktoriseringsscheman samtidigt. Som standard anvÀnds följande i klustret:
- servicekontots token â för Service Accounts;
- X509 â för anvĂ€ndare.
FrÄgan om hantering av ServiceAccounts faller utanför denna artikel, och för dem som vill lÀra sig mer rekommenderar jag att börja med . Vi ska istÀllet titta nÀrmare pÄ frÄgan om X509-certifikat.
Certifikat för anvÀndare (X.509)
Det klassiska sÀttet att hantera certifikat innebÀr:
- generering av en nyckel:
mkdir -p ~/mynewuser/.certs/ openssl genrsa -out ~/.certs/mynewuser.key 2048 - generering av en certifikatförfrÄgan:
openssl req -new -key ~/mynewuser/.certs/mynewuser.key -out ~/mynewuser/.certs/mynewuser.csr -subj "/CN=mynewuser/O=company" - behandling av certifikatförfrÄgan med hjÀlp av CA-nycklarna i Kubernetes-klustret, erhÄllande av anvÀndarcertifikatet (för att fÄ certifikatet mÄste ett konto med tillgÄng till nyckeln för certifikatmyndigheten i Kubernetes-klustret anvÀndas, som som standard ligger i
/etc/kubernetes/pki/ca.key):openssl x509 -req -in ~/mynewuser/.certs/mynewuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out ~/mynewuser/.certs/mynewuser.crt -days 500 - skapa en konfigurationsfil:
- beskrivning av klustret (ange adress och plats för CA-certifikatfilen för den specifika installationen av klustret):
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.100.200:6443 - eller â som inteett rekommenderat alternativ â det gĂ„r att hoppa över rötternas certifikat (dĂ„ kommer kubectl inte att kontrollera api-serverns giltighet i klustret):
kubectl config set-cluster kubernetes --insecure-skip-tls-verify=true --server=https://192.168.100.200:6443 - lÀgga till anvÀndaren i konfigurationsfilen:
kubectl config set-credentials mynewuser --client-certificate=.certs/mynewuser.crt --client-key=.certs/mynewuser.key - lÀgga till kontext:
kubectl config set-context mynewuser-context --cluster=kubernetes --namespace=target-namespace --user=mynewuser - ange standardkontext:
kubectl config use-context mynewuser-context
- beskrivning av klustret (ange adress och plats för CA-certifikatfilen för den specifika installationen av klustret):
Efter de ovan nÀmnda ÄtgÀrderna kommer filen .kube/config att skapa en konfiguration av följande typ:
apiVersion: v1
clusters:
- cluster:
certificate-authority: /etc/kubernetes/pki/ca.crt
server: https://192.168.100.200:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
namespace: target-namespace
user: mynewuser
name: mynewuser-context
current-context: mynewuser-context
kind: Config
preferences: {}
users:
- name: mynewuser
user:
client-certificate: /home/mynewuser/.certs/mynewuser.crt
client-key: /home/mynewuser/.certs/mynewuser.keyFör att underlÀtta överföringen av konfigurationen mellan konton och servrar Àr det anvÀndbart att redigera vÀrdena för följande nycklar:
-
certificate-authority -
client-certificate -
client-key
För detta kan man koda de angivna filerna med hjÀlp av base64 och skriva in dem i konfigurationen, genom att lÀgga till suffixet -data, dvs. fÄ certificate-authority-data och sÄ vidare.
Certifikat med kubeadm
Med releasen att arbete med certifikat har blivit mycket enklare tack vare alpha-versionen av dess stöd i . HÀr Àr ett exempel pÄ hur konfigurationen för anvÀndarens nycklar kan se ut:
kubeadm alpha kubeconfig user --client-name=mynewuser --apiserver-advertise-address 192.168.100.200 NB: Den nödvÀndiga advertise address kan ses i konfigurationen av api-servern, som som standard ligger i /etc/kubernetes/manifests/kube-apiserver.yaml.
Den resulterande konfigurationen kommer att skrivas ut i stdout. Den mÄste sparas i ~/.kube/config anvÀndarkontot eller i en fil som anges i miljövariabeln KUBECONFIG.
GrÀva djupare
För den som vill gÄ djupare in i de beskrivna frÄgorna:
- om arbete med certifikat i den officiella Kubernetes-dokumentationen;
- , som tar upp certifikatfrÄgan ur praktisk synvinkel.
- om autentisering i Kubernetes.
Behörighet
Det autentiserade kontot har som standard inga rÀttigheter att agera i klustret. För att ge behörigheter i Kubernetes finns en behörighetsmekanism.
Före version 1.6 anvÀndes en behörighetstyp som kallas ABAC (Attributbaserad Ätkomstkontroll). Mer information om detta finns i . Denna metod anses idag vara förÄldrad (legacy), men du kan fortfarande anvÀnda den samtidigt med andra behörighetstyper.
Det aktuella (och mer flexibla) sÀttet att dela upp ÄtkomstrÀttigheter till klustret kallas RBAC (). Den introducerades som stabil i version . RBAC implementerar en rÀttighetsmodell dÀr allt som inte Àr uttryckligen tillÄtet Àr förbjudet.
För att aktivera RBAC, mÄste du köra Kubernetes api-server med parametern --authorization-mode=RBAC. Parametrarna stÀlls in i manifestet för konfigureringen av api-servern, som som standard ligger pÄ vÀgen /etc/kubernetes/manifests/kube-apiserver.yaml, i avsnittet command. Men i alla fall Àr RBAC som standard redan aktiverat, sÄ det Àr förmodligen inget att oroa sig för: detta kan bekrÀftas av vÀrdet authorization-mode (i den redan nÀmnda kube-apiserver.yaml). För övrigt kan det finnas andra typer av behörighet bland dess vÀrden (node, webhook, always allow), men vi lÀmnar deras behandling utanför detta material.
För övrigt har vi redan publicerat en tillrÀckligt detaljerad beskrivning av principerna och sÀrskiljningarna av arbetet med RBAC, sÄ jag begrÀnsar mig hÀr till en kort upprÀkning av grunderna och exempel.
För hantering av Ätkomst i Kubernetes via RBAC anvÀnds följande API-entiteter:
-
RollochClusterRoleâ roller som anvĂ€nds för att beskriva Ă„tkomstrĂ€ttigheter: -
Rollmöjliggör att beskriva rÀttigheter inom ett namnrymde; -
ClusterRoleâ inom klustret, inklusive kluster-specifika objekt som noder, non-resources urls (dvs. inte relaterade till Kubernetes-resurser â till exempel,/version,/logs,/api*); -
RoleBindingochClusterRoleBindingâ anvĂ€nds för att bindaRollochClusterRoletill en anvĂ€ndare, anvĂ€ndargrupp eller ServiceAccount.
Entiteterna Role och RoleBinding Àr begrÀnsade till namnrymden, dvs. de mÄste vara inom samma namnrymd. Men RoleBinding kan referera till ClusterRole, vilket möjliggör skapandet av en uppsÀttning typiska behörigheter och hantering av Ätkomst med hjÀlp av dessa.
Roller beskriver behörigheter med hjÀlp av uppsÀttningar regler som innehÄller:
- API-grupper â se om apiGroups och kommandot
kubectl api-resources; - resurser (resources:
pod,namnrymd,deploymentoch liknande); - verb (verbs:
set,updateoch liknande). - resursnamn (
resourceNames) â för fall nĂ€r det Ă€r nödvĂ€ndigt att ge Ă„tkomst till en specifik resurs, inte alla resurser av den typen.
En mer detaljerad genomgĂ„ng av autentisering i Kubernetes kan hittas pĂ„ sidan . IstĂ€llet för detta (eller snarare â som tillĂ€gg till detta) fĂ„r ni exempel som illustrerar dess funktion.
Exempel pÄ RBAC-enheter
En enkel Roll, som tillÄter att fÄ lista och status pÄ poddar och övervaka dem i namnrymden target-namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: target-namespace
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"] Exempel ClusterRole, vilket möjliggör att fÄ lista och status pÄ poddar och övervaka dem i hela klustret:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# avsnittet "namespace" finns inte, eftersom ClusterRole anvÀnds för hela klustret
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"] Exempel RoleBinding, vilket ger anvÀndaren mynewuser "lÀsa" poddar i namnrymden my-namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: target-namespace
subjects:
- kind: User
name: mynewuser # anvÀndarnamn Àr skiftlÀgeskÀnsligt!
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role # hĂ€r bör vara âRoleâ eller âClusterRoleâ
name: pod-reader # namnet pÄ Role som finns i samma namnrymd,
# eller namnet pÄ ClusterRole vars anvÀndning
# vi vill tillÄta för anvÀndaren
apiGroup: rbac.authorization.k8s.ioHĂ€ndelsegranskning
Schematisk kan Kubernetes-arkitekturen representeras som följande:

Den centrala komponenten i Kubernetes som Àr ansvarig för att bearbeta förfrÄgningar Àr api-server. Alla operationer med klustret gÄr genom det. Mer om dessa interna mekanismer kan lÀsas i artikeln "».
Systemaudit Àr en intressant funktion i Kubernetes som som standard Àr avstÀngd. Den gör det möjligt att logga alla anrop till Kubernetes API. Som man lÀtt kan förstÄ, görs alla ÄtgÀrder relaterade till kontroll och förÀndring av klustrets tillstÄnd via detta API. En bra beskrivning av dess möjligheter kan (som vanligt) hittas i K8s. Nedan kommer jag att försöka förklara Àmnet pÄ ett enklare sÀtt.
SÄ, För att aktivera audit, mÄste vi överföra tre obligatoriska parametrar till containern i api-servern, mer om dem finns nedan:
-
--audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml -
--audit-log-path=/var/log/kube-audit/audit.log -
--audit-log-format=json
Förutom dessa tre nödvÀndiga parametrar finns det mÄnga ytterligare instÀllningar relaterade till audit: frÄn loggrotation till beskrivningar av webhook. HÀr Àr ett exempel pÄ loggrotationsparametrar:
-
--audit-log-maxbackup=10 -
--audit-log-maxsize=100 -
--audit-log-maxage=7
Men vi kommer inte att gĂ„ djupare in pĂ„ dem â alla detaljer kan hittas i .
Som redan nÀmnts stÀlls alla parametrar in i manifestet med konfigurationen av api-servern (som standard /etc/kubernetes/manifests/kube-apiserver.yaml), i sektionen command. LÄt oss ÄtervÀnda till de tre obligatoriska parametrarna och gÄ igenom dem:
-
audit-policy-fileâ sökvĂ€g till YAML-filen med beskrivningen av audit policyn. Vi kommer tillbaka till dess innehĂ„ll, men lĂ„t mig pĂ„peka att filen mĂ„ste vara lĂ€sbar för processen api-server. DĂ€rför mĂ„ste den monteras inuti containern, vilket kan göras genom att lĂ€gga till följande kod i de relevanta sektionerna av konfigurationsfilen:volumeMounts: - mountPath: /etc/kubernetes/policies name: policies readOnly: true volumes: - hostPath: path: /etc/kubernetes/policies type: DirectoryOrCreate name: policies -
audit-log-pathâ sökvĂ€g till loggfilen. SökvĂ€gen mĂ„ste ocksĂ„ vara tillgĂ€nglig för processen api-server, sĂ„ vi beskriver ocksĂ„ dess montering:volumeMounts: - mountPath: /var/log/kube-audit name: logs readOnly: false volumes: - hostPath: path: /var/log/kube-audit type: DirectoryOrCreate name: logs -
audit-log-formatâ formatet för auditloggen. Som standard Ă€r dettajson, men det finns ocksĂ„ ett förĂ„ldrat textformat (legacy).
Auditpolicy
Nu om den nĂ€mnda filen med beskrivningen av loggningspolicyn. Det första begreppet audit policy â Ă€r detta nivĂ„, loggningsnivĂ„. Dessa kan vara följande:
-
Noneâ ingen loggning; -
Metadataâ logga metadata om begĂ€ran: anvĂ€ndare, tid för begĂ€ran, mĂ„linnehĂ„llet (pod, namespace osv.), typ av Ă„tgĂ€rd (verb) osv.; -
BegĂ€ranâ logga metadata och kropp av begĂ€ran; -
BegĂ€ranSvarâ logga metadata, kropp av begĂ€ran och kropp av svar.
De senaste tvÄ nivÄerna (BegÀran och BegÀranSvar) loggar inte begÀrningar som inte har riktat sig mot resurser (begÀrningar till sÄ kallade non-resources urls).
Dessutom passerar alla begÀrningar genom flera stadier:
-
BegĂ€ranMottagenâ steg dĂ€r begĂ€ran har mottagits av hanteraren och inte har vidarebefordrats i kedjan av hanterare; -
SvarStartadâ svaret har skickats, men före kroppens svar. Genereras för lĂ„nga begĂ€rningar (till exempel,övervaka); -
SvarFullstĂ€ndigâ svarskroppen har skickats, mer information kommer inte att skickas; -
Panikâ hĂ€ndelser genereras nĂ€r ett avvikande tillstĂ„nd upptĂ€ckts.
För att hoppa över vissa stadier kan man anvĂ€nda hoppaĂverStadier.
I policydokumentet kan vi beskriva flera sektioner med olika loggnivÄer. Den första lÀmpliga regeln som hittas i beskrivningen av policyn kommer att tillÀmpas.
Demon kubelet övervakar Àndringar i manifestet med konfigurationen för api-servern och nÀr sÄdana upptÀckts, startar den om containern med api-servern. Men det finns en viktig detalj: Àndringar i policyn kommer att ignoreras av dem.Efter att ha gjort Àndringar i policydokumentet krÀvs det att man startar om api-servern manuellt. Eftersom api-servern har startats som , kommandot kubectl ta bort kommer inte att leda till att den startas om. Man mÄste manuellt göra docker stop pÄ kube-master dÀr revisionspolicyn har Àndrats:
docker stop $(docker ps | grep k8s_kube-apiserver | awk '{print $1}')Vid aktivering av revisionen Àr det viktigt att komma ihÄg att belastningen pÄ kube-apiservern ökar.. FöretrÀdesvis ökar minnesanvÀndningen för att lagra begÀrningskontext. Loggningen börjar först efter att svaret har skickats. Belastningen beror ocksÄ pÄ konfigurationen av revisionspolicyn.
Exempel pÄ policyer
LÄt oss gÄ igenom strukturen av policydokumenten med exempel.
HÀr Àr en enkel fil policy, för att logga allt pÄ nivÄ Metadata:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata I policyn kan man ange en lista med anvÀndare (AnvÀndare och ServiceAccounts) och anvÀndargrupper. Till exempel, sÄ hÀr kommer vi att ignorera systemanvÀndare, men logga allt annat pÄ nivÄ BegÀran:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: None
userGroups:
- "system:serviceaccounts"
- "system:nodes"
users:
- "system:anonymous"
- "system:apiserver"
- "system:kube-controller-manager"
- "system:kube-scheduler"
- level: RequestDet finns ocksÄ möjlighet att beskriva mÄl:
- namnrymder (
namnrymder); - verb (verbs:
hÀmta,update,ta bortoch andra); - resurser (resources, nÀmligen:
pod,configmapsoch sÄ vidare) och resursgrupper (apiGroups).
Observera! Resurser och resursgrupper (API-grupper, dvs. apiGroups), samt deras versioner som Àr installerade i klustret, kan hÀmtas med kommandona:
kubectl api-resources
kubectl api-versionsFöljande audit policy ges som en demonstration av bÀsta praxis i :
apiVersion: audit.k8s.io/v1beta1
kind: Policy
# Utesluta loggning av steget RequestReceived
omitStages:
- "RequestReceived"
rules:
# Utesluta loggning av hÀndelser som bedöms som obetydliga och ofarliga:
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # detta Àr api-gruppen med ett tomt namn, som hör till
# de grundlĂ€ggande resurserna i Kubernetes, kallade âcoreâ
resources: ["endpoints", "services"]
- level: None
users: ["system:unsecured"]
namespaces: ["kube-system"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["configmaps"]
- level: None
users: ["kubelet"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes"]
- level: None
users:
- system:kube-controller-manager
- system:kube-scheduler
- system:serviceaccount:kube-system:endpoint-controller
verbs: ["get", "update"]
namespaces: ["kube-system"]
resources:
- group: "" # core
resources: ["endpoints"]
- level: None
users: ["system:apiserver"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["namespaces"]
# Utesluta loggning av anrop till read-only URLs:
- level: None
nonResourceURLs:
- /healthz*
- /version
- /swagger*
# Utesluta loggning av meddelanden som rör resurstypen âeventsâ:
- level: None
resources:
- group: "" # core
resources: ["events"]
# Resurser av typ Secret, ConfigMap och TokenReview kan innehÄlla hemliga data,
# sÄ vi loggar endast metadata relaterade till dessa begÀrningar
- level: Metadata
resources:
- group: "" # core
resources: ["secrets", "configmaps"]
- group: authentication.k8s.io
resources: ["tokenreviews"]
# Ă
tgÀrder av typen get, list och watch kan vara resurskrÀvande; vi loggar inte dem
- level: Request
verbs: ["get", "list", "watch"]
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
# Standard loggnivÄ för standard API-resurser
- level: RequestResponse
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "networking.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
# Standard loggnivÄ för alla andra förfrÄgningar
- level: MetadataEtt annat bra exempel pĂ„ audit policy â .
För att snabbt kunna reagera pÄ audit-hÀndelser finns möjligheten att beskriva en webhook. Denna frÄga beskrivs i , jag kommer att lÀmna det utanför denna artikel.
Sammanfattning
Artikeln ger en översikt över sĂ€kerhetsmekanismerna i Kubernetes-kluster som möjliggör skapandet av personliga anvĂ€ndarkonton, separation av deras rĂ€ttigheter och registrering av deras aktiviteter. Jag hoppas att det kommer att vara till hjĂ€lp för dem som har stött pĂ„ sĂ„dana frĂ„gor i teorin eller redan i praktiken. Jag rekommenderar ocksĂ„ att lĂ€sa igenom listan över andra resurser om sĂ€kerhet i Kubernetes som anges i "P.S.", â kanske finner du i dem de nödvĂ€ndiga detaljerna om aktuella problem.
P.S.
LÀs Àven i vÄr blogg:
- «»;
- «»;
- «»;
- «»;
- «».
KĂ€lla: habr.com
