Pavel Selivanov, architect des solutions chez Southbridge et instructeur de Slurm, a présenté une conférence à DevOpsConf 2019. Cette conférence fait partie d'un des sujets approfondis du cours sur Kubernetes « Slurm Mega ».
se déroule à Moscou du 18 au 20 novembre.
â Moscou, du 22 au 24 novembre.
sont toujours disponibles.

Sous le lien â transcription de la confĂ©rence.
Bonjour à tous, collÚgues et sympathisants. Aujourd'hui, je vais parler de la sécurité.
Je constate qu'il y a beaucoup de spécialistes de la sécurité dans la salle aujourd'hui. Je m'excuse à l'avance si j'utilise des termes du domaine de la sécurité qui ne sont pas conformes à vos habitudes.
Il se trouve qu'il y a environ six mois, j'ai eu entre les mains un cluster Kubernetes public. Public â cela signifie qu'il y a un certain nombre d'espaces de noms, dans lesquels il y a des utilisateurs, isolĂ©s dans leur propre espace de noms. Tous ces utilisateurs appartiennent Ă diffĂ©rentes entreprises. Eh bien, il Ă©tait prĂ©vu d'utiliser ce cluster comme CDN. C'est-Ă -dire qu'on vous donne un cluster, on vous attribue un utilisateur, vous arrivez dans votre espace de noms et dĂ©ployez vos frontaux.
Ma précédente entreprise a tenté de vendre un tel service. Et on m'a demandé de tester le cluster pour voir si cette solution convenait ou non.
Je suis donc arrivĂ© dans ce cluster. On m'a donnĂ© des droits limitĂ©s, un espace de noms limitĂ©. Les personnes lĂ -bas comprenaient ce qu'Ă©tait la sĂ©curitĂ©. Ils savaient ce qu'Ă©tait le contrĂŽle d'accĂšs basĂ© sur les rĂŽles (RBAC) dans Kubernetes â et ils l'ont configurĂ© de telle sorte que je ne pouvais pas exĂ©cuter des pods sĂ©parĂ©ment des dĂ©ploiements. Je ne me souviens pas de la tĂąche que j'essayais de rĂ©soudre en lançant un pod sans dĂ©ploiement, mais j'avais trĂšs envie de lancer simplement un pod. J'ai dĂ©cidĂ© par chance de vĂ©rifier quels droits j'avais dans le cluster, ce que je pouvais faire, ce que je ne pouvais pas faire, ce qu'ils avaient configurĂ©. J'en profiterai aussi pour expliquer ce qui n'est pas configurĂ© correctement dans leur RBAC.
Il s'est avéré qu'aprÚs deux minutes, j'ai obtenu les droits d'administrateur sur leur cluster, j'ai regardé dans tous les espaces de noms voisins et j'ai vu des frontaux de production en cours d'exécution, provenant d'entreprises qui avaient déjà acheté le service et s'étaient déployées. J'ai failli me retenir de venir sur le front de quelqu'un et de mettre un mot vulgaire sur la page d'accueil.
Je vais expliquer avec des exemples comment j'ai fait cela et comment s'en protéger.
Mais d'abord, permettez-moi de me présenter. Je m'appelle Pavel Selivanov. Je suis architecte chez Southbridge. Je m'y connais en Kubernetes, DevOps et dans les derniÚres technologies tendances. Mes collÚgues ingénieurs chez Southbridge s'occupent de tout cela, et je fais office de consultant.
En plus de notre activité principale, nous avons récemment lancé des projets appelés Slurm. Nous essayons de partager notre expertise sur Kubernetes avec le grand public et d'apprendre à d'autres à utiliser K8s.
De quoi je vais parler aujourd'hui. Le sujet de ma prĂ©sentation est Ă©vident â la sĂ©curitĂ© des clusters Kubernetes. Mais je tiens Ă prĂ©ciser que c'est un sujet trĂšs vaste â et donc je vais tout de suite dire ce dont je ne parlerai pas. Je ne vais pas aborder les termes dĂ©jĂ mille fois vus sur Internet, comme le RBAC et les certificats.
Je vais parler de ce qui nous prĂ©occupe, mes collĂšgues et moi, en ce qui concerne la sĂ©curitĂ© des clusters Kubernetes. Nous voyons ces problĂšmes chez les fournisseurs de clusters Kubernetes et chez les clients qui viennent Ă nous. MĂȘme chez les clients qui viennent d'autres entreprises de consulting en administration. En rĂ©alitĂ©, l'ampleur du problĂšme est Ă©norme.
Je vais aborder trois points aujourd'hui :
- Les droits des utilisateurs vs les droits des pods. Les droits des utilisateurs et les droits des pods ne sont pas la mĂȘme chose.
- Collecte d'informations sur le cluster. Je montrerai comment il est possible de recueillir toutes les informations nécessaires sur un cluster sans avoir de droits particuliers.
- Attaque DoS sur le cluster. Si nous ne pouvons pas collecter d'informations, nous pouvons néanmoins rendre le cluster inutilisable. Je parlerai des attaques DoS sur les composants de gestion du cluster.
Une autre chose gĂ©nĂ©rale que je mentionnerai â sur quoi j'ai testĂ© tout ça, sur quoi je peux affirmer que cela fonctionne.
Nous prenons comme base l'installation d'un cluster Kubernetes via Kubespray. Pour ceux qui ne le savent pas, c'est en fait un ensemble de rĂŽles pour Ansible. Nous l'utilisons constamment dans notre travail. C'est bien car on peut l'installer n'importe oĂč â que ce soit sur du matĂ©riel ou dans le cloud. Une mĂ©thode d'installation convient en principe Ă tout.
Dans ce cluster, j'aurai Kubernetes v1.14.5. L'ensemble du cluster Kube que nous allons examiner est divisé en espaces de noms, chaque espace de noms appartenant à une équipe distincte, avec accÚs uniquement pour les membres de cette équipe. Ils ne peuvent pas entrer dans d'autres espaces de noms, seulement dans le leur. Il existe cependant un compte administrateur qui a des droits sur l'ensemble du cluster.

J'avais promis que notre premiÚre étape serait d'obtenir les droits d'administration sur le cluster. Nous avons besoin d'un pod spécialement préparé qui va compromettre le cluster Kubernetes. Tout ce que nous avons à faire, c'est de l'appliquer au cluster Kubernetes.
kubectl apply -f pod.yamlCe pod atterrira sur l'un des maßtres du cluster Kubernetes. Ensuite, le cluster nous renverra joyeusement un fichier nommé admin.conf. Ce fichier contient tous les certificats de l'administrateur, ainsi que la configuration de l'API du cluster. Voilà comment on peut facilement obtenir un accÚs administratif, je pense que cela fonctionne pour 98 % des clusters Kubernetes.
Je le rĂ©pĂšte, ce pod a Ă©tĂ© créé par un dĂ©veloppeur dans votre cluster, qui a la possibilitĂ© de dĂ©ployer ses propositions dans un petit espace de noms, tout en Ă©tant limitĂ© par RBAC. Il n'avait aucun droit particulier. Cependant, le certificat est quand mĂȘme revenu.
à présent, parlons du pod spécialement préparé. Nous le lançons sur n'importe quelle image. Par exemple, utilisons debian:jessie.
Nous avons cette configuration :
tolerations:
- effect: NoSchedule
operator: Exists
nodeSelector:
node-role.kubernetes.io/master: "" Qu'est-ce qu'une tolĂ©rance ? Les maĂźtres dans le cluster Kubernetes sont gĂ©nĂ©ralement marquĂ©s par une caractĂ©ristique appelĂ©e taint ("contamination" en anglais). L'idĂ©e de cette "contamination" est qu'aucun pod ne peut ĂȘtre affectĂ© aux nĆuds maĂźtres. Mais rien n'empĂȘche un pod d'indiquer qu'il est tolĂ©rant Ă cette "contamination". La section Toleration indique justement que si un certain nĆud a NoSchedule, alors notre pod est tolĂ©rant Ă cette contamination - et il n'y a aucun problĂšme.
Ensuite, nous prĂ©cisons que notre pod n'est pas seulement tolĂ©rant, mais qu'il souhaite en fait ĂȘtre affectĂ© spĂ©cifiquement Ă un maĂźtre. Parce que sur les maĂźtres se trouvent les Ă©lĂ©ments les plus prĂ©cieux dont nous avons besoin - tous les certificats. Nous spĂ©cifions donc nodeSelector - et nous avons une Ă©tiquette standard sur les maĂźtres qui permet de sĂ©lectionner parmi tous les nĆuds du cluster ceux qui sont des maĂźtres.
Avec ces deux sections, le pod arrivera certainement sur le maßtre. Et il sera autorisé à y résider.
Mais simplement arriver sur le maßtre ne suffit pas. Cela ne nous apportera rien. Donc, plus loin, nous avons ces deux éléments :
hostNetwork: true
hostPID: true Nous indiquons que notre pod, que nous dĂ©ployons, vivra dans l'espace de noms du nĆud, dans l'espace de noms rĂ©seau et dans l'espace de noms PID. Une fois le pod lancĂ© sur le maĂźtre, il pourra voir toutes les interfaces rĂ©elles et vivantes de ce nĆud, Ă©couter tout le trafic et voir les PID de tous les processus.
Ensuite, il ne reste plus qu'Ă prendre etcd et Ă lire ce que vous voulez.
Le plus intéressant est cette fonctionnalité de Kubernetes qui est présente par défaut.
volumeMounts:
- mountPath: /host
name: host
volumes:
- hostPath:
path: /
type: Directory
name: host Et l'essence de cette fonctionnalitĂ© est que nous pouvons, dans le pod que nous lançons, mĂȘme sans droits sur ce cluster, spĂ©cifier que nous voulons crĂ©er un volume de type hostPath. Cela signifie prendre un chemin depuis l'hĂŽte sur lequel nous allons nous exĂ©cuter â et le prendre comme volume. Et ensuite, nous le nommons name: host. Ce hostPath est montĂ© Ă l'intĂ©rieur du pod. Dans cet exemple, dans le rĂ©pertoire /host.
Je rĂ©pĂšte encore une fois. Nous avons dit au pod d'arriver sur le maĂźtre, d'obtenir hostNetwork et hostPID â et de monter tout le root du maĂźtre Ă l'intĂ©rieur de ce pod.
Vous comprenez qu'au niveau de Debian, nous avons un bash qui s'exécute en tant que root. Cela signifie que nous venons d'obtenir les privilÚges root sur le maßtre, sans avoir de droits dans le cluster Kubernetes.
La tùche suivante consiste à entrer dans le pod dans le répertoire /host /etc/kubernetes/pki, si je ne me trompe pas, et à récupérer tous les certificats du maßtre du cluster et, par conséquent, à devenir l'administrateur du cluster.
Si on y regarde de plus prĂšs, ce sont quelques-unes des permissions les plus dangereuses dans les pods â peu importe les droits de l'utilisateur :

Si j'ai le droit de lancer un pod dans un espace de noms du cluster, alors ce pod a ces droits par dĂ©faut. Je peux lancer des pods privilĂ©giĂ©s, et cela signifie pratiquement avoir tous les droits, presque un accĂšs root sur le nĆud.
Mon prĂ©fĂ©rĂ© â l'utilisateur root. Et Kubernetes a cette option ExĂ©cuter En Tant Que Non-Root. C'est une sorte de protection contre les hackers. Savez-vous ce qu'est un « virus moldave » ? Si vous ĂȘtes un hacker et que vous venez dans mon cluster Kubernetes, alors nous, pauvres administrateurs, vous demandons : « Veuillez indiquer, s'il vous plaĂźt, dans vos pods, par lesquels vous allez pirater mon cluster, exĂ©cuter en tant que non-root. Sinon, vous risquez de lancer un processus dans votre pod sous root, et il vous sera trĂšs facile de me pirater. ProtĂ©gez-vous, s'il vous plaĂźt, vous-mĂȘme ».
Le volume host path â Ă mon avis, c'est le moyen le plus rapide d'obtenir le rĂ©sultat souhaitĂ© du cluster Kubernetes.
Mais que faire avec tout cela ?
Une rĂ©flexion qui devrait venir Ă l'esprit de tout administrateur normal confrontĂ© Ă Kubernetes : « Ah, je l'avais dit, Kubernetes ne fonctionne pas. Il a des failles. Et tout ça, c'est nul ». En rĂ©alitĂ©, il existe un truc qu'on appelle la documentation, et si l'on y jette un coup d'Ćil, il y a une section .
C'est un objet yaml â que nous pouvons crĂ©er dans un cluster Kubernetes â qui contrĂŽle les aspects de sĂ©curitĂ© spĂ©cifiquement dans la description des pods. Autrement dit, il contrĂŽle effectivement les droits d'utilisation de divers hostNetwork, hostPID, et certains types de volumes qui existent dans les pods lors du dĂ©marrage. Avec la Pod Security Policy, tout cela peut ĂȘtre dĂ©crit.
Ce qui est intéressant dans la Pod Security Policy, c'est que dans le cluster Kubernetes, tous les installateurs de PSP ne sont pas définis, ils sont tout simplement désactivés par défaut. La Pod Security Policy s'active grùce à un plugin d'admission.
D'accord, déployons la Pod Security Policy dans le cluster, disons que nous avons certains pods de service dans un namespace, auxquels seuls les administrateurs ont accÚs. Disons que dans tous les autres pods, les droits sont limités. Parce qu'il est probable que les développeurs n'ont pas besoin de lancer des pods privilégiés dans votre cluster.
Et il semblerait que tout va bien. Et notre cluster Kubernetes ne peut pas ĂȘtre compromis en deux minutes.
Il y a un problĂšme. TrĂšs probablement, si vous avez un cluster Kubernetes, un systĂšme de surveillance est installĂ© dans votre cluster. Je parie mĂȘme que si votre cluster a une surveillance, elle s'appelle Prometheus.
Ce que je vais dire maintenant sera valable aussi bien pour l'opérateur Prometheus que pour Prometheus installé dans sa forme pure. La question est que si je ne peux pas obtenir rapidement un administrateur dans le cluster, cela signifie que je dois chercher davantage. Et je peux chercher à l'aide de votre surveillance.
Il est probable que tout le monde ait lu les mĂȘmes articles sur HabrĂ©, et que la surveillance se trouve dans le namespace monitoring. Le chart Helm de tout le monde s'appelle Ă peu prĂšs de la mĂȘme maniĂšre. Je suppose que si vous faites helm install stable/prometheus, vous obtiendrez des noms Ă peu prĂšs similaires. Et il est mĂȘme probable que je n'aurai pas Ă deviner le nom DNS dans votre cluster. Parce qu'il est standard.

Ensuite, nous avons un namespace dev, dans lequel nous pouvons lancer un pod. Et ensuite, Ă partir de ce pod, il est trĂšs facile de faire cela :
$ curl http://prometheus-kube-state-metrics.monitoring prometheus-kube-state-metrics est l'un des exporters de Prometheus, qui collecte des mĂ©triques depuis l'API de Kubernetes lui-mĂȘme. Il y a beaucoup de donnĂ©es sur ce qui est en cours d'exĂ©cution dans votre cluster, ce que c'est, et quels problĂšmes vous pourriez rencontrer.
Prenons un exemple simple :
kube_pod_container_info{namespace="kube-system",pod="kube-apiserver-k8s-1",container="kube-apiserver",image=
"gcr.io/google-containers/kube-apiserver:v1.14.5"
,image_id="docker-pullable://gcr.io/google-containers/kube-apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a9638ee634989",container_id="docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2853397d7daf08e72c22d3cf8b"} 1
En effectuant une simple requĂȘte curl depuis un pod non privilĂ©giĂ©, vous pouvez obtenir ce genre d'informations. Si vous ne savez pas quelle version de Kubernetes vous exĂ©cutez, elle vous le dira facilement.
Et ce qui est le plus intĂ©ressant, c'est qu'en plus d'appeler kube-state-metrics, vous pouvez Ă©galement vous adresser directement Ă Prometheus. Vous pouvez collecter des mĂ©triques de lĂ -bas. ThĂ©oriquement, vous pouvez mĂȘme construire une requĂȘte depuis le cluster vers Prometheus qui pourrait simplement le dĂ©sactiver. Et votre surveillance cesserait complĂštement de fonctionner dans le cluster.
La question se pose alors : est-ce qu'une surveillance externe surveille votre surveillance ? Je viens d'acquĂ©rir la possibilitĂ© d'agir dans le cluster Kubernetes sans aucune consĂ©quences. Vous ne saurez mĂȘme pas que j'agis lĂ -bas, car la surveillance n'existe dĂ©jĂ plus.
Tout comme avec les PSP, on a l'impression que le problĂšme vient de ces technologies Ă la mode â Kubernetes, Prometheus â qui semblent ne pas fonctionner et ĂȘtre pleines de failles. En rĂ©alitĂ©, ce n'est pas le cas.
Il existe une chose â .
Si vous ĂȘtes un administrateur raisonnable, vous savez probablement que Network Policy est un autre yaml, qu'il y en a dĂ©jĂ beaucoup dans le cluster. Et certaines politiques de rĂ©seau ne sont sĂ»rement pas nĂ©cessaires. Et mĂȘme si vous avez lu ce qu'est une Network Policy, que c'est un pare-feu yaml de Kubernetes qui permet de restreindre les droits d'accĂšs entre les namespaces, entre les pods, vous avez sĂ»rement dĂ©cidĂ© que le pare-feu au format yaml dans Kubernetes relĂšve simplement d'abstractions supplĂ©mentaires... Non, ce n'est dĂ©finitivement pas nĂ©cessaire.
MĂȘme si vos experts en sĂ©curitĂ© ne vous ont pas informĂ© qu'il est trĂšs facile de construire un pare-feu avec votre Kubernetes, et qu'il peut ĂȘtre trĂšs granulaire. S'ils ne le savent pas encore et ne vous sollicitent pas : « Allez, donnez, donnez⊠» Dans tous les cas, vous aurez besoin des Network Policies pour restreindre l'accĂšs Ă certains espaces serveurs qui peuvent ĂȘtre sollicitĂ©s depuis votre cluster sans aucune autorisation.
Comme dans l'exemple que j'ai donné, il est possible d'accéder aux kube state metrics de n'importe quel namespace dans le cluster Kubernetes sans avoir de droits. Les politiques réseau ont bloqué l'accÚs depuis tous les autres namespaces vers le namespace de surveillance, et voilà : pas d'accÚs, pas de problÚme. Dans tous les charts disponibles, tant dans le Prometheus standard que dans celui dédié à l'opérateur, il suffit d'activer l'option pour les policies réseau dans les valeurs Helm. Il suffit d'activer cela, et elles fonctionneront.
Il y a néanmoins un problÚme. En tant qu'administrateur raisonnable, vous avez probablement décidé que les policies réseau n'étaient pas nécessaires. Et aprÚs avoir lu plusieurs articles sur des ressources comme Habr, vous avez conclu que flannel, surtout en mode host-gateway, est la meilleure option que vous puissiez choisir.
Que faire ?
Vous pouvez essayer de redĂ©ployer la solution rĂ©seau que vous avez dans votre cluster Kubernetes et la remplacer par quelque chose de plus fonctionnel. Par exemple, Calico. Mais je veux tout de suite dire que changer la solution rĂ©seau dans un cluster Kubernetes en fonctionnement est assez complexe. Je l'ai rĂ©solu deux fois (dans les deux cas, cependant, thĂ©oriquement), mais nous avons mĂȘme montrĂ© comment le faire lors des Slurm. Pour nos Ă©tudiants, nous avons montrĂ© comment changer la solution rĂ©seau dans un cluster Kubernetes. En principe, vous pouvez essayer de le faire de telle maniĂšre qu'il n'y ait pas de temps d'arrĂȘt sur le cluster de production. Mais il est probable que cela ne fonctionne pas.
Et le problĂšme se rĂ©sout en fait trĂšs simplement. Il y a des certificats dans le cluster, et vous savez que vos certificats vont expirer dans un an. Eh bien, la solution normale avec les certificats dans le cluster est : pourquoi s'embĂȘter, nous allons simplement mettre en place un nouveau cluster Ă cĂŽtĂ©, laissant l'ancien expirer, et nous dĂ©ploierons tout de nouveau. Certes, lorsque l'ancien expirera, il sera hors service pendant une journĂ©e, mais au moins, nous aurons un nouveau cluster.
Lorsque vous mettrez en place un nouveau cluster, nâoubliez pas dâintĂ©grer Calico au lieu de flannel.
Que faire si vos certificats sont valables pour cent ans et que vous ne prévoyez pas de redéployer le cluster ? Il existe un outil appelé Kube-RBAC-Proxy. C'est un développement trÚs intéressant qui permet de s'intégrer, en tant que conteneur sidecar, à n'importe quel pod dans un cluster Kubernetes. Il ajoute en fait une autorisation via RBAC de Kubernetes à ce pod.
Il y a un problÚme. Auparavant, dans l'opérateur Prometheus, cette solution Kube-RBAC-Proxy était intégrée. Mais ce n'est plus le cas. Les versions modernes reposent sur le fait que vous avez une politique réseau et que vous les utilisez pour bloquer l'accÚs. Par conséquent, il faudra légÚrement modifier le chart. En fait, si vous allez dans , il y a des exemples d'utilisation en tant que sidecars, et il faudra modifier le chart au minimum.
Il y a aussi un petit autre problÚme. Ce n'est pas seulement Prometheus qui expose ses métriques à tout le monde. Tous nos composants du cluster Kubernetes peuvent également fournir leurs propres métriques.
Mais comme je l'ai déjà dit, si vous ne pouvez pas accéder au cluster et collecter des informations, vous pouvez au moins causer des problÚmes.
Je vais donc rapidement vous montrer deux façons de nuire à la santé d'un cluster Kubernetes.
Vous allez rire lorsque je vais vous en parler, ce sont deux cas de la vie réelle.
PremiĂšre mĂ©thode. Ăpuisement des ressources.
Nous allons lancer un autre pod spécial. Il aura une section comme celle-ci.
resources:
requests:
cpu: 4
memory: 4Gi Comme vous le savez, les requests correspondent Ă la quantitĂ© de CPU et de mĂ©moire qui est rĂ©servĂ©e pour des pods spĂ©cifiques avec des requests. Si nous avons un hĂŽte Ă quatre cĆurs dans le cluster Kubernetes, et qu'un pod arrive avec des requests de quatre CPUs, cela signifie qu'aucun autre pod avec des requests ne pourra arriver sur cet hĂŽte.
Si je lance un tel pod, puis que je fais la commande :
$ kubectl scale special-pod --replicas=...Alors personne ne pourra se dĂ©ployer dans le cluster Kubernetes. Parce que toutes les nodes seront Ă court de requests. De cette maniĂšre, j'arrĂȘterai votre cluster Kubernetes. Si je fais cela le soir, je peux arrĂȘter les dĂ©ploiements pendant un bon moment.
Si nous consultons Ă nouveau la documentation de Kubernetes, nous y trouverons un concept appelĂ© Limit Range. Il dĂ©finit les ressources pour les objets du cluster. Vous pouvez Ă©crire un objet Limit Range en YAML, l'appliquer Ă certains espaces de noms â et ensuite, dans cet espace de noms, vous pouvez spĂ©cifier que vous avez des ressources par dĂ©faut, maximales et minimales pour les pods.
Avec cette fonctionnalitĂ©, nous pouvons limiter les utilisateurs dans des espaces de noms de produits spĂ©cifiques en ce qui concerne leurs capacitĂ©s Ă indiquer certaines choses sur leurs pods. Mais malheureusement, mĂȘme si vous dites Ă l'utilisateur qu'il ne doit pas lancer de pods avec des requĂȘtes supĂ©rieures Ă un CPU, il existe une commande fantastique pour le scale, ou bien Ă travers le tableau de bord, ils peuvent effectuer un scale.
Et de là découle la deuxiÚme méthode. Lançons 11 111 111 111 111 pods. C'est onze milliards. Ce n'est pas que j'ai inventé ce nombre, c'est quelque chose que j'ai réellement vu.
Une histoire rĂ©elle. Tard dans la soirĂ©e, je m'apprĂȘtais Ă quitter le bureau. Je vois dans un coin un groupe de dĂ©veloppeurs qui s'affairent devant leurs ordinateurs portables. Je m'approche d'eux et je demande : « Que vous est-il arrivĂ© ? »
Un peu plus tĂŽt, vers neuf heures du soir, l'un des dĂ©veloppeurs se prĂ©parait Ă rentrer chez lui. Il a dĂ©cidĂ© : « Je vais faire un scale de mon application Ă un ». Il a appuyĂ© sur un, et internet a lĂ©gĂšrement ralenti. Il a de nouveau appuyĂ© sur un, a appuyĂ© sur un, a cliquĂ© sur EntrĂ©e. Il a essayĂ© tout ce qu'il pouvait. Ă ce moment-lĂ , internet s'est rĂ©veillĂ© â et tout a commencĂ© Ă se mettre Ă l'Ă©chelle jusqu'Ă ce nombre.
En rĂ©alitĂ©, cette histoire ne se passait pas sur Kubernetes, Ă l'Ă©poque c'Ă©tait Nomad. Cela s'est terminĂ© par des heures de tentatives pour arrĂȘter Nomad de ses tentatives obstinĂ©es de scalabilitĂ©, Nomad a rĂ©pondu qu'il ne cesserait pas de scaler et qu'il ne ferait rien d'autre. « Je suis fatiguĂ©, je pars. » Et il s'est repliĂ©.
Naturellement, j'ai essayĂ© de faire la mĂȘme chose sur Kubernetes. Onze milliards de pods n'ont pas ravi Kubernetes, il a dit : « Je ne peux pas. Ăa dĂ©passe les limites internes. » Mais un milliard de pods a fonctionnĂ©.
En rĂ©ponse Ă un milliard de pods, il n'est pas entrĂ© dans Kubernetes. Il a vraiment commencĂ© Ă s'Ă©tendre. Plus le processus avançait, plus il lui fallait de temps pour crĂ©er de nouveaux pods. Mais le processus avançait toujours. Le seul problĂšme est que si je peux lancer des pods Ă volontĂ© dans mon espace de noms, mĂȘme sans requĂȘtes ni limites, je pourrais lancer avec certaines tĂąches un nombre de pods tel que ces tĂąches commenceront Ă saturer les nĆuds en mĂ©moire et en CPU. Lorsque je lance autant de pods, les informations doivent ĂȘtre stockĂ©es, c'est-Ă -dire dans etcd. Et quand trop d'informations y entrent, le stockage commence Ă rĂ©pondre beaucoup trop lentement â et Kubernetes commence Ă ralentir.
Et il y a un autre problĂšme... Comme vous le savez, les composants de gestion de Kubernetes ne sont pas une seule piĂšce centrale, mais plusieurs composants. Parmi eux se trouvent le contrĂŽleur de gestion, le planificateur, etc. Tous ces Ă©lĂ©ments commenceront Ă travailler simultanĂ©ment sur des tĂąches inutiles et peu productives, ce qui prendra de plus en plus de temps Ă mesure que le temps passe. Le contrĂŽleur de gestion crĂ©era de nouveaux pods. Le planificateur tentera de leur trouver un nouveau nĆud. Les nouveaux nĆuds dans votre cluster seront probablement bientĂŽt Ă©puisĂ©s. Le cluster Kubernetes commencera Ă fonctionner de plus en plus lentement.
Mais j'ai décidé d'aller encore plus loin. Comme vous le savez, dans Kubernetes, il existe une chose appelée service. Eh bien, par défaut, dans vos clusters, le service fonctionne probablement avec des IP tables.
Si vous lancez un milliard de pods, par exemple, puis que vous forcez Kubernetes à créer de nouveaux services avec un script :
for i in {1..1111111}; do
kubectl expose deployment test --port 80
--overrides="{"apiVersion": "v1",
"metadata": {"name": "nginx$i"}}";
done Sur tous les nĆuds du cluster, de nouvelles rĂšgles iptables seront gĂ©nĂ©rĂ©es presque simultanĂ©ment. En effet, pour chaque service, un milliard de rĂšgles iptables seront gĂ©nĂ©rĂ©es.
J'ai testĂ© cela sur quelques milliers, jusqu'Ă une dizaine. Et le problĂšme est qu'Ă ce stade, il devient assez problĂ©matique de se connecter en SSH Ă un nĆud. Parce que les paquets, en passant par un tel nombre de chaĂźnes, ne se comportent pas trĂšs bien.
Et tout cela peut Ă©galement ĂȘtre rĂ©solu Ă l'aide de Kubernetes. Il existe un objet appelĂ© Resource quota. Il dĂ©finit le nombre de ressources et d'objets disponibles pour un namespace dans le cluster. Nous pouvons crĂ©er un objet yaml dans chaque namespace du cluster Kubernetes. GrĂące Ă cet objet, nous pouvons dĂ©finir qu'un certain nombre de requĂȘtes et de limites sont allouĂ©s Ă ce namespace, et nous pouvons ensuite indiquer qu'il est possible de crĂ©er 10 services et 10 pods dans ce namespace. Et le dĂ©veloppeur peut mĂȘme se faire des soucis en soirĂ©e. Kubernetes lui dira : « Vous ne pouvez pas augmenter vos pods Ă ce nombre, car cela dĂ©passe le quota de ressources ». VoilĂ , le problĂšme est rĂ©solu. .
Un problÚme se pose à ce sujet. Vous ressentez à quel point il devient difficile de créer un namespace dans Kubernetes. Pour le créer, nous devons tenir compte de beaucoup de choses.
Resource quota + Limit Range + RBAC
⹠Création du namespace
⹠Création d'une limitrange à l'intérieur
⹠Création d'un resourcequota à l'intérieur
⹠Création d'un serviceaccount pour CI
⹠Création d'un rolebinding pour CI et utilisateurs
⹠Lancement optionnel des pods de service nécessaires
C'est pourquoi, profitant de l'occasion, je voudrais partager mes développements. Il existe un outil appelé opérateur SDK. C'est une façon d'écrire des opérateurs pour Kubernetes dans le cluster. Vous pouvez écrire des opérateurs en utilisant Ansible.
Au départ, nous avions écrit sur Ansible, puis j'ai vu qu'il existait un opérateur SDK et j'ai réécrit le rÎle Ansible en opérateur. Cet opérateur permet de créer dans le cluster Kubernetes un objet appelé commande. à l'intérieur de cette commande, il permet de décrire en yaml l'environnement pour cette commande. Et à l'intérieur de l'environnement de la commande, il permet de décrire combien de ressources nous allouons.
Petite .
Et en conclusion. Que faire de tout cela ?
D'abord. La Pod Security Policy - c'est bien. Et mĂȘme si aucun des installateurs de Kubernetes ne les utilise encore Ă ce jour, il est nĂ©anmoins nĂ©cessaire de les utiliser dans vos clusters.
La Network Policy - ce n'est pas une autre fonctionnalité inutile. C'est quelque chose dont on a réellement besoin dans le cluster.
LimitRange/ResourceQuota - il est temps de les utiliser. Nous avons commencé à les utiliser depuis longtemps, et j'étais convaincu que tout le monde les appliquait. Il s'est avéré que c'est assez rare.
En plus de ce que j'ai mentionné lors de mon discours, il y a des fonctionnalités non documentées qui permettent d'attaquer le cluster. Cela a été récemment publié. .
Certaines choses sont tellement tristes et choquantes. Par exemple, dans certaines conditions, les kubelets dans le cluster Kubernetes peuvent exposer le contenu du répertoire des warlocks à un utilisateur non autorisé.
Il y a des instructions sur la façon de reproduire tout ce que j'ai prĂ©sentĂ©. Il y a des fichiers avec des exemples de production, montrant Ă quoi ressemblent ResourceQuota et Pod Security Policy. Et tout cela peut ĂȘtre explorĂ©.
Merci Ă tous.
Source : habr.com
