Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b531ba9b2b | |||
| 288e68d45b | |||
| dcc578aa0f | |||
| 04aa3aade6 | |||
| cfb0fdf517 | |||
| 2fddca0e4d | |||
| cd31e31a98 | |||
| 2a5540ac61 | |||
| cf9fa4de8e | |||
| 857efcab73 | |||
| 65d36413fb | |||
| d0a13e0713 | |||
| 428552906a | |||
| 14f32a3b31 | |||
| 3d6f72ffc4 | |||
| a0325251ab | |||
| 54bf3977fe |
+1
-1
@@ -5,7 +5,7 @@ charset = utf-8
|
||||
max_line_length = 80
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{css,html,js,json,sass,md,mmark,toml,yaml}]
|
||||
[*.{html,js,json,sass,md,mmark,toml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
<!-- 🛈
|
||||
|
||||
Hello!
|
||||
|
||||
Remember to ADD A DESCRIPTION and delete this note before submitting
|
||||
your pull request. The description should explain what will change,
|
||||
and why.
|
||||
|
||||
PLEASE title the FIRST commit appropriately, so that if you squash all
|
||||
your commits into one, the combined commit message makes sense.
|
||||
For overall help on editing and submitting pull requests, visit:
|
||||
https://kubernetes.io/docs/contribute/start/#improve-existing-content
|
||||
|
||||
Use the default base branch, “master”, if you're documenting existing
|
||||
features in the English localization.
|
||||
|
||||
If you're working on a different localization (not English), or you
|
||||
are documenting a feature that will be part of a future release, see
|
||||
https://kubernetes.io/docs/contribute/start#choose-which-git-branch-to-use
|
||||
for advice.
|
||||
|
||||
-->
|
||||
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
> Remember to delete this note before submitting your pull request.
|
||||
>
|
||||
> For pull requests on 1.18 Features: set Milestone to 1.18 and Base Branch to dev-1.18
|
||||
>
|
||||
> For pull requests on Chinese localization, set Base Branch to release-1.16
|
||||
> Feel free to ask questions in #kubernetes-docs-zh
|
||||
>
|
||||
> For pull requests on Korean Localization: set Base Branch to dev-1.16-ko.\<latest team milestone>
|
||||
>
|
||||
> If you need Help on editing and submitting pull requests, visit:
|
||||
> https://kubernetes.io/docs/contribute/start/#improve-existing-content.
|
||||
>
|
||||
> If you need Help on choosing which branch to use, visit:
|
||||
> https://kubernetes.io/docs/contribute/start#choose-which-git-branch-to-use.
|
||||
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
DOCKER = docker
|
||||
HUGO_VERSION = $(shell grep ^HUGO_VERSION netlify.toml | tail -n 1 | cut -d '=' -f 2 | tr -d " \"\n")
|
||||
HUGO_VERSION = 0.59.1
|
||||
DOCKER_IMAGE = kubernetes-hugo
|
||||
DOCKER_RUN = $(DOCKER) run --rm --interactive --tty --volume $(CURDIR):/src
|
||||
NODE_BIN = node_modules/.bin
|
||||
@@ -18,18 +18,15 @@ build: ## Build site with production settings and put deliverables in ./public
|
||||
build-preview: ## Build site with drafts and future posts enabled
|
||||
hugo --buildDrafts --buildFuture
|
||||
|
||||
deploy-preview: ## Deploy preview site via netlify
|
||||
hugo --enableGitInfo --buildFuture -b $(DEPLOY_PRIME_URL)
|
||||
|
||||
functions-build:
|
||||
$(NETLIFY_FUNC) build functions-src
|
||||
|
||||
check-headers-file:
|
||||
scripts/check-headers-file.sh
|
||||
|
||||
production-build: build check-headers-file ## Build the production site and ensure that noindex headers aren't added
|
||||
production-build: check-hugo-versions build check-headers-file ## Build the production site and ensure that noindex headers aren't added
|
||||
|
||||
non-production-build: ## Build the non-production site, which adds noindex headers to prevent indexing
|
||||
non-production-build: check-hugo-versions ## Build the non-production site, which adds noindex headers to prevent indexing
|
||||
hugo --enableGitInfo
|
||||
|
||||
serve: ## Boot the development server.
|
||||
@@ -47,3 +44,6 @@ docker-serve:
|
||||
test-examples:
|
||||
scripts/test_examples.sh install
|
||||
scripts/test_examples.sh run
|
||||
|
||||
check-hugo-versions:
|
||||
scripts/hugo-version-check.sh $(HUGO_VERSION)
|
||||
|
||||
+12
-29
@@ -30,6 +30,7 @@ aliases:
|
||||
- onlydole
|
||||
- parispittman
|
||||
- vonguard
|
||||
- onlydole
|
||||
sig-docs-de-owners: # Admins for German content
|
||||
- bene2k1
|
||||
- mkorbi
|
||||
@@ -39,34 +40,38 @@ aliases:
|
||||
- mkorbi
|
||||
- rlenferink
|
||||
sig-docs-en-owners: # Admins for English content
|
||||
- bradamant3
|
||||
- bradtopol
|
||||
- daminisatya
|
||||
- gochist
|
||||
- jaredbhatti
|
||||
- jimangel
|
||||
- kbarnard10
|
||||
- kbhawkey
|
||||
- makoscafee
|
||||
- onlydole
|
||||
- Rajakavitha1
|
||||
- ryanmcginnis
|
||||
- sftim
|
||||
- simplytunde
|
||||
- steveperry-53
|
||||
- tengqm
|
||||
- vineethreddy02
|
||||
- xiangpengzhao
|
||||
- zacharysarah
|
||||
- zparnold
|
||||
sig-docs-en-reviews: # PR reviews for English content
|
||||
- bradamant3
|
||||
- bradtopol
|
||||
- daminisatya
|
||||
- gochist
|
||||
- jaredbhatti
|
||||
- jimangel
|
||||
- kbarnard10
|
||||
- kbhawkey
|
||||
- makoscafee
|
||||
- onlydole
|
||||
- rajakavitha1
|
||||
- rajeshdeshpande02
|
||||
- ryanmcginnis
|
||||
- sftim
|
||||
- simplytunde
|
||||
- steveperry-53
|
||||
- tengqm
|
||||
- xiangpengzhao
|
||||
@@ -92,8 +97,6 @@ aliases:
|
||||
- jygastaud
|
||||
- awkif
|
||||
- oussemos
|
||||
- anthonydahanne
|
||||
- feloy
|
||||
sig-docs-fr-reviews: # PR reviews for French content
|
||||
- remyleone
|
||||
- perriea
|
||||
@@ -106,8 +109,6 @@ aliases:
|
||||
- jygastaud
|
||||
- awkif
|
||||
- oussemos
|
||||
- anthonydahanne
|
||||
- feloy
|
||||
sig-docs-hi-owners: # Admins for Hindi content
|
||||
- avidLearnerInProgress
|
||||
- daminisatya
|
||||
@@ -128,10 +129,12 @@ aliases:
|
||||
- fabriziopandini
|
||||
- mattiaperi
|
||||
- micheleberardi
|
||||
- rlenferink
|
||||
sig-docs-it-reviews: # PR reviews for Italian content
|
||||
- fabriziopandini
|
||||
- mattiaperi
|
||||
- micheleberardi
|
||||
- rlenferink
|
||||
sig-docs-ja-owners: # Admins for Japanese content
|
||||
- cstoku
|
||||
- inductor
|
||||
@@ -148,7 +151,6 @@ aliases:
|
||||
- gochist
|
||||
- ianychoi
|
||||
- seokho-son
|
||||
- ysyukr
|
||||
- zacharysarah
|
||||
sig-docs-ko-reviews: # PR reviews for Korean content
|
||||
- ClaudiaJKang
|
||||
@@ -157,6 +159,7 @@ aliases:
|
||||
- seokho-son
|
||||
- ysyukr
|
||||
sig-docs-maintainers: # Website maintainers
|
||||
- bradamant3
|
||||
- jimangel
|
||||
- kbarnard10
|
||||
- pwittrock
|
||||
@@ -182,7 +185,6 @@ aliases:
|
||||
- idealhack
|
||||
- markthink
|
||||
- SataQiu
|
||||
- tanjunchen
|
||||
- tengqm
|
||||
- xiangpengzhao
|
||||
- xichengliudui
|
||||
@@ -192,12 +194,10 @@ aliases:
|
||||
- femrtnz
|
||||
- jcjesus
|
||||
- devlware
|
||||
- jhonmike
|
||||
sig-docs-pt-reviews: # PR reviews for Portugese content
|
||||
- femrtnz
|
||||
- jcjesus
|
||||
- devlware
|
||||
- jhonmike
|
||||
sig-docs-vi-owners: # Admins for Vietnamese content
|
||||
- huynguyennovem
|
||||
- ngtuna
|
||||
@@ -216,20 +216,3 @@ aliases:
|
||||
- aisonaku
|
||||
- potapy4
|
||||
- dianaabv
|
||||
sig-docs-pl-owners: # Admins for Polish content
|
||||
- mfilocha
|
||||
- nvtkaszpir
|
||||
sig-docs-pl-reviews: # PR reviews for Polish content
|
||||
- mfilocha
|
||||
- nvtkaszpir
|
||||
- kpucynski
|
||||
sig-docs-uk-owners: # Admins for Ukrainian content
|
||||
- anastyakulyk
|
||||
- butuzov
|
||||
- MaxymVlasov
|
||||
sig-docs-uk-reviews: # PR reviews for Ukrainian content
|
||||
- anastyakulyk
|
||||
- butuzov
|
||||
- idvoretskyi
|
||||
- MaxymVlasov
|
||||
- Potapy4
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ El método recomendado para levantar una copia local del sitio web kubernetes.io
|
||||
|
||||
> Para Windows, algunas otras herramientas como Make son necesarias. Puede instalarlas utilizando el gestor [Chocolatey](https://chocolatey.org). `choco install make` o siguiendo las instrucciones de [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm).
|
||||
|
||||
> Si prefiere levantar el sitio web sin utilizar **Docker**, puede seguir las instrucciones disponibles en la sección [Levantando kubernetes.io en local con Hugo](#levantando-kubernetesio-en-local-con-hugo).
|
||||
> Si prefiere levantar el sitio web sin utilizar **Docker**, puede seguir las instrucciones disponibles en la sección [Levantando kubernetes.io en local con Hugo](#levantando-kubernetes.io-en-local-con-hugo).
|
||||
|
||||
Una vez tenga Docker [configurado en su máquina](https://www.docker.com/get-started), puede construir la imagen de Docker `kubernetes-hugo` localmente ejecutando el siguiente comando en la raíz del repositorio:
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ La façon recommandée d'exécuter le site web Kubernetes localement est d'utili
|
||||
|
||||
> Si vous êtes sous Windows, vous aurez besoin de quelques outils supplémentaires que vous pouvez installer avec [Chocolatey](https://chocolatey.org). `choco install install make`
|
||||
|
||||
> Si vous préférez exécuter le site Web localement sans Docker, voir [Exécuter le site localement avec Hugo](#exécuter-le-site-localement-en-utilisant-hugo) ci-dessous.
|
||||
> Si vous préférez exécuter le site Web localement sans Docker, voir [Exécuter le site localement avec Hugo](#running-the-site-locally-using-hugo) ci-dessous.
|
||||
|
||||
Si vous avez Docker [up and running](https://www.docker.com/get-started), construisez l'image Docker `kubernetes-hugo' localement:
|
||||
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@ Selamat datang! Repositori ini merupakan wadah bagi semua komponen yang dibutuhk
|
||||
|
||||
Pertama, kamu dapat menekan tombol **Fork** yang berada pada bagian atas layar, untuk menyalin repositori pada akun Github-mu. Salinan ini disebut sebagai **fork**. Kamu dapat menambahkan konten pada **fork** yang kamu miliki, setelah kamu merasa cukup untuk menambahkan konten yang kamu miliki dan ingin memberikan konten tersebut pada kami, kamu dapat melihat **fork** yang telah kamu buat dan membuat **pull request** untuk memberi tahu kami bahwa kamu ingin menambahkan konten yang telah kamu buat.
|
||||
|
||||
Setelah kamu membuat sebuah **pull request**, seorang **reviewer** akan memberikan masukan terhadap konten yang kamu sediakan serta beberapa hal yang dapat kamu lakukan apabila perbaikan diperlukan terhadap konten yang telah kamu sediakan. Sebagai seorang yang membuat **pull request**, **sudah menjadi kewajiban kamu untuk melakukan modifikasi terhadap konten yang kamu berikan sesuai dengan masukan yang diberikan oleh seorang reviewer Kubernetes**. Perlu kamu ketahui bahwa kamu dapat saja memiliki lebih dari satu orang **reviewer Kubernetes** atau dalam kasus kamu bisa saja mendapatkan **reviewer Kubernetes** yang berbeda dengan **reviewer Kubernetes** awal yang ditugaskan untuk memberikan masukan terhadap konten yang kamu sediakan. Selain itu, seorang **reviewer Kubernetes** bisa saja meminta masukan teknis dari [reviewer teknis Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) jika diperlukan.
|
||||
Setelah kamu membuat sebuah **pull request**, seorang **reviewer** akan memberikan masukan terhadap konten yang kamu sediakan serta beberapa hal yang dapat kamu lakukan apabila perbaikan diperlukan terhadap konten yang telah kamu sediakan. Sebagai seorang yang membuat **pull request**, **sudah menjadi kewajiban kamu untuk melakukan modifikasi terhadap konten yang kamu berikan sesuai dengan masukan yang diberikan oleh seorang reviewer Kubernetes**. Perlu kamu ketahui bahwa kamu dapat saja memiliki lebih dari satu orang **reviewer Kubernetes** atau dalam kasus kamu bisa saja mendapatkan **reviewer Kubernetes** yang berbeda dengan **reviewer Kubernetes** awal yang ditugaskan untuk memberikan masukan terhadap konten yang kamu sediakan. Selain itu, seorang **reviewer Kubernetes** bisa saja meminta masukan teknis dari [reviewer teknis Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) jika diperlukan.
|
||||
|
||||
Untuk informasi lebih lanjut mengenai tata cara melakukan kontribusi, kamu dapat melihat tautan di bawah ini:
|
||||
|
||||
@@ -21,11 +21,11 @@ Untuk informasi lebih lanjut mengenai tata cara melakukan kontribusi, kamu dapat
|
||||
|
||||
## Menjalankan Dokumentasi Kubernetes pada Mesin Lokal Kamu
|
||||
|
||||
Petunjuk yang disarankan untuk menjalankan Dokumentasi Kubernetes pada mesin lokal kamus adalah dengan menggunakan [Docker](https://docker.com) **image** yang memiliki **package** [Hugo](https://gohugo.io), **Hugo** sendiri merupakan generator website statis.
|
||||
Petunjuk yang disarankan untuk menjalankan Dokumentasi Kubernetes pada mesin lokal kamus adalah dengan menggunakan [Docker](https://docker.com) **image** yang memiliki **package** [Hugo](https://gohugo.io), **Hugo** sendiri merupakan generator website statis.
|
||||
|
||||
> Jika kamu menggunakan Windows, kamu mungkin membutuhkan beberapa langkah tambahan untuk melakukan instalasi perangkat lunak yang dibutuhkan. Instalasi ini dapat dilakukan dengan menggunakan [Chocolatey](https://chocolatey.org). `choco install make`
|
||||
|
||||
> Jika kamu ingin menjalankan **website** tanpa menggunakan **Docker**, kamu dapat melihat tautan berikut [Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo](#petunjuk-untuk-menjalankan-website-pada-mesin-lokal-dengan-menggunakan-hugo) di bagian bawah.
|
||||
> Jika kamu ingin menjalankan **website** tanpa menggunakan **Docker**, kamu dapat melihat tautan berikut [Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo](#petunjuk-untuk-menjalankan-website-pada-mesin-lokal-denga-menggunakan-hugo) di bagian bawah.
|
||||
|
||||
Jika kamu sudah memiliki **Docker** [yang sudah dapat digunakan](https://www.docker.com/get-started), kamu dapat melakukan **build** `kubernetes-hugo` **Docker image** secara lokal:
|
||||
|
||||
@@ -44,7 +44,7 @@ Buka **browser** kamu ke http://localhost:1313 untuk melihat laman dokumentasi.
|
||||
|
||||
## Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo
|
||||
|
||||
Kamu dapat melihat [dokumentasi resmi Hugo](https://gohugo.io/getting-started/installing/) untuk mengetahui langkah yang diperlukan untuk melakukan instalasi **Hugo**. Pastikan kamu melakukan instalasi versi **Hugo** sesuai dengan versi yang tersedia pada **environment variable** `HUGO_VERSION` pada **file**[`netlify.toml`](netlify.toml#L9).
|
||||
Kamu dapat melihat [dokumentasi resmi Hugo](https://gohugo.io/getting-started/installing/) untuk mengetahui langkah yang diperlukan untuk melakukan instalasi **Hugo**. Pastikan kamu melakukan instalasi versi **Hugo** sesuai dengan versi yang tersedia pada **environment variable** `HUGO_VERSION` pada **file**[`netlify.toml`](netlify.toml#L9).
|
||||
|
||||
Untuk menjalankan laman pada mesin lokal setelah instalasi **Hugo**, kamu dapat menjalankan perintah berikut:
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# La documentazione di Kubernetes
|
||||
|
||||
[](https://travis-ci.org/kubernetes/website)
|
||||
[](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
Benvenuto! Questo repository contiene tutte le informazioni necessarie per creare la [documentazione e il sito web di Kubernetes](https://kubernetes.io/). Siamo onorati che tu voglia contribuire!
|
||||
|
||||
## Come contribuire alla documentazione
|
||||
|
||||
Puoi premere il pulsante **Fork** in alto nella parte destra dello schermo per creare una copia di questo repository sotto la tua utenza di GitHub. Questa copia è chiamata un *fork*. Puoi fare tutte le modifiche che vuoi nel tuo fork, e quando sei pronto a mandarci i cambiamenti, vai sulla pagina del tuo fork e crea una nuova pull request per farcelo sapere.
|
||||
|
||||
Una volta che hai creato la pull request, un reviewer (revisore) Kubernetes la prenderà in carico per fornire un feedback chiaro e concretamente attuabile. Come owner della pull request, **è tua responsabilità modificare la tua pull request per rispondere al feedback che ti è stato fornito dal reviewer Kubernetes**. Inoltre, tieni presente che potresti ricevere feedback da più di un Reviewer di Kubernetes, incluse quindi persone diverse da quella che ti ha fornito il primo feedback. In alcuni casi, uno dei tuoi reviewer potrebbe richiedere una revisione tecnica da un [technical reviewer di Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) quando necessario. I reviewer faranno del loro meglio per fornire feedback in modo tempestivo, ma i tempi di risposta possono variare in base alle circostanze.
|
||||
|
||||
Per maggiori informazioni su come contribuire alla documentazione Kubernetes, vedi:
|
||||
|
||||
* [Cominciare a contribuire](https://kubernetes.io/docs/contribute/start/)
|
||||
* [Vedere le modifiche localmente](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
|
||||
* [Utilizzare i template delle pagine](http://kubernetes.io/docs/contribute/style/page-templates/)
|
||||
* [Guida Stilistica per la documentazione di Kubernetes](http://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
* [Tradurre la documentazione di Kubernetes](https://kubernetes.io/docs/contribute/localization/)
|
||||
|
||||
## Eseguire il sito Web localmente usando Docker
|
||||
|
||||
Il modo consigliato per eseguire localmente il sito Web Kubernetes prevede l'utilizzo di un'immagine [Docker](https://docker.com) inclusa nel sito e configurata con tutti i software necessari, a partire dal generatore di siti web statici [Hugo](https://gohugo.io).
|
||||
|
||||
> Se stai utilizzando Windows, avrai bisogno di alcuni strumenti aggiuntivi che puoi installare con [Chocolatey](https://chocolatey.org). `choco install make`
|
||||
|
||||
> Se preferisci eseguire il sito Web localmente senza Docker, vedi [Eseguire il sito Web localmente utilizzando Hugo](#eseguire-il-sito-web-localmente-utilizzando-hugo) di seguito.
|
||||
|
||||
Se hai Docker [attivo e funzionante](https://www.docker.com/get-started), crea l'immagine Docker `kubernetes-hugo` localmente:
|
||||
|
||||
```bash
|
||||
make docker-image
|
||||
```
|
||||
|
||||
Dopo aver creato l'immagine, è possibile eseguire il sito Web localmente:
|
||||
|
||||
```bash
|
||||
make docker-serve
|
||||
```
|
||||
|
||||
Apri il tuo browser su http://localhost:1313 per visualizzare il sito Web. Mentre modifichi i file sorgenti, Hugo aggiorna automaticamente il sito Web e forza un aggiornamento della pagina visualizzata nel browser.
|
||||
|
||||
## Eseguire il sito Web localmente utilizzando Hugo
|
||||
|
||||
Vedi la [documentazione ufficiale di Hugo](https://gohugo.io/getting-started/installing/) per le istruzioni di installazione di Hugo. Assicurati di installare esattamente la versione di Hugo specificata dalla variabile d'ambiente `HUGO_VERSION` nel file [`netlify.toml`](netlify.toml#L9).
|
||||
|
||||
Per eseguire il sito Web localmente dopo aver installato Hugo:
|
||||
|
||||
```bash
|
||||
make serve
|
||||
```
|
||||
|
||||
Questo comando avvierà il server Hugo locale sulla porta 1313. Apri il tuo browser su http://localhost:1313 per visualizzare il sito Web. Mentre apporti modifiche ai file di origine, Hugo aggiorna il sito Web e forza un aggiornamento del browser.
|
||||
|
||||
## Community, discussioni, contribuire e supporto
|
||||
|
||||
Scopri come interagire con la community di Kubernetes nella [pagina della community](http://kubernetes.io/community/).
|
||||
|
||||
Puoi contattare i maintainers di questo progetto su:
|
||||
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
### Codice di condotta
|
||||
|
||||
La partecipazione alla comunità Kubernetes è regolata dal [Codice di condotta di Kubernetes](code-of-conduct.md).
|
||||
|
||||
## Grazie!
|
||||
|
||||
Kubernetes prospera grazie alla partecipazione della comunity e apprezziamo i tuoi contributi al nostro sito Web e alla nostra documentazione!
|
||||
@@ -1,87 +0,0 @@
|
||||
# Dokumentacja projektu Kubernetes
|
||||
|
||||
[](https://travis-ci.org/kubernetes/website)
|
||||
[](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
Witamy!
|
||||
|
||||
W tym repozytorium znajdziesz wszystko, czego potrzebujesz do zbudowania [strony internetowej Kubernetesa wraz z dokumentacją](https://kubernetes.io/). Bardzo nam miło, że chcesz wziąć udział w jej współtworzeniu!
|
||||
|
||||
## Twój wkład w dokumentację
|
||||
|
||||
Możesz kliknąć w przycisk **Fork** w prawym górnym rogu ekranu, aby stworzyć kopię tego repozytorium na swoim koncie GitHub. Taki rodzaj kopii (odgałęzienia) nazywa się *fork*. Zmieniaj w nim, co chcesz, a kiedy będziesz już gotowy/a przesłać te zmiany do nas, przejdź do swojej kopii i stwórz nowy *pull request*, abyśmy zostali o tym poinformowani.
|
||||
|
||||
Po stworzeniu *pull request*, jeden z recenzentów projektu Kubernetes podejmie się przekazania jasnych wskazówek pozwalających podjąć następne działania. Na Tobie, jako właścicielu *pull requesta*, **spoczywa odpowiedzialność za wprowadzenie poprawek zgodnie z uwagami recenzenta.** Może też się zdarzyć, że swoje uwagi zgłosi więcej niż jeden recenzent, lub że recenzję będzie robił ktoś inny, niż ten, kto został przydzielony na początku. W niektórych przypadkach, jeśli zajdzie taka potrzeba, recenzent może poprosić dodatkowo o recenzję jednego z [recenzentów technicznych](https://github.com/kubernetes/website/wiki/Tech-reviewers). Recenzenci zrobią wszystko, aby odpowiedzieć sprawnie, ale konkretny czas odpowiedzi zależy od wielu czynników.
|
||||
|
||||
Więcej informacji na temat współpracy przy tworzeniu dokumentacji znajdziesz na stronach:
|
||||
|
||||
* [Jak rozpocząć współpracę](https://kubernetes.io/docs/contribute/start/)
|
||||
* [Podgląd wprowadzanych zmian w dokumentacji](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
|
||||
* [Szablony stron](http://kubernetes.io/docs/contribute/style/page-templates/)
|
||||
* [Styl pisania dokumentacji](http://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
* [Lokalizacja dokumentacji Kubernetes](https://kubernetes.io/docs/contribute/localization/)
|
||||
|
||||
## Różne wersje językowe `README.md`
|
||||
| | |
|
||||
|---|---|
|
||||
|[README po francusku](README-fr.md)|[README po koreańsku](README-ko.md)|
|
||||
|[README po niemiecku](README-de.md)|[README po portugalsku](README-pt.md)|
|
||||
|[README w hindi](README-hi.md)|[README po hiszpańsku](README-es.md)|
|
||||
|[README po indonezyjsku](README-id.md)|[README po chińsku](README-zh.md)|
|
||||
|[README po japońsku](README-ja.md)|[README po polsku](README-pl.md)|
|
||||
|||
|
||||
|
||||
## Jak uruchomić lokalną kopię strony przy pomocy Dockera?
|
||||
|
||||
Zalecaną metodą uruchomienia serwisu internetowego Kubernetesa lokalnie jest użycie specjalnego obrazu [Dockera](https://docker.com), który zawiera generator stron statycznych [Hugo](https://gohugo.io).
|
||||
|
||||
> Użytkownicy Windows będą potrzebowali dodatkowych narzędzi, które mogą zainstalować przy pomocy [Chocolatey](https://chocolatey.org).
|
||||
|
||||
```bash
|
||||
choco install make
|
||||
```
|
||||
|
||||
> Jeśli wolisz uruchomić serwis lokalnie bez Dockera, przeczytaj [jak uruchomić serwis lokalnie przy pomocy Hugo](#jak-uruchomić-lokalną-kopię-strony-przy-pomocy-hugo) poniżej.
|
||||
|
||||
Jeśli [zainstalowałeś i uruchomiłeś](https://www.docker.com/get-started) już Dockera, zbuduj obraz `kubernetes-hugo` lokalnie:
|
||||
|
||||
```bash
|
||||
make docker-image
|
||||
```
|
||||
|
||||
Po zbudowaniu obrazu, możesz uruchomić serwis lokalnie:
|
||||
|
||||
```bash
|
||||
make docker-serve
|
||||
```
|
||||
|
||||
Aby obejrzeć zawartość serwisu otwórz w przeglądarce adres http://localhost:1313. Po każdej zmianie plików źródłowych, Hugo automatycznie aktualizuje stronę i odświeża jej widok w przeglądarce.
|
||||
|
||||
## Jak uruchomić lokalną kopię strony przy pomocy Hugo?
|
||||
|
||||
Zajrzyj do [oficjalnej dokumentacji Hugo](https://gohugo.io/getting-started/installing/) po instrukcję instalacji. Upewnij się, że instalujesz rozszerzoną wersję Hugo, określoną przez zmienną środowiskową `HUGO_VERSION` w pliku [`netlify.toml`](netlify.toml#L9).
|
||||
|
||||
Aby uruchomić serwis lokalnie po instalacji Hugo, napisz:
|
||||
|
||||
```bash
|
||||
make serve
|
||||
```
|
||||
|
||||
Zostanie uruchomiony lokalny serwer Hugo na porcie 1313. Otwórz w przeglądarce adres http://localhost:1313, aby obejrzeć zawartość serwisu. Po każdej zmianie plików źródłowych, Hugo automatycznie aktualizuje stronę i odświeża jej widok w przeglądarce.
|
||||
|
||||
## Społeczność, listy dyskusyjne, uczestnictwo i wsparcie
|
||||
|
||||
Zajrzyj na stronę [społeczności](http://kubernetes.io/community/), aby dowiedzieć się, jak możesz zaangażować się w jej działania.
|
||||
|
||||
Możesz kontaktować się z gospodarzami projektu za pomocą:
|
||||
|
||||
* [Komunikatora Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
* [List dyskusyjnych](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
### Zasady postępowania
|
||||
|
||||
Udział w działaniach społeczności Kubernetes jest regulowany przez [Kodeks postępowania](code-of-conduct.md).
|
||||
|
||||
## Dziękujemy!
|
||||
|
||||
Kubernetes rozkwita dzięki zaangażowaniu społeczności — doceniamy twój wkład w tworzenie naszego serwisu i dokumentacji!
|
||||
+7
-7
@@ -7,7 +7,7 @@
|
||||
|
||||
## Вклад в документацию
|
||||
|
||||
Нажмите на кнопку **Fork** в правом верхнем углу, чтобы создать копию этого репозитория в ваш GitHub-аккаунт. Эта копия называется *форк-репозиторием*. Делайте любые изменения в вашем форк-репозитории, и когда вы будете готовы опубликовать изменения, откройте форк-репозиторий и создайте новый пулреквест, чтобы уведомить нас.
|
||||
Нажмите на кнопку **Fork** в правом верхнем углу, чтобы создать копию этого репозитория в ваш GitHub-аккаунт. Это копия называется *форк-репозиторием*. Делайте любые изменения в вашем форк-репозитории, и когда вы будете готовы опубликовать изменения, откройте форк-репозиторий и создайте новый пулреквест, чтобы уведомить нас.
|
||||
|
||||
После того, как вы отправите пулреквест, ревьювер Kubernetes даст по нему обратную связь. Вы, как автор пулреквеста, **должны обновить свой пулреквест после его рассмотрения ревьювером Kubernetes.** Вполне возможно, что более одного ревьювера Kubernetes оставят свои комментарии или даже может быть так, что новый комментарий ревьювера Kubernetes будет отличаться от первоначального назначенного ревьювера. Кроме того, в некоторых случаях один из ревьюверов может запросить технический обзор у [технического ревьювера Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers), если это будет необходимо. Ревьюверы сделают все возможное, чтобы как можно оперативно оставить свои предложения и пожелания, но время ответа может варьироваться в зависимости от обстоятельств.
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
> Если вы используете Windows, вам необходимо установить дополнительные инструменты через [Chocolatey](https://chocolatey.org). `choco install make`
|
||||
|
||||
> Если вы хотите запустить сайт локально без Docker, обратитесь к разделу [Запуск сайта с помощью Hugo](#запуск-сайта-с-помощью-hugo) ниже на этой странице.
|
||||
> Если вы хотите запустить сайт локально без Docker, обратитесь к разделу [Запуск сайта с помощью Hugo](#running-the-site-locally-using-hugo) ниже на этой странице.
|
||||
|
||||
Когда Docker [установлен и запущен](https://www.docker.com/get-started), соберите локально Docker-образ `kubernetes-hugo`, выполнив команду в консоли:
|
||||
|
||||
@@ -50,9 +50,9 @@ make docker-serve
|
||||
|
||||
Откройте браузер и перейдите по ссылке http://localhost:1313, чтобы открыть сайт. Если вы редактируете исходные файлы сайта, Hugo автоматически применит изменения и обновит страницу в браузере.
|
||||
|
||||
## Запуск сайта с помощью Hugo
|
||||
## Запуск сайта с помощью Hugo {#running-the-site-locally-using-hugo}
|
||||
|
||||
Обратитесь к [официальной документации Hugo](https://gohugo.io/getting-started/installing/), чтобы установить Hugo. Убедитесь, что вы установили правильную версию Hugo, которая устанавливается в переменной окружения `HUGO_VERSION` в файле [`netlify.toml`](netlify.toml#L10).
|
||||
Обратитесь к [официальной документации Hugo](https://gohugo.io/getting-started/installing/), чтобы установить Hugo. Убедитесь, что вы установили правильную версию Hugo, которая устанавливается в переменной окружения `HUGO_VERSION` в файле [`netlify.toml`](netlify.toml#L9).
|
||||
|
||||
После установки Hugo, чтобы запустить сайт, выполните в консоли:
|
||||
|
||||
@@ -60,7 +60,7 @@ make docker-serve
|
||||
make serve
|
||||
```
|
||||
|
||||
Эта команда запустит сервер Hugo на порту 1313. Откройте браузер и перейдите по ссылке http://localhost:1313, чтобы открыть сайт. Если вы отредактируете исходные файлы сайта, Hugo автоматически применит изменения и обновит страницу в браузере.
|
||||
Эта команда запустит сервер Hugo на порту 1313. Откройте браузер и перейдите по ссылке http://localhost:1313, чтобы открыть сайта. Если вы отредактируете исходные файлы сайта, Hugo автоматически применит изменения и обновит страницу в браузере.
|
||||
|
||||
## Сообщество, обсуждение, вклад и поддержка
|
||||
|
||||
@@ -71,9 +71,9 @@ make serve
|
||||
- [Канал в Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
- [Рассылка](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
### Кодекс поведения
|
||||
### Нормы поведения
|
||||
|
||||
Участие в сообществе Kubernetes регулируется [кодексом поведения Kubernetes](code-of-conduct.md).
|
||||
Участие в сообществе Kubernetes регулируется [нормами поведения Kubernetes](code-of-conduct.md).
|
||||
|
||||
## Спасибо!
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# Документація Kubernetes
|
||||
|
||||
[](https://travis-ci.org/kubernetes/website)
|
||||
[](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
Вітаємо! В цьому репозиторії міститься все необхідне для роботи над [сайтом і документацією Kubernetes](https://kubernetes.io/). Ми щасливі, що ви хочете зробити свій внесок!
|
||||
|
||||
## Внесок у документацію
|
||||
|
||||
Ви можете створити копію цього репозиторія у своєму акаунті на GitHub, натиснувши на кнопку **Fork**, що розташована справа зверху. Ця копія називатиметься *fork* (відгалуження). Зробіть будь-які необхідні зміни у своєму відгалуженні. Коли ви будете готові надіслати їх нам, перейдіть до свого відгалуження і створіть новий pull request, щоб сповістити нас.
|
||||
|
||||
Після того, як ви створили pull request, рецензент Kubernetes зобов’язується надати вам по ньому чіткий і конструктивний коментар. **Ваш обов’язок як творця pull request - відкоригувати його відповідно до зауважень рецензента Kubernetes.** Також, зауважте: може статися так, що ви отримаєте коментарі від декількох рецензентів Kubernetes або від іншого рецензента, ніж той, якого вам було призначено від початку. Крім того, за потреби один із ваших рецензентів може запросити технічну перевірку від одного з [технічних рецензентів Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers). Рецензенти намагатимуться відреагувати вчасно, проте час відповіді може відрізнятися в залежності від обставин.
|
||||
|
||||
Більше інформації про внесок у документацію Kubernetes ви знайдете у наступних джерелах:
|
||||
|
||||
* [Внесок: з чого почати](https://kubernetes.io/docs/contribute/start/)
|
||||
* [Візуалізація запропонованих змін до документації](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
|
||||
* [Використання шаблонів сторінок](http://kubernetes.io/docs/contribute/style/page-templates/)
|
||||
* [Керівництво зі стилю оформлення документації](http://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
* [Переклад документації Kubernetes іншими мовами](https://kubernetes.io/docs/contribute/localization/)
|
||||
|
||||
## Запуск сайту локально за допомогою Docker
|
||||
|
||||
Для локального запуску сайту Kubernetes рекомендовано запустити спеціальний [Docker](https://docker.com)-образ, що містить генератор статичних сайтів [Hugo](https://gohugo.io).
|
||||
|
||||
> Якщо ви працюєте під Windows, вам знадобиться ще декілька інструментів, які можна встановити за допомогою [Chocolatey](https://chocolatey.org). `choco install make`
|
||||
|
||||
> Якщо ви вважаєте кращим запустити сайт локально без використання Docker, дивіться пункт нижче [Запуск сайту локально за допомогою Hugo](#запуск-сайту-локально-зa-допомогою-hugo).
|
||||
|
||||
Якщо у вас вже [запущений](https://www.docker.com/get-started) Docker, зберіть локальний Docker-образ `kubernetes-hugo`:
|
||||
|
||||
```bash
|
||||
make docker-image
|
||||
```
|
||||
|
||||
Після того, як образ зібрано, ви можете запустити сайт локально:
|
||||
|
||||
```bash
|
||||
make docker-serve
|
||||
```
|
||||
|
||||
Відкрийте у своєму браузері http://localhost:1313, щоб побачити сайт. По мірі того, як ви змінюєте вихідний код, Hugo актуалізує сайт відповідно до внесених змін і оновлює сторінку у браузері.
|
||||
|
||||
## Запуск сайту локально зa допомогою Hugo
|
||||
|
||||
Для інструкцій по установці Hugo дивіться [офіційну документацію](https://gohugo.io/getting-started/installing/). Обов’язково встановіть розширену версію Hugo, яка позначена змінною оточення `HUGO_VERSION` у файлі [`netlify.toml`](netlify.toml#L9).
|
||||
|
||||
Після установки Hugo, запустіть сайт локально командою:
|
||||
|
||||
```bash
|
||||
make serve
|
||||
```
|
||||
|
||||
Команда запустить локальний Hugo-сервер на порту 1313. Відкрийте у своєму браузері http://localhost:1313, щоб побачити сайт. По мірі того, як ви змінюєте вихідний код, Hugo актуалізує сайт відповідно до внесених змін і оновлює сторінку у браузері.
|
||||
|
||||
## Спільнота, обговорення, внесок і підтримка
|
||||
|
||||
Дізнайтеся, як долучитися до спільноти Kubernetes на [сторінці спільноти](http://kubernetes.io/community/).
|
||||
|
||||
Для зв’язку із супроводжуючими проекту скористайтеся:
|
||||
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
- [Поштова розсилка](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
### Кодекс поведінки
|
||||
|
||||
Участь у спільноті Kubernetes визначається правилами [Кодексу поведінки спільноти Kubernetes](code-of-conduct.md).
|
||||
|
||||
## Дякуємо!
|
||||
|
||||
Долучення до спільноти - запорука успішного розвитку Kubernetes. Ми цінуємо ваш внесок у наш сайт і документацію!
|
||||
+1
-1
@@ -26,7 +26,7 @@ Cách được đề xuất để chạy trang web Kubernetes cục bộ là dù
|
||||
|
||||
> Nếu bạn làm việc trên môi trường Windows, bạn sẽ cần thêm môt vài công cụ mà bạn có thể cài đặt với [Chocolatey](https://chocolatey.org). `choco install make`
|
||||
|
||||
> Nếu bạn không muốn dùng Docker để chạy trang web cục bộ, hãy xem [Chạy website cục bộ dùng Hugo](#chạy-website-cục-bộ-dùng-hugo) dưới đây.
|
||||
> Nếu bạn không muốn dùng Docker để chạy trang web cục bộ, hãy xem [Chạy website cục bộ dùng Hugo](#Chạy website cục bộ dùng Hugo) dưới đây.
|
||||
|
||||
Nếu bạn có Docker đang [up và running](https://www.docker.com/get-started), build `kubernetes-hugo` Docker image cục bộ:
|
||||
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ Open up your browser to http://localhost:1313 to view the website. As you make c
|
||||
<!--
|
||||
## Running the website locally using Hugo
|
||||
-->
|
||||
## 使用 Hugo 在本地运行网站 {#running-the-site-locally-using-hugo}
|
||||
## 使用 Hugo 在本地运行网站
|
||||
|
||||
<!--
|
||||
See the [official Hugo documentation](https://gohugo.io/getting-started/installing/) for Hugo installation instructions.
|
||||
|
||||
@@ -27,8 +27,7 @@ For more information about contributing to the Kubernetes documentation, see:
|
||||
|[Hindi README](README-hi.md)|[Spanish README](README-es.md)|
|
||||
|[Indonesian README](README-id.md)|[Chinese README](README-zh.md)|
|
||||
|[Japanese README](README-ja.md)|[Vietnamese README](README-vi.md)|
|
||||
|[Russian README](README-ru.md)|[Italian README](README-it.md)|
|
||||
|[Polish README](README-pl.md)|[Ukrainian README](README-uk.md)|
|
||||
|[Russian README](README-ru.md)|
|
||||
|||
|
||||
|
||||
## Running the website locally using Docker
|
||||
@@ -37,7 +36,7 @@ The recommended way to run the Kubernetes website locally is to run a specialize
|
||||
|
||||
> If you are running on Windows, you'll need a few more tools which you can install with [Chocolatey](https://chocolatey.org). `choco install make`
|
||||
|
||||
> If you'd prefer to run the website locally without Docker, see [Running the website locally using Hugo](#running-the-website-locally-using-hugo) below.
|
||||
> If you'd prefer to run the website locally without Docker, see [Running the website locally using Hugo](#running-the-site-locally-using-hugo) below.
|
||||
|
||||
If you have Docker [up and running](https://www.docker.com/get-started), build the `kubernetes-hugo` Docker image locally:
|
||||
|
||||
|
||||
+1
-1
@@ -10,6 +10,6 @@
|
||||
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
||||
# INSTRUCTIONS AT https://kubernetes.io/security/
|
||||
|
||||
bradamant3
|
||||
jimangel
|
||||
kbarnard10
|
||||
zacharysarah
|
||||
|
||||
@@ -107,9 +107,9 @@ header
|
||||
z-index: 8888
|
||||
background-color: transparent
|
||||
box-shadow: 0 0 0 transparent
|
||||
overflow: hidden
|
||||
transition: 0.3s
|
||||
text-align: center
|
||||
overflow: hidden
|
||||
|
||||
|
||||
.logo
|
||||
@@ -245,7 +245,6 @@ header
|
||||
background-color: white
|
||||
|
||||
#mainNav
|
||||
|
||||
h5
|
||||
color: $blue
|
||||
font-weight: normal
|
||||
@@ -578,9 +577,6 @@ section
|
||||
li
|
||||
display: inline-block
|
||||
height: 100%
|
||||
margin-right: 10px
|
||||
&:last-child
|
||||
margin-right: 0
|
||||
|
||||
a
|
||||
display: block
|
||||
@@ -601,11 +597,11 @@ section
|
||||
#vendorStrip
|
||||
line-height: 44px
|
||||
max-width: 100%
|
||||
overflow-x: auto
|
||||
-webkit-overflow-scrolling: touch
|
||||
|
||||
ul
|
||||
float: none
|
||||
overflow-x: auto
|
||||
|
||||
#searchBox
|
||||
float: none
|
||||
@@ -1055,9 +1051,6 @@ dd
|
||||
a.issue
|
||||
margin-left: 0px
|
||||
|
||||
.gridPageHome .flyout-button
|
||||
display: none
|
||||
|
||||
.feedback--no
|
||||
margin-left: 1em
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ $video-section-height: 550px
|
||||
padding-right: 10px
|
||||
|
||||
#home
|
||||
section, header
|
||||
section, header, footer
|
||||
.main-section
|
||||
max-width: 1000px
|
||||
|
||||
@@ -178,18 +178,16 @@ $video-section-height: 550px
|
||||
nav
|
||||
overflow: hidden
|
||||
margin-bottom: 20px
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
|
||||
a
|
||||
width: auto
|
||||
width: 16.65%
|
||||
float: left
|
||||
font-size: 24px
|
||||
font-weight: 300
|
||||
white-space: nowrap
|
||||
|
||||
.social
|
||||
padding: 0
|
||||
padding: 0 30px
|
||||
max-width: 1200px
|
||||
|
||||
div
|
||||
|
||||
@@ -133,21 +133,18 @@ $feature-box-div-width: 45%
|
||||
max-width: 25%
|
||||
max-height: 100%
|
||||
transform: translateY(-50%)
|
||||
width: 100%
|
||||
|
||||
&:nth-child(odd)
|
||||
padding-right: 210px
|
||||
|
||||
.image-wrapper
|
||||
right: 0
|
||||
text-align: right
|
||||
|
||||
&:nth-child(even)
|
||||
padding-left: 210px
|
||||
|
||||
.image-wrapper
|
||||
left: 0
|
||||
text-align: left
|
||||
|
||||
&:nth-child(1)
|
||||
padding-right: 0
|
||||
@@ -222,8 +219,9 @@ $feature-box-div-width: 45%
|
||||
footer
|
||||
nav
|
||||
text-align: center
|
||||
|
||||
a
|
||||
width: auto
|
||||
width: 30%
|
||||
padding: 0 20px
|
||||
|
||||
.social
|
||||
|
||||
+26
-51
@@ -25,8 +25,7 @@ enableGitInfo = true
|
||||
|
||||
# Norwegian ("no") is sometimes but not currently used for testing.
|
||||
# Hindi is disabled because it's currently in development.
|
||||
# Italian is disabled until it meets minimum standards for quality.
|
||||
disableLanguages = ["hi", "it", "no"]
|
||||
disableLanguages = ["hi", "no"]
|
||||
|
||||
[blackfriday]
|
||||
hrefTargetBlank = true
|
||||
@@ -66,10 +65,10 @@ time_format_blog = "Monday, January 02, 2006"
|
||||
description = "Production-Grade Container Orchestration"
|
||||
showedit = true
|
||||
|
||||
latest = "v1.18"
|
||||
latest = "v1.17"
|
||||
|
||||
fullversion = "v1.18.0"
|
||||
version = "v1.18"
|
||||
fullversion = "v1.17.0"
|
||||
version = "v1.17"
|
||||
githubbranch = "master"
|
||||
docsbranch = "master"
|
||||
deprecated = false
|
||||
@@ -83,6 +82,12 @@ announcement = false
|
||||
# announcement_message is only displayed when announcement = true; update with your specific message
|
||||
announcement_message = "The Kubernetes Documentation team would like your feedback! Please take a <a href='https://www.surveymonkey.com/r/8R237FN' target='_blank'>short survey</a> so we can improve the Kubernetes online documentation."
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.17.0"
|
||||
version = "v1.17"
|
||||
githubbranch = "v1.17.0"
|
||||
docsbranch = "release-1.17"
|
||||
url = "https://kubernetes.io"
|
||||
|
||||
[params.pushAssets]
|
||||
css = [
|
||||
@@ -96,40 +101,33 @@ js = [
|
||||
]
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.18.0"
|
||||
version = "v1.18"
|
||||
githubbranch = "v1.18.0"
|
||||
docsbranch = "release-1.18"
|
||||
url = "https://kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.17.4"
|
||||
version = "v1.17"
|
||||
githubbranch = "v1.17.4"
|
||||
docsbranch = "release-1.17"
|
||||
url = "https://v1-17.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.16.8"
|
||||
fullversion = "v1.16.3"
|
||||
version = "v1.16"
|
||||
githubbranch = "v1.16.8"
|
||||
githubbranch = "v1.16.3"
|
||||
docsbranch = "release-1.16"
|
||||
url = "https://v1-16.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.15.11"
|
||||
fullversion = "v1.15.6"
|
||||
version = "v1.15"
|
||||
githubbranch = "v1.15.11"
|
||||
githubbranch = "v1.15.6"
|
||||
docsbranch = "release-1.15"
|
||||
url = "https://v1-15.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.14.10"
|
||||
fullversion = "v1.14.9"
|
||||
version = "v1.14"
|
||||
githubbranch = "v1.14.10"
|
||||
githubbranch = "v1.14.9"
|
||||
docsbranch = "release-1.14"
|
||||
url = "https://v1-14.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.13.12"
|
||||
version = "v1.13"
|
||||
githubbranch = "v1.13.12"
|
||||
docsbranch = "release-1.13"
|
||||
url = "https://v1-13.docs.kubernetes.io"
|
||||
|
||||
# Language definitions.
|
||||
|
||||
[languages]
|
||||
@@ -175,7 +173,7 @@ language_alternatives = ["en"]
|
||||
|
||||
[languages.fr]
|
||||
title = "Kubernetes"
|
||||
description = "Solution professionnelle d’orchestration de conteneurs"
|
||||
description = "Production-Grade Container Orchestration"
|
||||
languageName ="Français"
|
||||
weight = 5
|
||||
contentDir = "content/fr"
|
||||
@@ -188,7 +186,7 @@ language_alternatives = ["en"]
|
||||
[languages.it]
|
||||
title = "Kubernetes"
|
||||
description = "Production-Grade Container Orchestration"
|
||||
languageName ="Italian"
|
||||
languageName = "Italiano"
|
||||
weight = 6
|
||||
contentDir = "content/it"
|
||||
|
||||
@@ -223,7 +221,7 @@ language_alternatives = ["en"]
|
||||
|
||||
[languages.es]
|
||||
title = "Kubernetes"
|
||||
description = "Orquestación de contenedores para producción"
|
||||
description = "Production-Grade Container Orchestration"
|
||||
languageName ="Español"
|
||||
weight = 9
|
||||
contentDir = "content/es"
|
||||
@@ -287,26 +285,3 @@ time_format_blog = "02.01.2006"
|
||||
# A list of language codes to look for untranslated content, ordered from left to right.
|
||||
language_alternatives = ["en"]
|
||||
|
||||
[languages.pl]
|
||||
title = "Kubernetes"
|
||||
description = "Produkcyjny system zarządzania kontenerami"
|
||||
languageName = "Polski"
|
||||
weight = 13
|
||||
contentDir = "content/pl"
|
||||
|
||||
[languages.pl.params]
|
||||
time_format_blog = "01.02.2006"
|
||||
# A list of language codes to look for untranslated content, ordered from left to right.
|
||||
language_alternatives = ["en"]
|
||||
|
||||
[languages.uk]
|
||||
title = "Kubernetes"
|
||||
description = "Довершена система оркестрації контейнерів"
|
||||
languageName = "Українська"
|
||||
weight = 14
|
||||
contentDir = "content/uk"
|
||||
|
||||
[languages.uk.params]
|
||||
time_format_blog = "02.01.2006"
|
||||
# A list of language codes to look for untranslated content, ordered from left to right.
|
||||
language_alternatives = ["en"]
|
||||
|
||||
@@ -44,12 +44,12 @@ Kubernetes ist Open Source und bietet Ihnen die Freiheit, die Infrastruktur vor
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://events.linuxfoundation.org/events/kubecon-cloudnativecon-europe-2020/" button id="desktopKCButton">Besuchen Sie die KubeCon vom 30 März-2 Apr. 2020 in Amsterdam</a>
|
||||
<a href="https://events.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019" button id="desktopKCButton">KubeCon vom 18-21. November 2019 in San Diego</a>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://www.lfasiallc.cn/kubecon-cloudnativecon-open-source-summit-china/" button id="desktopKCButton">Besuchen Sie die KubeCon vom 28-30 Juli 2020 in Shanghai</a>
|
||||
<a href="https://events.linuxfoundation.org/events/kubecon-cloudnativecon-europe-2020/" button id="desktopKCButton">KubeCon vom 30 März-2 Apr. 2020 in Amsterdam</a>
|
||||
</div>
|
||||
<div id="videoPlayer">
|
||||
<iframe data-url="https://www.youtube.com/embed/H06qrNmGqyE?autoplay=1" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
title: Community
|
||||
layout: basic
|
||||
cid: community
|
||||
css: /css/community.css
|
||||
---
|
||||
|
||||
<div class="community_main">
|
||||
<h1>Kubernetes Community Code of Conduct</h1>
|
||||
|
||||
Kubernetes folgt dem
|
||||
<a href="https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/de.md">CNCF Verhaltenskodex</a>.
|
||||
Der Kodex befindet sich weiter unten auf der Seite, wie er auch in
|
||||
<a href="https://github.com/cncf/foundation/blob/214585e24aab747fb85c2ea44fbf4a2442e30de6/code-of-conduct-languages/de.md">Commit 214585e</a> gefunden werden kann.
|
||||
Wenn dir auffällt, dass die hier gezeigte Version nicht mehr aktuell ist,
|
||||
<a href="https://github.com/kubernetes/website/issues/new">eröffne bitte ein Issue</a>.
|
||||
|
||||
Wenn dir bei einem Event, einem Meeting, in Slack oder einem anderen
|
||||
Kommunikationskanal ein Verstoß gegen den Verhaltenskodex auffällt, wende dich an das <a href="https://git.k8s.io/community/committee-code-of-conduct">Kubernetes Code of Conduct Committee</a>.
|
||||
Du kannst das Komitee über E-Mail erreichen: <a href="mailto:conduct@kubernetes.io">conduct@kubernetes.io</a>.
|
||||
Deine Anonymität wird geschützt.
|
||||
|
||||
<div class="cncf_coc_container">
|
||||
{{< include "/static/cncf-code-of-conduct.md" >}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,2 +0,0 @@
|
||||
The files in this directory have been imported from other sources. Do not
|
||||
edit them directly, except by replacing them with new versions.
|
||||
@@ -1,30 +0,0 @@
|
||||
<!-- Do not edit this file directly. Get the latest from
|
||||
https://github.com/cncf/foundation/blob/master/code-of-conduct.md -->
|
||||
## CNCF Gemeinschafts-Verhaltenskodex v1.0
|
||||
|
||||
### Verhaltenskodex für Mitwirkende
|
||||
|
||||
Als Mitwirkende und Betreuer dieses Projekts und im Interesse der Förderung einer offenen und einladenden Gemeinschaft verpflichten wir uns dazu, alle Menschen zu respektieren, die durch Berichterstattung, Veröffentlichung von Eigenschaftsanfragen, Aktualisierung der Dokumentation, Einreichung von Pull-Anfragen oder Patches und anderen Aktivitäten einen Beitrag leisten.
|
||||
|
||||
Wir sind bestrebt, die Teilnahme an diesem Projekt für alle zu einer belästigungsfreien Erfahrung zu machen, unabhängig von Erfahrungsstand, Geschlecht, geschlechtsspezifischer Identität und Ausdruck, sexueller Orientierung, Behinderung, persönlichem Aussehen, Körpergröße, Rasse, ethnischer Herkunft, Alter, Religion oder Nationalität.
|
||||
|
||||
Beispiele für unzumutbares Verhalten der Teilnehmer sind:
|
||||
|
||||
- Der Gebrauch von sexualisierter Sprache oder Bildern
|
||||
- Persönliche Angriffe
|
||||
- Trolling oder beleidigende/herabwürdigende Kommentare
|
||||
- Öffentliche oder private Belästigungen
|
||||
- Veröffentlichung privater Informationen anderer, wie z.B. physischer oder elektronischer Adressen, ohne ausdrückliche Genehmigung
|
||||
- Anderes unethisches oder unprofessionelles Verhalten.
|
||||
|
||||
Projektbetreuer haben das Recht und die Verantwortung, Kommentare, Commits, Code, Wiki-Bearbeitungen, Probleme und andere Beiträge zu entfernen, zu bearbeiten oder abzulehnen, die nicht mit diesem Verhaltenskodex übereinstimmen. Mit der Annahme dieses Verhaltenskodex verpflichten sich die Projektbetreuer, diese Grundsätze fair und konsequent auf jeden Aspekt der Projektleitung anzuwenden. Projektbetreuer, die den Verhaltenskodex nicht befolgen oder durchsetzen, können dauerhaft vom Projektteam ausgeschlossen werden.
|
||||
|
||||
Dieser Verhaltenskodex gilt sowohl innerhalb von Projekträumen als auch in öffentlichen Räumen, wenn eine Person das Projekt oder seine Gemeinschaft vertritt.
|
||||
|
||||
Fälle von missbräuchlichem, belästigendem oder anderweitig unzumutbarem Verhalten in Kubernetes können gemeldet werden, indem Sie sich an das [Kubernetes Komitee für Verhaltenskodex](https://git.k8s.io/community/committee-code-of-conduct) wenden unter <conduct@kubernetes.io>. Für andere Projekte wenden Sie sich bitte an einen CNCF-Projektbetreuer oder an unseren Mediator, Mishi Choudhary <mishi@linux.com>.
|
||||
|
||||
Dieser Verhaltenskodex wurde aus dem Contributor Covenant übernommen (http://contributor-covenant.org), Version 1.2.0, verfügbar unter http://contributor-covenant.org/version/1/2/0/
|
||||
|
||||
### CNCF Verhaltenskodex für Veranstaltungen
|
||||
|
||||
Für CNCF Veranstaltungen gilt der Verhaltenskodex der Linux Foundation, der auf der Veranstaltungsseite verfügbar ist. Diese ist so konzipiert, dass sie mit der oben genannten Richtlinie kompatibel ist und enthält auch weitere Details zur Reaktion auf Vorfälle.
|
||||
@@ -52,7 +52,7 @@ Wenn Sie beispielsweise mit der Kubernetes-API ein Deployment-Objekt erstellen,
|
||||
|
||||
### Kubernetes Master
|
||||
|
||||
Der Kubernetes-Master ist für Erhalt des gewünschten Status Ihres Clusters verantwortlich. Wenn Sie mit Kubernetes interagieren, beispielsweise mit dem Kommandozeilen-Tool `kubectl`, kommunizieren Sie mit dem Kubernetes-Master Ihres Clusters.
|
||||
Der Kubernetes-Master ist für Erhalt des gewünschten Status Ihres Clusters verantwortlich. Wenn Sie mit Kubernetes interagieren, beispielsweise mit dem Kommanduzeilen-Tool `kubectl`, kommunizieren Sie mit dem Kubernetes-Master Ihres Clusters.
|
||||
|
||||
> Der Begriff "Master" bezeichnet dabei eine Reihe von Prozessen, die den Clusterstatus verwalten. Normalerweise werden diese Prozesse alle auf einem einzigen Node im Cluster ausgeführt. Dieser Node wird auch als Master bezeichnet. Der Master kann repliziert werden, um die Verfügbarkeit und Redundanz zu erhöhen.
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
title: Addons Installieren
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
|
||||
Add-Ons erweitern die Funktionalität von Kubernetes.
|
||||
|
||||
Diese Seite gibt eine Übersicht über einige verfügbare Add-Ons und verweist auf die entsprechenden Installationsanleitungen.
|
||||
|
||||
Die Add-Ons in den einzelnen Kategorien sind alphabetisch sortiert - Die Reihenfolge impliziert keine bevorzugung einzelner Projekte.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Networking und Network Policy
|
||||
|
||||
* [ACI](https://www.github.com/noironetworks/aci-containers) bietet Container-Networking und Network-Security mit Cisco ACI.
|
||||
* [Calico](https://docs.projectcalico.org/latest/introduction/) ist ein Networking- und Network-Policy-Provider. Calico unterstützt eine Reihe von Networking-Optionen, damit Du die richtige für deinen Use-Case wählen kannst. Dies beinhaltet Non-Overlaying and Overlaying-Networks mit oder ohne BGP. Calico nutzt die gleiche Engine um Network-Policies für Hosts, Pods und (falls Du Istio & Envoy benutzt) Anwendungen auf Service-Mesh-Ebene durchzusetzen.
|
||||
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install) vereint Flannel und Calico um Networking- und Network-Policies bereitzustellen.
|
||||
* [Cilium](https://github.com/cilium/cilium) ist ein L3 Network- and Network-Policy-Plugin welches das transparent HTTP/API/L7-Policies durchsetzen kann. Sowohl Routing- als auch Overlay/Encapsulation-Modes werden uterstützt. Außerdem kann Cilium auf andere CNI-Plugins aufsetzen.
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) ermöglicht das nahtlose Verbinden von Kubernetes mit einer Reihe an CNI-Plugins wie z.B. Calico, Canal, Flannel, Romana, oder Weave.
|
||||
* [Contiv](http://contiv.github.io) bietet konfigurierbares Networking (Native L3 auf BGP, Overlay mit vxlan, Klassisches L2, Cisco-SDN/ACI) für verschiedene Anwendungszwecke und auch umfangreiches Policy-Framework. Das Contiv-Projekt ist vollständig [Open Source](http://github.com/contiv). Der [installer](http://github.com/contiv/install) bietet sowohl kubeadm als auch nicht-kubeadm basierte Installationen.
|
||||
* [Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), basierend auf [Tungsten Fabric](https://tungsten.io), ist eine Open Source, multi-Cloud Netzwerkvirtualisierungs- und Policy-Management Plattform. Contrail und Tungsten Fabric sind mit Orechstratoren wie z.B. Kubernetes, OpenShift, OpenStack und Mesos integriert und bieten Isolationsmodi für Virtuelle Maschinen, Container (bzw. Pods) und Bare Metal workloads.
|
||||
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md) ist ein Overlay-Network-Provider der mit Kubernetes genutzt werden kann.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/) ist eine Network-Lösung die Mehrfach-Network in Kubernetes ermöglicht.
|
||||
* [Multus](https://github.com/Intel-Corp/multus-cni) ist ein Multi-Plugin für Mehrfachnetzwerk-Unterstützung um alle CNI-Plugins (z.B. Calico, Cilium, Contiv, Flannel), zusätzlich zu SRIOV-, DPDK-, OVS-DPDK- und VPP-Basierten Workloads in Kubernetes zu unterstützen.
|
||||
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) Container Plug-in (NCP) bietet eine Integration zwischen VMware NSX-T und einem Orchestator wie z.B. Kubernetes. Außerdem bietet es eine Integration zwischen NSX-T und Containerbasierten CaaS/PaaS-Plattformen wie z.B. Pivotal Container Service (PKS) und OpenShift.
|
||||
* [Nuage](https://github.com/nuagenetworks/nuage-kubernetes/blob/v5.1.1-1/docs/kubernetes-1-installation.rst) ist eine SDN-Plattform die Policy-Basiertes Networking zwischen Kubernetes Pods und nicht-Kubernetes Umgebungen inklusive Sichtbarkeit und Security-Monitoring bereitstellt.
|
||||
* [Romana](http://romana.io) ist eine Layer 3 Network-Lösung für Pod-Netzwerke welche auch die [NetworkPolicy API](/docs/concepts/services-networking/network-policies/) unterstützt. Details zur Installation als kubeadm Add-On sind [hier](https://github.com/romana/romana/tree/master/containerize) verfügbar.
|
||||
* [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) bietet Networking and Network-Policies und arbeitet auf beiden Seiten der Network-Partition ohne auf eine externe Datenbank angwiesen zu sein.
|
||||
|
||||
## Service-Discovery
|
||||
|
||||
* [CoreDNS](https://coredns.io) ist ein flexibler, erweiterbarer DNS-Server der in einem Cluster [installiert](https://github.com/coredns/deployment/tree/master/kubernetes) werden kann und das Cluster-interne DNS für Pods bereitzustellen.
|
||||
|
||||
## Visualisierung & Überwachung
|
||||
|
||||
* [Dashboard](https://github.com/kubernetes/dashboard#kubernetes-dashboard) ist ein Dashboard Web Interface für Kubernetes.
|
||||
* [Weave Scope](https://www.weave.works/documentation/scope-latest-installing/#k8s) ist ein Tool um Container, Pods, Services usw. Grafisch zu visualieren. Kann in Verbindung mit einem [Weave Cloud Account](https://cloud.weave.works/) genutzt oder selbst gehosted werden.
|
||||
|
||||
## Infrastruktur
|
||||
|
||||
* [KubeVirt](https://kubevirt.io/user-guide/docs/latest/administration/intro.html#cluster-side-add-on-deployment) ist ein Add-On um Virtuelle Maschinen in Kubernetes auszuführen. Wird typischer auf Bare-Metal Clustern eingesetzt.
|
||||
|
||||
## Legacy Add-Ons
|
||||
|
||||
Es gibt einige weitere Add-Ons die in dem abgekündigten [cluster/addons](https://git.k8s.io/kubernetes/cluster/addons)-Verzeichnis dokumentiert sind.
|
||||
|
||||
Add-Ons die ordentlich gewartet werden dürfen gerne hier aufgezählt werden. Wir freuen uns auf PRs!
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -96,7 +96,7 @@ Das Google service Konto der Instanz hat einen `https://www.googleapis.com/auth/
|
||||
|
||||
Kubernetes eine native Unterstützung für die [Amazon Elastic Container Registry](https://aws.amazon.com/ecr/) wenn Knoten AWS EC2 Instanzen sind.
|
||||
|
||||
Es muss einfach nur der komplette Image Name (z.B. `ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag`) in der Pod - Definition genutzt werden.
|
||||
Es muss einfah nur der komplette Image Name (z.B. `ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag`) in der Pod - Definition genutzt werden.
|
||||
|
||||
Alle Benutzer eines Clusters die Pods erstellen dürfen können dann jedes der Images in der ECR Registry zum Ausführen von Pods nutzen.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Kubernetes Dokumentation
|
||||
noedit: true
|
||||
cid: docsHome
|
||||
layout: docsportal_home
|
||||
class: gridPage gridPageHome
|
||||
class: gridPage
|
||||
linkTitle: "Home"
|
||||
main_menu: true
|
||||
weight: 10
|
||||
|
||||
@@ -15,5 +15,5 @@ tags:
|
||||
|
||||
<!--more-->
|
||||
|
||||
Halten Sie immer einen Sicherungsplan für etcds Daten für Ihren Kubernetes-Cluster bereit. Ausführliche Informationen zu etcd finden Sie in der [etcd Dokumentation](https://etcd.io/docs).
|
||||
Halten Sie immer einen Sicherungsplan für etcds Daten für Ihren Kubernetes-Cluster bereit. Ausführliche Informationen zu etcd finden Sie in der [etcd Dokumentation](https://github.com/coreos/etcd/blob/master/Documentation/docs.md).
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ source <(kubectl completion bash) # Wenn Sie autocomplete in bash in der aktuell
|
||||
echo "source <(kubectl completion bash)" >> ~/.bashrc # Fügen Sie der Bash-Shell dauerhaft Autocomplete hinzu.
|
||||
```
|
||||
|
||||
Sie können auch ein Abkürzungsalias für `kubectl` verwenden, welches auch mit Vervollständigung funktioniert:
|
||||
Sie können auch ein Abkürzungsalias für `kubectl` verwenden, weleches auch mit Vervollständigung funktioniert:
|
||||
|
||||
```bash
|
||||
alias k=kubectl
|
||||
@@ -180,7 +180,7 @@ kubectl get events --sort-by=.metadata.creationTimestamp
|
||||
|
||||
## Ressourcen aktualisieren
|
||||
|
||||
Ab Version 1.11 ist das `rolling-update` veraltet (Lesen Sie [CHANGELOG-1.11.md](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.11.md) für weitere Informationen), verwenden Sie stattdessen `rollout`.
|
||||
Ab Version 1.11 ist das `rolling-update` veraltet (Lesen Sie [CHANGELOG-1.11.md](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md) für weitere Informationen), verwenden Sie stattdessen `rollout`.
|
||||
|
||||
```bash
|
||||
kubectl set image deployment/frontend www=image:v2 # Fortlaufende Aktualisierung der "www" Container der "Frontend"-Bereitstellung, Aktualisierung des Images
|
||||
|
||||
@@ -7,96 +7,76 @@ content_template: templates/concept
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
Diese Sektion umfasst verschiedene Optionen zum Einrichten und Betrieb von Kubernetes.
|
||||
Auf dieser Seite finden Sie die Lösung, die Ihren Anforderungen am besten entspricht.
|
||||
|
||||
Verschiedene Kubernetes Lösungen haben verschiedene Anforderungen: Einfache Wartung, Sicherheit, Kontrolle, verfügbare Resourcen und erforderliches Fachwissen zum Betrieb und zur Verwaltung dess folgende Diagramm zeigt die möglichen Abstraktionen eines Kubernetes-Clusters und ob eine Abstraktion selbst verwaltet oder von einem Anbieter verwaltet wird.
|
||||
|
||||
Sie können einen Kubernetes-Cluster auf einer lokalen Maschine, Cloud, On-Prem Datacenter bereitstellen; oder wählen Sie einen verwalteten Kubernetes-Cluster. Sie können auch eine individuelle Lösung über eine grosse Auswahl an Cloud Anbietern oder Bare-Metal-Umgebungen nutzen.
|
||||
|
||||
Noch einfacher können Sie einen Kubernetes-Cluster in einer Lern- und Produktionsumgebung erstellen.
|
||||
Die Entscheidung, wo Kubernetes ausgeführt wird, hängt davon ab, welche Ressourcen Sie zur Verfügung haben und wie viel Flexibilität Sie benötigen.
|
||||
Sie können Kubernetes fast überall ausführen, von Ihrem Laptop über VMs bei einem Cloud-Anbieter bis hin zu Bare-Metal-Servern.
|
||||
Sie können einen vollständig verwalteten Cluster einrichten, indem Sie einen einzelnen Befehl ausführen oder einen eigenen benutzerdefinierten Cluster auf Ihren Bare-Metal-Servern erstellen.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Lernumgebung
|
||||
## Lösungen für lokale Maschinen
|
||||
|
||||
Benutzen Sie eine Docker-basierende Lösung, wenn Sie Kubernetes erlernen wollen: Von der Kubernetes-Community unterstützte Werkzeuge oder Werkzeuge in einem Ökosystem zum Einrichten eines Kubernetes-Clusters auf einer lokalen Maschine.
|
||||
Eine lokale Lösung ist eine einfache Möglichkeit, mit Kubernetes anzufangen.
|
||||
Sie können Kubernetes-Cluster erstellen und testen, ohne sich Gedanken über den Verbrauch von Cloud-Ressourcen und -Kontingenten machen zu müssen.
|
||||
|
||||
{{< table caption="Tabelle mit Lösungen für lokale Maschinen, in der die Tools aufgeführt sind, die von der Community und dem Ökosystem für die Bereitstellung von Kubernetes unterstützt werden." >}}
|
||||
Sie sollten eine lokale Lösung auswählen, wenn Sie:
|
||||
|
||||
|Community |Ökosystem |
|
||||
| ------------ | -------- |
|
||||
| [Minikube](/docs/setup/learning-environment/minikube/) | [CDK on LXD](https://www.ubuntu.com/kubernetes/docs/install-local) |
|
||||
| [kind (Kubernetes IN Docker)](https://github.com/kubernetes-sigs/kind) | [Docker Desktop](https://www.docker.com/products/docker-desktop)|
|
||||
| | [Minishift](https://docs.okd.io/latest/minishift/)|
|
||||
| | [MicroK8s](https://microk8s.io/)|
|
||||
| | [IBM Cloud Private-CE (Community Edition)](https://github.com/IBM/deploy-ibm-cloud-private) |
|
||||
| | [IBM Cloud Private-CE (Community Edition) on Linux Containers](https://github.com/HSBawa/icp-ce-on-linux-containers)|
|
||||
| | [k3s](https://k3s.io)|
|
||||
* Zum ausprobieren oder wenn Sie etwas über Kubernetes lernen möchten
|
||||
* Cluster lokal entwickeln und testen
|
||||
|
||||
Wählen Sie eine [lokale Lösung](/de/docs/setup/) aus.
|
||||
|
||||
## Gehostete Lösungen
|
||||
|
||||
Gehostete Lösungen sind eine bequeme Möglichkeit, Kubernetes-Cluster zu erstellen und zu warten.
|
||||
Sie verwalten und betreiben Ihre Cluster, so dass Sie dies nicht tun müssen.
|
||||
|
||||
Sie sollten eine gehostete Lösung auswählen, wenn Sie:
|
||||
|
||||
* Eine vollständig verwaltete Lösung wünschen
|
||||
* Sie möchten sich auf die Entwicklung Ihrer Apps oder Dienste konzentrieren
|
||||
* Sie haben kein dediziertes Site-Reliability-Engineering-Team (SRE), möchten jedoch eine hohe Verfügbarkeit
|
||||
* Sie haben keine Ressourcen zum Hosten und Überwachen Ihrer Cluster
|
||||
|
||||
Wählen Sie eine [gehostete Lösung](/de/docs/setup/) aus.
|
||||
|
||||
## Schlüsselfertige Cloud-Lösungen
|
||||
|
||||
|
||||
## Produktionsumgebung
|
||||
Mit diesen Lösungen können Sie Kubernetes-Cluster mit nur wenigen Befehlen erstellen. Sie werden aktiv entwickelt und verfügen über eine Community-Unterstützung.
|
||||
Sie können auch auf einer Reihe von Cloud-IaaS-Anbietern gehostet werden, und bieten mehr Freiheit und Flexibilität für eine Gegenleistung.
|
||||
|
||||
Überlegen Sie sich bei der Bewertung einer Lösung für eine Produktionsumgebung, welche Aspekte des Betriebs eines Kubernetes-Clusters (oder von _abstractions_) Sie selbst verwalten oder an einen Anbieter auslagern möchten.
|
||||
Sie sollten eine schlüsselfertige Cloud-Lösung auswählen, wenn Sie:
|
||||
|
||||
Einige mögliche Abstraktionen von Kubernetes-Clustern sind {{< glossary_tooltip text="applications" term_id="applications" >}}, {{< glossary_tooltip text="data plane" term_id="data-plane" >}}, {{< glossary_tooltip text="control plane" term_id="control-plane" >}}, {{< glossary_tooltip text="cluster infrastructure" term_id="cluster-infrastructure" >}} und {{< glossary_tooltip text="cluster operations" term_id="cluster-operations" >}}.
|
||||
* Mehr Kontrolle über Ihre Cluster haben möchten, als die gehosteten Lösungen zulassen
|
||||
* Mehr operative Verantwortung übernehmen Möchten
|
||||
|
||||
Das folgende Diagramm zeigt die möglichen Abstraktionen eines Kubernetes-Clusters und ob eine Abstraktion selbst verwaltet oder von einem Anbieter verwaltet wird.
|
||||
Wählen Sie eine [schlüsselfertige Cloud-Lösung](/de/docs/setup/) aus.
|
||||
|
||||
Lösungen für Produktionsumgebungen
|
||||
## Schlüsselfertige On-Premises-Lösungen
|
||||
|
||||
{{< table caption="Tabelle für Produktionsumgebungs-Lösungen listet Anbieter und deren Lösungen auf." >}}
|
||||
Mit diesen Lösungen können Sie Kubernetes-Cluster mit nur wenigen Befehlen in Ihrem internen, sicheren Cloud-Netzwerk erstellen.
|
||||
|
||||
Die folgende Tabelle für Produktionsumgebungs-Lösungen listet Anbieter und deren Lösungen auf.
|
||||
Sie sollten eine schlüsselfertige lokal betriebene Cloud-Lösung auswählen, wenn Sie:
|
||||
|
||||
|Providers | Managed | Turnkey cloud | On-Prem Datacenter | Custom (cloud) | Custom (On-premises VMs)| Custom (Bare Metal) |
|
||||
| --------- | ------ | ------ | ------ | ------ | ------ | ----- |
|
||||
| [Agile Stacks](https://www.agilestacks.com/products/kubernetes)| | ✔ | ✔ | | |
|
||||
| [Alibaba Cloud](https://www.alibabacloud.com/product/kubernetes)| | ✔ | | | |
|
||||
| [Amazon](https://aws.amazon.com) | [Amazon EKS](https://aws.amazon.com/eks/) |[Amazon EC2](https://aws.amazon.com/ec2/) | | | |
|
||||
| [AppsCode](https://appscode.com/products/pharmer/) | ✔ | | | | |
|
||||
| [APPUiO](https://appuio.ch/) | ✔ | ✔ | ✔ | | | |
|
||||
| [Banzai Cloud Pipeline Kubernetes Engine (PKE)](https://banzaicloud.com/products/pke/) | | ✔ | | ✔ | ✔ | ✔ |
|
||||
| [CenturyLink Cloud](https://www.ctl.io/) | | ✔ | | | |
|
||||
| [Cisco Container Platform](https://cisco.com/go/containers) | | | ✔ | | |
|
||||
| [Cloud Foundry Container Runtime (CFCR)](https://docs-cfcr.cfapps.io/) | | | | ✔ |✔ |
|
||||
| [CloudStack](https://cloudstack.apache.org/) | | | | | ✔|
|
||||
| [Canonical](https://ubuntu.com/kubernetes) | ✔ | ✔ | ✔ | ✔ |✔ | ✔
|
||||
| [Containership](https://containership.io) | ✔ |✔ | | | |
|
||||
| [D2iQ](https://d2iq.com/) | | [Kommander](https://d2iq.com/solutions/ksphere) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) |
|
||||
| [Digital Rebar](https://provision.readthedocs.io/en/tip/README.html) | | | | | | ✔
|
||||
| [DigitalOcean](https://www.digitalocean.com/products/kubernetes/) | ✔ | | | | |
|
||||
| [Docker Enterprise](https://www.docker.com/products/docker-enterprise) | |✔ | ✔ | | | ✔
|
||||
| [Gardener](https://gardener.cloud/) | ✔ | ✔ | ✔ | ✔ | ✔ | [Custom Extensions](https://github.com/gardener/gardener/blob/master/docs/extensions/overview.md) |
|
||||
| [Giant Swarm](https://www.giantswarm.io/) | ✔ | ✔ | ✔ | |
|
||||
| [Google](https://cloud.google.com/) | [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/) | [Google Compute Engine (GCE)](https://cloud.google.com/compute/)|[GKE On-Prem](https://cloud.google.com/gke-on-prem/) | | | | | | | |
|
||||
| [IBM](https://www.ibm.com/in-en/cloud) | [IBM Cloud Kubernetes Service](https://cloud.ibm.com/kubernetes/catalog/cluster)| |[IBM Cloud Private](https://www.ibm.com/in-en/cloud/private) | |
|
||||
| [Ionos](https://www.ionos.com/enterprise-cloud) | [Ionos Managed Kubernetes](https://www.ionos.com/enterprise-cloud/managed-kubernetes) | [Ionos Enterprise Cloud](https://www.ionos.com/enterprise-cloud) | |
|
||||
| [Kontena Pharos](https://www.kontena.io/pharos/) | |✔| ✔ | | |
|
||||
| [KubeOne](https://kubeone.io/) | | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
| [Kubermatic](https://kubermatic.io/) | ✔ | ✔ | ✔ | ✔ | ✔ | |
|
||||
| [KubeSail](https://kubesail.com/) | ✔ | | | | |
|
||||
| [Kubespray](https://kubespray.io/#/) | | | |✔ | ✔ | ✔ |
|
||||
| [Kublr](https://kublr.com/) |✔ | ✔ |✔ |✔ |✔ |✔ |
|
||||
| [Microsoft Azure](https://azure.microsoft.com) | [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service/) | | | | |
|
||||
| [Mirantis Cloud Platform](https://www.mirantis.com/software/kubernetes/) | | | ✔ | | |
|
||||
| [Nirmata](https://www.nirmata.com/) | | ✔ | ✔ | | |
|
||||
| [Nutanix](https://www.nutanix.com/en) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | | | [Nutanix AHV](https://www.nutanix.com/products/acropolis/virtualization) |
|
||||
| [OpenNebula](https://www.opennebula.org) |[OpenNebula Kubernetes](https://marketplace.opennebula.systems/docs/service/kubernetes.html) | | | | |
|
||||
| [OpenShift](https://www.openshift.com) |[OpenShift Dedicated](https://www.openshift.com/products/dedicated/) and [OpenShift Online](https://www.openshift.com/products/online/) | | [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) | | [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) |[OpenShift Container Platform](https://www.openshift.com/products/container-platform/)
|
||||
| [Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE)](https://docs.cloud.oracle.com/iaas/Content/ContEng/Concepts/contengoverview.htm) | ✔ | ✔ | | | |
|
||||
| [oVirt](https://www.ovirt.org/) | | | | | ✔ |
|
||||
| [Pivotal](https://pivotal.io/) | | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | | |
|
||||
| [Platform9](https://platform9.com/) | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | ✔ | ✔ | ✔
|
||||
| [Rancher](https://rancher.com/) | | [Rancher 2.x](https://rancher.com/docs/rancher/v2.x/en/) | | [Rancher Kubernetes Engine (RKE)](https://rancher.com/docs/rke/latest/en/) | | [k3s](https://k3s.io/)
|
||||
| [StackPoint](https://stackpoint.io/) | ✔ | ✔ | | | |
|
||||
| [Supergiant](https://supergiant.io/) | |✔ | | | |
|
||||
| [SUSE](https://www.suse.com/) | | ✔ | | | |
|
||||
| [SysEleven](https://www.syseleven.io/) | ✔ | | | | |
|
||||
| [Tencent Cloud](https://intl.cloud.tencent.com/) | [Tencent Kubernetes Engine](https://intl.cloud.tencent.com/product/tke) | ✔ | ✔ | | | ✔ |
|
||||
| [VEXXHOST](https://vexxhost.com/) | ✔ | ✔ | | | |
|
||||
| [VMware](https://cloud.vmware.com/) | [VMware Cloud PKS](https://cloud.vmware.com/vmware-cloud-pks) |[VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) | [VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) | [VMware Essential PKS](https://cloud.vmware.com/vmware-essential-pks) | |[VMware Essential PKS](https://cloud.vmware.com/vmware-essential-pks)
|
||||
| [Z.A.R.V.I.S.](https://zarvis.ai/) | ✔ | | | | | |
|
||||
* Cluster in Ihrem privaten Cloud-Netzwerk bereitstellen möchten
|
||||
* Ein engagiertes SRE-Team haben
|
||||
* Über die Ressourcen zum Hosten und Überwachen Ihrer Cluster verfügen
|
||||
|
||||
Wählen Sie eine [schlüsselfertige On-Premises-Lösung](/de/docs/setup/) aus.
|
||||
|
||||
## Individuelle Lösungen
|
||||
|
||||
Individuelle Lösungen geben Ihnen die größte Freiheit in Ihren Clustern, erfordern jedoch das meiste Know-how.
|
||||
Diese Lösungen reichen von Bare-Metal-Anbietern bis hin zu Cloud-Anbietern mit unterschiedlichen Betriebssystemen.
|
||||
|
||||
Wählen Sie eine [individuelle Lösung](/de/docs/setup/) aus.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
Gehen Sie zu [Auswählen der richtigen Lösung](/de/docs/setup/) für eine vollständige Liste der möglichen Lösungen.
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: Indivduelle Cloud-Lösungen
|
||||
weight: 50
|
||||
---
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Cluster mit kubeadm bootstrappen"
|
||||
weight: 30
|
||||
---
|
||||
|
||||
@@ -205,7 +205,7 @@ Weitere Informationen zu unterstützten Treibern und zur Installation von Plugin
|
||||
|
||||
### Lokale Images durch erneute Verwendung des Docker-Daemon ausführen
|
||||
|
||||
Wenn Sie eine einzige Kubernetes VM verwenden, ist es sehr praktisch, den integrierten Docker-Daemon von Minikube wiederzuverwenden; Dies bedeutet, dass Sie auf Ihrem lokalen Computer keine Docker-Registy erstellen und das Image in die Registry importieren müssen - Sie können einfach innerhalb desselben Docker-Daemons wie Minikube arbeiten, was lokale Experimente beschleunigt. Stellen Sie einfach sicher, dass Sie Ihr Docker-Image mit einem anderen Element als 'latest' versehen, und verwenden Sie dieses Tag, wenn Sie das Image laden. Andernfalls, wenn Sie keine Version Ihres Images angeben, wird es als `:latest` angenommen, mit der Pull-Image-Richtlinie von `Always` entsprechend, was schließlich zu `ErrImagePull` führen kann, da Sie möglicherweise noch keine Versionen Ihres Docker-Images in der Standard-Docker-Registry (normalerweise DockerHub) haben.
|
||||
Wenn Sie eine einzige Kubernetes VM verwenden, ist es sehr praktisch, den integrierten Docker-Daemon von Minikube wiederzuverwenden; Dies bedeutet, dass Sie auf Ihrem lokalen Computer keine Docker-Registy erstellen und das Image in die Registry importortieren müssen - Sie können einfach innerhalb desselben Docker-Daemons wie Minikube arbeiten, was lokale Experimente beschleunigt. Stellen Sie einfach sicher, dass Sie Ihr Docker-Image mit einem anderen Element als 'latest' versehen, und verwenden Sie dieses Tag, wenn Sie das Image laden. Andernfalls, wenn Sie keine Version Ihres Images angeben, wird es als `:latest` angenommen, mit der Pull-Image-Richtlinie von `Always` entsprechend, was schließlich zu `ErrImagePull` führen kann, da Sie möglicherweise noch keine Versionen Ihres Docker-Images in der Standard-Docker-Registry (normalerweise DockerHub) haben.
|
||||
|
||||
Um mit dem Docker-Daemon auf Ihrem Mac/Linux-Computer arbeiten zu können, verwenden Sie den `docker-env`-Befehl in Ihrer Shell:
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: Lokale VMs
|
||||
weight: 60
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: Schlüsselfertige Cloud-Lösungen
|
||||
weight: 40
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Windows in Kubernetes"
|
||||
weight: 65
|
||||
---
|
||||
@@ -49,7 +49,7 @@ Minikube unterstützt auch die Option `--vm-driver=none`, mit der die Kubernetes
|
||||
Die einfachste Möglichkeit, Minikube unter macOS zu installieren, ist die Verwendung von [Homebrew](https://brew.sh):
|
||||
|
||||
```shell
|
||||
brew install minikube
|
||||
brew cask install minikube
|
||||
```
|
||||
|
||||
Sie können es auch auf macOS installieren, indem Sie eine statische Binärdatei herunterladen:
|
||||
|
||||
@@ -145,7 +145,7 @@ Um den "Hallo-Welt"-Container außerhalb des virtuellen Netzwerks von Kubernetes
|
||||
```
|
||||
|
||||
Bei Cloud-Anbietern, die Load-Balancer unterstützen, wird eine externe IP-Adresse für den Zugriff auf den Dienst bereitgestellt.
|
||||
Bei Minikube ermöglicht der Typ `LoadBalancer` den Dienst über den Befehl `minikube service` verfügbar zu machen.
|
||||
Bei Minikube ermöglicht der Typ `LoadBalancer` den Dienst über den Befehl `minikube service` verfuügbar zu machen.
|
||||
|
||||
|
||||
3. Führen Sie den folgenden Befehl aus:
|
||||
|
||||
@@ -45,12 +45,12 @@ Kubernetes is open source giving you the freedom to take advantage of on-premise
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccnceu20" button id="desktopKCButton">Attend KubeCon in Amsterdam on August 13-16, 2020</a>
|
||||
<a href="https://events.linuxfoundation.org/events/kubecon-cloudnativecon-europe-2020/" button id="desktopKCButton">Attend KubeCon in Amsterdam on Mar. 30-Apr. 2, 2020</a>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccncna20" button id="desktopKCButton">Attend KubeCon in Boston on November 17-20, 2020</a>
|
||||
<a href="https://events.linuxfoundation.cn/kubecon-cloudnativecon-open-source-summit-china/" button id="desktopKCButton">Attend KubeCon in Shanghai on July 28-30, 2020</a>
|
||||
</div>
|
||||
<div id="videoPlayer">
|
||||
<iframe data-url="https://www.youtube.com/embed/H06qrNmGqyE?autoplay=1" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
@@ -97,11 +97,3 @@ semantics to fields! It's also going to improve support for CRDs and unions!
|
||||
- Some kubectl apply features are missing from diff and could be useful, like the ability
|
||||
to filter by label, or to display pruned resources.
|
||||
- Eventually, kubectl diff will use server-side apply!
|
||||
|
||||
{{< note >}}
|
||||
|
||||
The flag `kubectl apply --server-dry-run` is deprecated in v1.18.
|
||||
Use the flag `--dry-run=server` for using server-side dry-run in
|
||||
`kubectl apply` and other subcommands.
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
@@ -52,7 +52,7 @@ In this way, admission controllers and policy management help make sure that app
|
||||
|
||||
To illustrate how admission controller webhooks can be leveraged to establish custom security policies, let’s consider an example that addresses one of the shortcomings of Kubernetes: a lot of its defaults are optimized for ease of use and reducing friction, sometimes at the expense of security. One of these settings is that containers are by default allowed to run as root (and, without further configuration and no `USER` directive in the Dockerfile, will also do so). Even though containers are isolated from the underlying host to a certain extent, running containers as root does increase the risk profile of your deployment— and should be avoided as one of many [security best practices](https://www.stackrox.com/post/2018/12/6-container-security-best-practices-you-should-be-following/). The [recently exposed runC vulnerability](https://www.stackrox.com/post/2019/02/the-runc-vulnerability-a-deep-dive-on-protecting-yourself/) ([CVE-2019-5736](https://nvd.nist.gov/vuln/detail/CVE-2019-5736)), for example, could be exploited only if the container ran as root.
|
||||
|
||||
You can use a custom mutating admission controller webhook to apply more secure defaults: unless explicitly requested, our webhook will ensure that pods run as a non-root user (we assign the user ID 1234 if no explicit assignment has been made). Note that this setup does not prevent you from deploying any workloads in your cluster, including those that legitimately require running as root. It only requires you to explicitly enable this riskier mode of operation in the deployment configuration, while defaulting to non-root mode for all other workloads.
|
||||
You can use a custom mutating admission controller webhook to apply more secure defaults: unless explicitly requested, our webhook will ensure that pods run as a non-root user (we assign the user ID 1234 if no explicit assignment has been made). Note that this setup does not prevent you from deploying any workloads in your cluster, including those that legitimately require running as root. It only requires you to explicitly enable this risker mode of operation in the deployment configuration, while defaulting to non-root mode for all other workloads.
|
||||
|
||||
The full code along with deployment instructions can be found in our accompanying [GitHub repository](https://github.com/stackrox/admission-controller-webhook-demo). Here, we will highlight a few of the more subtle aspects about how webhooks work.
|
||||
|
||||
@@ -80,7 +80,7 @@ webhooks:
|
||||
resources: ["pods"]
|
||||
```
|
||||
|
||||
This configuration defines a `webhook webhook-server.webhook-demo.svc`, and instructs the Kubernetes API server to consult the service `webhook-server` in `namespace webhook-demo` whenever a pod is created by making a HTTP POST request to the `/mutate` URL. For this configuration to work, several prerequisites have to be met.
|
||||
This configuration defines a `webhook webhook-server.webhook-demo.svc`, and instructs the Kubernetes API server to consult the service `webhook-server` in n`amespace webhook-demo` whenever a pod is created by making a HTTP POST request to the `/mutate` URL. For this configuration to work, several prerequisites have to be met.
|
||||
|
||||
## Webhook REST API
|
||||
|
||||
|
||||
@@ -12,45 +12,21 @@ When APIs evolve, the old API is deprecated and eventually removed.
|
||||
|
||||
The **v1.16** release will stop serving the following deprecated API versions in favor of newer and more stable API versions:
|
||||
|
||||
* NetworkPolicy in the **extensions/v1beta1** API version is no longer served
|
||||
* Migrate to use the **networking.k8s.io/v1** API version, available since v1.8.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* PodSecurityPolicy in the **extensions/v1beta1** API version
|
||||
* NetworkPolicy (in the **extensions/v1beta1** API group)
|
||||
* Migrate to use the **networking.k8s.io/v1** API, available since v1.8.
|
||||
Existing persisted data can be retrieved/updated via the **networking.k8s.io/v1** API.
|
||||
* PodSecurityPolicy (in the **extensions/v1beta1** API group)
|
||||
* Migrate to use the **policy/v1beta1** API, available since v1.10.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* DaemonSet in the **extensions/v1beta1** and **apps/v1beta2** API versions is no longer served
|
||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* Notable changes:
|
||||
* `spec.templateGeneration` is removed
|
||||
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||
* `spec.updateStrategy.type` now defaults to `RollingUpdate` (the default in `extensions/v1beta1` was `OnDelete`)
|
||||
* Deployment in the **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions is no longer served
|
||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* Notable changes:
|
||||
* `spec.rollbackTo` is removed
|
||||
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||
* `spec.progressDeadlineSeconds` now defaults to `600` seconds (the default in `extensions/v1beta1` was no deadline)
|
||||
* `spec.revisionHistoryLimit` now defaults to `10` (the default in `apps/v1beta1` was `2`, the default in `extensions/v1beta1` was to retain all)
|
||||
* `maxSurge` and `maxUnavailable` now default to `25%` (the default in `extensions/v1beta1` was `1`)
|
||||
* StatefulSet in the **apps/v1beta1** and **apps/v1beta2** API versions is no longer served
|
||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* Notable changes:
|
||||
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||
* `spec.updateStrategy.type` now defaults to `RollingUpdate` (the default in `apps/v1beta1` was `OnDelete`)
|
||||
* ReplicaSet in the **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions is no longer served
|
||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* Notable changes:
|
||||
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||
Existing persisted data can be retrieved/updated via the **policy/v1beta1** API.
|
||||
* DaemonSet, Deployment, StatefulSet, and ReplicaSet (in the **extensions/v1beta1** and **apps/v1beta2** API groups)
|
||||
* Migrate to use the **apps/v1** API, available since v1.9.
|
||||
Existing persisted data can be retrieved/updated via the **apps/v1** API.
|
||||
|
||||
The **v1.22** release will stop serving the following deprecated API versions in favor of newer and more stable API versions:
|
||||
The **v1.20** release will stop serving the following deprecated API versions in favor of newer and more stable API versions:
|
||||
|
||||
* Ingress in the **extensions/v1beta1** API version will no longer be served
|
||||
* Migrate to use the **networking.k8s.io/v1beta1** API version, available since v1.14.
|
||||
Existing persisted data can be retrieved/updated via the new version.
|
||||
* Ingress (in the **extensions/v1beta1** API group)
|
||||
* Migrate to use the **networking.k8s.io/v1beta1** API, serving Ingress since v1.14.
|
||||
Existing persisted data can be retrieved/updated via the **networking.k8s.io/v1beta1** API.
|
||||
|
||||
# What To Do
|
||||
|
||||
@@ -84,8 +60,8 @@ apiserver startup arguments:
|
||||
|
||||
Deprecations are announced in the Kubernetes release notes. You can see these
|
||||
announcements in
|
||||
[1.14](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.14.md#deprecations)
|
||||
and [1.15](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.15.md#deprecations-and-removals).
|
||||
[1.14](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#deprecations)
|
||||
and [1.15](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.15.md#deprecations-and-removals).
|
||||
|
||||
You can read more [in our deprecation policy document](https://kubernetes.io/docs/reference/using-api/deprecation-policy/#deprecating-parts-of-the-api)
|
||||
about the deprecation policies for Kubernetes APIs, and other Kubernetes components.
|
||||
|
||||
@@ -92,7 +92,7 @@ Verify that the pod is RUNNING after some time
|
||||
kubectl get pods web-server
|
||||
```
|
||||
|
||||
```
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-server 1/1 Running 0 39s
|
||||
```
|
||||
@@ -103,7 +103,7 @@ To confirm that the CSI driver is actually serving your requests it may be prude
|
||||
kubectl logs {CSIdriverPodName} --container={CSIdriverContainerName}
|
||||
```
|
||||
|
||||
```
|
||||
```shell
|
||||
/csi.v1.Controller/ControllerPublishVolume called with request: ...
|
||||
Attaching disk ... to ...
|
||||
ControllerPublishVolume succeeded for disk ... to instance ...
|
||||
|
||||
@@ -7,7 +7,7 @@ slug: Remembering-Brad-Childs
|
||||
|
||||
**Authors:** Paul Morie, Red Hat
|
||||
|
||||
Last year, the Kubernetes family lost one of its own. Brad Childs was a
|
||||
Earlier this year, the Kubernetes family lost one of its own. Brad Childs was a
|
||||
SIG Storage chair and long time contributor to the project. Brad worked on a
|
||||
number of features in storage and was known as much for his friendliness and
|
||||
sense of humor as for his technical contributions and leadership.
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Announcing the Kubernetes bug bounty program"
|
||||
date: 2020-01-14T09:00:00-08:00
|
||||
slug: kubernetes-bug-bounty-announcement
|
||||
---
|
||||
|
||||
**Authors:** Maya Kaczorowski and Tim Allclair, Google, on behalf of the [Kubernetes Product Security Committee](https://github.com/kubernetes/community/tree/master/committee-product-security)
|
||||
|
||||
|
||||
Today, the [Kubernetes Product Security Committee](https://github.com/kubernetes/community/tree/master/committee-product-security) is launching a [new bug bounty program](https://hackerone.com/kubernetes), funded by the [CNCF](https://www.cncf.io/), to reward researchers finding security vulnerabilities in Kubernetes.
|
||||
|
||||
## Setting up a new bug bounty program
|
||||
|
||||
We aimed to set up this bug bounty program as transparently as possible, with [an initial proposal](https://docs.google.com/document/d/1dvlQsOGODhY3blKpjTg6UXzRdPzv5y8V55RD_Pbo7ag/edit#heading=h.7t1efwpev42p), [evaluation of vendors](https://github.com/kubernetes/kubernetes/issues/73079), and [working draft of the components in scope](https://github.com/kubernetes/community/blob/master/contributors/guide/bug-bounty.md). Once we onboarded the selected bug bounty program vendor, [HackerOne](https://www.hackerone.com/), these documents were further refined based on the feedback from HackerOne, as well as what was learned in the recent [Kubernetes security audit](https://github.com/kubernetes/community/blob/master/wg-security-audit/findings/Kubernetes%20Final%20Report.pdf). The bug bounty program has been in a private release for several months now, with invited researchers able to submit bugs and help us test the triage process. After almost two years since the initial proposal, the program is now ready for all security researchers to contribute!
|
||||
|
||||
What’s exciting is that this is rare: a bug bounty for an open-source infrastructure tool. Some open-source bug bounty programs exist, such as the [Internet Bug Bounty](https://internetbugbounty.org/), this mostly covers core components that are consistently deployed across environments; but most bug bounties are still for hosted web apps. In fact, with more than[ 100 certified distributions of Kubernetes](https://www.cncf.io/certification/kcsp/), the bug bounty program needs to apply to the Kubernetes code that powers all of them. By far, the most time-consuming challenge here has been ensuring that the program provider (HackerOne) and their researchers who do the first line triage have the awareness of Kubernetes and the ability to easily test the validity of a reported bug. As part of the bootstrapping process, HackerOne had their team pass the [Certified Kubernetes Administrator](https://www.cncf.io/certification/cka/) (CKA) exam.
|
||||
|
||||
## What’s in scope
|
||||
|
||||
The bug bounty scope covers code from the main Kubernetes organizations on GitHub, as well as continuous integration, release, and documentation artifacts. Basically, most content you’d think of as ‘core’ Kubernetes, included at [https://github.com/kubernetes](https://github.com/kubernetes), is in scope. We’re particularly interested in cluster attacks, such as privilege escalations, authentication bugs, and remote code execution in the kubelet or API server. Any information leak about a workload, or unexpected permission changes is also of interest. Stepping back from the cluster admin’s view of the world, you’re also encouraged to look at the Kubernetes supply chain, including the build and release processes, which would allow any unauthorized access to commits, or the ability to publish unauthorized artifacts.
|
||||
|
||||
Notably out of scope is the community management tooling, e.g., the Kubernetes mailing lists or Slack channel. Container escapes, attacks on the Linux kernel, or other dependencies, such as etcd, are also out of scope and should be reported to the appropriate party. We would still appreciate that any Kubernetes vulnerability, even if not in scope for the bug bounty, be [disclosed privately](https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability) to the Kubernetes Product Security Committee. See the full scope on the [program reporting page](https://hackerone.com/kubernetes).
|
||||
|
||||
## How Kubernetes handles vulnerabilities and disclosures
|
||||
|
||||
Kubernetes’ [Product Security Committee](https://github.com/kubernetes/community/tree/master/committee-product-security) is a group of security-focused maintainers who are responsible for receiving and responding to reports of security issues in Kubernetes. This follows the documented [security vulnerability response process](https://kubernetes.io/docs/reference/issues-security/security/), which includes initial triage, assessing impact, generating and rolling out a fix.
|
||||
|
||||
With our bug bounty program, initial triage and initial assessment are handled by the bug bounty provider, in this case, HackerOne, enabling us better scale our limited Kubernetes security experts to handle only valid reports. Nothing else in this process is changing - the Product Security Committee will continue to develop fixes, build private patches, and coordinate special security releases. New releases with security patches will be announced at [kubernetes-security-announce@googlegroups.com](https://groups.google.com/forum/#!forum/kubernetes-security-announce).
|
||||
|
||||
If you want to report a bug, you don’t need to use the bug bounty - you can still follow the [existing process](https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability) and report what you’ve found at [security@kubernetes.io](mailto:security@kubernetes.io).
|
||||
|
||||
## Get started
|
||||
|
||||
Just as many organizations support open source by hiring developers, paying bug bounties directly supports security researchers. This bug bounty is a critical step for Kubernetes to build up its community of security researchers and reward their hard work.
|
||||
|
||||
If you’re a security researcher, and new to Kubernetes, check out these resources to learn more and get started bug hunting:
|
||||
|
||||
|
||||
|
||||
* **Hardening guides**
|
||||
* Kubernetes.io: [https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/](https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/)
|
||||
* **Frameworks**
|
||||
* CIS benchmarks: [https://www.cisecurity.org/benchmark/kubernetes/](https://www.cisecurity.org/benchmark/kubernetes/)
|
||||
* NIST 800-190: [https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf)
|
||||
* **Talks**
|
||||
* The Devil in the Details: Kubernetes’ First Security Assessment (KubeCon NA 2019): [https://www.youtube.com/watch?v=vknE5XEa_Do](https://www.youtube.com/watch?v=vknE5XEa_Do)
|
||||
* Crafty Requests: Deep Dive into Kubernetes CVE-2018-1002105 (KubeCon EU 2019): [https://www.youtube.com/watch?v=VjSJqc13PNk](https://www.youtube.com/watch?v=VjSJqc13PNk)
|
||||
* A Hacker’s Guide to Kubernetes and the Cloud (KubeCon EU 2018): [https://www.youtube.com/watch?v=dxKpCO2dAy8](https://www.youtube.com/watch?v=dxKpCO2dAy8)
|
||||
* Shipping in pirate-infested waters (KubeCon NA 2017): [https://www.youtube.com/watch?v=ohTq0no0ZVU](https://www.youtube.com/watch?v=ohTq0no0ZVU)
|
||||
* Hacking and Hardening Kubernetes clusters by example (KubeCon NA 2017): [https://www.youtube.com/watch?v=vTgQLzeBfRU](https://www.youtube.com/watch?v=vTgQLzeBfRU)
|
||||
|
||||
If you find something, please report a security bug to the Kubernetes bug bounty at [https://hackerone.com/kubernetes](https://hackerone.com/kubernetes).
|
||||
|
||||
|
||||
<!-- Docs to Markdown version 1.0β17 -->
|
||||
@@ -1,143 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Kubernetes on MIPS"
|
||||
date: 2020-01-15
|
||||
slug: Kubernetes-on-MIPS
|
||||
---
|
||||
|
||||
**Authors:** TimYin Shi, Dominic Yin, Wang Zhan, Jessica Jiang, Will Cai, Jeffrey Gao, Simon Sun (Inspur)
|
||||
|
||||
## Background
|
||||
|
||||
[MIPS](https://en.wikipedia.org/wiki/MIPS_architecture) (Microprocessor without Interlocked Pipelined Stages) is a reduced instruction set computer (RISC) instruction set architecture (ISA), appeared in 1981 and developed by MIPS Technologies. Now MIPS architecture is widely used in many electronic products.
|
||||
|
||||
[Kubernetes](https://kubernetes.io) has officially supported a variety of CPU architectures such as x86, arm/arm64, ppc64le, s390x. However, it's a pity that Kubernetes doesn't support MIPS. With the widespread use of cloud native technology, users under MIPS architecture also have an urgent demand for Kubernetes on MIPS.
|
||||
|
||||
## Achievements
|
||||
|
||||
For many years, to enrich the ecology of the open-source community, we have been working on adjusting MIPS architecture for Kubernetes use cases. With the continuous iterative optimization and the performance improvement of the MIPS CPU, we have made some breakthrough progresses on the mips64el platform.
|
||||
|
||||
Over the years, we have been actively participating in the Kubernetes community and have rich experience in the using and optimization of Kubernetes technology. Recently, we tried to adapt the MIPS architecture platform for Kubernetes and achieved a new a stage on that journey. The team has completed migration and adaptation of Kubernetes and related components, built not only a stable and highly available MIPS cluster but also completed the conformance test for Kubernetes v1.16.2.
|
||||
|
||||

|
||||
|
||||
_Figure 1 Kubernetes on MIPS_
|
||||
|
||||
## K8S-MIPS component build
|
||||
|
||||
Almost all native cloud components related to Kubernetes do not provide a MIPS version installation package or image. The prerequisite of deploying Kubernetes on the MIPS platform is to compile and build all required components on the mips64el platform. These components include:
|
||||
|
||||
- golang
|
||||
- docker-ce
|
||||
- hyperkube
|
||||
- pause
|
||||
- etcd
|
||||
- calico
|
||||
- coredns
|
||||
- metrics-server
|
||||
|
||||
Thanks to the excellent design of Golang and its good support for the MIPS platform, the compilation processes of the above cloud native components are greatly simplified. First of all, we compiled Golang on the latest stable version for the mips64el platform, and then we compiled most of the above components with source code.
|
||||
|
||||
During the compilation processes, we inevitably encountered many platform compatibility problems, such as a Golang system call compatibility problem (syscall), typecasting of syscall. Stat_t from uint32 to uint64, patching for EpollEvent, and so on.
|
||||
|
||||
To build K8S-MIPS components, we used cross-compilation technology. Our process involved integrating a QEMU tool to translate MIPS CPU instructions and modifying the build script of Kubernetes and E2E image script of Kubernetes, Hyperkube, and E2E test images on MIPS architecture.
|
||||
|
||||
After successfully building the above components, we use tools such as kubespray and kubeadm to complete kubernetes cluster construction.
|
||||
|
||||
| Name | Version | MIPS Repository |
|
||||
| ------------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| golang on MIPS | 1.12.5 | - |
|
||||
| docker-ce on MIPS | 18.09.8 | - |
|
||||
| metrics-server for CKE on MIPS | 0.3.2 | `registry.inspurcloud.cn/library/cke/kubernetes/metrics-server-mips64el:v0.3.2` |
|
||||
| etcd for CKE on MIPS | 3.2.26 | `registry.inspurcloud.cn/library/cke/etcd/etcd-mips64el:v3.2.26` |
|
||||
| pause for CKE on MIPS | 3.1 | `registry.inspurcloud.cn/library/cke/kubernetes/pause-mips64el:3.1` |
|
||||
| hyperkube for CKE on MIPS | 1.14.3 | `registry.inspurcloud.cn/library/cke/kubernetes/hyperkube-mips64el:v1.14.3` |
|
||||
| coredns for CKE on MIPS | 1.6.5 | `registry.inspurcloud.cn/library/cke/kubernetes/coredns-mips64el:v1.6.5` |
|
||||
| calico for CKE on MIPS | 3.8.0 | `registry.inspurcloud.cn/library/cke/calico/cni-mips64el:v3.8.0` `registry.inspurcloud.cn/library/cke/calico/ctl-mips64el:v3.8.0` `registry.inspurcloud.cn/library/cke/calico/node-mips64el:v3.8.0` `registry.inspurcloud.cn/library/cke/calico/kube-controllers-mips64el:v3.8.0` |
|
||||
|
||||
**Note**: CKE is a Kubernetes-based cloud container engine launched by Inspur
|
||||
|
||||

|
||||
|
||||
_Figure 2 K8S-MIPS Cluster Components_
|
||||
|
||||

|
||||
|
||||
_Figure 3 CPU Architecture_
|
||||
|
||||

|
||||
|
||||
_Figure 4 Cluster Node Information_
|
||||
|
||||
## Run K8S Conformance Test
|
||||
|
||||
The most straightforward way to verify the stability and availability of the K8S-MIPS cluster is to run a Kubernetes [conformance test](https://github.com/kubernetes/kubernetes/blob/v1.16.2/cluster/images/conformance/README.md).
|
||||
|
||||
Conformance is a standalone container to launch Kubernetes end-to-end tests for conformance testing.
|
||||
|
||||
Once the test has started, it launches several pods for various end-to-end tests. The source code of those images used by these pods is mostly from `kubernetes/test/images`, and the built images are at `gcr.io/kubernetes-e2e-test-images`. Since there are no MIPS images in the repository, we must first build all needed images to run the test.
|
||||
|
||||
### Build needed images for test
|
||||
|
||||
The first step is to find all needed images for the test. We can run `sonobuoy images-p e2e` command to list all images, or we can find those images in [/test/utils/image/manifest.go](https://github.com/kubernetes/kubernetes/blob/master/test/utils/image/manifest.go). Although Kubernetes officially has a complete Makefile and shell-script that provides commands for building test images, there are still a number of architecture-related issues that have not been resolved, such as the incompatibilities of base images and dependencies. So we cannot directly build mips64el architecture images by executing these commands.
|
||||
|
||||
Most test images are in golang, then compiled into binaries and built as Docker image based on the corresponding Dockerfile. These images are easy to build. But note that most images are using alpine as their base image, which does not officially support mips64el architecture for now. For this moment, we are unable to make mips64el version of [alpine](https://www.alpinelinux.org/), so we have to replace the alpine to existing MIPS images, such as Debian-stretch, fedora, ubuntu. Replacing the base image also requires replacing the command to install the dependencies, even the version of these dependencies.
|
||||
|
||||
Some images are not in `kubernetes/test/images`, such as `gcr.io/google-samples/gb-frontend:v6`. There is no clear documentation explaining where these images are locaated, though we found the source code in repository [github.com/GoogleCloudPlatform/kubernetes-engine-samples](https://github.com/GoogleCloudPlatform/kubernetes-engine-samples). We soon ran into new problems: to build these google sample images, we have to build the base image it uses, even the base image of the base images, such as `php:5-apache`, `redis`, and `perl`.
|
||||
|
||||
After a long process of building an image, we finished with about four dozen images, including the images used by the test pod, and the base images. The last step before we run the tests is to place all those images into every node in the cluster and make sure the Pod image pull policy is `imagePullPolicy: ifNotPresent`.
|
||||
|
||||
Here are some of the images we built:
|
||||
|
||||
- `docker.io/library/busybox:1.29`
|
||||
- `docker.io/library/nginx:1.14-alpine`
|
||||
- `docker.io/library/nginx:1.15-alpine`
|
||||
- `docker.io/library/perl:5.26`
|
||||
- `docker.io/library/httpd:2.4.38-alpine`
|
||||
- `docker.io/library/redis:5.0.5-alpine`
|
||||
- `gcr.io/google-containers/conformance:v1.16.2`
|
||||
- `gcr.io/google-containers/hyperkube:v1.16.2`
|
||||
- `gcr.io/google-samples/gb-frontend:v6`
|
||||
- `gcr.io/kubernetes-e2e-test-images/agnhost:2.6`
|
||||
- `gcr.io/kubernetes-e2e-test-images/apparmor-loader:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/dnsutils:1.1`
|
||||
- `gcr.io/kubernetes-e2e-test-images/echoserver:2.2`
|
||||
- `gcr.io/kubernetes-e2e-test-images/ipc-utils:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/jessie-dnsutils:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/kitten:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/metadata-concealment:1.2`
|
||||
- `gcr.io/kubernetes-e2e-test-images/mounttest-user:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/mounttest:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/nautilus:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/nonewprivs:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/nonroot:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/resource-consumer-controller:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/resource-consumer:1.5`
|
||||
- `gcr.io/kubernetes-e2e-test-images/sample-apiserver:1.10`
|
||||
- `gcr.io/kubernetes-e2e-test-images/test-webserver:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/volume/gluster:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/volume/iscsi:2.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/volume/nfs:1.0`
|
||||
- `gcr.io/kubernetes-e2e-test-images/volume/rbd:1.0.1`
|
||||
- `k8s.gcr.io/etcd:3.3.15`
|
||||
- `k8s.gcr.io/pause:3.1`
|
||||
|
||||
Finally, we ran the tests and got the test result, include `e2e.log`, which showed that all test cases passed. Additionally, we submitted our test result to [k8s-conformance](https://github.com/cncf/k8s-conformance) as a [pull request](https://github.com/cncf/k8s-conformance/pull/779).
|
||||
|
||||

|
||||
|
||||
_Figure 5 Pull request for conformance test results_
|
||||
|
||||
## What's next
|
||||
|
||||
We built the kubernetes-MIPS component manually and finished the conformance test, which verified the feasibility of Kubernetes On the MIPS platform and greatly enhanced our confidence in promoting the support of the MIPS architecture by Kubernetes.
|
||||
|
||||
In the future, we plan to actively contribute our experience and achievements to the community, submit PR, and patch for MIPS. We hope that more developers and companies in the community join us and promote Kubernetes on MIPS.
|
||||
|
||||
Contribution plan:
|
||||
|
||||
- contribute the source of e2e test images for MIPS
|
||||
- contribute the source of hyperkube for MIPS
|
||||
- contribute the source of deploy tools like kubeadm for MIPS
|
||||
|
||||
---
|
||||
@@ -1,99 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Reviewing 2019 in Docs"
|
||||
date: 2020-01-21
|
||||
slug: reviewing-2019-in-docs
|
||||
---
|
||||
|
||||
**Author:** Zach Corleissen (Cloud Native Computing Foundation)
|
||||
|
||||
Hi, folks! I'm one of the co-chairs for the Kubernetes documentation special interest group (SIG Docs). This blog post is a review of SIG Docs in 2019. Our contributors did amazing work last year, and I want to highlight their successes.
|
||||
|
||||
Although I review 2019 in this post, my goal is to point forward to 2020. I observe some trends in SIG Docs–some good, others troubling. I want to raise visibility before those challenges increase in severity.
|
||||
|
||||
## The good
|
||||
|
||||
There was much to celebrate in SIG Docs in 2019.
|
||||
|
||||
Kubernetes docs started the year with three localizations in progress. By the end of the year, we ended with ten localizations available, four of which (Chinese, French, Japanese, Korean) are reasonably complete. The Korean and French teams deserve special mentions for their contributions to git best practices across all localizations (Korean team) and help bootstrapping other localizations (French team).
|
||||
|
||||
Despite significant transition over the year, SIG Docs [improved its review velocity](https://k8s.devstats.cncf.io/d/44/pr-time-to-approve-and-merge?orgId=1&var-period=w&var-repogroup_name=SIG%20Docs&var-apichange=All&var-size_name=All&var-kind_name=All), with a median review time from PR open to merge of just over 24 hours.
|
||||
|
||||
Issue triage improved significantly in both volume and speed, largely due to the efforts of GitHub users @sftim, @tengqm, and @kbhawkey.
|
||||
|
||||
Doc sprints remain valuable at KubeCon contributor days, introducing new contributors to Kubernetes documentation.
|
||||
|
||||
The docs component of Kubernetes quarterly releases improved over 2019, thanks to iterative playbook improvements from release leads and their teams.
|
||||
|
||||
Site traffic increased over the year. The website ended the year with ~6 million page views per month in December, up from ~5M page views in January. The kubernetes.io website had 851k site visitors in October, a new all-time high. Reader satisfaction [remains general](https://kubernetes.io/blog/2019/10/29/kubernetes-documentation-end-user-survey/).
|
||||
|
||||
We onboarded a new SIG chair: @jimangel, a Cloud Architect at General Motors. Jim was a docs contributor for a year, during which he led the 1.14 docs release, before stepping up as chair.
|
||||
|
||||
|
||||
|
||||
## The not so good
|
||||
|
||||
While reader satisfaction is decent, **most respondents indicated dissatisfaction with stale content** in every area: concepts, tasks, tutorials, and reference. Additionally, readers requested more diagrams, advanced conceptual content, and code samples—things that technical writers excel at providing.
|
||||
|
||||
SIG Docs continues to solve how best to handle [third-party content](https://github.com/kubernetes/enhancements/pull/1327). **There's too much vendor content on kubernetes.io**, and guidelines for adding or rejecting third-party content remain unclear. The discussion so far has been powerful, including pushback demanding greater collaborative input—a powerful reminder that Kubernetes is in all ways a communal effort.
|
||||
|
||||
|
||||
We're in the middle of our third chair transition in 18 months. Each chair transition has been healthy and collegial, but it's still a lot of turnover in a short time. Chairing any open source project is difficult, but especially so with SIG Docs. Chairship of SIG Docs requires a steep learning curve across multiple domains: docs (both written and generated from spec), information architecture, specialized contribution paths (for example, localization), how to run a release cycle, website development, CI/CD, community management, on and on. It's a role that requires multiple people to function successfully without burning people out. Training replacements is time-intensive.
|
||||
|
||||
Perhaps most pressing in the Not So Good category is that SIG Docs currently has only one technical writer dedicated full-time to Kubernetes docs. This has impacts on Kubernetes docs: some obvious, some less so.
|
||||
|
||||
## Impacts of understaffing on Kubernetes docs
|
||||
|
||||
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Me today: <a href="https://t.co/cDpHOWEsjf">pic.twitter.com/cDpHOWEsjf</a></p>— Benjamin Elder (@BenTheElder) <a href="https://twitter.com/BenTheElder/status/1215453579651104768?ref_src=twsrc%5Etfw">January 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
If Kubernetes continues through 2020 without more technical writers dedicated to the docs, here's what I see as the most likely possibilities.
|
||||
|
||||
### But first, a disclaimer
|
||||
|
||||
{{< caution >}}
|
||||
|
||||
It is very hard to predict, especially the future.
|
||||
-Niels Bohr
|
||||
|
||||
{{< /caution >}}
|
||||
|
||||
|
||||
Some of my predictions are almost certainly wrong. Any errors are mine alone.
|
||||
|
||||
That said...
|
||||
|
||||
### Effects in 2020
|
||||
|
||||
Current levels of function aren't self-sustaining. Even with a strong playbook, the release cycle still requires expert support from at least one (and usually two) chairs during every cycle. Without fail, each release breaks in new and unexpected ways, and it requires familiarity and expertise to diagnose and resolve. As chairs continue to cycle—and to be clear, regular transitions are part of a healthy project—we accrue the risks associated with a pool lacking sufficient professional depth and employer support.
|
||||
|
||||
Oddly enough, one of the challenges to staffing is that the docs appear good enough. Based on site analytics and survey responses, readers are pleased with the quality of the docs. When folks visit the site, they generally find what they need and behave like satisfied visitors.
|
||||
|
||||
The danger is that this will change over time: slowly with occasional losses of function, annoying at first, then increasingly critical. The more time passes without adequate staffing, the more difficult and costly fixes will become.
|
||||
|
||||
I suspect this is true because the challenges we face now at decent levels of reader satisfaction are already difficult to fix. API reference generation is complex and brittle; the site's UI is outdated; and our most consistent requests are for more tutorials, advanced concepts, diagrams, and code samples, all of which require ongoing, dedicated time to create.
|
||||
|
||||
**Release support remains strong.**
|
||||
|
||||
The release team continues a solid habit of leaving each successive team with better support than the previous release. This mostly takes the form of iterative improvements to the [docs release playbook](https://github.com/kubernetes/community/tree/master/sig-release#docs-lead), producing better documentation and reducing siloed knowledge.
|
||||
|
||||
**Staleness accelerates.**
|
||||
|
||||
Conceptual content becomes less accurate or relevant as features change or deprecate. Tutorial content degrades for the same reason.
|
||||
|
||||
The content structure will also degrade: the categories of concepts, tasks, and tutorials are legacy categories that may not best fit the needs of current readers, let alone future ones.
|
||||
|
||||
Cruft accumulates for both readers and contributors. Reference docs become increasingly brittle without intervention.
|
||||
|
||||
**Critical knowledge vanishes.**
|
||||
|
||||
As I mentioned previously, SIG Docs has a wide range of functions, some with a steep learning curve. As contributors change roles or jobs, their expertise and availability will diminish or reduce to zero. Contributors with specific knowledge may not be available for consultation, exposing critical vulnerabilities in docs function. Specific examples include reference generation and chair leadership.
|
||||
|
||||
### That's a lot to take in
|
||||
|
||||
It's difficult to strike a balance between the importance of SIG Docs' work to the community and our users, the joy it brings me personally, and the fact that things can't remain as they are without significant negative impacts (eventually). SIG Docs is by no means dying; it's a vibrant community with active contributors doing cool things. It's also a community with some critical knowledge and capacity shortages that can only be remedied with trained, paid staff dedicated to documentation.
|
||||
|
||||
## What the community can do for healthy docs
|
||||
|
||||
Hire technical writers dedicated to Kubernetes docs. Support advanced content creation, not just release docs and incremental feature updates.
|
||||
|
||||
Thanks, and Happy 2020.
|
||||
@@ -1,251 +0,0 @@
|
||||
---
|
||||
title: CSI Ephemeral Inline Volumes
|
||||
date: 2020-01-21
|
||||
---
|
||||
|
||||
**Author:** Patrick Ohly (Intel)
|
||||
|
||||
Typically, volumes provided by an external storage driver in
|
||||
Kubernetes are *persistent*, with a lifecycle that is completely
|
||||
independent of pods or (as a special case) loosely coupled to the
|
||||
first pod which uses a volume ([late binding
|
||||
mode](https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode)).
|
||||
The mechanism for requesting and defining such volumes in Kubernetes
|
||||
are [Persistent Volume Claim (PVC) and Persistent Volume
|
||||
(PV)](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)
|
||||
objects. Originally, volumes that are backed by a Container Storage Interface
|
||||
(CSI) driver could only be used via this PVC/PV mechanism.
|
||||
|
||||
But there are also use cases for data volumes whose content and
|
||||
lifecycle is tied to a pod. For example, a driver might populate a
|
||||
volume with dynamically created secrets that are specific to the
|
||||
application running in the pod. Such volumes need to be created
|
||||
together with a pod and can be deleted as part of pod termination
|
||||
(*ephemeral*). They get defined as part of the pod spec (*inline*).
|
||||
|
||||
Since Kubernetes 1.15, CSI drivers can also be used for such
|
||||
*ephemeral inline* volumes. The [CSIInlineVolume feature
|
||||
gate](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
had to be set to enable it in 1.15 because support was still in alpha
|
||||
state. In 1.16, the feature reached beta state, which typically means
|
||||
that it is enabled in clusters by default.
|
||||
|
||||
CSI drivers have to be adapted to support this because although two
|
||||
existing CSI gRPC calls are used (`NodePublishVolume` and `NodeUnpublishVolume`),
|
||||
the way how they are
|
||||
used is different and not covered by the CSI spec: for ephemeral
|
||||
volumes, only `NodePublishVolume` is invoked by `kubelet` when asking
|
||||
the CSI driver for a volume. All other calls
|
||||
(like `CreateVolume`, `NodeStageVolume`, etc.) are skipped. The volume
|
||||
parameters are provided in the pod spec and from there copied into the
|
||||
`NodePublishVolumeRequest.volume_context` field. There are currently
|
||||
no standardized parameters; even common ones like size must be
|
||||
provided in a format that is defined by the CSI driver. Likewise, only
|
||||
`NodeUnpublishVolume` gets called after the pod has terminated and the
|
||||
volume needs to be removed.
|
||||
|
||||
Initially, the assumption was that CSI drivers would be specifically
|
||||
written to provide either persistent or ephemeral volumes. But there
|
||||
are also drivers which provide storage that is useful in both modes:
|
||||
for example, [PMEM-CSI](https://github.com/intel/pmem-csi) manages
|
||||
persistent memory (PMEM), a new kind of local storage that is provided
|
||||
by [Intel® Optane™ DC Persistent
|
||||
Memory](https://www.intel.com/content/www/us/en/architecture-and-technology/optane-dc-persistent-memory.html). Such
|
||||
memory is useful both as persistent data storage (faster than normal SSDs)
|
||||
and as ephemeral scratch space (higher capacity than DRAM).
|
||||
|
||||
Therefore the support in Kubernetes 1.16 was extended:
|
||||
* Kubernetes and users can determine which kind of volumes a driver
|
||||
supports via the `volumeLifecycleModes` field in the [`CSIDriver`
|
||||
object](https://kubernetes-csi.github.io/docs/csi-driver-object.html#what-fields-does-the-csidriver-object-have).
|
||||
* Drivers can get information about the volume mode by enabling the
|
||||
["pod info on
|
||||
mount"](https://kubernetes-csi.github.io/docs/pod-info.html) feature
|
||||
which then will add the new `csi.storage.k8s.io/ephemeral` entry to
|
||||
the `NodePublishRequest.volume_context`.
|
||||
|
||||
For more information about implementing support of ephemeral inline
|
||||
volumes in a CSI driver, see the [Kubernetes-CSI
|
||||
documentation](https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html)
|
||||
and the [original design
|
||||
document](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190122-csi-inline-volumes.md).
|
||||
|
||||
What follows in this blog post are usage examples based on real drivers
|
||||
and a summary at the end.
|
||||
|
||||
# Examples
|
||||
|
||||
## [PMEM-CSI](https://github.com/intel/pmem-csi)
|
||||
|
||||
Support for ephemeral inline volumes was added in [release
|
||||
v0.6.0](https://github.com/intel/pmem-csi/releases/tag/v0.6.0). The
|
||||
driver can be used on hosts with real Intel® Optane™ DC Persistent
|
||||
Memory, on [special machines in
|
||||
GCE](https://github.com/intel/pmem-csi/blob/v0.6.0/examples/gce.md) or
|
||||
with hardware emulated by QEMU. The latter is fully [integrated into
|
||||
the
|
||||
makefile](https://github.com/intel/pmem-csi/tree/v0.6.0#qemu-and-kubernetes)
|
||||
and only needs Go, Docker and KVM, so that approach was used for this
|
||||
example:
|
||||
|
||||
```sh
|
||||
git clone --branch release-0.6 https://github.com/intel/pmem-csi
|
||||
cd pmem-csi
|
||||
TEST_DISTRO=clear TEST_DISTRO_VERSION=32080 TEST_PMEM_REGISTRY=intel make start
|
||||
```
|
||||
|
||||
Bringing up the four-node cluster can take a while but eventually should end with:
|
||||
|
||||
```
|
||||
The test cluster is ready. Log in with /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm, run kubectl once logged in.
|
||||
Alternatively, KUBECONFIG=/work/pmem-csi/_work/pmem-govm/kube.config can also be used directly.
|
||||
|
||||
To try out the pmem-csi driver persistent volumes:
|
||||
...
|
||||
|
||||
To try out the pmem-csi driver ephemeral volumes:
|
||||
cat deploy/kubernetes-1.17/pmem-app-ephemeral.yaml | /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm kubectl create -f -
|
||||
```
|
||||
|
||||
`deploy/kubernetes-1.17/pmem-app-ephemeral.yaml` specifies one volume:
|
||||
|
||||
```
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: my-csi-app-inline-volume
|
||||
spec:
|
||||
containers:
|
||||
- name: my-frontend
|
||||
image: busybox
|
||||
command: [ "sleep", "100000" ]
|
||||
volumeMounts:
|
||||
- mountPath: "/data"
|
||||
name: my-csi-volume
|
||||
volumes:
|
||||
- name: my-csi-volume
|
||||
csi:
|
||||
driver: pmem-csi.intel.com
|
||||
fsType: "xfs"
|
||||
volumeAttributes:
|
||||
size: "2Gi"
|
||||
nsmode: "fsdax"
|
||||
```
|
||||
|
||||
Once we have created that pod, we can inspect the result:
|
||||
|
||||
```sh
|
||||
kubectl describe pods/my-csi-app-inline-volume
|
||||
```
|
||||
|
||||
```
|
||||
Name: my-csi-app-inline-volume
|
||||
...
|
||||
Volumes:
|
||||
my-csi-volume:
|
||||
Type: CSI (a Container Storage Interface (CSI) volume source)
|
||||
Driver: pmem-csi.intel.com
|
||||
FSType: xfs
|
||||
ReadOnly: false
|
||||
VolumeAttributes: nsmode=fsdax
|
||||
size=2Gi
|
||||
```
|
||||
|
||||
```sh
|
||||
kubectl exec my-csi-app-inline-volume -- df -h /data
|
||||
```
|
||||
|
||||
```
|
||||
Filesystem Size Used Available Use% Mounted on
|
||||
/dev/ndbus0region0fsdax/d7eb073f2ab1937b88531fce28e19aa385e93696
|
||||
1.9G 34.2M 1.8G 2% /data
|
||||
```
|
||||
|
||||
|
||||
## [Image Populator](https://github.com/kubernetes-csi/csi-driver-image-populator)
|
||||
|
||||
The image populator automatically unpacks a container image and makes
|
||||
its content available as an ephemeral volume. It's still in
|
||||
development, but canary images are already available which can be
|
||||
installed with:
|
||||
|
||||
```sh
|
||||
kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-csidriverinfo.yaml
|
||||
kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-daemonset.yaml
|
||||
```
|
||||
|
||||
This example pod will run nginx and have it serve data that
|
||||
comes from the `kfox1111/misc:test` image:
|
||||
|
||||
```sh
|
||||
kubectl create -f - <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.16-alpine
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumes:
|
||||
- name: data
|
||||
csi:
|
||||
driver: image.csi.k8s.io
|
||||
volumeAttributes:
|
||||
image: kfox1111/misc:test
|
||||
EOF
|
||||
```
|
||||
|
||||
```sh
|
||||
kubectl exec nginx -- cat /usr/share/nginx/html/test
|
||||
```
|
||||
|
||||
That `test` file just contains a single word:
|
||||
```
|
||||
testing
|
||||
```
|
||||
|
||||
Such data containers can be built with Dockerfiles such as:
|
||||
```
|
||||
FROM scratch
|
||||
COPY index.html /index.html
|
||||
```
|
||||
|
||||
## [cert-manager-csi](https://github.com/jetstack/cert-manager-csi)
|
||||
|
||||
cert-manager-csi works together with
|
||||
[cert-manager](https://github.com/jetstack/cert-manager). The goal for
|
||||
this driver is to facilitate requesting and mounting certificate key
|
||||
pairs to pods seamlessly. This is useful for facilitating mTLS, or
|
||||
otherwise securing connections of pods with guaranteed present
|
||||
certificates whilst having all of the features that cert-manager
|
||||
provides. This project is experimental.
|
||||
|
||||
|
||||
# Next steps
|
||||
|
||||
One of the issues with ephemeral inline volumes is that pods get
|
||||
scheduled by Kubernetes onto nodes without knowing anything about the
|
||||
currently available storage on that node. Once the pod has been
|
||||
scheduled, the CSI driver must make the volume available one that
|
||||
node. If that is currently not possible, the pod cannot start. This
|
||||
will be retried until eventually the volume becomes ready. The
|
||||
[storage capacity tracking
|
||||
KEP](https://github.com/kubernetes/enhancements/pull/1353) is an
|
||||
attempt to address this problem.
|
||||
|
||||
A related KEP introduces a [standardized size
|
||||
parameter](https://github.com/kubernetes/enhancements/pull/1409).
|
||||
|
||||
Currently, CSI ephemeral inline volumes stay in beta while issues like
|
||||
these are getting discussed. Your feedback is needed to decide how to
|
||||
proceed with this feature. For the KEPs, the two PRs linked to above
|
||||
is a good place to comment. The SIG Storage also [meets
|
||||
regularly](https://github.com/kubernetes/community/tree/master/sig-storage#meetings)
|
||||
and can be reached via [Slack and a mailing
|
||||
list](https://github.com/kubernetes/community/tree/master/sig-storage#contact).
|
||||
@@ -1,110 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "KubeInvaders - Gamified Chaos Engineering Tool for Kubernetes"
|
||||
date: 2020-01-22
|
||||
slug: kubeinvaders-gamified-chaos-engineering-tool-for-kubernetes
|
||||
---
|
||||
|
||||
**Authors** Eugenio Marzo, Sourcesense
|
||||
|
||||
Some months ago, I released my latest project called KubeInvaders. The
|
||||
first time I shared it with the community was during an Openshift
|
||||
Commons Briefing session. Kubenvaders is a Gamified Chaos Engineering
|
||||
tool for Kubernetes and Openshift and helps test how resilient your
|
||||
Kubernetes cluster is, in a fun way.
|
||||
|
||||
It is like Space Invaders, but the aliens are pods.
|
||||
|
||||

|
||||
|
||||
During my presentation at Codemotion Milan 2019, I started saying "of
|
||||
course you can do it with few lines of Bash, but it is boring."
|
||||
|
||||

|
||||
|
||||
Using the code above you can kill random pods across a Kubernetes cluster, but I
|
||||
think it is much more fun with the spaceship of KubeInvaders.
|
||||
|
||||
I published the code at
|
||||
[https://github.com/lucky-sideburn/KubeInvaders](https://github.com/lucky-sideburn/KubeInvaders)
|
||||
and there is a little community that is growing gradually. Some people
|
||||
love to use it for demo sessions killing pods on a big screen.
|
||||
|
||||

|
||||
|
||||
## How to install KubeInvaders
|
||||
|
||||
I defined multiples modes to install it:
|
||||
|
||||
1. Helm Chart
|
||||
[https://github.com/lucky-sideburn/KubeInvaders/tree/master/helm-charts/kubeinvaders](https://github.com/lucky-sideburn/KubeInvaders/tree/master/helm-charts/kubeinvaders)
|
||||
|
||||
2. Manual Installation for Openshift using a template
|
||||
[https://github.com/lucky-sideburn/KubeInvaders\#install-kubeinvaders-on-openshift](https://github.com/lucky-sideburn/KubeInvaders#install-kubeinvaders-on-openshift)
|
||||
|
||||
3. Manual Installation for Kubernetes
|
||||
[https://github.com/lucky-sideburn/KubeInvaders\#install-kubeinvaders-on-kubernetes](https://github.com/lucky-sideburn/KubeInvaders#install-kubeinvaders-on-kubernetes)
|
||||
|
||||
The preferred way, of course, is with a Helm chart:
|
||||
|
||||
```
|
||||
# Please set target_namespace to set your target namespace!
|
||||
helm install --set-string target_namespace="namespace1,namespace2" \
|
||||
--name kubeinvaders --namespace kubeinvaders ./helm-charts/kubeinvaders
|
||||
```
|
||||
|
||||
## How to use KubeInvaders
|
||||
|
||||
Once it is installed on your cluster you can use the following
|
||||
functionalities:
|
||||
|
||||
* Key 'a' — Switch to automatic pilot
|
||||
* Key 'm' — Switch to manual pilot
|
||||
* Key 'i' — Show pod's name. Move the ship towards an alien
|
||||
* Key 'h' — Print help
|
||||
* Key 'n' — Jump between different namespaces (my favorite feature!)
|
||||
|
||||
## Tuning KubeInvaders
|
||||
|
||||
At Codemotion Milan 2019, my colleagues and I organized a desk with a
|
||||
game station for playing KubeInvaders. People had to fight with Kubernetes to
|
||||
win a t-shirt.
|
||||
|
||||
If you have pods that require a few seconds to start, you may lose. It
|
||||
is possible to set the complexity of the game with these parameters as
|
||||
environmment variables in the Kubernetes deployment:
|
||||
|
||||
* ALIENPROXIMITY — Reduce this value to increase the distance between aliens;
|
||||
* HITSLIMIT — Seconds of CPU time to wait before shooting;
|
||||
* UPDATETIME — Seconds to wait before updating pod status (you can set also 0.x Es: 0.5);
|
||||
|
||||
The result is a harder game experience against the machine.
|
||||
|
||||
## Use cases
|
||||
|
||||
Adopting chaos engineering strategies for your production environment is
|
||||
really useful, because it is the only way to test if a system supports
|
||||
unexpected destructive events.
|
||||
|
||||
KubeInvaders is a game — so please do not take it too seriously! — but it demonstrates
|
||||
some important use cases:
|
||||
|
||||
* Test how resilient Kubernetes clusters are on unexpected pod deletion
|
||||
* Collect metrics like pod restart time
|
||||
* Tune readiness probes
|
||||
|
||||
## Next steps
|
||||
|
||||
I want to continue to add some cool features and integrate it into a
|
||||
Kubernetes dashboard because I am planning to transform it into a
|
||||
"Gamified Chaos Engineering and Development Tool for Kubernetes", to help
|
||||
developer to interact with deployments in a Kubernetes environment. For
|
||||
example:
|
||||
|
||||
* Point to the aliens to get pod logs
|
||||
* Deploy Helm charts by shooting some particular objects
|
||||
* Read messages stored in a specific label present in a deployment
|
||||
|
||||
Please feel free to contribute to
|
||||
[https://github.com/lucky-sideburn/KubeInvaders](https://github.com/lucky-sideburn/KubeInvaders)
|
||||
and stay updated following \#kubeinvaders news [on Twitter](https://twitter.com/luckysideburn).
|
||||
-760
@@ -1,760 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Deploying External OpenStack Cloud Provider with Kubeadm"
|
||||
date: 2020-02-07
|
||||
slug: Deploying-External-OpenStack-Cloud-Provider-with-Kubeadm
|
||||
---
|
||||
This document describes how to install a single control-plane Kubernetes cluster v1.15 with kubeadm on CentOS, and then deploy an external OpenStack cloud provider and Cinder CSI plugin to use Cinder volumes as persistent volumes in Kubernetes.
|
||||
|
||||
### Preparation in OpenStack
|
||||
|
||||
This cluster runs on OpenStack VMs, so let's create a few things in OpenStack first.
|
||||
|
||||
* A project/tenant for this Kubernetes cluster
|
||||
* A user in this project for Kubernetes, to query node information and attach volumes etc
|
||||
* A private network and subnet
|
||||
* A router for this private network and connect it to a public network for floating IPs
|
||||
* A security group for all Kubernetes VMs
|
||||
* A VM as a control-plane node and a few VMs as worker nodes
|
||||
|
||||
The security group will have the following rules to open ports for Kubernetes.
|
||||
|
||||
**Control-Plane Node**
|
||||
|
||||
|Protocol | Port Number | Description|
|
||||
|----------|-------------|------------|
|
||||
|TCP |6443|Kubernetes API Server|
|
||||
|TCP|2379-2380|etcd server client API|
|
||||
|TCP|10250|Kubelet API|
|
||||
|TCP|10251|kube-scheduler|
|
||||
|TCP|10252|kube-controller-manager|
|
||||
|TCP|10255|Read-only Kubelet API|
|
||||
|
||||
**Worker Nodes**
|
||||
|
||||
|Protocol | Port Number | Description|
|
||||
|----------|-------------|------------|
|
||||
|TCP|10250|Kubelet API|
|
||||
|TCP|10255|Read-only Kubelet API|
|
||||
|TCP|30000-32767|NodePort Services|
|
||||
|
||||
**CNI ports on both control-plane and worker nodes**
|
||||
|
||||
|Protocol | Port Number | Description|
|
||||
|----------|-------------|------------|
|
||||
|TCP|179|Calico BGP network|
|
||||
|TCP|9099|Calico felix (health check)|
|
||||
|UDP|8285|Flannel|
|
||||
|UDP|8472|Flannel|
|
||||
|TCP|6781-6784|Weave Net|
|
||||
|UDP|6783-6784|Weave Net|
|
||||
|
||||
CNI specific ports are only required to be opened when that particular CNI plugin is used. In this guide, we will use Weave Net. Only the Weave Net ports (TCP 6781-6784 and UDP 6783-6784), will need to be opened in the security group.
|
||||
|
||||
The control-plane node needs at least 2 cores and 4GB RAM. After the VM is launched, verify its hostname and make sure it is the same as the node name in Nova.
|
||||
If the hostname is not resolvable, add it to `/etc/hosts`.
|
||||
|
||||
For example, if the VM is called master1, and it has an internal IP 192.168.1.4. Add that to `/etc/hosts` and set hostname to master1.
|
||||
```shell
|
||||
echo "192.168.1.4 master1" >> /etc/hosts
|
||||
|
||||
hostnamectl set-hostname master1
|
||||
```
|
||||
### Install Docker and Kubernetes
|
||||
|
||||
Next, we'll follow the official documents to install docker and Kubernetes using kubeadm.
|
||||
|
||||
Install Docker following the steps from the [container runtime](/docs/setup/production-environment/container-runtimes/) documentation.
|
||||
|
||||
Note that it is a [best practice to use systemd as the cgroup driver](/docs/setup/production-environment/container-runtimes/#cgroup-drivers) for Kubernetes.
|
||||
If you use an internal container registry, add them to the docker config.
|
||||
```shell
|
||||
# Install Docker CE
|
||||
## Set up the repository
|
||||
### Install required packages.
|
||||
|
||||
yum install yum-utils device-mapper-persistent-data lvm2
|
||||
|
||||
### Add Docker repository.
|
||||
|
||||
yum-config-manager \
|
||||
--add-repo \
|
||||
https://download.docker.com/linux/centos/docker-ce.repo
|
||||
|
||||
## Install Docker CE.
|
||||
|
||||
yum update && yum install docker-ce-18.06.2.ce
|
||||
|
||||
## Create /etc/docker directory.
|
||||
|
||||
mkdir /etc/docker
|
||||
|
||||
# Configure the Docker daemon
|
||||
|
||||
cat > /etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"exec-opts": ["native.cgroupdriver=systemd"],
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "100m"
|
||||
},
|
||||
"storage-driver": "overlay2",
|
||||
"storage-opts": [
|
||||
"overlay2.override_kernel_check=true"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
mkdir -p /etc/systemd/system/docker.service.d
|
||||
|
||||
# Restart Docker
|
||||
systemctl daemon-reload
|
||||
systemctl restart docker
|
||||
systemctl enable docker
|
||||
```
|
||||
|
||||
Install kubeadm following the steps from the [Installing Kubeadm](/docs/setup/production-environment/tools/kubeadm/install-kubeadm/) documentation.
|
||||
|
||||
```shell
|
||||
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
|
||||
[kubernetes]
|
||||
name=Kubernetes
|
||||
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
repo_gpgcheck=1
|
||||
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||
EOF
|
||||
|
||||
# Set SELinux in permissive mode (effectively disabling it)
|
||||
# Caveat: In a production environment you may not want to disable SELinux, please refer to Kubernetes documents about SELinux
|
||||
setenforce 0
|
||||
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
|
||||
|
||||
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
|
||||
|
||||
systemctl enable --now kubelet
|
||||
|
||||
cat <<EOF > /etc/sysctl.d/k8s.conf
|
||||
net.bridge.bridge-nf-call-ip6tables = 1
|
||||
net.bridge.bridge-nf-call-iptables = 1
|
||||
EOF
|
||||
sysctl --system
|
||||
|
||||
# check if br_netfilter module is loaded
|
||||
lsmod | grep br_netfilter
|
||||
|
||||
# if not, load it explicitly with
|
||||
modprobe br_netfilter
|
||||
```
|
||||
|
||||
The official document about how to create a single control-plane cluster can be found from the [Creating a single control-plane cluster with kubeadm](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) documentation.
|
||||
|
||||
We'll largely follow that document but also add additional things for the cloud provider.
|
||||
To make things more clear, we'll use a `kubeadm-config.yml` for the control-plane node.
|
||||
In this config we specify to use an external OpenStack cloud provider, and where to find its config.
|
||||
We also enable storage API in API server's runtime config so we can use OpenStack volumes as persistent volumes in Kubernetes.
|
||||
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: InitConfiguration
|
||||
nodeRegistration:
|
||||
kubeletExtraArgs:
|
||||
cloud-provider: "external"
|
||||
---
|
||||
apiVersion: kubeadm.k8s.io/v1beta2
|
||||
kind: ClusterConfiguration
|
||||
kubernetesVersion: "v1.15.1"
|
||||
apiServer:
|
||||
extraArgs:
|
||||
enable-admission-plugins: NodeRestriction
|
||||
runtime-config: "storage.k8s.io/v1=true"
|
||||
controllerManager:
|
||||
extraArgs:
|
||||
external-cloud-volume-plugin: openstack
|
||||
extraVolumes:
|
||||
- name: "cloud-config"
|
||||
hostPath: "/etc/kubernetes/cloud-config"
|
||||
mountPath: "/etc/kubernetes/cloud-config"
|
||||
readOnly: true
|
||||
pathType: File
|
||||
networking:
|
||||
serviceSubnet: "10.96.0.0/12"
|
||||
podSubnet: "10.224.0.0/16"
|
||||
dnsDomain: "cluster.local"
|
||||
```
|
||||
|
||||
Now we'll create the cloud config, `/etc/kubernetes/cloud-config`, for OpenStack.
|
||||
Note that the tenant here is the one we created for all Kubernetes VMs in the beginning.
|
||||
All VMs should be launched in this project/tenant.
|
||||
In addition you need to create a user in this tenant for Kubernetes to do queries.
|
||||
The ca-file is the CA root certificate for OpenStack's API endpoint, for example `https://openstack.cloud:5000/v3`
|
||||
At the time of writing the cloud provider doesn't allow insecure connections (skip CA check).
|
||||
|
||||
```ini
|
||||
[Global]
|
||||
region=RegionOne
|
||||
username=username
|
||||
password=password
|
||||
auth-url=https://openstack.cloud:5000/v3
|
||||
tenant-id=14ba698c0aec4fd6b7dc8c310f664009
|
||||
domain-id=default
|
||||
ca-file=/etc/kubernetes/ca.pem
|
||||
|
||||
[LoadBalancer]
|
||||
subnet-id=b4a9a292-ea48-4125-9fb2-8be2628cb7a1
|
||||
floating-network-id=bc8a590a-5d65-4525-98f3-f7ef29c727d5
|
||||
|
||||
[BlockStorage]
|
||||
bs-version=v2
|
||||
|
||||
[Networking]
|
||||
public-network-name=public
|
||||
ipv6-support-disabled=false
|
||||
```
|
||||
|
||||
Next run kubeadm to initiate the control-plane node
|
||||
```shell
|
||||
kubeadm init --config=kubeadm-config.yml
|
||||
```
|
||||
|
||||
With the initialization completed, copy admin config to .kube
|
||||
```shell
|
||||
mkdir -p $HOME/.kube
|
||||
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||
```
|
||||
|
||||
At this stage, the control-plane node is created but not ready. All the nodes have the taint `node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule` and are waiting to be initialized by the cloud-controller-manager.
|
||||
```console
|
||||
# kubectl describe no master1
|
||||
Name: master1
|
||||
Roles: master
|
||||
......
|
||||
Taints: node-role.kubernetes.io/master:NoSchedule
|
||||
node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
|
||||
node.kubernetes.io/not-ready:NoSchedule
|
||||
......
|
||||
```
|
||||
Now deploy the OpenStack cloud controller manager into the cluster, following [using controller manager with kubeadm](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-controller-manager-with-kubeadm.md).
|
||||
|
||||
Create a secret with the cloud-config for the openstack cloud provider.
|
||||
```shell
|
||||
kubectl create secret -n kube-system generic cloud-config --from-literal=cloud.conf="$(cat /etc/kubernetes/cloud-config)" --dry-run -o yaml > cloud-config-secret.yaml
|
||||
kubectl apply -f cloud-config-secret.yaml
|
||||
```
|
||||
|
||||
Get the CA certificate for OpenStack API endpoints and put that into `/etc/kubernetes/ca.pem`.
|
||||
|
||||
Create RBAC resources.
|
||||
```shell
|
||||
kubectl apply -f https://github.com/kubernetes/cloud-provider-openstack/raw/release-1.15/cluster/addons/rbac/cloud-controller-manager-roles.yaml
|
||||
kubectl apply -f https://github.com/kubernetes/cloud-provider-openstack/raw/release-1.15/cluster/addons/rbac/cloud-controller-manager-role-bindings.yaml
|
||||
```
|
||||
|
||||
We'll run the OpenStack cloud controller manager as a DaemonSet rather than a pod.
|
||||
The manager will only run on the control-plane node, so if there are multiple control-plane nodes, multiple pods will be run for high availability.
|
||||
Create `openstack-cloud-controller-manager-ds.yaml` containing the following manifests, then apply it.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: cloud-controller-manager
|
||||
namespace: kube-system
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: openstack-cloud-controller-manager
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: openstack-cloud-controller-manager
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: openstack-cloud-controller-manager
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: openstack-cloud-controller-manager
|
||||
spec:
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/master: ""
|
||||
securityContext:
|
||||
runAsUser: 1001
|
||||
tolerations:
|
||||
- key: node.cloudprovider.kubernetes.io/uninitialized
|
||||
value: "true"
|
||||
effect: NoSchedule
|
||||
- key: node-role.kubernetes.io/master
|
||||
effect: NoSchedule
|
||||
- effect: NoSchedule
|
||||
key: node.kubernetes.io/not-ready
|
||||
serviceAccountName: cloud-controller-manager
|
||||
containers:
|
||||
- name: openstack-cloud-controller-manager
|
||||
image: docker.io/k8scloudprovider/openstack-cloud-controller-manager:v1.15.0
|
||||
args:
|
||||
- /bin/openstack-cloud-controller-manager
|
||||
- --v=1
|
||||
- --cloud-config=$(CLOUD_CONFIG)
|
||||
- --cloud-provider=openstack
|
||||
- --use-service-account-credentials=true
|
||||
- --address=127.0.0.1
|
||||
volumeMounts:
|
||||
- mountPath: /etc/kubernetes/pki
|
||||
name: k8s-certs
|
||||
readOnly: true
|
||||
- mountPath: /etc/ssl/certs
|
||||
name: ca-certs
|
||||
readOnly: true
|
||||
- mountPath: /etc/config
|
||||
name: cloud-config-volume
|
||||
readOnly: true
|
||||
- mountPath: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
|
||||
name: flexvolume-dir
|
||||
- mountPath: /etc/kubernetes
|
||||
name: ca-cert
|
||||
readOnly: true
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
env:
|
||||
- name: CLOUD_CONFIG
|
||||
value: /etc/config/cloud.conf
|
||||
hostNetwork: true
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
|
||||
type: DirectoryOrCreate
|
||||
name: flexvolume-dir
|
||||
- hostPath:
|
||||
path: /etc/kubernetes/pki
|
||||
type: DirectoryOrCreate
|
||||
name: k8s-certs
|
||||
- hostPath:
|
||||
path: /etc/ssl/certs
|
||||
type: DirectoryOrCreate
|
||||
name: ca-certs
|
||||
- name: cloud-config-volume
|
||||
secret:
|
||||
secretName: cloud-config
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: openstack-ca-cert
|
||||
```
|
||||
|
||||
When the controller manager is running, it will query OpenStack to get information about the nodes and remove the taint. In the node info you'll see the VM's UUID in OpenStack.
|
||||
```console
|
||||
# kubectl describe no master1
|
||||
Name: master1
|
||||
Roles: master
|
||||
......
|
||||
Taints: node-role.kubernetes.io/master:NoSchedule
|
||||
node.kubernetes.io/not-ready:NoSchedule
|
||||
......
|
||||
sage:docker: network plugin is not ready: cni config uninitialized
|
||||
......
|
||||
PodCIDR: 10.224.0.0/24
|
||||
ProviderID: openstack:///548e3c46-2477-4ce2-968b-3de1314560a5
|
||||
|
||||
```
|
||||
Now install your favourite CNI and the control-plane node will become ready.
|
||||
|
||||
For example, to install Weave Net, run this command:
|
||||
```shell
|
||||
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
|
||||
```
|
||||
|
||||
Next we'll set up worker nodes.
|
||||
|
||||
Firstly, install docker and kubeadm in the same way as how they were installed in the control-plane node.
|
||||
To join them to the cluster we need a token and ca cert hash from the output of control-plane node installation.
|
||||
If it is expired or lost we can recreate it using these commands.
|
||||
|
||||
```shell
|
||||
# check if token is expired
|
||||
kubeadm token list
|
||||
|
||||
# re-create token and show join command
|
||||
kubeadm token create --print-join-command
|
||||
|
||||
```
|
||||
|
||||
Create `kubeadm-config.yml` for worker nodes with the above token and ca cert hash.
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1beta2
|
||||
discovery:
|
||||
bootstrapToken:
|
||||
apiServerEndpoint: 192.168.1.7:6443
|
||||
token: 0c0z4p.dnafh6vnmouus569
|
||||
caCertHashes: ["sha256:fcb3e956a6880c05fc9d09714424b827f57a6fdc8afc44497180905946527adf"]
|
||||
kind: JoinConfiguration
|
||||
nodeRegistration:
|
||||
kubeletExtraArgs:
|
||||
cloud-provider: "external"
|
||||
|
||||
```
|
||||
apiServerEndpoint is the control-plane node, token and caCertHashes can be taken from the join command printed in the output of 'kubeadm token create' command.
|
||||
|
||||
Run kubeadm and the worker nodes will be joined to the cluster.
|
||||
```shell
|
||||
kubeadm join --config kubeadm-config.yml
|
||||
```
|
||||
|
||||
At this stage we'll have a working Kubernetes cluster with an external OpenStack cloud provider.
|
||||
The provider tells Kubernetes about the mapping between Kubernetes nodes and OpenStack VMs.
|
||||
If Kubernetes wants to attach a persistent volume to a pod, it can find out which OpenStack VM the pod is running on from the mapping, and attach the underlying OpenStack volume to the VM accordingly.
|
||||
|
||||
### Deploy Cinder CSI
|
||||
|
||||
The integration with Cinder is provided by an external Cinder CSI plugin, as described in the [Cinder CSI](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-cinder-csi-plugin.md) documentation.
|
||||
|
||||
We'll perform the following steps to install the Cinder CSI plugin.
|
||||
Firstly, create a secret with CA certs for OpenStack's API endpoints. It is the same cert file as what we use in cloud provider above.
|
||||
```shell
|
||||
kubectl create secret -n kube-system generic openstack-ca-cert --from-literal=ca.pem="$(cat /etc/kubernetes/ca.pem)" --dry-run -o yaml > openstack-ca-cert.yaml
|
||||
kubectl apply -f openstack-ca-cert.yaml
|
||||
```
|
||||
Then create RBAC resources.
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/release-1.15/manifests/cinder-csi-plugin/cinder-csi-controllerplugin-rbac.yaml
|
||||
kubectl apply -f https://github.com/kubernetes/cloud-provider-openstack/raw/release-1.15/manifests/cinder-csi-plugin/cinder-csi-nodeplugin-rbac.yaml
|
||||
```
|
||||
|
||||
The Cinder CSI plugin includes a controller plugin and a node plugin.
|
||||
The controller communicates with Kubernetes APIs and Cinder APIs to create/attach/detach/delete Cinder volumes. The node plugin in-turn runs on each worker node to bind a storage device (attached volume) to a pod, and unbind it during deletion.
|
||||
Create `cinder-csi-controllerplugin.yaml` and apply it to create csi controller.
|
||||
```yaml
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: csi-cinder-controller-service
|
||||
namespace: kube-system
|
||||
labels:
|
||||
app: csi-cinder-controllerplugin
|
||||
spec:
|
||||
selector:
|
||||
app: csi-cinder-controllerplugin
|
||||
ports:
|
||||
- name: dummy
|
||||
port: 12345
|
||||
|
||||
---
|
||||
kind: StatefulSet
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: csi-cinder-controllerplugin
|
||||
namespace: kube-system
|
||||
spec:
|
||||
serviceName: "csi-cinder-controller-service"
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: csi-cinder-controllerplugin
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: csi-cinder-controllerplugin
|
||||
spec:
|
||||
serviceAccount: csi-cinder-controller-sa
|
||||
containers:
|
||||
- name: csi-attacher
|
||||
image: quay.io/k8scsi/csi-attacher:v1.0.1
|
||||
args:
|
||||
- "--v=5"
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
env:
|
||||
- name: ADDRESS
|
||||
value: /var/lib/csi/sockets/pluginproxy/csi.sock
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
volumeMounts:
|
||||
- name: socket-dir
|
||||
mountPath: /var/lib/csi/sockets/pluginproxy/
|
||||
- name: csi-provisioner
|
||||
image: quay.io/k8scsi/csi-provisioner:v1.0.1
|
||||
args:
|
||||
- "--provisioner=csi-cinderplugin"
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
env:
|
||||
- name: ADDRESS
|
||||
value: /var/lib/csi/sockets/pluginproxy/csi.sock
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
volumeMounts:
|
||||
- name: socket-dir
|
||||
mountPath: /var/lib/csi/sockets/pluginproxy/
|
||||
- name: csi-snapshotter
|
||||
image: quay.io/k8scsi/csi-snapshotter:v1.0.1
|
||||
args:
|
||||
- "--connection-timeout=15s"
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
env:
|
||||
- name: ADDRESS
|
||||
value: /var/lib/csi/sockets/pluginproxy/csi.sock
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/csi/sockets/pluginproxy/
|
||||
name: socket-dir
|
||||
- name: cinder-csi-plugin
|
||||
image: docker.io/k8scloudprovider/cinder-csi-plugin:v1.15.0
|
||||
args :
|
||||
- /bin/cinder-csi-plugin
|
||||
- "--v=5"
|
||||
- "--nodeid=$(NODE_ID)"
|
||||
- "--endpoint=$(CSI_ENDPOINT)"
|
||||
- "--cloud-config=$(CLOUD_CONFIG)"
|
||||
- "--cluster=$(CLUSTER_NAME)"
|
||||
env:
|
||||
- name: NODE_ID
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: CSI_ENDPOINT
|
||||
value: unix://csi/csi.sock
|
||||
- name: CLOUD_CONFIG
|
||||
value: /etc/config/cloud.conf
|
||||
- name: CLUSTER_NAME
|
||||
value: kubernetes
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
volumeMounts:
|
||||
- name: socket-dir
|
||||
mountPath: /csi
|
||||
- name: secret-cinderplugin
|
||||
mountPath: /etc/config
|
||||
readOnly: true
|
||||
- mountPath: /etc/kubernetes
|
||||
name: ca-cert
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: socket-dir
|
||||
hostPath:
|
||||
path: /var/lib/csi/sockets/pluginproxy/
|
||||
type: DirectoryOrCreate
|
||||
- name: secret-cinderplugin
|
||||
secret:
|
||||
secretName: cloud-config
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: openstack-ca-cert
|
||||
```
|
||||
|
||||
|
||||
Create `cinder-csi-nodeplugin.yaml` and apply it to create csi node.
|
||||
```yaml
|
||||
kind: DaemonSet
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: csi-cinder-nodeplugin
|
||||
namespace: kube-system
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: csi-cinder-nodeplugin
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: csi-cinder-nodeplugin
|
||||
spec:
|
||||
serviceAccount: csi-cinder-node-sa
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: node-driver-registrar
|
||||
image: quay.io/k8scsi/csi-node-driver-registrar:v1.1.0
|
||||
args:
|
||||
- "--v=5"
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
- "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)"
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command: ["/bin/sh", "-c", "rm -rf /registration/cinder.csi.openstack.org /registration/cinder.csi.openstack.org-reg.sock"]
|
||||
env:
|
||||
- name: ADDRESS
|
||||
value: /csi/csi.sock
|
||||
- name: DRIVER_REG_SOCK_PATH
|
||||
value: /var/lib/kubelet/plugins/cinder.csi.openstack.org/csi.sock
|
||||
- name: KUBE_NODE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
volumeMounts:
|
||||
- name: socket-dir
|
||||
mountPath: /csi
|
||||
- name: registration-dir
|
||||
mountPath: /registration
|
||||
- name: cinder-csi-plugin
|
||||
securityContext:
|
||||
privileged: true
|
||||
capabilities:
|
||||
add: ["SYS_ADMIN"]
|
||||
allowPrivilegeEscalation: true
|
||||
image: docker.io/k8scloudprovider/cinder-csi-plugin:v1.15.0
|
||||
args :
|
||||
- /bin/cinder-csi-plugin
|
||||
- "--nodeid=$(NODE_ID)"
|
||||
- "--endpoint=$(CSI_ENDPOINT)"
|
||||
- "--cloud-config=$(CLOUD_CONFIG)"
|
||||
env:
|
||||
- name: NODE_ID
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
- name: CSI_ENDPOINT
|
||||
value: unix://csi/csi.sock
|
||||
- name: CLOUD_CONFIG
|
||||
value: /etc/config/cloud.conf
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
volumeMounts:
|
||||
- name: socket-dir
|
||||
mountPath: /csi
|
||||
- name: pods-mount-dir
|
||||
mountPath: /var/lib/kubelet/pods
|
||||
mountPropagation: "Bidirectional"
|
||||
- name: kubelet-dir
|
||||
mountPath: /var/lib/kubelet
|
||||
mountPropagation: "Bidirectional"
|
||||
- name: pods-cloud-data
|
||||
mountPath: /var/lib/cloud/data
|
||||
readOnly: true
|
||||
- name: pods-probe-dir
|
||||
mountPath: /dev
|
||||
mountPropagation: "HostToContainer"
|
||||
- name: secret-cinderplugin
|
||||
mountPath: /etc/config
|
||||
readOnly: true
|
||||
- mountPath: /etc/kubernetes
|
||||
name: ca-cert
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: socket-dir
|
||||
hostPath:
|
||||
path: /var/lib/kubelet/plugins/cinder.csi.openstack.org
|
||||
type: DirectoryOrCreate
|
||||
- name: registration-dir
|
||||
hostPath:
|
||||
path: /var/lib/kubelet/plugins_registry/
|
||||
type: Directory
|
||||
- name: kubelet-dir
|
||||
hostPath:
|
||||
path: /var/lib/kubelet
|
||||
type: Directory
|
||||
- name: pods-mount-dir
|
||||
hostPath:
|
||||
path: /var/lib/kubelet/pods
|
||||
type: Directory
|
||||
- name: pods-cloud-data
|
||||
hostPath:
|
||||
path: /var/lib/cloud/data
|
||||
type: Directory
|
||||
- name: pods-probe-dir
|
||||
hostPath:
|
||||
path: /dev
|
||||
type: Directory
|
||||
- name: secret-cinderplugin
|
||||
secret:
|
||||
secretName: cloud-config
|
||||
- name: ca-cert
|
||||
secret:
|
||||
secretName: openstack-ca-cert
|
||||
|
||||
```
|
||||
When they are both running, create a storage class for Cinder.
|
||||
|
||||
```yaml
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: csi-sc-cinderplugin
|
||||
provisioner: csi-cinderplugin
|
||||
```
|
||||
Then we can create a PVC with this class.
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: myvol
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
storageClassName: csi-sc-cinderplugin
|
||||
|
||||
```
|
||||
|
||||
When the PVC is created, a Cinder volume is created correspondingly.
|
||||
```console
|
||||
# kubectl get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
myvol Bound pvc-14b8bc68-6c4c-4dc6-ad79-4cb29a81faad 1Gi RWO csi-sc-cinderplugin 3s
|
||||
|
||||
```
|
||||
In OpenStack the volume name will match the Kubernetes persistent volume generated name. In this example it would be: _pvc-14b8bc68-6c4c-4dc6-ad79-4cb29a81faad_
|
||||
|
||||
Now we can create a pod with the PVC.
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: web
|
||||
spec:
|
||||
containers:
|
||||
- name: web
|
||||
image: nginx
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: 80
|
||||
hostPort: 8081
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: "/usr/share/nginx/html"
|
||||
name: mypd
|
||||
volumes:
|
||||
- name: mypd
|
||||
persistentVolumeClaim:
|
||||
claimName: myvol
|
||||
```
|
||||
When the pod is running, the volume will be attached to the pod.
|
||||
If we go back to OpenStack, we can see the Cinder volume is mounted to the worker node where the pod is running on.
|
||||
```console
|
||||
# openstack volume show 6b5f3296-b0eb-40cd-bd4f-2067a0d6287f
|
||||
+--------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+--------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| attachments | [{u'server_id': u'1c5e1439-edfa-40ed-91fe-2a0e12bc7eb4', u'attachment_id': u'11a15b30-5c24-41d4-86d9-d92823983a32', u'attached_at': u'2019-07-24T05:02:34.000000', u'host_name': u'compute-6', u'volume_id': u'6b5f3296-b0eb-40cd-bd4f-2067a0d6287f', u'device': u'/dev/vdb', u'id': u'6b5f3296-b0eb-40cd-bd4f-2067a0d6287f'}] |
|
||||
| availability_zone | nova |
|
||||
| bootable | false |
|
||||
| consistencygroup_id | None |
|
||||
| created_at | 2019-07-24T05:02:18.000000 |
|
||||
| description | Created by OpenStack Cinder CSI driver |
|
||||
| encrypted | False |
|
||||
| id | 6b5f3296-b0eb-40cd-bd4f-2067a0d6287f |
|
||||
| migration_status | None |
|
||||
| multiattach | False |
|
||||
| name | pvc-14b8bc68-6c4c-4dc6-ad79-4cb29a81faad |
|
||||
| os-vol-host-attr:host | rbd:volumes@rbd#rbd |
|
||||
| os-vol-mig-status-attr:migstat | None |
|
||||
| os-vol-mig-status-attr:name_id | None |
|
||||
| os-vol-tenant-attr:tenant_id | 14ba698c0aec4fd6b7dc8c310f664009 |
|
||||
| properties | attached_mode='rw', cinder.csi.openstack.org/cluster='kubernetes' |
|
||||
| replication_status | None |
|
||||
| size | 1 |
|
||||
| snapshot_id | None |
|
||||
| source_volid | None |
|
||||
| status | in-use |
|
||||
| type | rbd |
|
||||
| updated_at | 2019-07-24T05:02:35.000000 |
|
||||
| user_id | 5f6a7a06f4e3456c890130d56babf591 |
|
||||
+--------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
```
|
||||
|
||||
### Summary
|
||||
|
||||
In this walk-through, we deployed a Kubernetes cluster on OpenStack VMs and integrated it with OpenStack using an external OpenStack cloud provider. Then on this Kubernetes cluster we deployed Cinder CSI plugin which can create Cinder volumes and expose them in Kubernetes as persistent volumes.
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Contributor Summit Amsterdam Schedule Announced"
|
||||
date: 2020-02-18
|
||||
slug: Contributor-Summit-Amsterdam-Schedule-Announced
|
||||
---
|
||||
|
||||
**Authors:** Jeffrey Sica (Red Hat), Amanda Katona (VMware)
|
||||
|
||||
tl;dr [Registration is open](https://events.linuxfoundation.org/kubernetes-contributor-summit-europe/) and the [schedule is live](https://kcseu2020.sched.com/) so register now and we’ll see you in Amsterdam!
|
||||
|
||||
## Kubernetes Contributor Summit
|
||||
|
||||
**Sunday, March 29, 2020**
|
||||
|
||||
- Evening Contributor Celebration:
|
||||
[ZuidPool](https://www.zuid-pool.nl/en/)
|
||||
- Address: [Europaplein 22, 1078 GZ Amsterdam, Netherlands](https://www.google.com/search?q=KubeCon+Amsterdam+2020&ie=UTF-8&ibp=htl;events&rciv=evn&sa=X&ved=2ahUKEwiZoLvQ0dvnAhVST6wKHScBBZ8Q5bwDMAB6BAgSEAE#)
|
||||
- Time: 18:00 - 21:00
|
||||
|
||||
**Monday, March 30, 2020**
|
||||
|
||||
- All Day Contributor Summit:
|
||||
- [Amsterdam RAI](https://www.rai.nl/en/)
|
||||
- Address: [Europaplein 24, 1078 GZ Amsterdam, Netherlands](https://www.google.com/search?q=kubecon+amsterdam+2020&oq=kubecon+amste&aqs=chrome.0.35i39j69i57j0l4j69i61l2.3957j1j4&sourceid=chrome&ie=UTF-8&ibp=htl;events&rciv=evn&sa=X&ved=2ahUKEwiZoLvQ0dvnAhVST6wKHScBBZ8Q5bwDMAB6BAgSEAE#)
|
||||
- Time: 09:00 - 17:00 (Breakfast at 08:00)
|
||||
|
||||

|
||||
|
||||
Hello everyone and Happy 2020! It’s hard to believe that KubeCon EU 2020 is less than six weeks away, and with that another contributor summit! This year we have the pleasure of being in Amsterdam in early spring, so be sure to pack some warmer clothing. This summit looks to be exciting with a lot of fantastic community-driven content. We received **26** submissions from the CFP. From that, the events team selected **12** sessions. Each of the sessions falls into one of four categories:
|
||||
|
||||
* Community
|
||||
* Contributor Improvement
|
||||
* Sustainability
|
||||
* In-depth Technical
|
||||
|
||||
On top of the presentations, there will be a dedicated Docs Sprint as well as the New Contributor Workshop 101 and 201 Sessions. All told, we will have five separate rooms of content throughout the day on Monday. Please **[see the full schedule](https://kcseu2020.sched.com/)** to see what sessions you’d be interested in. We hope between the content provided and the inevitable hallway track, everyone has a fun and enriching experience.
|
||||
|
||||
Speaking of fun, the social Sunday night should be a blast! We’re hosting this summit’s social close to the conference center, at [ZuidPool](https://www.zuid-pool.nl/en/). There will be games, bingo, and unconference sign-up throughout the evening. It should be a relaxed way to kick off the week.
|
||||
|
||||
[Registration is open](https://events.linuxfoundation.org/kubernetes-contributor-summit-europe/)! Space is limited so it’s always a good idea to register early.
|
||||
|
||||
If you have any questions, reach out to the [Amsterdam Team](https://github.com/kubernetes/community/tree/master/events/2020/03-contributor-summit#team) on Slack in the [#contributor-summit](https://kubernetes.slack.com/archives/C7J893413) channel.
|
||||
|
||||
Hope to see you there!
|
||||
@@ -1,82 +0,0 @@
|
||||
---
|
||||
title: Bring your ideas to the world with kubectl plugins
|
||||
date: 2020-02-28
|
||||
---
|
||||
|
||||
**Author:** Cornelius Weig (TNG Technology Consulting GmbH)
|
||||
|
||||
`kubectl` is the most critical tool to interact with Kubernetes and has to address multiple user personas, each with their own needs and opinions.
|
||||
One way to make `kubectl` do what you need is to build new functionality into `kubectl`.
|
||||
|
||||
|
||||
## Challenges with building commands into `kubectl`
|
||||
|
||||
However, that's easier said than done. Being such an important cornerstone of
|
||||
Kubernetes, any meaningful change to `kubectl` needs to undergo a Kubernetes
|
||||
Enhancement Proposal (KEP) where the intended change is discussed beforehand.
|
||||
|
||||
When it comes to implementation, you'll find that `kubectl` is an ingenious and
|
||||
complex piece of engineering. It might take a long time to get used to
|
||||
the processes and style of the codebase to get done what you want to achieve. Next
|
||||
comes the review process which may go through several rounds until it meets all
|
||||
the requirements of the Kubernetes maintainers -- after all, they need to take
|
||||
over ownership of this feature and maintain it from the day it's merged.
|
||||
|
||||
When everything goes well, you can finally rejoice. Your code will be shipped
|
||||
with the next Kubernetes release. Well, that could mean you need to wait
|
||||
another 3 months to ship your idea in `kubectl` if you are unlucky.
|
||||
|
||||
So this was the happy path where everything goes well. But there are good
|
||||
reasons why your new functionality may never make it into `kubectl`. For one,
|
||||
`kubectl` has a particular look and feel and violating that style will not be
|
||||
acceptable by the maintainers. For example, an interactive command that
|
||||
produces output with colors would be inconsistent with the rest of `kubectl`.
|
||||
Also, when it comes to tools or commands useful only to a minuscule proportion
|
||||
of users, the maintainers may simply reject your proposal as `kubectl` needs to
|
||||
address common needs.
|
||||
|
||||
But this doesn’t mean you can’t ship your ideas to `kubectl` users.
|
||||
|
||||
## What if you didn’t have to change `kubectl` to add functionality?
|
||||
|
||||
This is where `kubectl` [plugins](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/) shine.
|
||||
Since `kubectl` v1.12, you can simply
|
||||
drop executables into your `PATH`, which follows the naming pattern
|
||||
`kubectl-myplugin`. Then you can execute this plugin as `kubectl myplugin`, and
|
||||
it will just feel like a normal sub-command of `kubectl`.
|
||||
|
||||
Plugins give you the opportunity to try out new experiences like terminal UIs,
|
||||
colorful output, specialized functionality, or other innovative ideas. You can
|
||||
go creative, as you’re the owner of your own plugin.
|
||||
|
||||
Further, plugins offer safe experimentation space for commands you’d like to
|
||||
propose to `kubectl`. By pre-releasing as a plugin, you can push your
|
||||
functionality faster to the end-users and quickly gather feedback. For example,
|
||||
the [kubectl-debug](https://github.com/verb/kubectl-debug) plugin is proposed
|
||||
to become a built-in command in `kubectl` in a
|
||||
[KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/20190805-kubectl-debug.md)).
|
||||
In the meanwhile, the plugin author can ship the functionality and collect
|
||||
feedback using the plugin mechanism.
|
||||
|
||||
## How to get started with developing plugins
|
||||
|
||||
If you already have an idea for a plugin, how do you best make it happen?
|
||||
First you have to ask yourself if you can implement it as a wrapper around
|
||||
existing `kubectl` functionality. If so, writing the plugin as a shell script
|
||||
is often the best way forward, because the resulting plugin will be small,
|
||||
works cross-platform, and has a high level of trust because it is not
|
||||
compiled.
|
||||
|
||||
On the other hand, if the plugin logic is complex, a general-purpose language
|
||||
is usually better. The canonical choice here is Go, because you can use the
|
||||
excellent `client-go` library to interact with the Kubernetes API. The Kubernetes
|
||||
maintained [sample-cli-plugin](https://github.com/kubernetes/sample-cli-plugin)
|
||||
demonstrates some best practices and can be used as a template for new plugin
|
||||
projects.
|
||||
|
||||
When the development is done, you just need to ship your plugin to the
|
||||
Kubernetes users. For the best plugin installation experience and discoverability,
|
||||
you should consider doing so via the
|
||||
[krew](https://github.com/kubernetes-sigs/krew) plugin manager. For an in-depth
|
||||
discussion about the technical details around `kubectl` plugins, refer to the
|
||||
documentation on [kubernetes.io](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/).
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Contributor Summit Amsterdam Postponed
|
||||
date: 2020-03-04
|
||||
slug: Contributor-Summit-Delayed
|
||||
---
|
||||
|
||||
**Authors:** Dawn Foster (VMware), Jorge Castro (VMware)
|
||||
|
||||
The CNCF has announced that [KubeCon + CloudNativeCon EU has been delayed](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/attend/novel-coronavirus-update/) until July/August of 2020. As a result the Contributor Summit planning team is weighing options for how to proceed. Here’s the current plan:
|
||||
|
||||
- There will be an in-person Contributor Summit as planned when KubeCon + CloudNativeCon is rescheduled.
|
||||
- We are looking at options for having additional virtual contributor activities in the meantime.
|
||||
|
||||
We will communicate via this blog and the usual communications channels on the final plan. Please bear with us as we adapt when we get more information. Thank you for being patient as the team pivots to bring you a great Contributor Summit!
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Join SIG Scalability and Learn Kubernetes the Hard Way
|
||||
date: 2020-03-19
|
||||
slug: join-sig-scalability
|
||||
---
|
||||
|
||||
**Authors:** Alex Handy
|
||||
|
||||
Contributing to SIG Scalability is a great way to learn Kubernetes in all its depth and breadth, and the team would love to have you [join as a contributor](https://github.com/kubernetes/community/tree/master/sig-scalability#scalability-special-interest-group). I took a look at the value of learning the hard way and interviewed the current SIG chairs to give you an idea of what contribution feels like.
|
||||
|
||||
## The value of Learning The Hard Way
|
||||
|
||||
There is a belief in the software development community that pushes for the most challenging and rigorous possible method of learning a new language or system. These tend to go by the moniker of "Learn \_\_ the Hard Way." Examples abound: Learn Code the Hard Way, Learn Python the Hard Way, and many others originating with Zed Shaw's courses in the topic.
|
||||
|
||||
While there are folks out there who offer you a "Learn Kubernetes the Hard Way" type experience (most notably [Kelsey Hightower's](https://github.com/kelseyhightower/kubernetes-the-hard-way)), any "Hard Way" project should attempt to cover every aspect of the core topic's principles.
|
||||
|
||||
Therefore, the real way to "Learn Kubernetes the Hard Way," is to join the CNCF and get involved in the project itself. And there is only one SIG that could genuinely offer a full-stack learning experience for Kubernetes: SIG Scalability.
|
||||
|
||||
The team behind SIG Scalability is responsible for detecting and dealing with issues that arise when Kubernetes clusters are working with upwards of a thousand nodes. Said [Wojiciech Tyczynski](https://github.com/wojtek-t), a staff software engineer at Google and a member of SIG Scalability, the standard size for a test cluster for this SIG is over 5,000 nodes.
|
||||
|
||||
And yet, this SIG is not composed of Ph.D.'s in highly scalable systems designs. Many of the folks working with Tyczynski, for example, joined the SIG knowing very little about these types of issues, and often, very little about Kubernetes.
|
||||
|
||||
Working on SIG Scalability is like jumping into the deep end of the pool to learn to swim, and the SIG is inherently concerned with the entire Kubernetes project. SIG Scalability focuses on how Kubernetes functions as a whole and at scale. The SIG Scalability team members have an impetus to learn about every system and to understand how all systems interact with one another.
|
||||
|
||||
## A complex and rewarding contributor experience
|
||||
|
||||
While that may sound complicated (and it is!), that doesn't mean it's outside the reach of an average developer, tester, or administrator. Google software developer Matt Matejczyk has only been on the team since the beginning of 2019, and he's been a valued member of the team since then, ferreting out bugs.
|
||||
|
||||
"I am new here," said Matejczyk. "I joined the team in January [2019]. Before that, I worked on AdWords at Google in New York. Why did I join? I knew some people there, so that was one of the decisions for me to move. I thought at that time that Kubernetes is a unique, cutting edge technology. I thought it'd be cool to work on that."
|
||||
|
||||
Matejczyk was correct about the coolness. "It's cool," he said. "So actually, ramping up on scalability is not easy. There are many things you need to understand. You need to understand Kubernetes very well. It can use every part of Kubernetes. I am still ramping up after these 8 months. I think it took me maybe 3 months to get up to decent speed."
|
||||
|
||||
When Matejczyk spoke to what he had worked on during those 8 months, he answered, "An interesting example is a regression I have been working on recently. We noticed the overall slowness of Kubernetes control plane in specific scenarios, and we couldn't attribute it to any particular component. In the end, we realized that everything boiled down to the memory allocation on the golang level. It was very counterintuitive to have two completely separate pieces of code (running as a part of the same binary) affecting the performance of each other only because one of them was allocating memory too fast. But connecting all the dots and getting to the bottom of regression like this gives great satisfaction."
|
||||
|
||||
Tyczynski said that "It's not only debugging regressions, but it's also debugging and finding bottlenecks. In general, those can be regressions, but those can be things we can improve. The other significant area is extending what we want to guarantee to users. Extending SLA and SLO coverage of the system so users can rely on what they can expect from the system in terms of performance and scalability. Matt is doing much work in extending our tests to be more representative and cover more Kubernetes concepts."
|
||||
|
||||
## Give SIG Scalability a try
|
||||
|
||||
The SIG Scalability team is always in need of new members, and if you're the sort of developer or tester who loves taking on new complex challenges, and perhaps loves learning things the hard way, consider joining this SIG. As the team points out, adding Kubernetes expertise to your resume is never a bad idea, and this is the one SIG where you can learn it all from top to bottom.
|
||||
|
||||
See [the SIG's documentation](https://github.com/kubernetes/community/tree/master/sig-scalability#scalability-special-interest-group) to learn about upcoming meetings, its charter, and more. You can also join the [#sig-scalability Slack channel](https://kubernetes.slack.com/archives/C09QZTRH7) to see what it's like. We hope to see you join in to take advantage of this great opportunity to learn Kubernetes and contribute back at the same time.
|
||||
@@ -1,135 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Kubernetes 1.18: Fit & Finish'
|
||||
date: 2020-03-25
|
||||
slug: kubernetes-1-18-release-announcement
|
||||
---
|
||||
|
||||
**Authors:** [Kubernetes 1.18 Release Team](https://github.com/kubernetes/sig-release/blob/master/releases/release-1.18/release_team.md)
|
||||
|
||||
We're pleased to announce the delivery of Kubernetes 1.18, our first release of 2020! Kubernetes 1.18 consists of 38 enhancements: 15 enhancements are moving to stable, 11 enhancements in beta, and 12 enhancements in alpha.
|
||||
|
||||
Kubernetes 1.18 is a "fit and finish" release. Significant work has gone into improving beta and stable features to ensure users have a better experience. An equal effort has gone into adding new developments and exciting new features that promise to enhance the user experience even more.
|
||||
Having almost as many enhancements in alpha, beta, and stable is a great achievement. It shows the tremendous effort made by the community on improving the reliability of Kubernetes as well as continuing to expand its existing functionality.
|
||||
|
||||
|
||||
## Major Themes
|
||||
|
||||
### Kubernetes Topology Manager Moves to Beta - Align Up!
|
||||
|
||||
A beta feature of Kubernetes in release 1.18, the [Topology Manager feature](https://github.com/nolancon/website/blob/f4200307260ea3234540ef13ed80de325e1a7267/content/en/docs/tasks/administer-cluster/topology-manager.md) enables NUMA alignment of CPU and devices (such as SR-IOV VFs) that will allow your workload to run in an environment optimized for low-latency. Prior to the introduction of the Topology Manager, the CPU and Device Manager would make resource allocation decisions independent of each other. This could result in undesirable allocations on multi-socket systems, causing degraded performance on latency critical applications.
|
||||
|
||||
### Serverside Apply Introduces Beta 2
|
||||
|
||||
Server-side Apply was promoted to Beta in 1.16, but is now introducing a second Beta in 1.18. This new version will track and manage changes to fields of all new Kubernetes objects, allowing you to know what changed your resources and when.
|
||||
|
||||
|
||||
### Extending Ingress with and replacing a deprecated annotation with IngressClass
|
||||
|
||||
In Kubernetes 1.18, there are two significant additions to Ingress: A new `pathType` field and a new `IngressClass` resource. The `pathType` field allows specifying how paths should be matched. In addition to the default `ImplementationSpecific` type, there are new `Exact` and `Prefix` path types.
|
||||
|
||||
The `IngressClass` resource is used to describe a type of Ingress within a Kubernetes cluster. Ingresses can specify the class they are associated with by using a new `ingressClassName` field on Ingresses. This new resource and field replace the deprecated `kubernetes.io/ingress.class` annotation.
|
||||
|
||||
### SIG-CLI introduces kubectl alpha debug
|
||||
|
||||
SIG-CLI was debating the need for a debug utility for quite some time already. With the development of [ephemeral containers](https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/), it became more obvious how we can support developers with tooling built on top of `kubectl exec`. The addition of the [`kubectl alpha debug` command](https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/20190805-kubectl-debug.md) (it is alpha but your feedback is more than welcome), allows developers to easily debug their Pods inside the cluster. We think this addition is invaluable. This command allows one to create a temporary container which runs next to the Pod one is trying to examine, but also attaches to the console for interactive troubleshooting.
|
||||
|
||||
|
||||
### Introducing Windows CSI support alpha for Kubernetes
|
||||
|
||||
The alpha version of CSI Proxy for Windows is being released with Kubernetes 1.18. CSI proxy enables CSI Drivers on Windows by allowing containers in Windows to perform privileged storage operations.
|
||||
|
||||
## Other Updates
|
||||
|
||||
### Graduated to Stable 💯
|
||||
|
||||
- [Taint Based Eviction](https://github.com/kubernetes/enhancements/issues/166)
|
||||
- [`kubectl diff`](https://github.com/kubernetes/enhancements/issues/491)
|
||||
- [CSI Block storage support](https://github.com/kubernetes/enhancements/issues/565)
|
||||
- [API Server dry run](https://github.com/kubernetes/enhancements/issues/576)
|
||||
- [Pass Pod information in CSI calls](https://github.com/kubernetes/enhancements/issues/603)
|
||||
- [Support Out-of-Tree vSphere Cloud Provider](https://github.com/kubernetes/enhancements/issues/670)
|
||||
- [Support GMSA for Windows workloads](https://github.com/kubernetes/enhancements/issues/689)
|
||||
- [Skip attach for non-attachable CSI volumes](https://github.com/kubernetes/enhancements/issues/770)
|
||||
- [PVC cloning](https://github.com/kubernetes/enhancements/issues/989)
|
||||
- [Moving kubectl package code to staging](https://github.com/kubernetes/enhancements/issues/1020)
|
||||
- [RunAsUserName for Windows](https://github.com/kubernetes/enhancements/issues/1043)
|
||||
- [AppProtocol for Services and Endpoints](https://github.com/kubernetes/enhancements/issues/1507)
|
||||
- [Extending Hugepage Feature](https://github.com/kubernetes/enhancements/issues/1539)
|
||||
- [client-go signature refactor to standardize options and context handling](https://github.com/kubernetes/enhancements/issues/1601)
|
||||
- [Node-local DNS cache](https://github.com/kubernetes/enhancements/issues/1024)
|
||||
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [EndpointSlice API](https://github.com/kubernetes/enhancements/issues/752)
|
||||
- [Moving kubectl package code to staging](https://github.com/kubernetes/enhancements/issues/1020)
|
||||
- [CertificateSigningRequest API](https://github.com/kubernetes/enhancements/issues/1513)
|
||||
- [Extending Hugepage Feature](https://github.com/kubernetes/enhancements/issues/1539)
|
||||
- [client-go signature refactor to standardize options and context handling](https://github.com/kubernetes/enhancements/issues/1601)
|
||||
|
||||
|
||||
### Release Notes
|
||||
|
||||
Check out the full details of the Kubernetes 1.18 release in our [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md).
|
||||
|
||||
|
||||
### Availability
|
||||
|
||||
Kubernetes 1.18 is available for download on [GitHub](https://github.com/kubernetes/kubernetes/releases/tag/v1.18.0). To get started with Kubernetes, check out these [interactive tutorials](https://kubernetes.io/docs/tutorials/) or run local Kubernetes clusters using Docker container “nodes” with [kind](https://kind.sigs.k8s.io/). You can also easily install 1.18 using [kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/).
|
||||
|
||||
### Release Team
|
||||
|
||||
This release is made possible through the efforts of hundreds of individuals who contributed both technical and non-technical content. Special thanks to the [release team](https://github.com/kubernetes/sig-release/blob/master/releases/release-1.18/release_team.md) led by Jorge Alarcon Ochoa, Site Reliability Engineer at Searchable AI. The 34 release team members coordinated many aspects of the release, from documentation to testing, validation, and feature completeness.
|
||||
|
||||
As the Kubernetes community has grown, our release process represents an amazing demonstration of collaboration in open source software development. Kubernetes continues to gain new users at a rapid pace. This growth creates a positive feedback cycle where more contributors commit code creating a more vibrant ecosystem. Kubernetes has had over [40,000 individual contributors](https://k8s.devstats.cncf.io/d/24/overall-project-statistics?orgId=1) to date and an active community of more than 3,000 people.
|
||||
|
||||
### Release Logo
|
||||
|
||||

|
||||
|
||||
#### Why the LHC?
|
||||
|
||||
The LHC is the world’s largest and most powerful particle accelerator. It is the result of the collaboration of thousands of scientists from around the world, all for the advancement of science. In a similar manner, Kubernetes has been a project that has united thousands of contributors from hundreds of organizations – all to work towards the same goal of improving cloud computing in all aspects! "A Bit Quarky" as the release name is meant to remind us that unconventional ideas can bring about great change and keeping an open mind to diversity will lead help us innovate.
|
||||
|
||||
|
||||
#### About the designer
|
||||
|
||||
Maru Lango is a designer currently based in Mexico City. While her area of expertise is Product Design, she also enjoys branding, illustration and visual experiments using CSS + JS and contributing to diversity efforts within the tech and design communities. You may find her in most social media as @marulango or check her website: https://marulango.com
|
||||
|
||||
### User Highlights
|
||||
|
||||
- Ericsson is using Kubernetes and other cloud native technology to deliver a [highly demanding 5G network](https://www.cncf.io/case-study/ericsson/) that resulted in up to 90 percent CI/CD savings.
|
||||
- Zendesk is using Kubernetes to [run around 70% of its existing applications](https://www.cncf.io/case-study/zendesk/). It’s also building all new applications to also run on Kubernetes, which has brought time savings, greater flexibility, and increased velocity to its application development.
|
||||
- LifeMiles has [reduced infrastructure spending by 50%](https://www.cncf.io/case-study/lifemiles/) because of its move to Kubernetes. It has also allowed them to double its available resource capacity.
|
||||
|
||||
### Ecosystem Updates
|
||||
|
||||
- The CNCF published the results of its [annual survey](https://www.cncf.io/blog/2020/03/04/2019-cncf-survey-results-are-here-deployments-are-growing-in-size-and-speed-as-cloud-native-adoption-becomes-mainstream/) showing that Kubernetes usage in production is skyrocketing. The survey found that 78% of respondents are using Kubernetes in production compared to 58% last year.
|
||||
- The “Introduction to Kubernetes” course hosted by the CNCF [surpassed 100,000 registrations](https://www.cncf.io/announcement/2020/01/28/cloud-native-computing-foundation-announces-introduction-to-kubernetes-course-surpasses-100000-registrations/).
|
||||
|
||||
### Project Velocity
|
||||
|
||||
The CNCF has continued refining DevStats, an ambitious project to visualize the myriad contributions that go into the project. [K8s DevStats](https://k8s.devstats.cncf.io/d/12/dashboards?orgId=1) illustrates the breakdown of contributions from major company contributors, as well as an impressive set of preconfigured reports on everything from individual contributors to pull request lifecycle times.
|
||||
|
||||
This past quarter, 641 different companies and over 6,409 individuals contributed to Kubernetes. [Check out DevStats](https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&var-period=m&var-repogroup_name=All) to learn more about the overall velocity of the Kubernetes project and community.
|
||||
|
||||
### Event Update
|
||||
|
||||
Kubecon + CloudNativeCon EU 2020 is being pushed back – for the more most up-to-date information, please check the [Novel Coronavirus Update page](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/attend/novel-coronavirus-update/).
|
||||
|
||||
### Upcoming Release Webinar
|
||||
|
||||
Join members of the Kubernetes 1.18 release team on April 23rd, 2020 to learn about the major features in this release including kubectl debug, Topography Manager, Ingress to V1 graduation, and client-go. Register here: https://www.cncf.io/webinars/kubernetes-1-18/.
|
||||
|
||||
### Get Involved
|
||||
|
||||
The simplest way to get involved with Kubernetes is by joining one of the many [Special Interest Groups](https://github.com/kubernetes/community/blob/master/sig-list.md) (SIGs) that align with your interests. Have something you’d like to broadcast to the Kubernetes community? Share your voice at our weekly [community meeting](https://github.com/kubernetes/community/tree/master/communication), and through the channels below. Thank you for your continued feedback and support.
|
||||
|
||||
- Follow us on Twitter [@Kubernetesio](https://twitter.com/kubernetesio) for latest updates
|
||||
- Join the community discussion on [Discuss](https://discuss.kubernetes.io/)
|
||||
- Join the community on [Slack](http://slack.k8s.io/)
|
||||
- Post questions (or answer questions) on [Stack Overflow](http://stackoverflow.com/questions/tagged/kubernetes)
|
||||
- Share your Kubernetes [story](https://docs.google.com/a/linuxfoundation.org/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform)
|
||||
- Read more about what’s happening with Kubernetes on the [blog](https://kubernetes.io/blog/)
|
||||
- Learn more about the [Kubernetes Release Team](https://github.com/kubernetes/sig-release/tree/master/release-team)
|
||||
@@ -1,503 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Kubernetes Topology Manager Moves to Beta - Align Up!"
|
||||
date: 2020-04-01
|
||||
slug: kubernetes-1-18-feature-topoloy-manager-beta
|
||||
---
|
||||
|
||||
**Authors:** Kevin Klues (NVIDIA), Victor Pickard (Red Hat), Conor Nolan (Intel)
|
||||
|
||||
This blog post describes the **<code>TopologyManager</code>**, a beta feature of Kubernetes in release 1.18. The **<code>TopologyManager</code>** feature enables NUMA alignment of CPUs and peripheral devices (such as SR-IOV VFs and GPUs), allowing your workload to run in an environment optimized for low-latency.
|
||||
|
||||
Prior to the introduction of the **<code>TopologyManager</code>**, the CPU and Device Manager would make resource allocation decisions independent of each other. This could result in undesirable allocations on multi-socket systems, causing degraded performance on latency critical applications. With the introduction of the **<code>TopologyManager</code>**, we now have a way to avoid this.
|
||||
|
||||
This blog post covers:
|
||||
|
||||
1. A brief introduction to NUMA and why it is important
|
||||
1. The policies available to end-users to ensure NUMA alignment of CPUs and devices
|
||||
1. The internal details of how the **<code>TopologyManager</code>** works
|
||||
1. Current limitations of the **<code>TopologyManager</code>**
|
||||
1. Future directions of the **<code>TopologyManager</code>**
|
||||
|
||||
## So, what is NUMA and why do I care?
|
||||
|
||||
The term NUMA stands for Non-Uniform Memory Access. It is a technology available on multi-cpu systems that allows different CPUs to access different parts of memory at different speeds. Any memory directly connected to a CPU is considered "local" to that CPU and can be accessed very fast. Any memory not directly connected to a CPU is considered "non-local" and will have variable access times depending on how many interconnects must be passed through in order to reach it. On modern systems, the idea of having "local" vs. "non-local" memory can also be extended to peripheral devices such as NICs or GPUs. For high performance, CPUs and devices should be allocated such that they have access to the same local memory.
|
||||
|
||||
All memory on a NUMA system is divided into a set of "NUMA nodes", with each node representing the local memory for a set of CPUs or devices. We talk about an individual CPU as being part of a NUMA node if its local memory is associated with that NUMA node.
|
||||
|
||||
We talk about a peripheral device as being part of a NUMA node based on the shortest number of interconnects that must be passed through in order to reach it.
|
||||
|
||||
For example, in Figure 1, CPUs 0-3 are said to be part of NUMA node 0, whereas CPUs 4-7 are part of NUMA node 1. Likewise GPU 0 and NIC 0 are said to be part of NUMA node 0 because they are attached to Socket 0, whose CPUs are all part of NUMA node 0. The same is true for GPU 1 and NIC 1 on NUMA node 1.
|
||||
|
||||
<p align="center">
|
||||
<img height="300" src="/images/blog/2020-03-25-kubernetes-1.18-release-announcement/example-numa-system.png">
|
||||
</p>
|
||||
|
||||
|
||||
**Figure 1:** An example system with 2 NUMA nodes, 2 Sockets with 4 CPUs each, 2 GPUs, and 2 NICs. CPUs on Socket 0, GPU 0, and NIC 0 are all part of NUMA node 0. CPUs on Socket 1, GPU 1, and NIC 1 are all part of NUMA node 1.
|
||||
|
||||
|
||||
Although the example above shows a 1-1 mapping of NUMA Node to Socket, this is not necessarily true in the general case. There may be multiple sockets on a single NUMA node, or individual CPUs of a single socket may be connected to different NUMA nodes. Moreover, emerging technologies such as Sub-NUMA Clustering ([available on recent intel CPUs](https://software.intel.com/en-us/articles/intel-xeon-processor-scalable-family-technical-overview)) allow single CPUs to be associated with multiple NUMA nodes so long as their memory access times to both nodes are the same (or have a negligible difference).
|
||||
|
||||
The **<code>TopologyManager</code>** has been built to handle all of these scenarios.
|
||||
|
||||
## Align Up! It's a TeaM Effort!
|
||||
|
||||
As previously stated, the **<code>TopologyManager</code>** allows users to align their CPU and peripheral device allocations by NUMA node. There are several policies available for this:
|
||||
|
||||
* **<code>none:</code>** this policy will not attempt to do any alignment of resources. It will act the same as if the **<code>TopologyManager</code>** were not present at all. This is the default policy.
|
||||
* **<code>best-effort:</code>** with this policy, the **<code>TopologyManager</code>** will attempt to align allocations on NUMA nodes as best it can, but will always allow the pod to start even if some of the allocated resources are not aligned on the same NUMA node.
|
||||
* **<code>restricted:</code>** this policy is the same as the **<code>best-effort</code>** policy, except it will fail pod admission if allocated resources cannot be aligned properly. Unlike with the **<code>single-numa-node</code>** policy, some allocations may come from multiple NUMA nodes if it is impossible to _ever_ satisfy the allocation request on a single NUMA node (e.g. 2 devices are requested and the only 2 devices on the system are on different NUMA nodes).
|
||||
* **<code>single-numa-node:</code>** this policy is the most restrictive and will only allow a pod to be admitted if _all_ requested CPUs and devices can be allocated from exactly one NUMA node.
|
||||
|
||||
It is important to note that the selected policy is applied to each container in a pod spec individually, rather than aligning resources across all containers together.
|
||||
|
||||
Moreover, a single policy is applied to _all_ pods on a node via a global **<code>kubelet</code>** flag, rather than allowing users to select different policies on a pod-by-pod basis (or a container-by-container basis). We hope to relax this restriction in the future.
|
||||
|
||||
The **<code>kubelet</code>** flag to set one of these policies can be seen below:
|
||||
|
||||
|
||||
```
|
||||
--topology-manager-policy=
|
||||
[none | best-effort | restricted | single-numa-node]
|
||||
```
|
||||
|
||||
|
||||
Additionally, the **<code>TopologyManager</code>** is protected by a feature gate. This feature gate has been available since Kubernetes 1.16, but has only been enabled by default since 1.18.
|
||||
|
||||
The feature gate can be enabled or disabled as follows (as described in more detail [here](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/)):
|
||||
|
||||
|
||||
```
|
||||
--feature-gates="...,TopologyManager=<true|false>"
|
||||
```
|
||||
|
||||
|
||||
In order to trigger alignment according to the selected policy, a user must request CPUs and peripheral devices in their pod spec, according to a certain set of requirements.
|
||||
|
||||
For peripheral devices, this means requesting devices from the available resources provided by a device plugin (e.g. **<code>intel.com/sriov</code>**, **<code>nvidia.com/gpu</code>**, etc.). This will only work if the device plugin has been extended to integrate properly with the **<code>TopologyManager</code>**. Currently, the only plugins known to have this extension are the [Nvidia GPU device plugin](https://github.com/NVIDIA/k8s-device-plugin/blob/5cb45d52afdf5798a40f8d0de049bce77f689865/nvidia.go#L74), and the [Intel SRIOV network device plugin](https://github.com/intel/sriov-network-device-plugin/blob/30e33f1ce2fc7b45721b6de8c8207e65dbf2d508/pkg/resources/pciNetDevice.go#L80). Details on how to extend a device plugin to integrate with the **<code>TopologyManager</code>** can be found [here](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#device-plugin-integration-with-the-topology-manager).
|
||||
|
||||
For CPUs, this requires that the **<code>CPUManager</code>** has been configured with its **<code>--static</code>** policy enabled and that the pod is running in the Guaranteed QoS class (i.e. all CPU and memory **<code>limits</code>** are equal to their respective CPU and memory **<code>requests</code>**). CPUs must also be requested in whole number values (e.g. **<code>1</code>**, **<code>2</code>**, **<code>1000m</code>**, etc). Details on how to set the **<code>CPUManager</code>** policy can be found [here](https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#cpu-management-policies).
|
||||
|
||||
For example, assuming the **<code>CPUManager</code>** is running with its **<code>--static</code>** policy enabled and the device plugins for **<code>gpu-vendor.com</code>**, and **<code>nic-vendor.com</code>** have been extended to integrate with the **<code>TopologyManager</code>** properly, the pod spec below is sufficient to trigger the **<code>TopologyManager</code>** to run its selected policy:
|
||||
|
||||
```
|
||||
spec:
|
||||
containers:
|
||||
- name: numa-aligned-container
|
||||
image: alpine
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2
|
||||
memory: 200Mi
|
||||
gpu-vendor.com/gpu: 1
|
||||
nic-vendor.com/nic: 1
|
||||
```
|
||||
|
||||
Following Figure 1 from the previous section, this would result in one of the following aligned allocations:
|
||||
|
||||
```
|
||||
{cpu: {0, 1}, gpu: 0, nic: 0}
|
||||
{cpu: {0, 2}, gpu: 0, nic: 0}
|
||||
{cpu: {0, 3}, gpu: 0, nic: 0}
|
||||
{cpu: {1, 2}, gpu: 0, nic: 0}
|
||||
{cpu: {1, 3}, gpu: 0, nic: 0}
|
||||
{cpu: {2, 3}, gpu: 0, nic: 0}
|
||||
|
||||
{cpu: {4, 5}, gpu: 1, nic: 1}
|
||||
{cpu: {4, 6}, gpu: 1, nic: 1}
|
||||
{cpu: {4, 7}, gpu: 1, nic: 1}
|
||||
{cpu: {5, 6}, gpu: 1, nic: 1}
|
||||
{cpu: {5, 7}, gpu: 1, nic: 1}
|
||||
{cpu: {6, 7}, gpu: 1, nic: 1}
|
||||
```
|
||||
|
||||
And that’s it! Just follow this pattern to have the **<code>TopologyManager</code>** ensure NUMA alignment across containers that request topology-aware devices and exclusive CPUs.
|
||||
|
||||
**NOTE:** if a pod is rejected by one of the **<code>TopologyManager</code>** policies, it will be placed in a **<code>Terminated</code>** state with a pod admission error and a reason of "**<code>TopologyAffinityError</code>**". Once a pod is in this state, the Kubernetes scheduler will not attempt to reschedule it. It is therefore recommended to use a [**<code>Deployment</code>**](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment) with replicas to trigger a redeploy of the pod on such a failure. An [external control loop](https://kubernetes.io/docs/concepts/architecture/controller/) can also be implemented to trigger a redeployment of pods that have a **<code>TopologyAffinityError</code>**.
|
||||
|
||||
## This is great, so how does it work under the hood?
|
||||
|
||||
Pseudocode for the primary logic carried out by the **<code>TopologyManager</code>** can be seen below:
|
||||
|
||||
```
|
||||
for container := range append(InitContainers, Containers...) {
|
||||
for provider := range HintProviders {
|
||||
hints += provider.GetTopologyHints(container)
|
||||
}
|
||||
|
||||
bestHint := policy.Merge(hints)
|
||||
|
||||
for provider := range HintProviders {
|
||||
provider.Allocate(container, bestHint)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The following diagram summarizes the steps taken during this loop:
|
||||
|
||||
<p align="center">
|
||||
<img weight="200" height="200" src="/images/blog/2020-03-25-kubernetes-1.18-release-announcement/numa-steps-during-loop.png">
|
||||
</p>
|
||||
|
||||
The steps themselves are:
|
||||
|
||||
1. Loop over all containers in a pod.
|
||||
1. For each container, gather "**<code>TopologyHints</code>**" from a set of "**<code>HintProviders</code>**" for each topology-aware resource type requested by the container (e.g. **<code>gpu-vendor.com/gpu</code>**, **<code>nic-vendor.com/nic</code>**, **<code>cpu</code>**, etc.).
|
||||
1. Using the selected policy, merge the gathered **<code>TopologyHints</code>** to find the "best" hint that aligns resource allocations across all resource types.
|
||||
1. Loop back over the set of hint providers, instructing them to allocate the resources they control using the merged hint as a guide.
|
||||
1. This loop runs at pod admission time and will fail to admit the pod if any of these steps fail or alignment cannot be satisfied according to the selected policy. Any resources allocated before the failure are cleaned up accordingly.
|
||||
|
||||
The following sections go into more detail on the exact structure of **<code>TopologyHints</code>** and **<code>HintProviders</code>**, as well as some details on the merge strategies used by each policy.
|
||||
|
||||
### TopologyHints
|
||||
|
||||
A **<code>TopologyHint</code>** encodes a set of constraints from which a given resource request can be satisfied. At present, the only constraint we consider is NUMA alignment. It is defined as follows:
|
||||
|
||||
```
|
||||
type TopologyHint struct {
|
||||
NUMANodeAffinity bitmask.BitMask
|
||||
Preferred bool
|
||||
}
|
||||
```
|
||||
|
||||
The **<code>NUMANodeAffinity</code>** field contains a bitmask of NUMA nodes where a resource request can be satisfied. For example, the possible masks on a system with 2 NUMA nodes include:
|
||||
|
||||
```
|
||||
{00}, {01}, {10}, {11}
|
||||
```
|
||||
|
||||
The **<code>Preferred</code>** field contains a boolean that encodes whether the given hint is "preferred" or not. With the **<code>best-effort</code>** policy, preferred hints will be given preference over non-preferred hints when generating a "best" hint. With the **<code>restricted</code>** and **<code>single-numa-node</code>** policies, non-preferred hints will be rejected.
|
||||
|
||||
In general, **<code>HintProviders</code>** generate **<code>TopologyHints</code>** by looking at the set of currently available resources that can satisfy a resource request. More specifically, they generate one **<code>TopologyHint</code>** for every possible mask of NUMA nodes where that resource request can be satisfied. If a mask cannot satisfy the request, it is omitted. For example, a **<code>HintProvider</code>** might provide the following hints on a system with 2 NUMA nodes when being asked to allocate 2 resources. These hints encode that both resources could either come from a single NUMA node (either 0 or 1), or they could each come from different NUMA nodes (but we prefer for them to come from just one).
|
||||
|
||||
```
|
||||
{01: True}, {10: True}, {11: False}
|
||||
```
|
||||
|
||||
At present, all **<code>HintProviders</code>** set the **<code>Preferred</code>** field to **<code>True</code>** if and only if the **<code>NUMANodeAffinity</code>** encodes a _minimal_ set of NUMA nodes that can satisfy the resource request. Normally, this will only be **<code>True</code>** for **<code>TopologyHints</code>** with a single NUMA node set in their bitmask. However, it may also be **<code>True</code>** if the only way to _ever_ satisfy the resource request is to span multiple NUMA nodes (e.g. 2 devices are requested and the only 2 devices on the system are on different NUMA nodes):
|
||||
|
||||
```
|
||||
{0011: True}, {0111: False}, {1011: False}, {1111: False}
|
||||
```
|
||||
|
||||
**NOTE:** Setting of the **<code>Preferred</code>** field in this way is _not_ based on the set of currently available resources. It is based on the ability to physically allocate the number of requested resources on some minimal set of NUMA nodes.
|
||||
|
||||
In this way, it is possible for a **<code>HintProvider</code>** to return a list of hints with _all_ **<code>Preferred</code>** fields set to **<code>False</code>** if an actual preferred allocation cannot be satisfied until other containers release their resources. For example, consider the following scenario from the system in Figure 1:
|
||||
|
||||
1. All but 2 CPUs are currently allocated to containers
|
||||
1. The 2 remaining CPUs are on different NUMA nodes
|
||||
1. A new container comes along asking for 2 CPUs
|
||||
|
||||
In this case, the only generated hint would be **<code>{11: False}</code>** and not **<code>{11: True}</code>**. This happens because it _is_ possible to allocate 2 CPUs from the same NUMA node on this system (just not right now, given the current allocation state). The idea being that it is better to fail pod admission and retry the deployment when the minimal alignment can be satisfied than to allow a pod to be scheduled with sub-optimal alignment.
|
||||
|
||||
### HintProviders
|
||||
|
||||
A **<code>HintProvider</code>** is a component internal to the **<code>kubelet</code>** that coordinates aligned resource allocations with the **<code>TopologyManager</code>**. At present, the only **<code>HintProviders</code>** in Kubernetes are the **<code>CPUManager</code>** and the **<code>DeviceManager</code>**. We plan to add support for **<code>HugePages</code>** soon.
|
||||
|
||||
As discussed previously, the **<code>TopologyManager</code>** both gathers **<code>TopologyHints</code>** from **<code>HintProviders</code>** as well as triggers aligned resource allocations on them using a merged "best" hint. As such, **<code>HintProviders</code>** implement the following interface:
|
||||
|
||||
```
|
||||
type HintProvider interface {
|
||||
GetTopologyHints(*v1.Pod, *v1.Container) map[string][]TopologyHint
|
||||
Allocate(*v1.Pod, *v1.Container) error
|
||||
}
|
||||
```
|
||||
|
||||
Notice that the call to **<code>GetTopologyHints()</code>** returns a **<code>map[string][]TopologyHint</code>**. This allows a single **<code>HintProvider</code>** to provide hints for multiple resource types instead of just one. For example, the **<code>DeviceManager</code>** requires this in order to pass hints back for every resource type registered by its plugins.
|
||||
|
||||
As **<code>HintProviders</code>** generate their hints, they only consider how alignment could be satisfied for _currently_ available resources on the system. Any resources already allocated to other containers are not considered.
|
||||
|
||||
For example, consider the system in Figure 1, with the following two containers requesting resources from it:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><strong><code>Container0</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>Container1</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
<pre>
|
||||
spec:
|
||||
containers:
|
||||
- name: numa-aligned-container0
|
||||
image: alpine
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2
|
||||
memory: 200Mi
|
||||
gpu-vendor.com/gpu: 1
|
||||
nic-vendor.com/nic: 1
|
||||
</pre>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<pre>
|
||||
spec:
|
||||
containers:
|
||||
- name: numa-aligned-container1
|
||||
image: alpine
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2
|
||||
memory: 200Mi
|
||||
gpu-vendor.com/gpu: 1
|
||||
nic-vendor.com/nic: 1
|
||||
</pre>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If **<code>Container0</code>** is the first container considered for allocation on the system, the following set of hints will be generated for the three topology-aware resource types in the spec.
|
||||
|
||||
```
|
||||
cpu: {{01: True}, {10: True}, {11: False}}
|
||||
gpu-vendor.com/gpu: {{01: True}, {10: True}}
|
||||
nic-vendor.com/nic: {{01: True}, {10: True}}
|
||||
```
|
||||
|
||||
With a resulting aligned allocation of:
|
||||
|
||||
```
|
||||
{cpu: {0, 1}, gpu: 0, nic: 0}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<img height="300" src="/images/blog/2020-03-25-kubernetes-1.18-release-announcement/numa-hint-provider1.png">
|
||||
</p>
|
||||
|
||||
|
||||
When considering **<code>Container1</code>** these resources are then presumed to be unavailable, and thus only the following set of hints will be generated:
|
||||
|
||||
```
|
||||
cpu: {{01: True}, {10: True}, {11: False}}
|
||||
gpu-vendor.com/gpu: {{10: True}}
|
||||
nic-vendor.com/nic: {{10: True}}
|
||||
```
|
||||
|
||||
With a resulting aligned allocation of:
|
||||
|
||||
|
||||
```
|
||||
{cpu: {4, 5}, gpu: 1, nic: 1}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<img height="300" src="/images/blog/2020-03-25-kubernetes-1.18-release-announcement/numa-hint-provider2.png">
|
||||
</p>
|
||||
|
||||
|
||||
**NOTE:** Unlike the pseudocode provided at the beginning of this section, the call to **<code>Allocate()</code>** does not actually take a parameter for the merged "best" hint directly. Instead, the **<code>TopologyManager</code>** implements the following **<code>Store</code>** interface that **<code>HintProviders</code>** can query to retrieve the hint generated for a particular container once it has been generated:
|
||||
|
||||
```
|
||||
type Store interface {
|
||||
GetAffinity(podUID string, containerName string) TopologyHint
|
||||
}
|
||||
```
|
||||
|
||||
Separating this out into its own API call allows one to access this hint outside of the pod admission loop. This is useful for debugging as well as for reporting generated hints in tools such as **<code>kubectl</code>**(not yet available).
|
||||
|
||||
### Policy.Merge
|
||||
|
||||
The merge strategy defined by a given policy dictates how it combines the set of **<code>TopologyHints</code>** generated by all **<code>HintProviders</code>** into a single **<code>TopologyHint</code>** that can be used to inform aligned resource allocations.
|
||||
|
||||
The general merge strategy for all supported policies begins the same:
|
||||
|
||||
1. Take the cross-product of **<code>TopologyHints</code>** generated for each resource type
|
||||
1. For each entry in the cross-product, **<code>bitwise-and</code>** the NUMA affinities of each **<code>TopologyHint</code>** together. Set this as the NUMA affinity in a resulting "merged" hint.
|
||||
1. If all of the hints in an entry have **<code>Preferred</code>** set to **<code>True</code>** , set **<code>Preferred</code>** to **<code>True</code>** in the resulting "merged" hint.
|
||||
1. If even one of the hints in an entry has **<code>Preferred</code>** set to **<code>False</code>** , set **<code>Preferred</code>** to **<code>False</code>** in the resulting "merged" hint. Also set **<code>Preferred</code>** to **<code>False</code>** in the "merged" hint if its NUMA affinity contains all 0s.
|
||||
|
||||
Following the example from the previous section with hints for **<code>Container0</code>** generated as:
|
||||
|
||||
```
|
||||
cpu: {{01: True}, {10: True}, {11: False}}
|
||||
gpu-vendor.com/gpu: {{01: True}, {10: True}}
|
||||
nic-vendor.com/nic: {{01: True}, {10: True}}
|
||||
```
|
||||
|
||||
The above algorithm results in the following set of cross-product entries and "merged" hints:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">cross-product entry
|
||||
<p>
|
||||
<strong><code>{cpu, gpu-vendor.com/gpu, nic-vendor.com/nic}</code></strong>
|
||||
</p>
|
||||
</td>
|
||||
<td align="center">"merged" hint
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{01: True}, {01: True}, {01: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{01: True}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{01: True}, {01: True}, {10: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{01: True}, {10: True}, {01: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{01: True}, {10: True}, {10: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{10: True}, {01: True}, {01: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{10: True}, {01: True}, {10: True}}</code></strong>
|
||||
</td align="center">
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{10: True}, {10: True}, {01: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{10: True}, {10: True}, {10: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{01: True}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{11: False}, {01: True}, {01: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{01: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{11: False}, {01: True}, {10: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{11: False}, {10: True}, {01: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{00: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<strong><code>{{11: False}, {10: True}, {10: True}}</code></strong>
|
||||
</td>
|
||||
<td align="center"><strong><code>{10: False}</code></strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
Once this list of "merged" hints has been generated, it is the job of the specific **<code>TopologyManager</code>** policy in use to decide which one to consider as the "best" hint.
|
||||
|
||||
In general, this involves:
|
||||
|
||||
1. Sorting merged hints by their "narrowness". Narrowness is defined as the number of bits set in a hint’s NUMA affinity mask. The fewer bits set, the narrower the hint. For hints that have the same number of bits set in their NUMA affinity mask, the hint with the most low order bits set is considered narrower.
|
||||
1. Sorting merged hints by their **<code>Preferred</code>** field. Hints that have **<code>Preferred</code>** set to **<code>True</code>** are considered more likely candidates than hints with **<code>Preferred</code>** set to **<code>False</code>**.
|
||||
1. Selecting the narrowest hint with the best possible setting for **<code>Preferred</code>**.
|
||||
|
||||
In the case of the **<code>best-effort</code>** policy this algorithm will always result in _some_ hint being selected as the "best" hint and the pod being admitted. This "best" hint is then made available to **<code>HintProviders</code>** so they can make their resource allocations based on it.
|
||||
|
||||
However, in the case of the **<code>restricted</code>** and **<code>single-numa-node</code>** policies, any selected hint with **<code>Preferred</code>** set to **<code>False</code>** will be rejected immediately, causing pod admission to fail and no resources to be allocated. Moreover, the **<code>single-numa-node</code>** will also reject a selected hint that has more than one NUMA node set in its affinity mask.
|
||||
|
||||
In the example above, the pod would be admitted by all policies with a hint of **<code>{01: True}</code>**.
|
||||
|
||||
## Upcoming enhancements
|
||||
|
||||
While the 1.18 release and promotion to Beta brings along some great enhancements and fixes, there are still a number of limitations, described [here](https://kubernetes.io/docs/tasks/administer-cluster/topology-manager/#known-limitations). We are already underway working to address these limitations and more.
|
||||
|
||||
This section walks through the set of enhancements we plan to implement for the **<code>TopologyManager</code>** in the near future. This list is not exhaustive, but it gives a good idea of the direction we are moving in. It is ordered by the timeframe in which we expect to see each enhancement completed.
|
||||
|
||||
If you would like to get involved in helping with any of these enhancements, please [join the weekly Kubernetes SIG-node meetings](https://github.com/kubernetes/community/tree/master/sig-node) to learn more and become part of the community effort!
|
||||
|
||||
### Supporting device-specific constraints
|
||||
|
||||
Currently, NUMA affinity is the only constraint considered by the **<code>TopologyManager</code>** for resource alignment. Moreover, the only scalable extensions that can be made to a **<code>TopologyHint</code>** involve _node-level_ constraints, such as PCIe bus alignment across device types. It would be intractable to try and add any _device-specific_ constraints to this struct (e.g. the internal NVLINK topology among a set of GPU devices).
|
||||
|
||||
As such, we propose an extension to the device plugin interface that will allow a plugin to state its topology-aware allocation preferences, without having to expose any device-specific topology information to the kubelet. In this way, the **<code>TopologyManager</code>** can be restricted to only deal with common node-level topology constraints, while still having a way of incorporating device-specific topology constraints into its allocation decisions.
|
||||
|
||||
Details of this proposal can be found [here](https://github.com/kubernetes/enhancements/pull/1121), and should be available as soon as Kubernetes 1.19.
|
||||
|
||||
### NUMA alignment for hugepages
|
||||
|
||||
As stated previously, the only two **<code>HintProviders</code>** currently available to the **<code>TopologyManager</code>** are the **<code>CPUManager</code>** and the **<code>DeviceManager</code>**. However, work is currently underway to add support for hugepages as well. With the completion of this work, the **<code>TopologyManager</code>** will finally be able to allocate memory, hugepages, CPUs and PCI devices all on the same NUMA node.
|
||||
|
||||
A [KEP](https://github.com/kubernetes/enhancements/blob/253f1e5bdd121872d2d0f7020a5ac0365b229e30/keps/sig-node/20200203-memory-manager.md) for this work is currently under review, and a prototype is underway to get this feature implemented very soon.
|
||||
|
||||
|
||||
### Scheduler awareness
|
||||
|
||||
Currently, the **<code>TopologyManager</code>** acts as a Pod Admission controller. It is not directly involved in the scheduling decision of where a pod will be placed. Rather, when the kubernetes scheduler (or whatever scheduler is running in the deployment), places a pod on a node to run, the **<code>TopologyManager</code>** will decide if the pod should be "admitted" or "rejected". If the pod is rejected due to lack of available NUMA aligned resources, things can get a little interesting. This kubernetes [issue](https://github.com/kubernetes/kubernetes/issues/84869) highlights and discusses this situation well.
|
||||
|
||||
So how do we go about addressing this limitation? We have the [Kubernetes Scheduling Framework](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20180409-scheduling-framework.md) to the rescue! This framework provides a new set of plugin APIs that integrate with the existing Kubernetes Scheduler and allow scheduling features, such as NUMA alignment, to be implemented without having to resort to other, perhaps less appealing alternatives, including writing your own scheduler, or even worse, creating a fork to add your own scheduler secret sauce.
|
||||
|
||||
The details of how to implement these extensions for integration with the **<code>TopologyManager</code>** have not yet been worked out. We still need to answer questions like:
|
||||
|
||||
* Will we require duplicated logic to determine device affinity in the **<code>TopologyManager</code>** and the scheduler?
|
||||
* Do we need a new API to get **<code>TopologyHints</code>** from the **<code>TopologyManager</code>** to the scheduler plugin?
|
||||
|
||||
Work on this feature should begin in the next couple of months, so stay tuned!
|
||||
|
||||
|
||||
### Per-pod alignment policy
|
||||
|
||||
As stated previously, a single policy is applied to _all_ pods on a node via a global **<code>kubelet</code>** flag, rather than allowing users to select different policies on a pod-by-pod basis (or a container-by-container basis).
|
||||
|
||||
While we agree that this would be a great feature to have, there are quite a few hurdles that need to be overcome before it is achievable. The biggest hurdle being that this enhancement will require an API change to be able to express the desired alignment policy in either the Pod spec or its associated **<code>[RuntimeClass](https://kubernetes.io/docs/concepts/containers/runtime-class/)</code>**.
|
||||
|
||||
We are only now starting to have serious discussions around this feature, and it is still a few releases away, at the best, from being available.
|
||||
|
||||
## Conclusion
|
||||
|
||||
With the promotion of the **<code>TopologyManager</code>** to Beta in 1.18, we encourage everyone to give it a try and look forward to any feedback you may have. Many fixes and enhancements have been worked on in the past several releases, greatly improving the functionality and reliability of the **<code>TopologyManager</code>** and its **<code>HintProviders</code>**. While there are still a number of limitations, we have a set of enhancements planned to address them, and look forward to providing you with a number of new features in upcoming releases.
|
||||
|
||||
If you have ideas for additional enhancements or a desire for certain features, don’t hesitate to let us know. The team is always open to suggestions to enhance and improve the **<code>TopologyManager</code>**.
|
||||
|
||||
We hope you have found this blog informative and useful! Let us know if you have any questions or comments. And, happy deploying…..Align Up!
|
||||
|
||||
|
||||
<!-- Docs to Markdown version 1.0β20 -->
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Kubernetes 1.18 Feature Server-side Apply Beta 2
|
||||
date: 2020-04-01
|
||||
slug: Kubernetes-1.18-Feature-Server-side-Apply-Beta-2
|
||||
---
|
||||
|
||||
**Authors:** Antoine Pelisse (Google)
|
||||
|
||||
## What is Server-side Apply?
|
||||
Server-side Apply is an important effort to migrate “kubectl apply” to the apiserver. It was started in 2018 by the Apply working group.
|
||||
|
||||
The use of kubectl to declaratively apply resources has exposed the following challenges:
|
||||
|
||||
- One needs to use the kubectl go code, or they have to shell out to kubectl.
|
||||
|
||||
- Strategic merge-patch, the patch format used by kubectl, grew organically and was challenging to fix while maintaining compatibility with various api-server versions.
|
||||
|
||||
- Some features are hard to implement directly on the client, for example, unions.
|
||||
|
||||
|
||||
Server-side Apply is a new merging algorithm, as well as tracking of field ownership, running on the Kubernetes api-server. Server-side Apply enables new features like conflict detection, so the system knows when two actors are trying to edit the same field.
|
||||
|
||||
## How does it work, what’s managedFields?
|
||||
Server-side Apply works by keeping track of which actor of the system has changed each field of an object. It does so by diffing all updates to objects, and recording all the fields that have changed as well the time of the operation. All this information is stored in the managedFields in the metadata of objects. Since objects can have many fields, this field can be quite large.
|
||||
|
||||
When someone applies, we can then use the information stored within managedFields to report relevant conflicts and help the merge algorithm to do the right thing.
|
||||
|
||||
## Wasn’t it already Beta before 1.18?
|
||||
Yes, Server-side Apply has been Beta since 1.16, but it didn’t track the owner for fields associated with objects that had not been applied. This means that most objects didn’t have the managedFields metadata stored, and conflicts for these objects cannot be resolved. With Kubernetes 1.18, all new objects will have the managedFields attached to them and provide accurate information on conflicts.
|
||||
|
||||
## How do I use it?
|
||||
The most common way to use this is through kubectl: `kubectl apply --server-side`. This is likely to show conflicts with other actors, including client-side apply. When that happens, conflicts can be forced by using the `--force-conflicts` flag, which will grab the ownership for the fields that have changed.
|
||||
|
||||
## Current limitations
|
||||
We have two important limitations right now, especially with sub-resources. The first is that if you apply with a status, the status is going to be ignored. We are still going to try and acquire the fields, which may lead to invalid conflicts. The other is that we do not update the managedFields on some sub-resources, including scale, so you may not see information about a horizontal pod autoscaler changing the number of replicas.
|
||||
|
||||
## What’s next?
|
||||
We are working hard to improve the experience of using server-side apply with kubectl, and we are trying to make it the default. As part of that, we want to improve the migration from client-side to server-side.
|
||||
|
||||
## Can I help?
|
||||
Of course! The working-group apply is available on slack #wg-apply, through the [mailing list](https://groups.google.com/forum/#!forum/kubernetes-wg-apply) and we also meet every other Tuesday at 9.30 PT on Zoom. We have lots of exciting features to build and can use all sorts of help.
|
||||
|
||||
We would also like to use the opportunity to thank the hard work of all the contributors involved in making this new beta possible:
|
||||
|
||||
* Daniel Smith
|
||||
* Jenny Buckley
|
||||
* Joe Betz
|
||||
* Julian Modesto
|
||||
* Kevin Wiesmüller
|
||||
* Maria Ntalla
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: Improvements to the Ingress API in Kubernetes 1.18
|
||||
date: 2020-04-02
|
||||
slug: Improvements-to-the-Ingress-API-in-Kubernetes-1.18
|
||||
---
|
||||
|
||||
**Authors:** Rob Scott (Google), Christopher M Luciano (IBM)
|
||||
|
||||
The Ingress API in Kubernetes has enabled a large number of controllers to provide simple and powerful ways to manage inbound network traffic to Kubernetes workloads. In Kubernetes 1.18, we've made 3 significant additions to this API:
|
||||
|
||||
* A new `pathType` field that can specify how Ingress paths should be matched.
|
||||
* A new `IngressClass` resource that can specify how Ingresses should be implemented by controllers.
|
||||
* Support for wildcards in hostnames.
|
||||
|
||||
## Better Path Matching With Path Types
|
||||
The new concept of a path type allows you to specify how a path should be matched. There are three supported types:
|
||||
|
||||
* __ImplementationSpecific (default):__ With this path type, matching is up to the controller implementing the `IngressClass`. Implementations can treat this as a separate `pathType` or treat it identically to the `Prefix` or `Exact` path types.
|
||||
* __Exact:__ Matches the URL path exactly and with case sensitivity.
|
||||
* __Prefix:__ Matches based on a URL path prefix split by `/`. Matching is case sensitive and done on a path element by element basis.
|
||||
|
||||
## Extended Configuration With Ingress Classes
|
||||
The Ingress resource was designed with simplicity in mind, providing a simple set of fields that would be applicable in all use cases. Over time, as use cases evolved, implementations began to rely on a long list of custom annotations for further configuration. The new `IngressClass` resource provides a way to replace some of those annotations.
|
||||
|
||||
Each `IngressClass` specifies which controller should implement Ingresses of the class and can reference a custom resource with additional parameters.
|
||||
```yaml
|
||||
apiVersion: "networking.k8s.io/v1beta1"
|
||||
kind: "IngressClass"
|
||||
metadata:
|
||||
name: "external-lb"
|
||||
spec:
|
||||
controller: "example.com/ingress-controller"
|
||||
parameters:
|
||||
apiGroup: "k8s.example.com/v1alpha"
|
||||
kind: "IngressParameters"
|
||||
name: "external-lb"
|
||||
```
|
||||
|
||||
### Specifying the Class of an Ingress
|
||||
A new `ingressClassName` field has been added to the Ingress spec that is used to reference the `IngressClass` that should be used to implement this Ingress.
|
||||
|
||||
### Deprecating the Ingress Class Annotation
|
||||
Before the `IngressClass` resource was added in Kubernetes 1.18, a similar concept of Ingress class was often specified with a `kubernetes.io/ingress.class` annotation on the Ingress. Although this annotation was never formally defined, it was widely supported by Ingress controllers, and should now be considered formally deprecated.
|
||||
|
||||
### Setting a Default IngressClass
|
||||
It’s possible to mark a specific `IngressClass` as default in a cluster. Setting the
|
||||
`ingressclass.kubernetes.io/is-default-class` annotation to true on an
|
||||
IngressClass resource will ensure that new Ingresses without an `ingressClassName` specified will be assigned this default `IngressClass`.
|
||||
|
||||
## Support for Hostname Wildcards
|
||||
Many Ingress providers have supported wildcard hostname matching like `*.foo.com` matching `app1.foo.com`, but until now the spec assumed an exact FQDN match of the host. Hosts can now be precise matches (for example “`foo.bar.com`”) or a wildcard (for example “`*.foo.com`”). Precise matches require that the http host header matches the Host setting. Wildcard matches require the http host header is equal to the suffix of the wildcard rule.
|
||||
|
||||
| Host | Host header | Match? |
|
||||
| ----------- |-------------------| --------------------------------------------------|
|
||||
| `*.foo.com` | `bar.foo.com` | Matches based on shared suffix |
|
||||
| `*.foo.com` | `baz.bar.foo.com` | No match, wildcard only covers a single DNS label |
|
||||
| `*.foo.com` | `foo.com` | No match, wildcard only covers a single DNS label |
|
||||
|
||||
### Putting it All Together
|
||||
These new Ingress features allow for much more configurability. Here’s an example of an Ingress that makes use of pathType, `ingressClassName`, and a hostname wildcard:
|
||||
|
||||
```yaml
|
||||
apiVersion: "networking.k8s.io/v1beta1"
|
||||
kind: "Ingress"
|
||||
metadata:
|
||||
name: "example-ingress"
|
||||
spec:
|
||||
ingressClassName: "external-lb"
|
||||
rules:
|
||||
- host: "*.example.com"
|
||||
http:
|
||||
paths:
|
||||
- path: "/example"
|
||||
pathType: "Prefix"
|
||||
backend:
|
||||
serviceName: "example-service"
|
||||
servicePort: 80
|
||||
```
|
||||
|
||||
### Ingress Controller Support
|
||||
Since these features are new in Kubernetes 1.18, each Ingress controller implementation will need some time to develop support for these new features. Check the documentation for your preferred Ingress controllers to see when they will support this new functionality.
|
||||
|
||||
## The Future of Ingress
|
||||
The Ingress API is on pace to graduate from beta to a stable API in Kubernetes 1.19. It will continue to provide a simple way to manage inbound network traffic for Kubernetes workloads. This API has intentionally been kept simple and lightweight, but there has been a desire for greater configurability for more advanced use cases.
|
||||
|
||||
Work is currently underway on a new highly configurable set of APIs that will provide an alternative to Ingress in the future. These APIs are being referred to as the new “Service APIs”. They are not intended to replace any existing APIs, but instead provide a more configurable alternative for complex use cases. For more information, check out the [Service APIs repo on GitHub](http://github.com/kubernetes-sigs/service-apis).
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Introducing Windows CSI support alpha for Kubernetes"
|
||||
date: 2020-04-03
|
||||
slug: kubernetes-1-18-feature-windows-csi-support-alpha
|
||||
---
|
||||
**Authors:** Authors: Deep Debroy [Docker], Jing Xu [Google], Krishnakumar R (KK) [Microsoft]
|
||||
|
||||
<em>The alpha version of [CSI Proxy][csi-proxy] for Windows is being released with Kubernetes 1.18. CSI proxy enables CSI Drivers on Windows by allowing containers in Windows to perform privileged storage operations.</em>
|
||||
|
||||
## Background
|
||||
|
||||
Container Storage Interface (CSI) for Kubernetes went GA in the Kubernetes 1.13 release. CSI has become the standard for exposing block and file storage to containerized workloads on Container Orchestration systems (COs) like Kubernetes. It enables third-party storage providers to write and deploy plugins without the need to alter the core Kubernetes codebase. All new storage features will utilize CSI, therefore it is important to get CSI drivers to work on Windows.
|
||||
|
||||
A CSI driver in Kubernetes has two main components: a controller plugin and a node plugin. The controller plugin generally does not need direct access to the host and can perform all its operations through the Kubernetes API and external control plane services (e.g. cloud storage service). The node plugin, however, requires direct access to the host for making block devices and/or file systems available to the Kubernetes kubelet. This was previously not possible for containers on Windows. With the release of [CSIProxy][csi-proxy], CSI drivers can now perform storage operations on the node. This inturn enables containerized CSI Drivers to run on Windows.
|
||||
|
||||
## CSI support for Windows clusters
|
||||
|
||||
CSI drivers (e.g. AzureDisk, GCE PD, etc.) are recommended to be deployed as containers. CSI driver’s node plugin typically runs on every worker node in the cluster (as a DaemonSet). Node plugin containers need to run with elevated privileges to perform storage related operations. However, Windows currently does not support privileged containers. To solve this problem, [CSIProxy][csi-proxy] makes it so that node plugins can now be deployed as unprivileged pods and then use the proxy to perform privileged storage operations on the node.
|
||||
|
||||
## Node plugin interactions with CSIProxy
|
||||
|
||||
The design of the CSI proxy is captured in this [KEP][kep]. The following diagram depicts the interactions with the CSI node plugin and CSI proxy.
|
||||
|
||||
<p align="center">
|
||||
<img src="/images/blog/2020-04-03-Introducing-Windows-CSI-support-alpha-for-Kubernetes/CSIProxyOverview.png">
|
||||
</p>
|
||||
|
||||
The CSI proxy runs as a process directly on the host on every windows node - very similar to kubelet. The CSI code in kubelet interacts with the [node driver registrar][nd-reg] component and the CSI node plugin. The node driver registrar is a community maintained CSI project which handles the registration of vendor specific node plugins. The kubelet initiates CSI gRPC calls like NodeStageVolume/NodePublishVolume on the node plugin as described in the figure. Node plugins interface with the CSIProxy process to perform local host OS storage related operations such as creation/enumeration of volumes, mounting/unmounting, etc.
|
||||
|
||||
## CSI proxy architecture and implementation
|
||||
|
||||
<p align="center">
|
||||
<img src="/images/blog/2020-04-03-Introducing-Windows-CSI-support-alpha-for-Kubernetes/CSIProxyArchitecture.png">
|
||||
</p>
|
||||
|
||||
In the alpha release, CSIProxy supports the following API groups:
|
||||
1. Filesystem
|
||||
1. Disk
|
||||
1. Volume
|
||||
1. SMB
|
||||
|
||||
CSI proxy exposes each API group via a Windows named pipe. The communication is performed using gRPC over these pipes. The client library from the CSI proxy project uses these pipes to interact with the CSI proxy APIs. For example, the filesystem APIs are exposed via a pipe like <code>\\.\pipe\csi-proxy-filesystem-v1alpha1</code> and volume APIs under the <code>\\.\pipe\csi-proxy-volume-v1alpha1</code>, and so on.
|
||||
|
||||
From each API group service, the calls are routed to the host API layer. The host API calls into the host Windows OS by either Powershell or Go standard library calls. For example, when the filesystem API [Rmdir][rmdir] is called the API group service would decode the grpc structure [RmdirRequest][rmdir-req] and find the directory to be removed and call into the Host APIs layer. This would result in a call to [os.Remove][os-rem], a Go standard library call, to perform the remove operation.
|
||||
|
||||
## Control flow details
|
||||
|
||||
The following figure uses CSI call NodeStageVolume as an example to explain the interaction between kubelet, CSI plugin, and CSI proxy for provisioning a fresh volume. After the node plugin receives a CSI RPC call, it makes a few calls to CSIproxy accordingly. As a result of the NodeStageVolume call, first the required disk is identified using either of the Disk API calls: ListDiskLocations (in AzureDisk driver) or GetDiskNumberByName (in GCE PD driver). If the disk is not partitioned, then the PartitionDisk (Disk API group) is called. Subsequently, Volume API calls such as ListVolumesOnDisk, FormatVolume and MountVolume are called to perform the rest of the required operations. Similar operations are performed in case of NodeUnstageVolume, NodePublishVolume, NodeUnpublishedVolume, etc.
|
||||
|
||||
<p align="center">
|
||||
<img src="/images/blog/2020-04-03-Introducing-Windows-CSI-support-alpha-for-Kubernetes/CSIProxyControlFlow.png">
|
||||
</p>
|
||||
|
||||
## Current support
|
||||
|
||||
CSI proxy is now available as alpha. You can find more details on the [CSIProxy][csi-proxy] GitHub repository. There are currently two cloud providers that provide alpha support for CSI drivers on Windows: Azure and GCE.
|
||||
|
||||
## Future plans
|
||||
|
||||
One key area of focus in beta is going to be Windows based build and CI/CD setup to improve the stability and quality of the code base. Another area is using Go based calls directly instead of Powershell commandlets to improve performance. Enhancing debuggability and adding more tests are other areas which the team will be looking into.
|
||||
|
||||
## How to get involved?
|
||||
|
||||
This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together. Those interested in getting involved with the design and development of CSI Proxy, or any part of the Kubernetes Storage system, may join the [Kubernetes Storage Special Interest Group][sig] (SIG). We’re rapidly growing and always welcome new contributors.
|
||||
|
||||
For those interested in more details, the [CSIProxy][csi-proxy] GitHub repository is a good place to start. In addition, the [#csi-windows][slack] channel on kubernetes slack is available for discussions specific to the CSI on Windows.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
We would like to thank Michelle Au for guiding us throughout this journey to alpha. We would like to thank Jean Rougé for contributions during the initial CSI proxy effort. We would like to thank Saad Ali for all the guidance with respect to the project and review/feedback on a draft of this blog. We would like to thank Patrick Lang and Mark Rossetti for helping us with Windows specific questions and details. Special thanks to Andy Zhang for reviews and guidance with respect to Azuredisk and Azurefile work. A big thank you to Paul Burt and Karen Chu for the review and suggestions on improving this blog post.
|
||||
|
||||
Last but not the least, we would like to thank the broader Kubernetes community who contributed at every step of the project.
|
||||
|
||||
|
||||
|
||||
[csi-proxy]: https://github.com/kubernetes-csi/csi-proxy
|
||||
[kep]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-windows/20190714-windows-csi-support.md
|
||||
[nd-reg]: https://kubernetes-csi.github.io/docs/node-driver-registrar.html
|
||||
[rmdir]: https://github.com/kubernetes-csi/csi-proxy/blob/master/client/api/filesystem/v1alpha1/api.proto
|
||||
[rmdir-req]: https://github.com/kubernetes-csi/csi-proxy/blob/master/client/api/filesystem/v1alpha1/api.pb.go
|
||||
[os-rem]: https://github.com/kubernetes-csi/csi-proxy/blob/master/internal/os/filesystem/api.go
|
||||
[sig]: https://github.com/kubernetes/community/tree/master/sig-storage
|
||||
[slack]: https://kubernetes.slack.com/messages/csi-windows
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "API Priority and Fairness Alpha"
|
||||
date: 2020-04-06
|
||||
slug: kubernetes-1-18-feature-api-priority-and-fairness-alpha
|
||||
---
|
||||
|
||||
**Authors:** Min Kim (Ant Financial), Mike Spreitzer (IBM), Daniel Smith (Google)
|
||||
|
||||
This blog describes “API Priority And Fairness”, a new alpha feature in Kubernetes 1.18. API Priority And Fairness permits cluster administrators to divide the concurrency of the control plane into different weighted priority levels. Every request arriving at a kube-apiserver will be categorized into one of the priority levels and get its fair share of the control plane’s throughput.
|
||||
|
||||
## What problem does this solve?
|
||||
Today the apiserver has a simple mechanism for protecting itself against CPU and memory overloads: max-in-flight limits for mutating and for readonly requests. Apart from the distinction between mutating and readonly, no other distinctions are made among requests; consequently, there can be undesirable scenarios where one subset of the requests crowds out other requests.
|
||||
|
||||
In short, it is far too easy for Kubernetes workloads to accidentally DoS the apiservers, causing other important traffic--like system controllers or leader elections---to fail intermittently. In the worst cases, a few broken nodes or controllers can push a busy cluster over the edge, turning a local problem into a control plane outage.
|
||||
|
||||
## How do we solve the problem?
|
||||
The new feature “API Priority and Fairness” is about generalizing the existing max-in-flight request handler in each apiserver, to make the behavior more intelligent and configurable. The overall approach is as follows.
|
||||
|
||||
1. Each request is matched by a _Flow Schema_. The Flow Schema states the Priority Level for requests that match it, and assigns a “flow identifier” to these requests. Flow identifiers are how the system determines whether requests are from the same source or not.
|
||||
2. Priority Levels may be configured to behave in several ways. Each Priority Level gets its own isolated concurrency pool. Priority levels also introduce the concept of queuing requests that cannot be serviced immediately.
|
||||
3. To prevent any one user or namespace from monopolizing a Priority Level, they may be configured to have multiple queues. [“Shuffle Sharding”](https://aws.amazon.com/builders-library/workload-isolation-using-shuffle-sharding/#What_is_shuffle_sharding.3F) is used to assign each flow of requests to a subset of the queues.
|
||||
4. Finally, when there is capacity to service a request, a [“Fair Queuing”](https://en.wikipedia.org/wiki/Fair_queuing) algorithm is used to select the next request. Within each priority level the queues compete with even fairness.
|
||||
|
||||
Early results have been very promising! Take a look at this [analysis](https://github.com/kubernetes/kubernetes/pull/88177#issuecomment-588945806).
|
||||
|
||||
## How do I try this out?
|
||||
You are required to prepare the following things in order to try out the feature:
|
||||
|
||||
* Download and install a kubectl greater than v1.18.0 version
|
||||
* Enabling the new API groups with the command line flag `--runtime-config="flowcontrol.apiserver.k8s.io/v1alpha1=true"` on the kube-apiservers
|
||||
* Switch on the feature gate with the command line flag `--feature-gates=APIPriorityAndFairness=true` on the kube-apiservers
|
||||
|
||||
After successfully starting your kube-apiservers, you will see a few default FlowSchema and PriorityLevelConfiguration resources in the cluster. These default configurations are designed for a general protection and traffic management for your cluster.
|
||||
You can examine and customize the default configuration by running the usual tools, e.g.:
|
||||
|
||||
* `kubectl get flowschemas`
|
||||
* `kubectl get prioritylevelconfigurations`
|
||||
|
||||
|
||||
## How does this work under the hood?
|
||||
Upon arrival at the handler, a request is assigned to exactly one priority level and exactly one flow within that priority level. Hence understanding how FlowSchema and PriorityLevelConfiguration works will be helping you manage the request traffic going through your kube-apiservers.
|
||||
|
||||
* FlowSchema: FlowSchema will identify a PriorityLevelConfiguration object and the way to compute the request’s “flow identifier”. Currently we support matching requests according to: the identity making the request, the verb, and the target object. The identity can match in terms of: a username, a user group name, or a ServiceAccount. And as for the target objects, we can match by apiGroup, resource[/subresource], and namespace.
|
||||
* The flow identifier is used for shuffle sharding, so it’s important that requests have the same flow identifier if they are from the same source! We like to consider scenarios with “elephants” (which send many/heavy requests) vs “mice” (which send few/light requests): it is important to make sure the elephant’s requests all get the same flow identifier, otherwise they will look like many different mice to the system!
|
||||
* See the API Documentation [here](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#flowschema-v1alpha1-flowcontrol-apiserver-k8s-io)!
|
||||
|
||||
* PriorityLevelConfiguration: Defines a priority level.
|
||||
* For apiserver self requests, and any reentrant traffic (e.g., admission webhooks which themselves make API requests), a Priority Level can be marked “exempt”, which means that no queueing or limiting of any sort is done. This is to prevent priority inversions.
|
||||
* Each non-exempt Priority Level is configured with a number of "concurrency shares" and gets an isolated pool of concurrency to use. Requests of that Priority Level run in that pool when it is not full, never anywhere else. Each apiserver is configured with a total concurrency limit (taken to be the sum of the old limits on mutating and readonly requests), and this is then divided among the Priority Levels in proportion to their concurrency shares.
|
||||
* A non-exempt Priority Level may select a number of queues and a "hand size" to use for the shuffle sharding. Shuffle sharding maps flows to queues in a way that is better than consistent hashing. A given flow has access to a small collection of queues, and for each incoming request the shortest queue is chosen. When a Priority Level has queues, it also sets a limit on queue length. There is also a limit placed on how long a request can wait in its queue; this is a fixed fraction of the apiserver's request timeout. A request that cannot be executed and cannot be queued (any longer) is rejected.
|
||||
* Alternatively, a non-exempt Priority Level may select immediate rejection instead of waiting in a queue.
|
||||
* See the [API documentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#prioritylevelconfiguration-v1alpha1-flowcontrol-apiserver-k8s-io) for this feature.
|
||||
|
||||
## What’s missing? When will there be a beta?
|
||||
We’re already planning a few enhancements based on alpha and there will be more as users send feedback to our community. Here’s a list of them:
|
||||
|
||||
* Traffic management for WATCH and EXEC requests
|
||||
* Adjusting and improving the default set of FlowSchema/PriorityLevelConfiguration
|
||||
* Enhancing observability on how this feature works
|
||||
* Join the discussion [here](https://github.com/kubernetes/enhancements/pull/1632)
|
||||
|
||||
Possibly treat LIST requests differently depending on an estimate of how big their result will be.
|
||||
|
||||
## How can I get involved?
|
||||
As always! Reach us on slack [#sig-api-machinery](https://kubernetes.slack.com/messages/sig-api-machinery), or through the [mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-api-machinery). We have lots of exciting features to build and can use all sorts of help.
|
||||
|
||||
Many thanks to the contributors that have gotten this feature this far: Aaron Prindle, Daniel Smith, Jonathan Tomer, Mike Spreitzer, Min Kim, Bruce Ma, Yu Liao, Mengyi Zhou!
|
||||
@@ -1,199 +0,0 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Kong Ingress Controller and Service Mesh: Setting up Ingress to Istio on Kubernetes'
|
||||
date: 2020-03-18
|
||||
slug: kong-ingress-controller-and-istio-service-mesh
|
||||
---
|
||||
|
||||
**Author:** Kevin Chen, Kong
|
||||
|
||||
Kubernetes has become the de facto way to orchestrate containers and the services within services. But how do we give services outside our cluster access to what is within? Kubernetes comes with the Ingress API object that manages external access to services within a cluster.
|
||||
|
||||
Ingress is a group of rules that will proxy inbound connections to endpoints defined by a backend. However, Kubernetes does not know what to do with Ingress resources without an Ingress controller, which is where an open source controller can come into play. In this post, we are going to use one option for this: the Kong Ingress Controller. The Kong Ingress Controller was open-sourced a year ago and recently reached one million downloads. In the recent 0.7 release, service mesh support was also added. Other features of this release include:
|
||||
|
||||
* **Built-In Kubernetes Admission Controller**, which validates Custom Resource Definitions (CRD) as they are created or updated and rejects any invalid configurations.
|
||||
* **In-memory Mode** - Each pod’s controller actively configures the Kong container in its pod, which limits the blast radius of failure of a single container of Kong or controller container to that pod only.
|
||||
* **Native gRPC Routing** - gRPC traffic can now be routed via Kong Ingress Controller natively with support for method-based routing.
|
||||
|
||||

|
||||
|
||||
If you would like a deeper dive into Kong Ingress Controller 0.7, please check out the [GitHub repository](https://github.com/Kong/kubernetes-ingress-controller).
|
||||
|
||||
But let’s get back to the service mesh support since that will be the main focal point of this blog post. Service mesh allows organizations to address microservices challenges related to security, reliability, and observability by abstracting inter-service communication into a mesh layer. But what if our mesh layer sits within Kubernetes and we still need to expose certain services beyond our cluster? Then you need an Ingress controller such as the Kong Ingress Controller. In this blog post, we’ll cover how to deploy Kong Ingress Controller as your Ingress layer to an Istio mesh. Let’s dive right in:
|
||||
|
||||

|
||||
|
||||
### Part 0: Set up Istio on Kubernetes
|
||||
|
||||
This blog will assume you have Istio set up on Kubernetes. If you need to catch up to this point, please check out the [Istio documentation](https://istio.io/docs/setup/). It will walk you through setting up Istio on Kubernetes.
|
||||
|
||||
### 1. Install the Bookinfo Application
|
||||
|
||||
First, we need to label the namespaces that will host our application and Kong proxy. To label our default namespace where the bookinfo app sits, run this command:
|
||||
|
||||
```
|
||||
$ kubectl label namespace default istio-injection=enabled
|
||||
namespace/default labeled
|
||||
```
|
||||
|
||||
Then create a new namespace that will be hosting our Kong gateway and the Ingress controller:
|
||||
|
||||
```
|
||||
$ kubectl create namespace kong
|
||||
namespace/kong created
|
||||
```
|
||||
|
||||
Because Kong will be sitting outside the default namespace, be sure you also label the Kong namespace with istio-injection enabled as well:
|
||||
|
||||
```
|
||||
$ kubectl label namespace kong istio-injection=enabled
|
||||
namespace/kong labeled
|
||||
```
|
||||
|
||||
Having both namespaces labeled `istio-injection=enabled` is necessary. Or else the default configuration will not inject a sidecar container into the pods of your namespaces.
|
||||
|
||||
Now deploy your BookInfo application with the following command:
|
||||
|
||||
```
|
||||
$ kubectl apply -f http://bit.ly/bookinfoapp
|
||||
service/details created
|
||||
serviceaccount/bookinfo-details created
|
||||
deployment.apps/details-v1 created
|
||||
service/ratings created
|
||||
serviceaccount/bookinfo-ratings created
|
||||
deployment.apps/ratings-v1 created
|
||||
service/reviews created
|
||||
serviceaccount/bookinfo-reviews created
|
||||
deployment.apps/reviews-v1 created
|
||||
deployment.apps/reviews-v2 created
|
||||
deployment.apps/reviews-v3 created
|
||||
service/productpage created
|
||||
serviceaccount/bookinfo-productpage created
|
||||
deployment.apps/productpage-v1 created
|
||||
```
|
||||
|
||||
Let’s double-check our Services and Pods to make sure that we have it all set up correctly:
|
||||
|
||||
```
|
||||
$ kubectl get services
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
details ClusterIP 10.97.125.254 <none> 9080/TCP 29s
|
||||
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29h
|
||||
productpage ClusterIP 10.97.62.68 <none> 9080/TCP 28s
|
||||
ratings ClusterIP 10.96.15.180 <none> 9080/TCP 28s
|
||||
reviews ClusterIP 10.104.207.136 <none> 9080/TCP 28s
|
||||
```
|
||||
|
||||
You should see four new services: details, productpage, ratings, and reviews. None of them have an external IP so we will use the [Kong gateway](https://github.com/Kong/kong) to expose the necessary services. And to check pods, run the following command:
|
||||
|
||||
```
|
||||
$ kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
details-v1-c5b5f496d-9wm29 2/2 Running 0 101s
|
||||
productpage-v1-7d6cfb7dfd-5mc96 2/2 Running 0 100s
|
||||
ratings-v1-f745cf57b-hmkwf 2/2 Running 0 101s
|
||||
reviews-v1-85c474d9b8-kqcpt 2/2 Running 0 101s
|
||||
reviews-v2-ccffdd984-9jnsj 2/2 Running 0 101s
|
||||
reviews-v3-98dc67b68-nzw97 2/2 Running 0 101s
|
||||
```
|
||||
|
||||
This command outputs useful data, so let’s take a second to understand it. If you examine the READY column, each pod has two containers running: the service and an Envoy sidecar injected alongside it. Another thing to highlight is that there are three review pods but only 1 review service. The Envoy sidecar will load balance the traffic to three different review pods that contain different versions, giving us the ability to A/B test our changes. With that said, you should now be able to access your product page!
|
||||
|
||||
```
|
||||
$ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
|
||||
<title>Simple Bookstore App</title>
|
||||
```
|
||||
|
||||
### 2. Kong Kubernetes Ingress Controller Without Database
|
||||
|
||||
To expose your services to the world, we will deploy Kong as the north-south traffic gateway. [Kong 1.1](https://github.com/Kong/kong/releases/tag/1.1.2) released with declarative configuration and DB-less mode. Declarative configuration allows you to specify the desired system state through a YAML or JSON file instead of a sequence of API calls. Using declarative config provides several key benefits to reduce complexity, increase automation and enhance system performance. And with the Kong Ingress Controller, any Ingress rules you apply to the cluster will automatically be configured on the Kong proxy. Let’s set up the Kong Ingress Controller and the actual Kong proxy first like this:
|
||||
|
||||
```
|
||||
$ kubectl apply -f https://bit.ly/k4k8s
|
||||
namespace/kong configured
|
||||
customresourcedefinition.apiextensions.k8s.io/kongconsumers.configuration.konghq.com created
|
||||
customresourcedefinition.apiextensions.k8s.io/kongcredentials.configuration.konghq.com created
|
||||
customresourcedefinition.apiextensions.k8s.io/kongingresses.configuration.konghq.com created
|
||||
customresourcedefinition.apiextensions.k8s.io/kongplugins.configuration.konghq.com created
|
||||
serviceaccount/kong-serviceaccount created
|
||||
clusterrole.rbac.authorization.k8s.io/kong-ingress-clusterrole created
|
||||
clusterrolebinding.rbac.authorization.k8s.io/kong-ingress-clusterrole-nisa-binding created
|
||||
configmap/kong-server-blocks created
|
||||
service/kong-proxy created
|
||||
service/kong-validation-webhook created
|
||||
deployment.apps/ingress-kong created
|
||||
```
|
||||
|
||||
To check if the Kong pod is up and running, run:
|
||||
|
||||
```
|
||||
$ kubectl get pods -n kong
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/ingress-kong-8b44c9856-9s42v 3/3 Running 0 2m26s
|
||||
```
|
||||
|
||||
There will be three containers within this pod. The first container is the Kong Gateway that will be the Ingress point to your cluster. The second container is the Ingress controller. It uses Ingress resources and updates the proxy to follow rules defined in the resource. And lastly, the third container is the Envoy proxy injected by Istio. Kong will route traffic through the Envoy sidecar proxy to the appropriate service. To send requests into the cluster via our newly deployed Kong Gateway, setup an environment variable with the a URL based on the IP address at which Kong is accessible.
|
||||
|
||||
```
|
||||
$ export PROXY_URL="$(minikube service -n kong kong-proxy --url | head -1)"
|
||||
$ echo $PROXY_URL
|
||||
http://192.168.99.100:32728
|
||||
```
|
||||
|
||||
Next, we need to change some configuration so that the side-car Envoy process can route the request correctly based on the host/authority header of the request. Run the following to stop the route from preserving host:
|
||||
|
||||
```
|
||||
$ echo "
|
||||
apiVersion: configuration.konghq.com/v1
|
||||
kind: KongIngress
|
||||
metadata:
|
||||
name: do-not-preserve-host
|
||||
route:
|
||||
preserve_host: false
|
||||
" | kubectl apply -f -
|
||||
kongingress.configuration.konghq.com/do-not-preserve-host created
|
||||
```
|
||||
|
||||
And annotate the existing productpage service to set service-upstream as true:
|
||||
|
||||
```
|
||||
$ kubectl annotate svc productpage Ingress.kubernetes.io/service-upstream="true"
|
||||
service/productpage annotated
|
||||
```
|
||||
|
||||
Now that we have everything set up, we can look at how to use the Ingress resource to help route external traffic to the services within your Istio mesh. We’ll create an Ingress rule that routes all traffic with the path of `/` to our productpage service:
|
||||
|
||||
```
|
||||
$ echo "
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: productpage
|
||||
annotations:
|
||||
configuration.konghq.com: do-not-preserve-host
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: productpage
|
||||
servicePort: 9080
|
||||
" | kubectl apply -f -
|
||||
ingress.extensions/productpage created
|
||||
```
|
||||
|
||||
And just like that, the Kong Ingress Controller is able to understand the rules you defined in the Ingress resource and routes it to the productpage service! To view the product page service’s GUI, go to `$PROXY_URL/productpage` in your browser. Or to test it in your command line, try:
|
||||
|
||||
```
|
||||
$ curl $PROXY_URL/productpage
|
||||
```
|
||||
|
||||
That is all I have for this walk-through. If you enjoyed the technologies used in this post, please check out their repositories since they are all open source and would love to have more contributors! Here are their links for your convenience:
|
||||
|
||||
* Kong: [[GitHub](https://github.com/Kong/kubernetes-ingress-controller)] [[Twitter](https://twitter.com/thekonginc)]
|
||||
* Kubernetes: [[GitHub](https://github.com/kubernetes/kubernetes)] [[Twitter](https://twitter.com/kubernetesio)]
|
||||
* Istio: [[GitHub](https://github.com/istio/istio)] [[Twitter](https://twitter.com/IstioMesh)]
|
||||
* Envoy: [[GitHub](https://github.com/envoyproxy/envoy)] [[Twitter](https://twitter.com/EnvoyProxy)]
|
||||
|
||||
Thank you for following along!
|
||||
@@ -6,8 +6,8 @@ cid: community
|
||||
|
||||
<div class="newcommunitywrapper">
|
||||
<div class="banner1">
|
||||
<img src="/images/community/kubernetes-community-final-02.jpg" alt="Kubernetes Conference Gallery" style="width:100%;padding-left:0px" class="desktop">
|
||||
<img src="/images/community/kubernetes-community-02-mobile.jpg" alt="Kubernetes Conference Gallery" style="width:100%;padding-left:0px" class="mobile">
|
||||
<img src="/images/community/kubernetes-community-final-02.jpg" alt="Kubernetes Conference Gallery" style="width:100%" class="desktop">
|
||||
<img src="/images/community/kubernetes-community-02-mobile.jpg" alt="Kubernetes Conference Gallery" style="width:100%" class="mobile">
|
||||
</div>
|
||||
|
||||
<div class="intro">
|
||||
|
||||
@@ -24,9 +24,9 @@ Once you've set your desired state, the *Kubernetes Control Plane* makes the clu
|
||||
* **[kubelet](/docs/admin/kubelet/)**, which communicates with the Kubernetes Master.
|
||||
* **[kube-proxy](/docs/admin/kube-proxy/)**, a network proxy which reflects Kubernetes networking services on each node.
|
||||
|
||||
## Kubernetes objects
|
||||
## Kubernetes Objects
|
||||
|
||||
Kubernetes contains a number of abstractions that represent the state of your system: deployed containerized applications and workloads, their associated network and disk resources, and other information about what your cluster is doing. These abstractions are represented by objects in the Kubernetes API. See [Understanding Kubernetes objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/#kubernetes-objects) for more details.
|
||||
Kubernetes contains a number of abstractions that represent the state of your system: deployed containerized applications and workloads, their associated network and disk resources, and other information about what your cluster is doing. These abstractions are represented by objects in the Kubernetes API. See [Understanding Kubernetes Objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/) for more details.
|
||||
|
||||
The basic Kubernetes objects include:
|
||||
|
||||
@@ -35,7 +35,7 @@ The basic Kubernetes objects include:
|
||||
* [Volume](/docs/concepts/storage/volumes/)
|
||||
* [Namespace](/docs/concepts/overview/working-with-objects/namespaces/)
|
||||
|
||||
Kubernetes also contains higher-level abstractions that rely on [controllers](/docs/concepts/architecture/controller/) to build upon the basic objects, and provide additional functionality and convenience features. These include:
|
||||
Kubernetes also contains higher-level abstractions that rely on [Controllers](/docs/concepts/architecture/controller/) to build upon the basic objects, and provide additional functionality and convenience features. These include:
|
||||
|
||||
* [Deployment](/docs/concepts/workloads/controllers/deployment/)
|
||||
* [DaemonSet](/docs/concepts/workloads/controllers/daemonset/)
|
||||
|
||||
@@ -224,7 +224,6 @@ rules:
|
||||
|
||||
The following cloud providers have implemented CCMs:
|
||||
|
||||
* [Alibaba Cloud](https://github.com/kubernetes/cloud-provider-alibaba-cloud)
|
||||
* [AWS](https://github.com/kubernetes/cloud-provider-aws)
|
||||
* [Azure](https://github.com/kubernetes/cloud-provider-azure)
|
||||
* [BaiduCloud](https://github.com/baidu/cloud-provider-baiducloud)
|
||||
|
||||
@@ -26,7 +26,7 @@ closer to the desired state, by turning equipment on or off.
|
||||
## Controller pattern
|
||||
|
||||
A controller tracks at least one Kubernetes resource type.
|
||||
These [objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/#kubernetes-objects)
|
||||
These [objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/)
|
||||
have a spec field that represents the desired state. The
|
||||
controller(s) for that resource are responsible for making the current
|
||||
state come closer to that desired state.
|
||||
@@ -113,15 +113,17 @@ useful changes, it doesn't matter if the overall state is or is not stable.
|
||||
As a tenet of its design, Kubernetes uses lots of controllers that each manage
|
||||
a particular aspect of cluster state. Most commonly, a particular control loop
|
||||
(controller) uses one kind of resource as its desired state, and has a different
|
||||
kind of resource that it manages to make that desired state happen. For example,
|
||||
a controller for Jobs tracks Job objects (to discover new work) and Pod objects
|
||||
(to run the Jobs, and then to see when the work is finished). In this case
|
||||
something else creates the Jobs, whereas the Job controller creates Pods.
|
||||
kind of resource that it manages to make that desired state happen.
|
||||
|
||||
It's useful to have simple controllers rather than one, monolithic set of control
|
||||
loops that are interlinked. Controllers can fail, so Kubernetes is designed to
|
||||
allow for that.
|
||||
|
||||
For example: a controller for Jobs tracks Job objects (to discover
|
||||
new work) and Pod object (to run the Jobs, and then to see when the work is
|
||||
finished). In this case something else creates the Jobs, whereas the Job
|
||||
controller creates Pods.
|
||||
|
||||
{{< note >}}
|
||||
There can be several controllers that create or update the same kind of object.
|
||||
Behind the scenes, Kubernetes controllers make sure that they only pay attention
|
||||
|
||||
@@ -97,28 +97,13 @@ public networks.
|
||||
|
||||
### SSH Tunnels
|
||||
|
||||
Kubernetes supports SSH tunnels to protect the Master → Cluster communication
|
||||
Kubernetes supports SSH tunnels to protect the Master -> Cluster communication
|
||||
paths. In this configuration, the apiserver initiates an SSH tunnel to each node
|
||||
in the cluster (connecting to the ssh server listening on port 22) and passes
|
||||
all traffic destined for a kubelet, node, pod, or service through the tunnel.
|
||||
This tunnel ensures that the traffic is not exposed outside of the network in
|
||||
which the nodes are running.
|
||||
|
||||
SSH tunnels are currently deprecated so you shouldn't opt to use them unless you
|
||||
know what you are doing. The Konnectivity service is a replacement for this
|
||||
communication channel.
|
||||
|
||||
### Konnectivity service
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
As a replacement to the SSH tunnels, the Konnectivity service provides TCP
|
||||
level proxy for the Master → Cluster communication. The Konnectivity consists of
|
||||
two parts, the Konnectivity server and the Konnectivity agents, running in the
|
||||
Master network and the Cluster network respectively. The Konnectivity agents
|
||||
initiate connections to the Konnectivity server and maintain the connections.
|
||||
All Master → Cluster traffic then goes through these connections.
|
||||
|
||||
See [Konnectivity Service Setup](/docs/tasks/setup-konnectivity/) on how to set
|
||||
it up in your cluster.
|
||||
SSH tunnels are currently deprecated so you shouldn't opt to use them unless you know what you are doing. A replacement for this communication channel is being designed.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -30,7 +30,7 @@ A node's status contains the following information:
|
||||
* [Capacity and Allocatable](#capacity)
|
||||
* [Info](#info)
|
||||
|
||||
Node status and other details about a node can be displayed using the following command:
|
||||
Node status and other details about a node can be displayed using below command:
|
||||
```shell
|
||||
kubectl describe node <insert-node-name-here>
|
||||
```
|
||||
@@ -72,7 +72,7 @@ The node condition is represented as a JSON object. For example, the following r
|
||||
]
|
||||
```
|
||||
|
||||
If the Status of the Ready condition remains `Unknown` or `False` for longer than the `pod-eviction-timeout` (an argument passed to the [kube-controller-manager](/docs/admin/kube-controller-manager/)), all the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on the node. The decision to delete the pods cannot be communicated to the kubelet until communication with the apiserver is re-established. In the meantime, the pods that are scheduled for deletion may continue to run on the partitioned node.
|
||||
If the Status of the Ready condition remains `Unknown` or `False` for longer than the `pod-eviction-timeout`, an argument is passed to the [kube-controller-manager](/docs/admin/kube-controller-manager/) and all the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on the node. The decision to delete the pods cannot be communicated to the kubelet until communication with the apiserver is re-established. In the meantime, the pods that are scheduled for deletion may continue to run on the partitioned node.
|
||||
|
||||
In versions of Kubernetes prior to 1.5, the node controller would [force delete](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods)
|
||||
these unreachable pods from the apiserver. However, in 1.5 and higher, the node controller does not force delete pods until it is
|
||||
@@ -83,8 +83,8 @@ Kubernetes causes all the Pod objects running on the node to be deleted from the
|
||||
|
||||
The node lifecycle controller automatically creates
|
||||
[taints](/docs/concepts/configuration/taint-and-toleration/) that represent conditions.
|
||||
The scheduler takes the Node's taints into consideration when assigning a Pod to a Node.
|
||||
Pods can also have tolerations which let them tolerate a Node's taints.
|
||||
When the scheduler is assigning a Pod to a Node, the scheduler takes the Node's taints
|
||||
into account, except for any taints that the Pod tolerates.
|
||||
|
||||
### Capacity and Allocatable {#capacity}
|
||||
|
||||
@@ -131,8 +131,6 @@ Kubernetes creates a node object internally (the representation), and
|
||||
validates the node by health checking based on the `metadata.name` field. If the node is valid -- that is, if all necessary
|
||||
services are running -- it is eligible to run a pod. Otherwise, it is
|
||||
ignored for any cluster activity until it becomes valid.
|
||||
The name of a Node object must be a valid
|
||||
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||
|
||||
{{< note >}}
|
||||
Kubernetes keeps the object for the invalid node and keeps checking to see whether it becomes valid.
|
||||
@@ -159,7 +157,7 @@ controller deletes the node from its list of nodes.
|
||||
The third is monitoring the nodes' health. The node controller is
|
||||
responsible for updating the NodeReady condition of NodeStatus to
|
||||
ConditionUnknown when a node becomes unreachable (i.e. the node controller stops
|
||||
receiving heartbeats for some reason, for example due to the node being down), and then later evicting
|
||||
receiving heartbeats for some reason, e.g. due to the node being down), and then later evicting
|
||||
all the pods from the node (using graceful termination) if the node continues
|
||||
to be unreachable. (The default timeouts are 40s to start reporting
|
||||
ConditionUnknown and 5m after that to start evicting pods.) The node controller
|
||||
@@ -184,13 +182,13 @@ a Lease object.
|
||||
timeout for unreachable nodes).
|
||||
- The kubelet creates and then updates its Lease object every 10 seconds
|
||||
(the default update interval). Lease updates occur independently from the
|
||||
`NodeStatus` updates. If the Lease update fails, the kubelet retries with exponential backoff starting at 200 milliseconds and capped at 7 seconds.
|
||||
`NodeStatus` updates.
|
||||
|
||||
#### Reliability
|
||||
|
||||
In Kubernetes 1.4, we updated the logic of the node controller to better handle
|
||||
cases when a large number of nodes have problems with reaching the master
|
||||
(e.g. because the master has networking problems). Starting with 1.4, the node
|
||||
(e.g. because the master has networking problem). Starting with 1.4, the node
|
||||
controller looks at the state of all nodes in the cluster when making a
|
||||
decision about pod eviction.
|
||||
|
||||
@@ -214,9 +212,9 @@ there is only one availability zone (the whole cluster).
|
||||
|
||||
A key reason for spreading your nodes across availability zones is so that the
|
||||
workload can be shifted to healthy zones when one entire zone goes down.
|
||||
Therefore, if all nodes in a zone are unhealthy then the node controller evicts at
|
||||
the normal rate of `--node-eviction-rate`. The corner case is when all zones are
|
||||
completely unhealthy (i.e. there are no healthy nodes in the cluster). In such a
|
||||
Therefore, if all nodes in a zone are unhealthy then node controller evicts at
|
||||
the normal rate `--node-eviction-rate`. The corner case is when all zones are
|
||||
completely unhealthy (i.e. there are no healthy nodes in the cluster). In such
|
||||
case, the node controller assumes that there's some problem with master
|
||||
connectivity and stops all evictions until some connectivity is restored.
|
||||
|
||||
@@ -277,12 +275,6 @@ and do not respect the unschedulable attribute on a node. This assumes that daem
|
||||
the machine even if it is being drained of applications while it prepares for a reboot.
|
||||
{{< /note >}}
|
||||
|
||||
{{< caution >}}
|
||||
`kubectl cordon` marks a node as 'unschedulable', which has the side effect of the service
|
||||
controller removing the node from any LoadBalancer node target lists it was previously
|
||||
eligible for, effectively removing incoming load balancer traffic from the cordoned node(s).
|
||||
{{< /caution >}}
|
||||
|
||||
### Node capacity
|
||||
|
||||
The capacity of the node (number of cpus and amount of memory) is part of the node object.
|
||||
|
||||
@@ -21,14 +21,14 @@ Add-ons in each section are sorted alphabetically - the ordering does not imply
|
||||
|
||||
|
||||
* [ACI](https://www.github.com/noironetworks/aci-containers) provides integrated container networking and network security with Cisco ACI.
|
||||
* [Calico](https://docs.projectcalico.org/latest/introduction/) is a networking and network policy provider. Calico supports a flexible set of networking options so you can choose the most efficient option for your situation, including non-overlay and overlay networks, with or without BGP. Calico uses the same engine to enforce network policy for hosts, pods, and (if using Istio & Envoy) applications at the service mesh layer.
|
||||
* [Calico](https://docs.projectcalico.org/latest/getting-started/kubernetes/) is a secure L3 networking and network policy provider.
|
||||
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install) unites Flannel and Calico, providing networking and network policy.
|
||||
* [Cilium](https://github.com/cilium/cilium) is a L3 network and network policy plugin that can enforce HTTP/API/L7 policies transparently. Both routing and overlay/encapsulation mode are supported, and it can work on top of other CNI plugins.
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) enables Kubernetes to seamlessly connect to a choice of CNI plugins, such as Calico, Canal, Flannel, Romana, or Weave.
|
||||
* [Contiv](http://contiv.github.io) provides configurable networking (native L3 using BGP, overlay using vxlan, classic L2, and Cisco-SDN/ACI) for various use cases and a rich policy framework. Contiv project is fully [open sourced](http://github.com/contiv). The [installer](http://github.com/contiv/install) provides both kubeadm and non-kubeadm based installation options.
|
||||
* [Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), based on [Tungsten Fabric](https://tungsten.io), is an open source, multi-cloud network virtualization and policy management platform. Contrail and Tungsten Fabric are integrated with orchestration systems such as Kubernetes, OpenShift, OpenStack and Mesos, and provide isolation modes for virtual machines, containers/pods and bare metal workloads.
|
||||
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md) is an overlay network provider that can be used with Kubernetes.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/) is a plugin to support multiple network interfaces in a Kubernetes pod.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/) is a network solution supporting multiple networking in Kubernetes.
|
||||
* [Multus](https://github.com/Intel-Corp/multus-cni) is a Multi plugin for multiple network support in Kubernetes to support all CNI plugins (e.g. Calico, Cilium, Contiv, Flannel), in addition to SRIOV, DPDK, OVS-DPDK and VPP based workloads in Kubernetes.
|
||||
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) Container Plug-in (NCP) provides integration between VMware NSX-T and container orchestrators such as Kubernetes, as well as integration between NSX-T and container-based CaaS/PaaS platforms such as Pivotal Container Service (PKS) and OpenShift.
|
||||
* [Nuage](https://github.com/nuagenetworks/nuage-kubernetes/blob/v5.1.1-1/docs/kubernetes-1-installation.rst) is an SDN platform that provides policy-based networking between Kubernetes Pods and non-Kubernetes environments with visibility and security monitoring.
|
||||
@@ -46,7 +46,7 @@ Add-ons in each section are sorted alphabetically - the ordering does not imply
|
||||
|
||||
## Infrastructure
|
||||
|
||||
* [KubeVirt](https://kubevirt.io/user-guide/#/installation/installation) is an add-on to run virtual machines on Kubernetes. Usually run on bare-metal clusters.
|
||||
* [KubeVirt](https://kubevirt.io/user-guide/docs/latest/administration/intro.html#cluster-side-add-on-deployment) is an add-on to run virtual machines on Kubernetes. Usually run on bare-metal clusters.
|
||||
|
||||
## Legacy Add-ons
|
||||
|
||||
|
||||
@@ -130,11 +130,11 @@ Finally, add the same parameters into the API server start parameters.
|
||||
Note that you may need to adapt the sample commands based on the hardware
|
||||
architecture and cfssl version you are using.
|
||||
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssl_1.4.1_linux_amd64 -o cfssl
|
||||
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o cfssl
|
||||
chmod +x cfssl
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssljson_1.4.1_linux_amd64 -o cfssljson
|
||||
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o cfssljson
|
||||
chmod +x cfssljson
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssl-certinfo_1.4.1_linux_amd64 -o cfssl-certinfo
|
||||
curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o cfssl-certinfo
|
||||
chmod +x cfssl-certinfo
|
||||
1. Create a directory to hold the artifacts and initialize cfssl:
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ Different settings can be applied to a load balancer service in AWS using _annot
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix`: Used to specify access log s3 bucket prefix.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags`: Used on the service to specify a comma-separated list of key-value pairs which will be recorded as additional tags in the ELB. For example: `"Key1=Val1,Key2=Val2,KeyNoVal1=,KeyNoVal2"`.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-backend-protocol`: Used on the service to specify the protocol spoken by the backend (pod) behind a listener. If `http` (default) or `https`, an HTTPS listener that terminates the connection and parses headers is created. If set to `ssl` or `tcp`, a "raw" SSL listener is used. If set to `http` and `aws-load-balancer-ssl-cert` is not used then a HTTP listener is used.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`: Used on the service to request a secure listener. Value is a valid certificate ARN. For more, see [ELB Listener Config](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html) CertARN is an IAM or CM certificate ARN, for example `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`: Used on the service to request a secure listener. Value is a valid certificate ARN. For more, see [ELB Listener Config](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html) CertARN is an IAM or CM certificate ARN, e.g. `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled`: Used on the service to enable or disable connection draining.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout`: Used on the service to specify a connection draining timeout.
|
||||
* `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout`: Used on the service to specify the idle connection timeout.
|
||||
|
||||
@@ -20,6 +20,7 @@ See the guides in [Setup](/docs/setup/) for examples of how to plan, set up, and
|
||||
Before choosing a guide, here are some considerations:
|
||||
|
||||
- Do you just want to try out Kubernetes on your computer, or do you want to build a high-availability, multi-node cluster? Choose distros best suited for your needs.
|
||||
- **If you are designing for high-availability**, learn about configuring [clusters in multiple zones](/docs/concepts/cluster-administration/federation/).
|
||||
- Will you be using **a hosted Kubernetes cluster**, such as [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/), or **hosting your own cluster**?
|
||||
- Will your cluster be **on-premises**, or **in the cloud (IaaS)**? Kubernetes does not directly support hybrid clusters. Instead, you can set up multiple clusters.
|
||||
- **If you are configuring Kubernetes on-premises**, consider which [networking model](/docs/concepts/cluster-administration/networking/) fits best.
|
||||
@@ -43,7 +44,7 @@ Note: Not all distros are actively maintained. Choose distros which have been te
|
||||
|
||||
* [Certificates](/docs/concepts/cluster-administration/certificates/) describes the steps to generate certificates using different tool chains.
|
||||
|
||||
* [Kubernetes Container Environment](/docs/concepts/containers/container-environment/) describes the environment for Kubelet managed containers on a Kubernetes node.
|
||||
* [Kubernetes Container Environment](/docs/concepts/containers/container-environment-variables/) describes the environment for Kubelet managed containers on a Kubernetes node.
|
||||
|
||||
* [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/) describes how to set up permissions for users and service accounts.
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: Controller manager metrics
|
||||
content_template: templates/concept
|
||||
weight: 100
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
Controller manager metrics provide important insight into the performance and health of
|
||||
the controller manager.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
## What are controller manager metrics
|
||||
|
||||
Controller manager metrics provide important insight into the performance and health of the controller manager.
|
||||
These metrics include common Go language runtime metrics such as go_routine count and controller specific metrics such as
|
||||
etcd request latencies or Cloudprovider (AWS, GCE, OpenStack) API latencies that can be used
|
||||
to gauge the health of a cluster.
|
||||
|
||||
Starting from Kubernetes 1.7, detailed Cloudprovider metrics are available for storage operations for GCE, AWS, Vsphere and OpenStack.
|
||||
These metrics can be used to monitor health of persistent volume operations.
|
||||
|
||||
For example, for GCE these metrics are called:
|
||||
|
||||
```
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "instance_list"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "disk_insert"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "disk_delete"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "attach_disk"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "detach_disk"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "list_disk"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
|
||||
In a cluster, controller-manager metrics are available from `http://localhost:10252/metrics`
|
||||
from the host where the controller-manager is running.
|
||||
|
||||
The metrics are emitted in [prometheus format](https://prometheus.io/docs/instrumenting/exposition_formats/) and are human readable.
|
||||
|
||||
In a production environment you may want to configure prometheus or some other metrics scraper
|
||||
to periodically gather these metrics and make them available in some kind of time series database.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
---
|
||||
title: Federation
|
||||
content_template: templates/concept
|
||||
weight: 80
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< deprecationfilewarning >}}
|
||||
{{< include "federation-deprecation-warning-note.md" >}}
|
||||
{{< /deprecationfilewarning >}}
|
||||
|
||||
This page explains why and how to manage multiple Kubernetes clusters using
|
||||
federation.
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
## Why federation
|
||||
|
||||
Federation makes it easy to manage multiple clusters. It does so by providing 2
|
||||
major building blocks:
|
||||
|
||||
* Sync resources across clusters: Federation provides the ability to keep
|
||||
resources in multiple clusters in sync. For example, you can ensure that the same deployment exists in multiple clusters.
|
||||
* Cross cluster discovery: Federation provides the ability to auto-configure DNS servers and load balancers with backends from all clusters. For example, you can ensure that a global VIP or DNS record can be used to access backends from multiple clusters.
|
||||
|
||||
Some other use cases that federation enables are:
|
||||
|
||||
* High Availability: By spreading load across clusters and auto configuring DNS
|
||||
servers and load balancers, federation minimises the impact of cluster
|
||||
failure.
|
||||
* Avoiding provider lock-in: By making it easier to migrate applications across
|
||||
clusters, federation prevents cluster provider lock-in.
|
||||
|
||||
|
||||
Federation is not helpful unless you have multiple clusters. Some of the reasons
|
||||
why you might want multiple clusters are:
|
||||
|
||||
* Low latency: Having clusters in multiple regions minimises latency by serving
|
||||
users from the cluster that is closest to them.
|
||||
* Fault isolation: It might be better to have multiple small clusters rather
|
||||
than a single large cluster for fault isolation (for example: multiple
|
||||
clusters in different availability zones of a cloud provider).
|
||||
* Scalability: There are scalability limits to a single kubernetes cluster (this
|
||||
should not be the case for most users. For more details:
|
||||
[Kubernetes Scaling and Performance Goals](https://git.k8s.io/community/sig-scalability/goals.md)).
|
||||
* [Hybrid cloud](#hybrid-cloud-capabilities): You can have multiple clusters on different cloud providers or
|
||||
on-premises data centers.
|
||||
|
||||
### Caveats
|
||||
|
||||
While there are a lot of attractive use cases for federation, there are also
|
||||
some caveats:
|
||||
|
||||
* Increased network bandwidth and cost: The federation control plane watches all
|
||||
clusters to ensure that the current state is as expected. This can lead to
|
||||
significant network cost if the clusters are running in different regions on
|
||||
a cloud provider or on different cloud providers.
|
||||
* Reduced cross cluster isolation: A bug in the federation control plane can
|
||||
impact all clusters. This is mitigated by keeping the logic in federation
|
||||
control plane to a minimum. It mostly delegates to the control plane in
|
||||
kubernetes clusters whenever it can. The design and implementation also errs
|
||||
on the side of safety and avoiding multi-cluster outage.
|
||||
* Maturity: The federation project is relatively new and is not very mature.
|
||||
Not all resources are available and many are still alpha. [Issue
|
||||
88](https://github.com/kubernetes/federation/issues/88) enumerates
|
||||
known issues with the system that the team is busy solving.
|
||||
|
||||
### Hybrid cloud capabilities
|
||||
|
||||
Federations of Kubernetes Clusters can include clusters running in
|
||||
different cloud providers (e.g. Google Cloud, AWS), and on-premises
|
||||
(e.g. on OpenStack). [Kubefed](/docs/tasks/federation/set-up-cluster-federation-kubefed/) is the recommended way to deploy federated clusters.
|
||||
|
||||
Thereafter, your [API resources](#api-resources) can span different clusters
|
||||
and cloud providers.
|
||||
|
||||
## Setting up federation
|
||||
|
||||
To be able to federate multiple clusters, you first need to set up a federation
|
||||
control plane.
|
||||
Follow the [setup guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) to set up the
|
||||
federation control plane.
|
||||
|
||||
## API resources
|
||||
|
||||
Once you have the control plane set up, you can start creating federation API
|
||||
resources.
|
||||
The following guides explain some of the resources in detail:
|
||||
|
||||
* [Cluster](/docs/tasks/federation/administer-federation/cluster/)
|
||||
* [ConfigMap](/docs/tasks/federation/administer-federation/configmap/)
|
||||
* [DaemonSets](/docs/tasks/federation/administer-federation/daemonset/)
|
||||
* [Deployment](/docs/tasks/federation/administer-federation/deployment/)
|
||||
* [Events](/docs/tasks/federation/administer-federation/events/)
|
||||
* [Hpa](/docs/tasks/federation/administer-federation/hpa/)
|
||||
* [Ingress](/docs/tasks/federation/administer-federation/ingress/)
|
||||
* [Jobs](/docs/tasks/federation/administer-federation/job/)
|
||||
* [Namespaces](/docs/tasks/federation/administer-federation/namespaces/)
|
||||
* [ReplicaSets](/docs/tasks/federation/administer-federation/replicaset/)
|
||||
* [Secrets](/docs/tasks/federation/administer-federation/secret/)
|
||||
* [Services](/docs/concepts/cluster-administration/federation-service-discovery/)
|
||||
|
||||
|
||||
The [API reference docs](/docs/reference/federation/) list all the
|
||||
resources supported by federation apiserver.
|
||||
|
||||
## Cascading deletion
|
||||
|
||||
Kubernetes version 1.6 includes support for cascading deletion of federated
|
||||
resources. With cascading deletion, when you delete a resource from the
|
||||
federation control plane, you also delete the corresponding resources in all underlying clusters.
|
||||
|
||||
Cascading deletion is not enabled by default when using the REST API. To enable
|
||||
it, set the option `DeleteOptions.orphanDependents=false` when you delete a
|
||||
resource from the federation control plane using the REST API. Using `kubectl
|
||||
delete`
|
||||
enables cascading deletion by default. You can disable it by running `kubectl
|
||||
delete --cascade=false`
|
||||
|
||||
Note: Kubernetes version 1.5 included cascading deletion support for a subset of
|
||||
federation resources.
|
||||
|
||||
## Scope of a single cluster
|
||||
|
||||
On IaaS providers such as Google Compute Engine or Amazon Web Services, a VM exists in a
|
||||
[zone](https://cloud.google.com/compute/docs/zones) or [availability
|
||||
zone](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html).
|
||||
We suggest that all the VMs in a Kubernetes cluster should be in the same availability zone, because:
|
||||
|
||||
- compared to having a single global Kubernetes cluster, there are fewer single-points of failure.
|
||||
- compared to a cluster that spans availability zones, it is easier to reason about the availability properties of a
|
||||
single-zone cluster.
|
||||
- when the Kubernetes developers are designing the system (e.g. making assumptions about latency, bandwidth, or
|
||||
correlated failures) they are assuming all the machines are in a single data center, or otherwise closely connected.
|
||||
|
||||
It is recommended to run fewer clusters with more VMs per availability zone; but it is possible to run multiple clusters per availability zones.
|
||||
|
||||
Reasons to prefer fewer clusters per availability zone are:
|
||||
|
||||
- improved bin packing of Pods in some cases with more nodes in one cluster (less resource fragmentation).
|
||||
- reduced operational overhead (though the advantage is diminished as ops tooling and processes mature).
|
||||
- reduced costs for per-cluster fixed resource costs, e.g. apiserver VMs (but small as a percentage
|
||||
of overall cluster cost for medium to large clusters).
|
||||
|
||||
Reasons to have multiple clusters include:
|
||||
|
||||
- strict security policies requiring isolation of one class of work from another (but, see Partitioning Clusters
|
||||
below).
|
||||
- test clusters to canary new Kubernetes releases or other cluster software.
|
||||
|
||||
## Selecting the right number of clusters
|
||||
|
||||
The selection of the number of Kubernetes clusters may be a relatively static choice, only revisited occasionally.
|
||||
By contrast, the number of nodes in a cluster and the number of pods in a service may change frequently according to
|
||||
load and growth.
|
||||
|
||||
To pick the number of clusters, first, decide which regions you need to be in to have adequate latency to all your end users, for services that will run
|
||||
on Kubernetes (if you use a Content Distribution Network, the latency requirements for the CDN-hosted content need not
|
||||
be considered). Legal issues might influence this as well. For example, a company with a global customer base might decide to have clusters in US, EU, AP, and SA regions.
|
||||
Call the number of regions to be in `R`.
|
||||
|
||||
Second, decide how many clusters should be able to be unavailable at the same time, while still being available. Call
|
||||
the number that can be unavailable `U`. If you are not sure, then 1 is a fine choice.
|
||||
|
||||
If it is allowable for load-balancing to direct traffic to any region in the event of a cluster failure, then
|
||||
you need at least the larger of `R` or `U + 1` clusters. If it is not (e.g. you want to ensure low latency for all
|
||||
users in the event of a cluster failure), then you need to have `R * (U + 1)` clusters
|
||||
(`U + 1` in each of `R` regions). In any case, try to put each cluster in a different zone.
|
||||
|
||||
Finally, if any of your clusters would need more than the maximum recommended number of nodes for a Kubernetes cluster, then
|
||||
you may need even more clusters. Kubernetes v1.3 supports clusters up to 1000 nodes in size. Kubernetes v1.8 supports
|
||||
clusters up to 5000 nodes. See [Building Large Clusters](/docs/setup/best-practices/cluster-large/) for more guidance.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
* Learn more about the [Federation
|
||||
proposal](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/multicluster/federation.md).
|
||||
* See this [setup guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) for cluster federation.
|
||||
* See this [Kubecon2016 talk on federation](https://www.youtube.com/watch?v=pq9lbkmxpS8)
|
||||
* See this [Kubecon2017 Europe update on federation](https://www.youtube.com/watch?v=kwOvOLnFYck)
|
||||
* See this [Kubecon2018 Europe update on sig-multicluster](https://www.youtube.com/watch?v=vGZo5DaThQU)
|
||||
* See this [Kubecon2018 Europe Federation-v2 prototype presentation](https://youtu.be/q27rbaX5Jis?t=7m20s)
|
||||
* See this [Federation-v2 Userguide](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md)
|
||||
{{% /capture %}}
|
||||
@@ -1,377 +0,0 @@
|
||||
---
|
||||
title: API Priority and Fairness
|
||||
content_template: templates/concept
|
||||
min-kubernetes-server-version: v1.18
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state state="alpha" for_k8s_version="v1.18" >}}
|
||||
|
||||
Controlling the behavior of the Kubernetes API server in an overload situation
|
||||
is a key task for cluster administrators. The {{< glossary_tooltip
|
||||
term_id="kube-apiserver" text="kube-apiserver" >}} has some controls available
|
||||
(i.e. the `--max-requests-inflight` and `--max-mutating-requests-inflight`
|
||||
command-line flags) to limit the amount of outstanding work that will be
|
||||
accepted, preventing a flood of inbound requests from overloading and
|
||||
potentially crashing the API server, but these flags are not enough to ensure
|
||||
that the most important requests get through in a period of high traffic.
|
||||
|
||||
The API Priority and Fairness feature (APF) is an alternative that improves upon
|
||||
aforementioned max-inflight limitations. APF classifies
|
||||
and isolates requests in a more fine-grained way. It also introduces
|
||||
a limited amount of queuing, so that no requests are rejected in cases
|
||||
of very brief bursts. Requests are dispatched from queues using a
|
||||
fair queuing technique so that, for example, a poorly-behaved
|
||||
{{< glossary_tooltip text="controller" term_id="controller" >}} need not
|
||||
starve others (even at the same priority level).
|
||||
|
||||
{{< caution >}}
|
||||
Requests classified as "long-running" — primarily watches — are not
|
||||
subject to the API Priority and Fairness filter. This is also true for
|
||||
the `--max-requests-inflight` flag without the API Priority and
|
||||
Fairness feature enabled.
|
||||
{{< /caution >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Enabling API Priority and Fairness
|
||||
|
||||
The API Priority and Fairness feature is controlled by a feature gate
|
||||
and is not enabled by default. See
|
||||
[Feature Gates](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
for a general explanation of feature gates and how to enable and disable them. The
|
||||
name of the feature gate for APF is "APIPriorityAndFairness". This
|
||||
feature also involves an {{< glossary_tooltip term_id="api-group"
|
||||
text="API Group" >}} that must be enabled. You can do these
|
||||
things by adding the following command-line flags to your
|
||||
`kube-apiserver` invocation:
|
||||
|
||||
```shell
|
||||
kube-apiserver \
|
||||
--feature-gates=APIPriorityAndFairness=true \
|
||||
--runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true \
|
||||
# …and other flags as usual
|
||||
```
|
||||
|
||||
The command-line flag `--enable-priority-and-fairness=false` will disable the
|
||||
API Priority and Fairness feature, even if other flags have enabled it.
|
||||
|
||||
## Concepts
|
||||
There are several distinct features involved in the API Priority and Fairness
|
||||
feature. Incoming requests are classified by attributes of the request using
|
||||
_FlowSchemas_, and assigned to priority levels. Priority levels add a degree of
|
||||
isolation by maintaining separate concurrency limits, so that requests assigned
|
||||
to different priority levels cannot starve each other. Within a priority level,
|
||||
a fair-queuing algorithm prevents requests from different _flows_ from starving
|
||||
each other, and allows for requests to be queued to prevent bursty traffic from
|
||||
causing failed requests when the average load is acceptably low.
|
||||
|
||||
### Priority Levels
|
||||
Without APF enabled, overall concurrency in
|
||||
the API server is limited by the `kube-apiserver` flags
|
||||
`--max-requests-inflight` and `--max-mutating-requests-inflight`. With APF
|
||||
enabled, the concurrency limits defined by these flags are summed and then the sum is divided up
|
||||
among a configurable set of _priority levels_. Each incoming request is assigned
|
||||
to a single priority level, and each priority level will only dispatch as many
|
||||
concurrent requests as its configuration allows.
|
||||
|
||||
The default configuration, for example, includes separate priority levels for
|
||||
leader-election requests, requests from built-in controllers, and requests from
|
||||
Pods. This means that an ill-behaved Pod that floods the API server with
|
||||
requests cannot prevent leader election or actions by the built-in controllers
|
||||
from succeeding.
|
||||
|
||||
### Queuing
|
||||
Even within a priority level there may be a large number of distinct sources of
|
||||
traffic. In an overload situation, it is valuable to prevent one stream of
|
||||
requests from starving others (in particular, in the relatively common case of a
|
||||
single buggy client flooding the kube-apiserver with requests, that buggy client
|
||||
would ideally not have much measurable impact on other clients at all). This is
|
||||
handled by use of a fair-queuing algorithm to process requests that are assigned
|
||||
the same priority level. Each request is assigned to a _flow_, identified by the
|
||||
name of the matching FlowSchema plus a _flow distinguisher_ — which
|
||||
is either the requesting user, the target resource's namespace, or nothing — and the
|
||||
system attempts to give approximately equal weight to requests in different
|
||||
flows of the same priority level.
|
||||
|
||||
After classifying a request into a flow, the API Priority and Fairness
|
||||
feature then may assign the request to a queue. This assignment uses
|
||||
a technique known as {{< glossary_tooltip term_id="shuffle-sharding"
|
||||
text="shuffle sharding" >}}, which makes relatively efficient use of
|
||||
queues to insulate low-intensity flows from high-intensity flows.
|
||||
|
||||
The details of the queuing algorithm are tunable for each priority level, and
|
||||
allow administrators to trade off memory use, fairness (the property that
|
||||
independent flows will all make progress when total traffic exceeds capacity),
|
||||
tolerance for bursty traffic, and the added latency induced by queuing.
|
||||
|
||||
### Exempt requests
|
||||
Some requests are considered sufficiently important that they are not subject to
|
||||
any of the limitations imposed by this feature. These exemptions prevent an
|
||||
improperly-configured flow control configuration from totally disabling an API
|
||||
server.
|
||||
|
||||
## Defaults
|
||||
The Priority and Fairness feature ships with a suggested configuration that
|
||||
should suffice for experimentation; if your cluster is likely to
|
||||
experience heavy load then you should consider what configuration will work best. The suggested configuration groups requests into five priority
|
||||
classes:
|
||||
|
||||
* The `system` priority level is for requests from the `system:nodes` group,
|
||||
i.e. Kubelets, which must be able to contact the API server in order for
|
||||
workloads to be able to schedule on them.
|
||||
|
||||
* The `leader-election` priority level is for leader election requests from
|
||||
built-in controllers (in particular, requests for `endpoints`, `configmaps`,
|
||||
or `leases` coming from the `system:kube-controller-manager` or
|
||||
`system:kube-scheduler` users and service accounts in the `kube-system`
|
||||
namespace). These are important to isolate from other traffic because failures
|
||||
in leader election cause their controllers to fail and restart, which in turn
|
||||
causes more expensive traffic as the new controllers sync their informers.
|
||||
|
||||
* The `workload-high` priority level is for other requests from built-in
|
||||
controllers.
|
||||
|
||||
* The `workload-low` priority level is for requests from any other service
|
||||
account, which will typically include all requests from controllers runing in
|
||||
Pods.
|
||||
|
||||
* The `global-default` priority level handles all other traffic, e.g.
|
||||
interactive `kubectl` commands run by nonprivileged users.
|
||||
|
||||
Additionally, there are two PriorityLevelConfigurations and two FlowSchemas that
|
||||
are built in and may not be overwritten:
|
||||
|
||||
* The special `exempt` priority level is used for requests that are not subject
|
||||
to flow control at all: they will always be dispatched immediately. The
|
||||
special `exempt` FlowSchema classifies all requests from the `system:masters`
|
||||
group into this priority level. You may define other FlowSchemas that direct
|
||||
other requests to this priority level, if appropriate.
|
||||
|
||||
* The special `catch-all` priority level is used in combination with the special
|
||||
`catch-all` FlowSchema to make sure that every request gets some kind of
|
||||
classification. Typically you should not rely on this catch-all configuration,
|
||||
and should create your own catch-all FlowSchema and PriorityLevelConfiguration
|
||||
(or use the `global-default` configuration that is installed by default) as
|
||||
appropriate. To help catch configuration errors that miss classifying some
|
||||
requests, the mandatory `catch-all` priority level only allows one concurrency
|
||||
share and does not queue requests, making it relatively likely that traffic
|
||||
that only matches the `catch-all` FlowSchema will be rejected with an HTTP 429
|
||||
error.
|
||||
|
||||
## Resources
|
||||
The flow control API involves two kinds of resources.
|
||||
[PriorityLevelConfigurations](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#prioritylevelconfiguration-v1alpha1-flowcontrol-apiserver-k8s-io)
|
||||
define the available isolation classes, the share of the available concurrency
|
||||
budget that each can handle, and allow for fine-tuning queuing behavior.
|
||||
[FlowSchemas](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#flowschema-v1alpha1-flowcontrol-apiserver-k8s-io)
|
||||
are used to classify individual inbound requests, matching each to a single
|
||||
PriorityLevelConfiguration.
|
||||
|
||||
### PriorityLevelConfiguration
|
||||
A PriorityLevelConfiguration represents a single isolation class. Each
|
||||
PriorityLevelConfiguration has an independent limit on the number of outstanding
|
||||
requests, and limitations on the number of queued requests.
|
||||
|
||||
Concurrency limits for PriorityLevelConfigurations are not specified in absolute
|
||||
number of requests, but rather in "concurrency shares." The total concurrency
|
||||
limit for the API Server is distributed among the existing
|
||||
PriorityLevelConfigurations in proportion with these shares. This allows a
|
||||
cluster administrator to scale up or down the total amount of traffic to a
|
||||
server by restarting `kube-apiserver` with a different value for
|
||||
`--max-requests-inflight` (or `--max-mutating-requests-inflight`), and all
|
||||
PriorityLevelConfigurations will see their maximum allowed concurrency go up (or
|
||||
down) by the same fraction.
|
||||
{{< caution >}}
|
||||
With the Priority and Fairness feature enabled, the total concurrency limit for
|
||||
the server is set to the sum of `--max-requests-inflight` and
|
||||
`--max-mutating-requests-inflight`. There is no longer any distinction made
|
||||
between mutating and non-mutating requests; if you want to treat them
|
||||
separately for a given resource, make separate FlowSchemas that match the
|
||||
mutating and non-mutating verbs respectively.
|
||||
{{< /caution >}}
|
||||
|
||||
When the volume of inbound requests assigned to a single
|
||||
PriorityLevelConfiguration is more than its permitted concurrency level, the
|
||||
`type` field of its specification determines what will happen to extra requests.
|
||||
A type of `Reject` means that excess traffic will immediately be rejected with
|
||||
an HTTP 429 (Too Many Requests) error. A type of `Queue` means that requests
|
||||
above the threshold will be queued, with the shuffle sharding and fair queuing techniques used
|
||||
to balance progress between request flows.
|
||||
|
||||
The queuing configuration allows tuning the fair queuing algorithm for a
|
||||
priority level. Details of the algorithm can be read in the [enhancement
|
||||
proposal](#what-s-next), but in short:
|
||||
|
||||
* Increasing `queues` reduces the rate of collisions between different flows, at
|
||||
the cost of increased memory usage. A value of 1 here effectively disables the
|
||||
fair-queuing logic, but still allows requests to be queued.
|
||||
|
||||
* Increasing `queueLengthLimit` allows larger bursts of traffic to be
|
||||
sustained without dropping any requests, at the cost of increased
|
||||
latency and memory usage.
|
||||
|
||||
* Changing `handSize` allows you to adjust the probability of collisions between
|
||||
different flows and the overall concurrency available to a single flow in an
|
||||
overload situation.
|
||||
{{< note >}}
|
||||
A larger `handSize` makes it less likely for two individual flows to collide
|
||||
(and therefore for one to be able to starve the other), but more likely that
|
||||
a small number of flows can dominate the apiserver. A larger `handSize` also
|
||||
potentially increases the amount of latency that a single high-traffic flow
|
||||
can cause. The maximum number of queued requests possible from a
|
||||
single flow is `handSize * queueLengthLimit`.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
Following is a table showing an interesting collection of shuffle
|
||||
sharding configurations, showing for each the probability that a
|
||||
given mouse (low-intensity flow) is squished by the elephants (high-intensity flows) for
|
||||
an illustrative collection of numbers of elephants. See
|
||||
https://play.golang.org/p/Gi0PLgVHiUg , which computes this table.
|
||||
|
||||
{{< table caption="Example Shuffle Sharding Configurations" >}}
|
||||
|HandSize| Queues| 1 elephant| 4 elephants| 16 elephants|
|
||||
|--------|-----------|------------|----------------|--------------------|
|
||||
| 12| 32| 4.428838398950118e-09| 0.11431348830099144| 0.9935089607656024|
|
||||
| 10| 32| 1.550093439632541e-08| 0.0626479840223545| 0.9753101519027554|
|
||||
| 10| 64| 6.601827268370426e-12| 0.00045571320990370776| 0.49999929150089345|
|
||||
| 9| 64| 3.6310049976037345e-11| 0.00045501212304112273| 0.4282314876454858|
|
||||
| 8| 64| 2.25929199850899e-10| 0.0004886697053040446| 0.35935114681123076|
|
||||
| 8| 128| 6.994461389026097e-13| 3.4055790161620863e-06| 0.02746173137155063|
|
||||
| 7| 128| 1.0579122850901972e-11| 6.960839379258192e-06| 0.02406157386340147|
|
||||
| 7| 256| 7.597695465552631e-14| 6.728547142019406e-08| 0.0006709661542533682|
|
||||
| 6| 256| 2.7134626662687968e-12| 2.9516464018476436e-07| 0.0008895654642000348|
|
||||
| 6| 512| 4.116062922897309e-14| 4.982983350480894e-09| 2.26025764343413e-05|
|
||||
| 6| 1024| 6.337324016514285e-16| 8.09060164312957e-11| 4.517408062903668e-07|
|
||||
|
||||
### FlowSchema
|
||||
|
||||
A FlowSchema matches some inbound requests and assigns them to a
|
||||
priority level. Every inbound request is tested against every
|
||||
FlowSchema in turn, starting with those with numerically lowest ---
|
||||
which we take to be the logically highest --- `matchingPrecedence` and
|
||||
working onward. The first match wins.
|
||||
|
||||
{{< caution >}}
|
||||
Only the first matching FlowSchema for a given request matters. If multiple
|
||||
FlowSchemas match a single inbound request, it will be assigned based on the one
|
||||
with the highest `matchingPrecedence`. If multiple FlowSchemas with equal
|
||||
`matchingPrecedence` match the same request, the one with lexicographically
|
||||
smaller `name` will win, but it's better not to rely on this, and instead to
|
||||
ensure that no two FlowSchemas have the same `matchingPrecedence`.
|
||||
{{< /caution >}}
|
||||
|
||||
A FlowSchema matches a given request if at least one of its `rules`
|
||||
matches. A rule matches if at least one of its `subjects` *and* at least
|
||||
one of its `resourceRules` or `nonResourceRules` (depending on whether the
|
||||
incoming request is for a resource or non-resource URL) matches the request.
|
||||
|
||||
For the `name` field in subjects, and the `verbs`, `apiGroups`, `resources`,
|
||||
`namespaces`, and `nonResourceURLs` fields of resource and non-resource rules,
|
||||
the wildcard `*` may be specified to match all values for the given field,
|
||||
effectively removing it from consideration.
|
||||
|
||||
A FlowSchema's `distinguisherMethod.type` determines how requests matching that
|
||||
schema will be separated into flows. It may be
|
||||
either `ByUser`, in which case one requesting user will not be able to starve
|
||||
other users of capacity, or `ByNamespace`, in which case requests for resources
|
||||
in one namespace will not be able to starve requests for resources in other
|
||||
namespaces of capacity, or it may be blank (or `distinguisherMethod` may be
|
||||
omitted entirely), in which case all requests matched by this FlowSchema will be
|
||||
considered part of a single flow. The correct choice for a given FlowSchema
|
||||
depends on the resource and your particular environment.
|
||||
|
||||
## Diagnostics
|
||||
Every HTTP response from an API server with the priority and fairness feature
|
||||
enabled has two extra headers: `X-Kubernetes-PF-FlowSchema-UID` and
|
||||
`X-Kubernetes-PF-PriorityLevel-UID`, noting the flow schema that matched the request
|
||||
and the priority level to which it was assigned, respectively. The API objects'
|
||||
names are not included in these headers in case the requesting user does not
|
||||
have permission to view them, so when debugging you can use a command like
|
||||
|
||||
```shell
|
||||
kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
|
||||
kubectl get prioritylevelconfigurations -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
|
||||
```
|
||||
|
||||
to get a mapping of UIDs to names for both FlowSchemas and
|
||||
PriorityLevelConfigurations.
|
||||
|
||||
## Observability
|
||||
When you enable the API Priority and Fairness feature, the kube-apiserver
|
||||
exports additional metrics. Monitoring these can help you determine whether your
|
||||
configuration is inappropriately throttling important traffic, or find
|
||||
poorly-behaved workloads that may be harming system health.
|
||||
|
||||
* `apiserver_flowcontrol_rejected_requests_total` counts requests that
|
||||
were rejected, grouped by the name of the assigned priority level,
|
||||
the name of the assigned FlowSchema, and the reason for rejection.
|
||||
The reason will be one of the following:
|
||||
* `queue-full`, indicating that too many requests were already
|
||||
queued,
|
||||
* `concurrency-limit`, indicating that the
|
||||
PriorityLevelConfiguration is configured to reject rather than
|
||||
queue excess requests, or
|
||||
* `time-out`, indicating that the request was still in the queue
|
||||
when its queuing time limit expired.
|
||||
|
||||
* `apiserver_flowcontrol_dispatched_requests_total` counts requests
|
||||
that began executing, grouped by the name of the assigned priority
|
||||
level and the name of the assigned FlowSchema.
|
||||
|
||||
* `apiserver_flowcontrol_current_inqueue_requests` gives the
|
||||
instantaneous total number of queued (not executing) requests,
|
||||
grouped by priority level and FlowSchema.
|
||||
|
||||
* `apiserver_flowcontrol_current_executing_requests` gives the instantaneous
|
||||
total number of executing requests, grouped by priority level and FlowSchema.
|
||||
|
||||
* `apiserver_flowcontrol_request_queue_length_after_enqueue` gives a
|
||||
histogram of queue lengths for the queues, grouped by priority level
|
||||
and FlowSchema, as sampled by the enqueued requests. Each request
|
||||
that gets queued contributes one sample to its histogram, reporting
|
||||
the length of the queue just after the request was added. Note that
|
||||
this produces different statistics than an unbiased survey would.
|
||||
{{< note >}}
|
||||
An outlier value in a histogram here means it is likely that a single flow
|
||||
(i.e., requests by one user or for one namespace, depending on
|
||||
configuration) is flooding the API server, and being throttled. By contrast,
|
||||
if one priority level's histogram shows that all queues for that priority
|
||||
level are longer than those for other priority levels, it may be appropriate
|
||||
to increase that PriorityLevelConfiguration's concurrency shares.
|
||||
{{< /note >}}
|
||||
|
||||
* `apiserver_flowcontrol_request_concurrency_limit` gives the computed
|
||||
concurrency limit (based on the API server's total concurrency limit and PriorityLevelConfigurations'
|
||||
concurrency shares) for each PriorityLevelConfiguration.
|
||||
|
||||
* `apiserver_flowcontrol_request_wait_duration_seconds` gives a histogram of how
|
||||
long requests spent queued, grouped by the FlowSchema that matched the
|
||||
request, the PriorityLevel to which it was assigned, and whether or not the
|
||||
request successfully executed.
|
||||
{{< note >}}
|
||||
Since each FlowSchema always assigns requests to a single
|
||||
PriorityLevelConfiguration, you can add the histograms for all the
|
||||
FlowSchemas for one priority level to get the effective histogram for
|
||||
requests assigned to that priority level.
|
||||
{{< /note >}}
|
||||
|
||||
* `apiserver_flowcontrol_request_execution_seconds` gives a histogram of how
|
||||
long requests took to actually execute, grouped by the FlowSchema that matched the
|
||||
request and the PriorityLevel to which it was assigned.
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
For background information on design details for API priority and fairness, see
|
||||
the [enhancement proposal](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/20190228-priority-and-fairness.md).
|
||||
You can make suggestions and feature requests via [SIG API
|
||||
Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery).
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -76,7 +76,7 @@ should set up a solution to address that.
|
||||
For example, in Kubernetes clusters, deployed by the `kube-up.sh` script,
|
||||
there is a [`logrotate`](https://linux.die.net/man/8/logrotate)
|
||||
tool configured to run each hour. You can also set up a container runtime to
|
||||
rotate application's logs automatically, for example by using Docker's `log-opt`.
|
||||
rotate application's logs automatically, e.g. by using Docker's `log-opt`.
|
||||
In the `kube-up.sh` script, the latter approach is used for COS image on GCP,
|
||||
and the former approach is used in any other environment. In both cases, by
|
||||
default rotation is configured to take place when log file exceeds 10MB.
|
||||
|
||||
@@ -424,24 +424,16 @@ At some point, you'll eventually need to update your deployed application, typic
|
||||
|
||||
We'll guide you through how to create and update applications with Deployments.
|
||||
|
||||
Let's say you were running version 1.14.2 of nginx:
|
||||
Let's say you were running version 1.7.9 of nginx:
|
||||
|
||||
```shell
|
||||
kubectl create deployment my-nginx --image=nginx:1.14.2
|
||||
kubectl run my-nginx --image=nginx:1.7.9 --replicas=3
|
||||
```
|
||||
```shell
|
||||
deployment.apps/my-nginx created
|
||||
```
|
||||
|
||||
with 3 replicas (so the old and new revisions can coexist):
|
||||
```shell
|
||||
kubectl scale deployment my-nginx --current-replicas=1 --replicas=3
|
||||
```
|
||||
```
|
||||
deployment.apps/my-nginx scaled
|
||||
```
|
||||
|
||||
To update to version 1.16.1, simply change `.spec.template.spec.containers[0].image` from `nginx:1.14.2` to `nginx:1.16.1`, with the kubectl commands we learned above.
|
||||
To update to version 1.9.1, simply change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`, with the kubectl commands we learned above.
|
||||
|
||||
```shell
|
||||
kubectl edit deployment/my-nginx
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
---
|
||||
title: Metrics For The Kubernetes Control Plane
|
||||
reviewers:
|
||||
- brancz
|
||||
- logicalhan
|
||||
- RainbowMango
|
||||
content_template: templates/concept
|
||||
weight: 60
|
||||
aliases:
|
||||
- controller-metrics.md
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
System component metrics can give a better look into what is happening inside them. Metrics are particularly useful for building dashboards and alerts.
|
||||
|
||||
Metrics in Kubernetes control plane are emitted in [prometheus format](https://prometheus.io/docs/instrumenting/exposition_formats/) and are human readable.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Metrics in Kubernetes
|
||||
|
||||
In most cases metrics are available on `/metrics` endpoint of the HTTP server. For components that doesn't expose endpoint by default it can be enabled using `--bind-address` flag.
|
||||
|
||||
Examples of those components:
|
||||
* {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}
|
||||
* {{< glossary_tooltip term_id="kube-proxy" text="kube-proxy" >}}
|
||||
* {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver" >}}
|
||||
* {{< glossary_tooltip term_id="kube-scheduler" text="kube-scheduler" >}}
|
||||
* {{< glossary_tooltip term_id="kubelet" text="kubelet" >}}
|
||||
|
||||
In a production environment you may want to configure [Prometheus Server](https://prometheus.io/) or some other metrics scraper
|
||||
to periodically gather these metrics and make them available in some kind of time series database.
|
||||
|
||||
Note that {{< glossary_tooltip term_id="kubelet" text="kubelet" >}} also exposes metrics in `/metrics/cadvisor`, `/metrics/resource` and `/metrics/probes` endpoints. Those metrics do not have same lifecycle.
|
||||
|
||||
If your cluster uses {{< glossary_tooltip term_id="rbac" text="RBAC" >}}, reading metrics requires authorization via a user, group or ServiceAccount with a ClusterRole that allows accessing `/metrics`.
|
||||
For example:
|
||||
```
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: prometheus
|
||||
rules:
|
||||
- nonResourceURLs:
|
||||
- "/metrics"
|
||||
verbs:
|
||||
- get
|
||||
```
|
||||
|
||||
## Metric lifecycle
|
||||
|
||||
Alpha metric → Stable metric → Deprecated metric → Hidden metric → Deletion
|
||||
|
||||
Alpha metrics have no stability guarantees; as such they can be modified or deleted at any time.
|
||||
|
||||
Stable metrics can be guaranteed to not change; Specifically, stability means:
|
||||
|
||||
* the metric itself will not be deleted (or renamed)
|
||||
* the type of metric will not be modified
|
||||
|
||||
Deprecated metric signal that the metric will eventually be deleted; to find which version, you need to check annotation, which includes from which kubernetes version that metric will be considered deprecated.
|
||||
|
||||
Before deprecation:
|
||||
|
||||
```
|
||||
# HELP some_counter this counts things
|
||||
# TYPE some_counter counter
|
||||
some_counter 0
|
||||
```
|
||||
|
||||
After deprecation:
|
||||
|
||||
```
|
||||
# HELP some_counter (Deprecated since 1.15.0) this counts things
|
||||
# TYPE some_counter counter
|
||||
some_counter 0
|
||||
```
|
||||
|
||||
Once a metric is hidden then by default the metrics is not published for scraping. To use a hidden metric, you need to override the configuration for the relevant cluster component.
|
||||
|
||||
Once a metric is deleted, the metric is not published. You cannot change this using an override.
|
||||
|
||||
|
||||
## Show Hidden Metrics
|
||||
|
||||
As described above, admins can enable hidden metrics through a command-line flag on a specific binary. This intends to be used as an escape hatch for admins if they missed the migration of the metrics deprecated in the last release.
|
||||
|
||||
The flag `show-hidden-metrics-for-version` takes a version for which you want to show metrics deprecated in that release. The version is expressed as x.y, where x is the major version, y is the minor version. The patch version is not needed even though a metrics can be deprecated in a patch release, the reason for that is the metrics deprecation policy runs against the minor release.
|
||||
|
||||
The flag can only take the previous minor version as it's value. All metrics hidden in previous will be emitted if admins set the previous version to `show-hidden-metrics-for-version`. The too old version is not allowed because this violates the metrics deprecated policy.
|
||||
|
||||
Take metric `A` as an example, here assumed that `A` is deprecated in 1.n. According to metrics deprecated policy, we can reach the following conclusion:
|
||||
|
||||
* In release `1.n`, the metric is deprecated, and it can be emitted by default.
|
||||
* In release `1.n+1`, the metric is hidden by default and it can be emitted by command line `show-hidden-metrics-for-version=1.n`.
|
||||
* In release `1.n+2`, the metric should be removed from the codebase. No escape hatch anymore.
|
||||
|
||||
If you're upgrading from release `1.12` to `1.13`, but still depend on a metric `A` deprecated in `1.12`, you should set hidden metrics via command line: `--show-hidden-metrics=1.12` and remember to remove this metric dependency before upgrading to `1.14`
|
||||
|
||||
## Component metrics
|
||||
|
||||
### kube-controller-manager metrics
|
||||
|
||||
Controller manager metrics provide important insight into the performance and health of the controller manager.
|
||||
These metrics include common Go language runtime metrics such as go_routine count and controller specific metrics such as
|
||||
etcd request latencies or Cloudprovider (AWS, GCE, OpenStack) API latencies that can be used
|
||||
to gauge the health of a cluster.
|
||||
|
||||
Starting from Kubernetes 1.7, detailed Cloudprovider metrics are available for storage operations for GCE, AWS, Vsphere and OpenStack.
|
||||
These metrics can be used to monitor health of persistent volume operations.
|
||||
|
||||
For example, for GCE these metrics are called:
|
||||
|
||||
```
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "instance_list"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "disk_insert"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "disk_delete"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "attach_disk"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "detach_disk"}
|
||||
cloudprovider_gce_api_request_duration_seconds { request = "list_disk"}
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
* Read about the [Prometheus text format](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md#text-based-format) for metrics
|
||||
* See the list of [stable Kubernetes metrics](https://github.com/kubernetes/kubernetes/blob/master/test/instrumentation/testdata/stable-metrics-list.yaml)
|
||||
* Read about the [Kubernetes deprecation policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/#deprecating-a-feature-or-behavior )
|
||||
{{% /capture %}}
|
||||
@@ -111,12 +111,6 @@ Using this CNI plugin allows Kubernetes pods to have the same IP address inside
|
||||
|
||||
Additionally, the CNI can be run alongside [Calico for network policy enforcement](https://docs.aws.amazon.com/eks/latest/userguide/calico.html). The AWS VPC CNI project is open source with [documentation on GitHub](https://github.com/aws/amazon-vpc-cni-k8s).
|
||||
|
||||
### Azure CNI for Kubernetes
|
||||
[Azure CNI](https://docs.microsoft.com/en-us/azure/virtual-network/container-networking-overview) is an [open source](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md) plugin that integrates Kubernetes Pods with an Azure Virtual Network (also known as VNet) providing network performance at par with VMs. Pods can connect to peered VNet and to on-premises over Express Route or site-to-site VPN and are also directly reachable from these networks. Pods can access Azure services, such as storage and SQL, that are protected by Service Endpoints or Private Link. You can use VNet security policies and routing to filter Pod traffic. The plugin assigns VNet IPs to Pods by utilizing a pool of secondary IPs pre-configured on the Network Interface of a Kubernetes node.
|
||||
|
||||
Azure CNI is available natively in the [Azure Kubernetes Service (AKS)] (https://docs.microsoft.com/en-us/azure/aks/configure-azure-cni).
|
||||
|
||||
|
||||
### Big Cloud Fabric from Big Switch Networks
|
||||
|
||||
[Big Cloud Fabric](https://www.bigswitch.com/container-network-automation) is a cloud native networking architecture, designed to run Kubernetes in private cloud/on-premises environments. Using unified physical & virtual SDN, Big Cloud Fabric tackles inherent container networking problems such as load balancing, visibility, troubleshooting, security policies & container traffic monitoring.
|
||||
|
||||
@@ -17,7 +17,7 @@ There are several ways to do this, and the recommended approaches all use
|
||||
[label selectors](/docs/concepts/overview/working-with-objects/labels/) to make the selection.
|
||||
Generally such constraints are unnecessary, as the scheduler will automatically do a reasonable placement
|
||||
(e.g. spread your pods across nodes, not place the pod on a node with insufficient free resources, etc.)
|
||||
but there are some circumstances where you may want more control on a node where a pod lands, for example to ensure
|
||||
but there are some circumstances where you may want more control on a node where a pod lands, e.g. to ensure
|
||||
that a pod ends up on a machine with an SSD attached to it, or to co-locate pods from two different
|
||||
services that communicate a lot into the same availability zone.
|
||||
|
||||
@@ -111,10 +111,9 @@ For example, `example.com.node-restriction.kubernetes.io/fips=true` or `example.
|
||||
`nodeSelector` provides a very simple way to constrain pods to nodes with particular labels. The affinity/anti-affinity
|
||||
feature, greatly expands the types of constraints you can express. The key enhancements are
|
||||
|
||||
1. The affinity/anti-affinity language is more expressive. The language offers more matching rules
|
||||
besides exact matches created with a logical AND operation;
|
||||
1. the language is more expressive (not just "AND of exact match")
|
||||
2. you can indicate that the rule is "soft"/"preference" rather than a hard requirement, so if the scheduler
|
||||
can't satisfy it, the pod will still be scheduled;
|
||||
can't satisfy it, the pod will still be scheduled
|
||||
3. you can constrain against labels on other pods running on the node (or other topological domain),
|
||||
rather than against labels on the node itself, which allows rules about which pods can and cannot be co-located
|
||||
|
||||
@@ -160,9 +159,9 @@ You can use `NotIn` and `DoesNotExist` to achieve node anti-affinity behavior, o
|
||||
If you specify both `nodeSelector` and `nodeAffinity`, *both* must be satisfied for the pod
|
||||
to be scheduled onto a candidate node.
|
||||
|
||||
If you specify multiple `nodeSelectorTerms` associated with `nodeAffinity` types, then the pod can be scheduled onto a node **only if all** `nodeSelectorTerms` can be satisfied.
|
||||
If you specify multiple `nodeSelectorTerms` associated with `nodeAffinity` types, then the pod can be scheduled onto a node **if one of** the `nodeSelectorTerms` is satisfied.
|
||||
|
||||
If you specify multiple `matchExpressions` associated with `nodeSelectorTerms`, then the pod can be scheduled onto a node **if one of** the `matchExpressions` is satisfied.
|
||||
If you specify multiple `matchExpressions` associated with `nodeSelectorTerms`, then the pod can be scheduled onto a node **only if all** `matchExpressions` can be satisfied.
|
||||
|
||||
If you remove or change the label of the node where the pod is scheduled, the pod won't be removed. In other words, the affinity selection works only at the time of scheduling the pod.
|
||||
|
||||
@@ -177,7 +176,7 @@ Y is expressed as a LabelSelector with an optional associated list of namespaces
|
||||
(and therefore the labels on pods are implicitly namespaced),
|
||||
a label selector over pod labels must specify which namespaces the selector should apply to. Conceptually X is a topology domain
|
||||
like node, rack, cloud provider zone, cloud provider region, etc. You express it using a `topologyKey` which is the
|
||||
key for the node label that the system uses to denote such a topology domain; for example, see the label keys listed above
|
||||
key for the node label that the system uses to denote such a topology domain, e.g. see the label keys listed above
|
||||
in the section [Interlude: built-in node labels](#built-in-node-labels).
|
||||
|
||||
{{< note >}}
|
||||
@@ -187,7 +186,7 @@ not recommend using them in clusters larger than several hundred nodes.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
Pod anti-affinity requires nodes to be consistently labelled, in other words every node in the cluster must have an appropriate label matching `topologyKey`. If some or all nodes are missing the specified `topologyKey` label, it can lead to unintended behavior.
|
||||
Pod anti-affinity requires nodes to be consistently labelled, i.e. every node in the cluster must have an appropriate label matching `topologyKey`. If some or all nodes are missing the specified `topologyKey` label, it can lead to unintended behavior.
|
||||
{{< /note >}}
|
||||
|
||||
As with node affinity, there are currently two types of pod affinity and anti-affinity, called `requiredDuringSchedulingIgnoredDuringExecution` and
|
||||
@@ -229,7 +228,7 @@ for performance and security reasons, there are some constraints on topologyKey:
|
||||
1. For affinity and for `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity,
|
||||
empty `topologyKey` is not allowed.
|
||||
2. For `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, the admission controller `LimitPodHardAntiAffinityTopology` was introduced to limit `topologyKey` to `kubernetes.io/hostname`. If you want to make it available for custom topologies, you may modify the admission controller, or simply disable it.
|
||||
3. For `preferredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, empty `topologyKey` is not allowed.
|
||||
3. For `preferredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, empty `topologyKey` is interpreted as "all topologies" ("all topologies" here is now limited to the combination of `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone` and `failure-domain.beta.kubernetes.io/region`).
|
||||
4. Except for the above cases, the `topologyKey` can be any legal label-key.
|
||||
|
||||
In addition to `labelSelector` and `topologyKey`, you can optionally specify a list `namespaces`
|
||||
@@ -319,7 +318,7 @@ spec:
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: web-app
|
||||
image: nginx:1.16-alpine
|
||||
image: nginx:1.12-alpine
|
||||
```
|
||||
|
||||
If we create the above two deployments, our three node cluster should look like below.
|
||||
@@ -367,7 +366,7 @@ Some of the limitations of using `nodeName` to select nodes are:
|
||||
some cases may be automatically deleted.
|
||||
- If the named node does not have the resources to accommodate the
|
||||
pod, the pod will fail and its reason will indicate why,
|
||||
for example OutOfmemory or OutOfcpu.
|
||||
e.g. OutOfmemory or OutOfcpu.
|
||||
- Node names in cloud environments are not always predictable or
|
||||
stable.
|
||||
|
||||
|
||||
@@ -68,7 +68,13 @@ resource requests/limits of that type for each Container in the Pod.
|
||||
## Meaning of CPU
|
||||
|
||||
Limits and requests for CPU resources are measured in *cpu* units.
|
||||
One cpu, in Kubernetes, is equivalent to **1 vCPU/Core** for cloud providers and **1 hyperthread** on bare-metal Intel processors.
|
||||
One cpu, in Kubernetes, is equivalent to:
|
||||
|
||||
- 1 AWS vCPU
|
||||
- 1 GCP Core
|
||||
- 1 Azure vCore
|
||||
- 1 IBM vCPU
|
||||
- 1 *Hyperthread* on a bare-metal Intel processor with Hyperthreading
|
||||
|
||||
Fractional requests are allowed. A Container with
|
||||
`spec.containers[].resources.requests.cpu` of `0.5` is guaranteed half as much
|
||||
@@ -185,10 +191,9 @@ resource limits, see the
|
||||
|
||||
The resource usage of a Pod is reported as part of the Pod status.
|
||||
|
||||
If optional [tools for monitoring](/docs/tasks/debug-application-cluster/resource-usage-monitoring/)
|
||||
are available in your cluster, then Pod resource usage can be retrieved either
|
||||
from the [Metrics API](/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#the-metrics-api)
|
||||
directly or from your monitoring tools.
|
||||
If [optional monitoring](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/cluster-monitoring/README.md)
|
||||
is configured for your cluster, then Pod resource usage can be retrieved from
|
||||
the monitoring system.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -386,7 +391,7 @@ spec:
|
||||
### How Pods with ephemeral-storage requests are scheduled
|
||||
|
||||
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
|
||||
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. For more information, see ["Node Allocatable"](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. For more information, see ["Node Allocatable"](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
|
||||
The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ This is a living document. If you think of something that is not on this list bu
|
||||
- Put object descriptions in annotations, to allow better introspection.
|
||||
|
||||
|
||||
## "Naked" Pods versus ReplicaSets, Deployments, and Jobs {#naked-pods-vs-replicasets-deployments-and-jobs}
|
||||
## "Naked" Pods vs ReplicaSets, Deployments, and Jobs
|
||||
|
||||
- Don't use naked Pods (that is, Pods not bound to a [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) or [Deployment](/docs/concepts/workloads/controllers/deployment/)) if you can avoid it. Naked Pods will not be rescheduled in the event of a node failure.
|
||||
|
||||
@@ -87,7 +87,7 @@ The [imagePullPolicy](/docs/concepts/containers/images/#updating-images) and the
|
||||
- `imagePullPolicy: Never`: the image is assumed to exist locally. No attempt is made to pull the image.
|
||||
|
||||
{{< note >}}
|
||||
To make sure the container always uses the same version of the image, you can specify its [digest](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier); replace `<image-name>:<tag>` with `<image-name>@<digest>` (for example, `image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`). The digest uniquely identifies a specific version of the image, so it is never updated by Kubernetes unless you change the digest value.
|
||||
To make sure the container always uses the same version of the image, you can specify its [digest](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier), for example `sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`. The digest uniquely identifies a specific version of the image, so it is never updated by Kubernetes unless you change the digest value.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
@@ -108,3 +108,4 @@ The caching semantics of the underlying image provider make even `imagePullPolic
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ weight: 20
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
|
||||
|
||||
|
||||
When you run a Pod on a Node, the Pod itself takes an amount of system resources. These
|
||||
resources are additional to the resources needed to run the container(s) inside the Pod.
|
||||
_Pod Overhead_ is a feature for accounting for the resources consumed by the Pod infrastructure
|
||||
_Pod Overhead_ is a feature for accounting for the resources consumed by the pod infrastructure
|
||||
on top of the container requests & limits.
|
||||
|
||||
|
||||
@@ -24,169 +24,33 @@ on top of the container requests & limits.
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
In Kubernetes, the Pod's overhead is set at
|
||||
## Pod Overhead
|
||||
|
||||
In Kubernetes, the pod's overhead is set at
|
||||
[admission](/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks)
|
||||
time according to the overhead associated with the Pod's
|
||||
time according to the overhead associated with the pod's
|
||||
[RuntimeClass](/docs/concepts/containers/runtime-class/).
|
||||
|
||||
When Pod Overhead is enabled, the overhead is considered in addition to the sum of container
|
||||
resource requests when scheduling a Pod. Similarly, Kubelet will include the Pod overhead when sizing
|
||||
the Pod cgroup, and when carrying out Pod eviction ranking.
|
||||
resource requests when scheduling a pod. Similarly, Kubelet will include the pod overhead when sizing
|
||||
the pod cgroup, and when carrying out pod eviction ranking.
|
||||
|
||||
## Enabling Pod Overhead {#set-up}
|
||||
### Set Up
|
||||
|
||||
You need to make sure that the `PodOverhead`
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled (it is on by default as of 1.18)
|
||||
across your cluster, and a `RuntimeClass` is utilized which defines the `overhead` field.
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled (it is off by default)
|
||||
across your cluster. This means:
|
||||
|
||||
## Usage example
|
||||
- in {{< glossary_tooltip text="kube-scheduler" term_id="kube-scheduler" >}}
|
||||
- in {{< glossary_tooltip text="kube-apiserver" term_id="kube-apiserver" >}}
|
||||
- in the {{< glossary_tooltip text="kubelet" term_id="kubelet" >}} on each Node
|
||||
- in any custom API servers that use feature gates
|
||||
|
||||
To use the PodOverhead feature, you need a RuntimeClass that defines the `overhead` field. As
|
||||
an example, you could use the following RuntimeClass definition with a virtualizing container runtime
|
||||
that uses around 120MiB per Pod for the virtual machine and the guest OS:
|
||||
|
||||
```yaml
|
||||
---
|
||||
kind: RuntimeClass
|
||||
apiVersion: node.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: kata-fc
|
||||
handler: kata-fc
|
||||
overhead:
|
||||
podFixed:
|
||||
memory: "120Mi"
|
||||
cpu: "250m"
|
||||
```
|
||||
|
||||
Workloads which are created which specify the `kata-fc` RuntimeClass handler will take the memory and
|
||||
cpu overheads into account for resource quota calculations, node scheduling, as well as Pod cgroup sizing.
|
||||
|
||||
Consider running the given example workload, test-pod:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: test-pod
|
||||
spec:
|
||||
runtimeClassName: kata-fc
|
||||
containers:
|
||||
- name: busybox-ctr
|
||||
image: busybox
|
||||
stdin: true
|
||||
tty: true
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 100Mi
|
||||
- name: nginx-ctr
|
||||
image: nginx
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 100Mi
|
||||
```
|
||||
|
||||
At admission time the RuntimeClass [admission controller](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)
|
||||
updates the workload's PodSpec to include the `overhead` as described in the RuntimeClass. If the PodSpec already has this field defined,
|
||||
the Pod will be rejected. In the given example, since only the RuntimeClass name is specified, the admission controller mutates the Pod
|
||||
to include an `overhead`.
|
||||
|
||||
After the RuntimeClass admission controller, you can check the updated PodSpec:
|
||||
|
||||
```bash
|
||||
kubectl get pod test-pod -o jsonpath='{.spec.overhead}'
|
||||
```
|
||||
|
||||
The output is:
|
||||
```
|
||||
map[cpu:250m memory:120Mi]
|
||||
```
|
||||
|
||||
If a ResourceQuota is defined, the sum of container requests as well as the
|
||||
`overhead` field are counted.
|
||||
|
||||
When the kube-scheduler is deciding which node should run a new Pod, the scheduler considers that Pod's
|
||||
`overhead` as well as the sum of container requests for that Pod. For this example, the scheduler adds the
|
||||
requests and the overhead, then looks for a node that has 2.25 CPU and 320 MiB of memory available.
|
||||
|
||||
Once a Pod is scheduled to a node, the kubelet on that node creates a new {{< glossary_tooltip text="cgroup" term_id="cgroup" >}}
|
||||
for the Pod. It is within this pod that the underlying container runtime will create containers.
|
||||
|
||||
If the resource has a limit defined for each container (Guaranteed QoS or Bustrable QoS with limits defined),
|
||||
the kubelet will set an upper limit for the pod cgroup associated with that resource (cpu.cfs_quota_us for CPU
|
||||
and memory.limit_in_bytes memory). This upper limit is based on the sum of the container limits plus the `overhead`
|
||||
defined in the PodSpec.
|
||||
|
||||
For CPU, if the Pod is Guaranteed or Burstable QoS, the kubelet will set `cpu.shares` based on the sum of container
|
||||
requests plus the `overhead` defined in the PodSpec.
|
||||
|
||||
Looking at our example, verify the container requests for the workload:
|
||||
```bash
|
||||
kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'
|
||||
```
|
||||
|
||||
The total container requests are 2000m CPU and 200MiB of memory:
|
||||
```
|
||||
map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]
|
||||
```
|
||||
|
||||
Check this against what is observed by the node:
|
||||
```bash
|
||||
kubectl describe node | grep test-pod -B2
|
||||
```
|
||||
|
||||
The output shows 2250m CPU and 320MiB of memory are requested, which includes PodOverhead:
|
||||
```
|
||||
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
|
||||
--------- ---- ------------ ---------- --------------- ------------- ---
|
||||
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
|
||||
```
|
||||
|
||||
## Verify Pod cgroup limits
|
||||
|
||||
Check the Pod's memory cgroups on the node where the workload is running. In the following example, [`crictl`](https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md)
|
||||
is used on the node, which provides a CLI for CRI-compatible container runtimes. This is an
|
||||
advanced example to show PodOverhead behavior, and it is not expected that users should need to check
|
||||
cgroups directly on the node.
|
||||
|
||||
First, on the particular node, determine the Pod identifier:
|
||||
|
||||
```bash
|
||||
# Run this on the node where the Pod is scheduled
|
||||
POD_ID="$(sudo crictl pods --name test-pod -q)"
|
||||
```
|
||||
|
||||
From this, you can determine the cgroup path for the Pod:
|
||||
```bash
|
||||
# Run this on the node where the Pod is scheduled
|
||||
sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath
|
||||
```
|
||||
|
||||
The resulting cgroup path includes the Pod's `pause` container. The Pod level cgroup is one directory above.
|
||||
```
|
||||
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"
|
||||
```
|
||||
|
||||
In this specific case, the pod cgroup path is `kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2`. Verify the Pod level cgroup setting for memory:
|
||||
```bash
|
||||
# Run this on the node where the Pod is scheduled.
|
||||
# Also, change the name of the cgroup to match the cgroup allocated for your pod.
|
||||
cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes
|
||||
```
|
||||
|
||||
This is 320 MiB, as expected:
|
||||
```
|
||||
335544320
|
||||
```
|
||||
|
||||
### Observability
|
||||
|
||||
A `kube_pod_overhead` metric is available in [kube-state-metrics](https://github.com/kubernetes/kube-state-metrics)
|
||||
to help identify when PodOverhead is being utilized and to help observe stability of workloads
|
||||
running with a defined Overhead. This functionality is not available in the 1.9 release of
|
||||
kube-state-metrics, but is expected in a following release. Users will need to build kube-state-metrics
|
||||
from source in the meantime.
|
||||
{{< note >}}
|
||||
Users who can write to RuntimeClass resources are able to have cluster-wide impact on
|
||||
workload performance. You can limit access to this ability using Kubernetes access controls.
|
||||
See [Authorization Overview](/docs/reference/access-authn-authz/authorization/) for more details.
|
||||
{{< /note >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -9,32 +9,49 @@ weight: 70
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.14" state="stable" >}}
|
||||
{{< feature-state for_k8s_version="1.14" state="stable" >}}
|
||||
|
||||
[Pods](/docs/user-guide/pods) can have _priority_. Priority indicates the
|
||||
importance of a Pod relative to other Pods. If a Pod cannot be scheduled, the
|
||||
scheduler tries to preempt (evict) lower priority Pods to make scheduling of the
|
||||
pending Pod possible.
|
||||
|
||||
In Kubernetes 1.9 and later, Priority also affects scheduling order of Pods and
|
||||
out-of-resource eviction ordering on the Node.
|
||||
|
||||
Pod priority and preemption graduated to beta in Kubernetes 1.11 and to GA in
|
||||
Kubernetes 1.14. They have been enabled by default since 1.11.
|
||||
|
||||
In Kubernetes versions where Pod priority and preemption is still an alpha-level
|
||||
feature, you need to explicitly enable it. To use these features in the older
|
||||
versions of Kubernetes, follow the instructions in the documentation for your
|
||||
Kubernetes version, by going to the documentation archive version for your
|
||||
Kubernetes version.
|
||||
|
||||
Kubernetes Version | Priority and Preemption State | Enabled by default
|
||||
------------------ | :---------------------------: | :----------------:
|
||||
1.8 | alpha | no
|
||||
1.9 | alpha | no
|
||||
1.10 | alpha | no
|
||||
1.11 | beta | yes
|
||||
1.14 | stable | yes
|
||||
|
||||
{{< warning >}}In a cluster where not all users are trusted, a
|
||||
malicious user could create pods at the highest possible priorities, causing
|
||||
other pods to be evicted/not get scheduled. To resolve this issue,
|
||||
[ResourceQuota](/docs/concepts/policy/resource-quotas/) is
|
||||
augmented to support Pod priority. An admin can create ResourceQuota for users
|
||||
at specific priority levels, preventing them from creating pods at high
|
||||
priorities. This feature is in beta since Kubernetes 1.12.
|
||||
{{< /warning >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
|
||||
{{< warning >}}
|
||||
In a cluster where not all users are trusted, a malicious user could create Pods
|
||||
at the highest possible priorities, causing other Pods to be evicted/not get
|
||||
scheduled.
|
||||
An administrator can use ResourceQuota to prevent users from creating pods at
|
||||
high priorities.
|
||||
|
||||
See [limit Priority Class consumption by default](/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default)
|
||||
for details.
|
||||
{{< /warning >}}
|
||||
|
||||
## How to use priority and preemption
|
||||
|
||||
To use priority and preemption:
|
||||
To use priority and preemption in Kubernetes 1.11 and later, follow these steps:
|
||||
|
||||
1. Add one or more [PriorityClasses](#priorityclass).
|
||||
|
||||
@@ -45,12 +62,6 @@ To use priority and preemption:
|
||||
|
||||
Keep reading for more information about these steps.
|
||||
|
||||
{{< note >}}
|
||||
Kubernetes already ships with two PriorityClasses:
|
||||
`system-cluster-critical` and `system-node-critical`.
|
||||
These are common classes and are used to [ensure that critical components are always scheduled first](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/).
|
||||
{{< /note >}}
|
||||
|
||||
If you try the feature and then decide to disable it, you must remove the
|
||||
PodPriority command-line flag or set it to `false`, and then restart the API
|
||||
server and scheduler. After the feature is disabled, the existing Pods keep
|
||||
@@ -60,20 +71,21 @@ Pods.
|
||||
|
||||
## How to disable preemption
|
||||
|
||||
{{< caution >}}
|
||||
Critical pods rely on scheduler preemption to be scheduled when a cluster
|
||||
is under resource pressure. For this reason, it is not recommended to
|
||||
disable preemption.
|
||||
{{< /caution >}}
|
||||
{{< note >}}
|
||||
In Kubernetes 1.12+, critical pods rely on scheduler preemption to be scheduled
|
||||
when a cluster is under resource pressure. For this reason, it is not
|
||||
recommended to disable preemption.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
In Kubernetes 1.15 and later, if the feature `NonPreemptingPriority` is enabled,
|
||||
In Kubernetes 1.15 and later,
|
||||
if the feature `NonPreemptingPriority` is enabled,
|
||||
PriorityClasses have the option to set `preemptionPolicy: Never`.
|
||||
This will prevent pods of that PriorityClass from preempting other pods.
|
||||
{{< /note >}}
|
||||
|
||||
Preemption is controlled by a kube-scheduler flag `disablePreemption`, which is
|
||||
set to `false` by default.
|
||||
In Kubernetes 1.11 and later, preemption is controlled by a kube-scheduler flag
|
||||
`disablePreemption`, which is set to `false` by default.
|
||||
If you want to disable preemption despite the above note, you can set
|
||||
`disablePreemption` to `true`.
|
||||
|
||||
@@ -99,9 +111,6 @@ priority class name to the integer value of the priority. The name is specified
|
||||
in the `name` field of the PriorityClass object's metadata. The value is
|
||||
specified in the required `value` field. The higher the value, the higher the
|
||||
priority.
|
||||
The name of a PriorityClass object must be a valid
|
||||
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names),
|
||||
and it cannot be prefixed with `system-`.
|
||||
|
||||
A PriorityClass object can have any 32-bit integer value smaller than or equal
|
||||
to 1 billion. Larger numbers are reserved for critical system Pods that should
|
||||
@@ -143,9 +152,12 @@ globalDefault: false
|
||||
description: "This priority class should be used for XYZ service pods only."
|
||||
```
|
||||
|
||||
## Non-preempting PriorityClass {#non-preempting-priority-class}
|
||||
### Non-preempting PriorityClasses (alpha) {#non-preempting-priority-class}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.15" state="alpha" >}}
|
||||
1.15 adds the `PreemptionPolicy` field as an alpha feature.
|
||||
It is disabled by default in 1.15,
|
||||
and requires the `NonPreemptingPriority`[feature gate](/docs/reference/command-line-tools-reference/feature-gates/
|
||||
) to be enabled.
|
||||
|
||||
Pods with `PreemptionPolicy: Never` will be placed in the scheduling queue
|
||||
ahead of lower-priority pods,
|
||||
@@ -169,10 +181,6 @@ which will allow pods of that PriorityClass to preempt lower-priority pods
|
||||
If `PreemptionPolicy` is set to `Never`,
|
||||
pods in that PriorityClass will be non-preempting.
|
||||
|
||||
The use of the `PreemptionPolicy` field requires the `NonPreemptingPriority`
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
to be enabled.
|
||||
|
||||
An example use case is for data science workloads.
|
||||
A user may submit a job that they want to be prioritized above other workloads,
|
||||
but do not wish to discard existing work by preempting running pods.
|
||||
@@ -180,7 +188,7 @@ The high priority job with `PreemptionPolicy: Never` will be scheduled
|
||||
ahead of other queued pods,
|
||||
as soon as sufficient cluster resources "naturally" become free.
|
||||
|
||||
### Example Non-preempting PriorityClass
|
||||
#### Example Non-preempting PriorityClass
|
||||
|
||||
```yaml
|
||||
apiVersion: scheduling.k8s.io/v1
|
||||
@@ -222,12 +230,12 @@ spec:
|
||||
|
||||
### Effect of Pod priority on scheduling order
|
||||
|
||||
When Pod priority is enabled, the scheduler orders pending Pods by
|
||||
their priority and a pending Pod is placed ahead of other pending Pods
|
||||
with lower priority in the scheduling queue. As a result, the higher
|
||||
priority Pod may be scheduled sooner than Pods with lower priority if
|
||||
its scheduling requirements are met. If such Pod cannot be scheduled,
|
||||
scheduler will continue and tries to schedule other lower priority Pods.
|
||||
In Kubernetes 1.9 and later, when Pod priority is enabled, scheduler orders
|
||||
pending Pods by their priority and a pending Pod is placed ahead of other
|
||||
pending Pods with lower priority in the scheduling queue. As a result, the
|
||||
higher priority Pod may be scheduled sooner than Pods with lower priority if its
|
||||
scheduling requirements are met. If such Pod cannot be scheduled, scheduler will
|
||||
continue and tries to schedule other lower priority Pods.
|
||||
|
||||
## Preemption
|
||||
|
||||
@@ -273,12 +281,12 @@ point that scheduler preempts victims and the time that Pod P is scheduled. In
|
||||
order to minimize this gap, one can set graceful termination period of lower
|
||||
priority Pods to zero or a small number.
|
||||
|
||||
#### PodDisruptionBudget is supported, but not guaranteed
|
||||
#### PodDisruptionBudget is supported, but not guaranteed!
|
||||
|
||||
A [Pod Disruption Budget (PDB)](/docs/concepts/workloads/pods/disruptions/)
|
||||
allows application owners to limit the number of Pods of a replicated application
|
||||
that are down simultaneously from voluntary disruptions. Kubernetes supports
|
||||
PDB when preempting Pods, but respecting PDB is best effort. The scheduler tries
|
||||
that are down simultaneously from voluntary disruptions. Kubernetes 1.9 supports
|
||||
PDB when preempting Pods, but respecting PDB is best effort. The Scheduler tries
|
||||
to find victims whose PDB are not violated by preemption, but if no such victims
|
||||
are found, preemption will still happen, and lower priority Pods will be removed
|
||||
despite their PDBs being violated.
|
||||
@@ -329,23 +337,28 @@ gone, and Pod P could possibly be scheduled on Node N.
|
||||
We may consider adding cross Node preemption in future versions if there is
|
||||
enough demand and if we find an algorithm with reasonable performance.
|
||||
|
||||
## Troubleshooting
|
||||
## Debugging Pod Priority and Preemption
|
||||
|
||||
Pod priority and pre-emption can have unwanted side effects. Here are some
|
||||
examples of potential problems and ways to deal with them.
|
||||
Pod Priority and Preemption is a major feature that could potentially disrupt
|
||||
Pod scheduling if it has bugs.
|
||||
|
||||
### Pods are preempted unnecessarily
|
||||
### Potential problems caused by Priority and Preemption
|
||||
|
||||
The followings are some of the potential problems that could be caused by bugs
|
||||
in the implementation of the feature. This list is not exhaustive.
|
||||
|
||||
#### Pods are preempted unnecessarily
|
||||
|
||||
Preemption removes existing Pods from a cluster under resource pressure to make
|
||||
room for higher priority pending Pods. If you give high priorities to
|
||||
certain Pods by mistake, these unintentionally high priority Pods may cause
|
||||
preemption in your cluster. Pod priority is specified by setting the
|
||||
`priorityClassName` field in the Pod's specification. The integer value for
|
||||
room for higher priority pending Pods. If a user gives high priorities to
|
||||
certain Pods by mistake, these unintentional high priority Pods may cause
|
||||
preemption in the cluster. As mentioned above, Pod priority is specified by
|
||||
setting the `priorityClassName` field of `podSpec`. The integer value of
|
||||
priority is then resolved and populated to the `priority` field of `podSpec`.
|
||||
|
||||
To address the problem, you can change the `priorityClassName` for those Pods
|
||||
to use lower priority classes, or leave that field empty. An empty
|
||||
`priorityClassName` is resolved to zero by default.
|
||||
To resolve the problem, `priorityClassName` of the Pods must be changed to use
|
||||
lower priority classes or should be left empty. Empty `priorityClassName` is
|
||||
resolved to zero by default.
|
||||
|
||||
When a Pod is preempted, there will be events recorded for the preempted Pod.
|
||||
Preemption should happen only when a cluster does not have enough resources for
|
||||
@@ -354,31 +367,29 @@ Pod (preemptor) is higher than the victim Pods. Preemption must not happen when
|
||||
there is no pending Pod, or when the pending Pods have equal or lower priority
|
||||
than the victims. If preemption happens in such scenarios, please file an issue.
|
||||
|
||||
### Pods are preempted, but the preemptor is not scheduled
|
||||
#### Pods are preempted, but the preemptor is not scheduled
|
||||
|
||||
When pods are preempted, they receive their requested graceful termination
|
||||
period, which is by default 30 seconds. If the victim Pods do not terminate within
|
||||
this period, they are forcibly terminated. Once all the victims go away, the
|
||||
preemptor Pod can be scheduled.
|
||||
period, which is by default 30 seconds, but it can be any different value as
|
||||
specified in the PodSpec. If the victim Pods do not terminate within this period,
|
||||
they are force-terminated. Once all the victims go away, the preemptor Pod can
|
||||
be scheduled.
|
||||
|
||||
While the preemptor Pod is waiting for the victims to go away, a higher priority
|
||||
Pod may be created that fits on the same Node. In this case, the scheduler will
|
||||
Pod may be created that fits on the same node. In this case, the scheduler will
|
||||
schedule the higher priority Pod instead of the preemptor.
|
||||
|
||||
This is expected behavior: the Pod with the higher priority should take the place
|
||||
of a Pod with a lower priority. Other controller actions, such as
|
||||
[cluster autoscaling](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaling),
|
||||
may eventually provide capacity to schedule the pending Pods.
|
||||
In the absence of such a higher priority Pod, we expect the preemptor Pod to be
|
||||
scheduled after the graceful termination period of the victims is over.
|
||||
|
||||
### Higher priority Pods are preempted before lower priority pods
|
||||
#### Higher priority Pods are preempted before lower priority pods
|
||||
|
||||
The scheduler tries to find nodes that can run a pending Pod. If no node is
|
||||
found, the scheduler tries to remove Pods with lower priority from an arbitrary
|
||||
node in order to make room for the pending pod.
|
||||
If a node with low priority Pods is not feasible to run the pending Pod, the scheduler
|
||||
may choose another node with higher priority Pods (compared to the Pods on the
|
||||
other node) for preemption. The victims must still have lower priority than the
|
||||
preemptor Pod.
|
||||
The scheduler tries to find nodes that can run a pending Pod and if no node is
|
||||
found, it tries to remove Pods with lower priority from one node to make room
|
||||
for the pending pod. If a node with low priority Pods is not feasible to run the
|
||||
pending Pod, the scheduler may choose another node with higher priority Pods
|
||||
(compared to the Pods on the other node) for preemption. The victims must still
|
||||
have lower priority than the preemptor Pod.
|
||||
|
||||
When there are multiple nodes available for preemption, the scheduler tries to
|
||||
choose the node with a set of Pods with lowest priority. However, if such Pods
|
||||
@@ -386,11 +397,13 @@ have PodDisruptionBudget that would be violated if they are preempted then the
|
||||
scheduler may choose another node with higher priority Pods.
|
||||
|
||||
When multiple nodes exist for preemption and none of the above scenarios apply,
|
||||
the scheduler chooses a node with the lowest priority.
|
||||
we expect the scheduler to choose a node with the lowest priority. If that is
|
||||
not the case, it may indicate a bug in the scheduler.
|
||||
|
||||
## Interactions between Pod priority and quality of service {#interactions-of-pod-priority-and-qos}
|
||||
## Interactions of Pod priority and QoS
|
||||
|
||||
Pod priority and {{< glossary_tooltip text="QoS class" term_id="qos-class" >}}
|
||||
Pod priority and
|
||||
[QoS](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/resource-qos.md)
|
||||
are two orthogonal features with few interactions and no default restrictions on
|
||||
setting the priority of a Pod based on its QoS classes. The scheduler's
|
||||
preemption logic does not consider QoS when choosing preemption targets.
|
||||
@@ -401,20 +414,15 @@ to schedule the preemptor Pod, or if the lowest priority Pods are protected by
|
||||
`PodDisruptionBudget`.
|
||||
|
||||
The only component that considers both QoS and Pod priority is
|
||||
[kubelet out-of-resource eviction](/docs/tasks/administer-cluster/out-of-resource/).
|
||||
[Kubelet out-of-resource eviction](/docs/tasks/administer-cluster/out-of-resource/).
|
||||
The kubelet ranks Pods for eviction first by whether or not their usage of the
|
||||
starved resource exceeds requests, then by Priority, and then by the consumption
|
||||
of the starved compute resource relative to the Pods’ scheduling requests.
|
||||
See
|
||||
[evicting end-user pods](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)
|
||||
for more details.
|
||||
|
||||
kubelet out-of-resource eviction does not evict Pods when their
|
||||
[Evicting end-user pods](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)
|
||||
for more details. Kubelet out-of-resource eviction does not evict Pods whose
|
||||
usage does not exceed their requests. If a Pod with lower priority is not
|
||||
exceeding its requests, it won't be evicted. Another Pod with higher priority
|
||||
that exceeds its requests may be evicted.
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
* Read about using ResourceQuotas in connection with PriorityClasses: [limit Priority Class consumption by default](/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default)
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -10,7 +10,7 @@ weight: 10
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
|
||||
{{< feature-state for_k8s_version="1.16" state="alpha" >}}
|
||||
|
||||
The kube-scheduler can be configured to enable bin packing of resources along with extended resources using `RequestedToCapacityRatioResourceAllocation` priority function. Priority functions can be used to fine-tune the kube-scheduler as per custom needs.
|
||||
|
||||
|
||||
+119
-65
@@ -3,14 +3,14 @@ reviewers:
|
||||
- ahg-g
|
||||
title: Scheduling Framework
|
||||
content_template: templates/concept
|
||||
weight: 60
|
||||
weight: 70
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.15" state="alpha" >}}
|
||||
{{< feature-state for_k8s_version="1.15" state="alpha" >}}
|
||||
|
||||
The scheduling framework is a pluggable architecture for Kubernetes Scheduler
|
||||
The scheduling framework is a new pluggable architecture for Kubernetes Scheduler
|
||||
that makes scheduler customizations easy. It adds a new set of "plugin" APIs to
|
||||
the existing scheduler. Plugins are compiled into the scheduler. The APIs
|
||||
allow most scheduling features to be implemented as plugins, while keeping the
|
||||
@@ -56,16 +56,16 @@ stateful tasks.
|
||||
|
||||
{{< figure src="/images/docs/scheduling-framework-extensions.png" title="scheduling framework extension points" >}}
|
||||
|
||||
### QueueSort {#queue-sort}
|
||||
### Queue sort
|
||||
|
||||
These plugins are used to sort Pods in the scheduling queue. A queue sort plugin
|
||||
essentially provides a `Less(Pod1, Pod2)` function. Only one queue sort
|
||||
essentially will provide a "less(Pod1, Pod2)" function. Only one queue sort
|
||||
plugin may be enabled at a time.
|
||||
|
||||
### PreFilter {#pre-filter}
|
||||
### Pre-filter
|
||||
|
||||
These plugins are used to pre-process info about the Pod, or to check certain
|
||||
conditions that the cluster or the Pod must meet. If a PreFilter plugin returns
|
||||
conditions that the cluster or the Pod must meet. If a pre-filter plugin returns
|
||||
an error, the scheduling cycle is aborted.
|
||||
|
||||
### Filter
|
||||
@@ -75,25 +75,28 @@ node, the scheduler will call filter plugins in their configured order. If any
|
||||
filter plugin marks the node as infeasible, the remaining plugins will not be
|
||||
called for that node. Nodes may be evaluated concurrently.
|
||||
|
||||
### PreScore {#pre-score}
|
||||
### Post-filter
|
||||
|
||||
These plugins are used to perform "pre-scoring" work, which generates a sharable
|
||||
state for Score plugins to use. If a PreScore plugin returns an error, the
|
||||
scheduling cycle is aborted.
|
||||
This is an informational extension point. Plugins will be called with a list of
|
||||
nodes that passed the filtering phase. A plugin may use this data to update
|
||||
internal state or to generate logs/metrics.
|
||||
|
||||
### Score {#scoring}
|
||||
**Note:** Plugins wishing to perform "pre-scoring" work should use the
|
||||
post-filter extension point.
|
||||
|
||||
### Scoring
|
||||
|
||||
These plugins are used to rank nodes that have passed the filtering phase. The
|
||||
scheduler will call each scoring plugin for each node. There will be a well
|
||||
defined range of integers representing the minimum and maximum scores. After the
|
||||
[NormalizeScore](#normalize-scoring) phase, the scheduler will combine node
|
||||
[normalize scoring](#normalize-scoring) phase, the scheduler will combine node
|
||||
scores from all plugins according to the configured plugin weights.
|
||||
|
||||
### NormalizeScore {#normalize-scoring}
|
||||
### Normalize scoring
|
||||
|
||||
These plugins are used to modify scores before the scheduler computes a final
|
||||
ranking of Nodes. A plugin that registers for this extension point will be
|
||||
called with the [Score](#scoring) results from the same plugin. This is called
|
||||
called with the [scoring](#scoring) results from the same plugin. This is called
|
||||
once per plugin per scheduling cycle.
|
||||
|
||||
For example, suppose a plugin `BlinkingLightScorer` ranks Nodes based on how
|
||||
@@ -101,7 +104,7 @@ many blinking lights they have.
|
||||
|
||||
```go
|
||||
func ScoreNode(_ *v1.pod, n *v1.Node) (int, error) {
|
||||
return getBlinkingLightCount(n)
|
||||
return getBlinkingLightCount(n)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -111,23 +114,21 @@ extension point.
|
||||
|
||||
```go
|
||||
func NormalizeScores(scores map[string]int) {
|
||||
highest := 0
|
||||
for _, score := range scores {
|
||||
highest = max(highest, score)
|
||||
}
|
||||
for node, score := range scores {
|
||||
scores[node] = score*NodeScoreMax/highest
|
||||
}
|
||||
highest := 0
|
||||
for _, score := range scores {
|
||||
highest = max(highest, score)
|
||||
}
|
||||
for node, score := range scores {
|
||||
scores[node] = score*NodeScoreMax/highest
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If any NormalizeScore plugin returns an error, the scheduling cycle is
|
||||
If any normalize-scoring plugin returns an error, the scheduling cycle is
|
||||
aborted.
|
||||
|
||||
{{< note >}}
|
||||
Plugins wishing to perform "pre-reserve" work should use the
|
||||
NormalizeScore extension point.
|
||||
{{< /note >}}
|
||||
**Note:** Plugins wishing to perform "pre-reserve" work should use the
|
||||
normalize-scoring extension point.
|
||||
|
||||
### Reserve
|
||||
|
||||
@@ -139,53 +140,53 @@ to prevent race conditions while the scheduler waits for the bind to succeed.
|
||||
|
||||
This is the last step in a scheduling cycle. Once a Pod is in the reserved
|
||||
state, it will either trigger [Unreserve](#unreserve) plugins (on failure) or
|
||||
[PostBind](#post-bind) plugins (on success) at the end of the binding cycle.
|
||||
[Post-bind](#post-bind) plugins (on success) at the end of the binding cycle.
|
||||
|
||||
*Note: This concept used to be referred to as "assume".*
|
||||
|
||||
### Permit
|
||||
|
||||
_Permit_ plugins are invoked at the end of the scheduling cycle for each Pod, to
|
||||
prevent or delay the binding to the candidate node. A permit plugin can do one of
|
||||
the three things:
|
||||
These plugins are used to prevent or delay the binding of a Pod. A permit plugin
|
||||
can do one of three things.
|
||||
|
||||
1. **approve** \
|
||||
Once all Permit plugins approve a Pod, it is sent for binding.
|
||||
Once all permit plugins approve a Pod, it is sent for binding.
|
||||
|
||||
1. **deny** \
|
||||
If any Permit plugin denies a Pod, it is returned to the scheduling queue.
|
||||
If any permit plugin denies a Pod, it is returned to the scheduling queue.
|
||||
This will trigger [Unreserve](#unreserve) plugins.
|
||||
|
||||
1. **wait** (with a timeout) \
|
||||
If a Permit plugin returns "wait", then the Pod is kept in an internal "waiting"
|
||||
Pods list, and the binding cycle of this Pod starts but directly blocks until it
|
||||
gets [approved](#frameworkhandle). If a timeout occurs, **wait** becomes **deny**
|
||||
and the Pod is returned to the scheduling queue, triggering [Unreserve](#unreserve)
|
||||
plugins.
|
||||
If a permit plugin returns "wait", then the Pod is kept in the permit phase
|
||||
until a [plugin approves it](#frameworkhandle). If a timeout occurs, **wait**
|
||||
becomes **deny** and the Pod is returned to the scheduling queue, triggering
|
||||
[Unreserve](#unreserve) plugins.
|
||||
|
||||
{{< note >}}
|
||||
While any plugin can access the list of "waiting" Pods and approve them
|
||||
(see [`FrameworkHandle`](#frameworkhandle)), we expect only the permit
|
||||
plugins to approve binding of reserved Pods that are in "waiting" state. Once a Pod
|
||||
is approved, it is sent to the [PreBind](#pre-bind) phase.
|
||||
{{< /note >}}
|
||||
**Approving a Pod binding**
|
||||
|
||||
### PreBind {#pre-bind}
|
||||
While any plugin can access the list of "waiting" Pods from the cache and
|
||||
approve them (see [`FrameworkHandle`](#frameworkhandle)) we expect only the permit
|
||||
plugins to approve binding of reserved Pods that are in "waiting" state. Once a
|
||||
Pod is approved, it is sent to the pre-bind phase.
|
||||
|
||||
### Pre-bind
|
||||
|
||||
These plugins are used to perform any work required before a Pod is bound. For
|
||||
example, a pre-bind plugin may provision a network volume and mount it on the
|
||||
target node before allowing the Pod to run there.
|
||||
|
||||
If any PreBind plugin returns an error, the Pod is [rejected](#unreserve) and
|
||||
If any pre-bind plugin returns an error, the Pod is [rejected](#unreserve) and
|
||||
returned to the scheduling queue.
|
||||
|
||||
### Bind
|
||||
|
||||
These plugins are used to bind a Pod to a Node. Bind plugins will not be called
|
||||
until all PreBind plugins have completed. Each bind plugin is called in the
|
||||
until all pre-bind plugins have completed. Each bind plugin is called in the
|
||||
configured order. A bind plugin may choose whether or not to handle the given
|
||||
Pod. If a bind plugin chooses to handle a Pod, **the remaining bind plugins are
|
||||
skipped**.
|
||||
|
||||
### PostBind {#post-bind}
|
||||
### Post-bind
|
||||
|
||||
This is an informational extension point. Post-bind plugins are called after a
|
||||
Pod is successfully bound. This is the end of a binding cycle, and can be used
|
||||
@@ -208,35 +209,88 @@ interfaces have the following form.
|
||||
|
||||
```go
|
||||
type Plugin interface {
|
||||
Name() string
|
||||
Name() string
|
||||
}
|
||||
|
||||
type QueueSortPlugin interface {
|
||||
Plugin
|
||||
Less(*v1.pod, *v1.pod) bool
|
||||
Plugin
|
||||
Less(*v1.pod, *v1.pod) bool
|
||||
}
|
||||
|
||||
type PreFilterPlugin interface {
|
||||
Plugin
|
||||
PreFilter(context.Context, *framework.CycleState, *v1.pod) error
|
||||
Plugin
|
||||
PreFilter(PluginContext, *v1.pod) error
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
## Plugin configuration
|
||||
# Plugin Configuration
|
||||
|
||||
You can enable or disable plugins in the scheduler configuration. If you are using
|
||||
Kubernetes v1.18 or later, most scheduling
|
||||
[plugins](/docs/reference/scheduling/profiles/#scheduling-plugins) are in use and
|
||||
enabled by default.
|
||||
Plugins can be enabled in the scheduler configuration. Also, default plugins can
|
||||
be disabled in the configuration. In 1.15, there are no default plugins for the
|
||||
scheduling framework.
|
||||
|
||||
In addition to default plugins, you can also implement your own scheduling
|
||||
plugins and get them configured along with default plugins. You can visit
|
||||
[scheduler-plugins](https://github.com/kubernetes-sigs/scheduler-plugins) for more details.
|
||||
The scheduler configuration can include configuration for plugins as well. Such
|
||||
configurations are passed to the plugins at the time the scheduler initializes
|
||||
them. The configuration is an arbitrary value. The receiving plugin should
|
||||
decode and process the configuration.
|
||||
|
||||
If you are using Kubernetes v1.18 or later, you can configure a set of plugins as
|
||||
a scheduler profile and then define multiple profiles to fit various kinds of workload.
|
||||
Learn more at [multiple profiles](/docs/reference/scheduling/profiles/#multiple-profiles).
|
||||
The following example shows a scheduler configuration that enables some
|
||||
plugins at `reserve` and `preBind` extension points and disables a plugin. It
|
||||
also provides a configuration to plugin `foo`.
|
||||
|
||||
```yaml
|
||||
apiVersion: kubescheduler.config.k8s.io/v1alpha1
|
||||
kind: KubeSchedulerConfiguration
|
||||
|
||||
...
|
||||
|
||||
plugins:
|
||||
reserve:
|
||||
enabled:
|
||||
- name: foo
|
||||
- name: bar
|
||||
disabled:
|
||||
- name: baz
|
||||
preBind:
|
||||
enabled:
|
||||
- name: foo
|
||||
disabled:
|
||||
- name: baz
|
||||
|
||||
pluginConfig:
|
||||
- name: foo
|
||||
args: >
|
||||
Arbitrary set of args to plugin foo
|
||||
```
|
||||
|
||||
When an extension point is omitted from the configuration default plugins for
|
||||
that extension points are used. When an extension point exists and `enabled` is
|
||||
provided, the `enabled` plugins are called in addition to default plugins.
|
||||
Default plugins are called first and then the additional enabled plugins are
|
||||
called in the same order specified in the configuration. If a different order of
|
||||
calling default plugins is desired, default plugins must be `disabled` and
|
||||
`enabled` in the desired order.
|
||||
|
||||
Assuming there is a default plugin called `foo` at `reserve` and we are adding
|
||||
plugin `bar` that we want to be invoked before `foo`, we should disable `foo`
|
||||
and enable `bar` and `foo` in order. The following example shows the
|
||||
configuration that achieves this:
|
||||
|
||||
```yaml
|
||||
apiVersion: kubescheduler.config.k8s.io/v1alpha1
|
||||
kind: KubeSchedulerConfiguration
|
||||
|
||||
...
|
||||
|
||||
plugins:
|
||||
reserve:
|
||||
enabled:
|
||||
- name: bar
|
||||
- name: foo
|
||||
disabled:
|
||||
- name: foo
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -73,7 +73,6 @@ A toleration "matches" a taint if the keys are the same and the effects are the
|
||||
`Operator` defaults to `Equal` if not specified.
|
||||
|
||||
{{< note >}}
|
||||
|
||||
There are two special cases:
|
||||
|
||||
* An empty `key` with operator `Exists` matches all keys, values and effects which means this
|
||||
@@ -89,9 +88,8 @@ tolerations:
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key"
|
||||
operator: "Exists"
|
||||
operator: "Exists"
|
||||
```
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
The above example used `effect` of `NoSchedule`. Alternatively, you can use `effect` of `PreferNoSchedule`.
|
||||
@@ -197,13 +195,11 @@ on the special hardware nodes. This will make sure that these special hardware
|
||||
nodes are dedicated for pods requesting such hardware and you don't have to
|
||||
manually add tolerations to your pods.
|
||||
|
||||
* **Taint based Evictions**: A per-pod-configurable eviction behavior
|
||||
* **Taint based Evictions (beta feature)**: A per-pod-configurable eviction behavior
|
||||
when there are node problems, which is described in the next section.
|
||||
|
||||
## Taint based Evictions
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
|
||||
|
||||
Earlier we mentioned the `NoExecute` taint effect, which affects pods that are already
|
||||
running on the node as follows
|
||||
|
||||
@@ -231,9 +227,9 @@ certain condition is true. The following taints are built in:
|
||||
as unusable. After a controller from the cloud-controller-manager initializes
|
||||
this node, the kubelet removes this taint.
|
||||
|
||||
In case a node is to be evicted, the node controller or the kubelet adds relevant taints
|
||||
with `NoExecute` effect. If the fault condition returns to normal the kubelet or node
|
||||
controller can remove the relevant taint(s).
|
||||
In version 1.13, the `TaintBasedEvictions` feature is promoted to beta and enabled by default, hence the taints are automatically
|
||||
added by the NodeController (or kubelet) and the normal logic for evicting pods from nodes
|
||||
based on the Ready NodeCondition is disabled.
|
||||
|
||||
{{< note >}}
|
||||
To maintain the existing [rate limiting](/docs/concepts/architecture/nodes/)
|
||||
@@ -242,7 +238,7 @@ in a rate-limited way. This prevents massive pod evictions in scenarios such
|
||||
as the master becoming partitioned from the nodes.
|
||||
{{< /note >}}
|
||||
|
||||
The feature, in combination with `tolerationSeconds`, allows a pod
|
||||
This beta feature, in combination with `tolerationSeconds`, allows a pod
|
||||
to specify how long it should stay bound to a node that has one or both of these problems.
|
||||
|
||||
For example, an application with a lot of local state might want to stay
|
||||
@@ -279,13 +275,15 @@ admission controller](https://git.k8s.io/kubernetes/plugin/pkg/admission/default
|
||||
* `node.kubernetes.io/unreachable`
|
||||
* `node.kubernetes.io/not-ready`
|
||||
|
||||
This ensures that DaemonSet pods are never evicted due to these problems.
|
||||
This ensures that DaemonSet pods are never evicted due to these problems,
|
||||
which matches the behavior when this feature is disabled.
|
||||
|
||||
## Taint Nodes by Condition
|
||||
|
||||
The node lifecycle controller automatically creates taints corresponding to
|
||||
Node conditions with `NoSchedule` effect.
|
||||
Node conditions.
|
||||
Similarly the scheduler does not check Node conditions; instead the scheduler checks taints. This assures that Node conditions don't affect what's scheduled onto the Node. The user can choose to ignore some of the Node's problems (represented as Node conditions) by adding appropriate Pod tolerations.
|
||||
Note that `TaintNodesByCondition` only taints nodes with `NoSchedule` effect. `NoExecute` effect is controlled by `TaintBasedEviction` which is a beta feature and enabled by default since version 1.13.
|
||||
|
||||
Starting in Kubernetes 1.8, the DaemonSet controller automatically adds the
|
||||
following `NoSchedule` tolerations to all daemons, to prevent DaemonSets from
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
reviewers:
|
||||
- mikedanese
|
||||
- thockin
|
||||
title: Container Environment
|
||||
title: Container Environment Variables
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
---
|
||||
@@ -116,7 +116,7 @@ Events:
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* Learn more about the [Container environment](/docs/concepts/containers/container-environment/).
|
||||
* Learn more about the [Container environment](/docs/concepts/containers/container-environment-variables/).
|
||||
* Get hands-on experience
|
||||
[attaching handlers to Container lifecycle events](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/).
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ Credentials can be provided in several ways:
|
||||
- use IAM roles and policies to control access to OCIR repositories
|
||||
- Using Azure Container Registry (ACR)
|
||||
- Using IBM Cloud Container Registry
|
||||
- use IAM roles and policies to grant access to IBM Cloud Container Registry
|
||||
- Configuring Nodes to Authenticate to a Private Registry
|
||||
- all pods can read any configured private registries
|
||||
- requires node configuration by cluster administrator
|
||||
@@ -125,9 +124,9 @@ Troubleshooting:
|
||||
- Verify all requirements above.
|
||||
- Get $REGION (e.g. `us-west-2`) credentials on your workstation. SSH into the host and run Docker manually with those creds. Does it work?
|
||||
- Verify kubelet is running with `--cloud-provider=aws`.
|
||||
- Increase kubelet log level verbosity to at least 3 and check kubelet logs (e.g. `journalctl -u kubelet`) for log lines like:
|
||||
- `aws_credentials.go:109] unable to get ECR credentials from cache, checking ECR API`
|
||||
- `aws_credentials.go:116] Got ECR credentials from ECR API for <AWS account ID for ECR>.dkr.ecr.<AWS region>.amazonaws.com`
|
||||
- Check kubelet logs (e.g. `journalctl -u kubelet`) for log lines like:
|
||||
- `plugins.go:56] Registering credential provider: aws-ecr-key`
|
||||
- `provider.go:91] Refreshing cache for provider: *aws_credentials.ecrProvider`
|
||||
|
||||
### Using Azure Container Registry (ACR)
|
||||
When using [Azure Container Registry](https://azure.microsoft.com/en-us/services/container-registry/)
|
||||
@@ -149,11 +148,11 @@ Once you have those variables filled in you can
|
||||
[configure a Kubernetes Secret and use it to deploy a Pod](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod).
|
||||
|
||||
### Using IBM Cloud Container Registry
|
||||
IBM Cloud Container Registry provides a multi-tenant private image registry that you can use to safely store and share your images. By default, images in your private registry are scanned by the integrated Vulnerability Advisor to detect security issues and potential vulnerabilities. Users in your IBM Cloud account can access your images, or you can use IAM roles and policies to grant access to IBM Cloud Container Registry namespaces.
|
||||
IBM Cloud Container Registry provides a multi-tenant private image registry that you can use to safely store and share your Docker images. By default, images in your private registry are scanned by the integrated Vulnerability Advisor to detect security issues and potential vulnerabilities. Users in your IBM Cloud account can access your images, or you can create a token to grant access to registry namespaces.
|
||||
|
||||
To install the IBM Cloud Container Registry CLI plug-in and create a namespace for your images, see [Getting started with IBM Cloud Container Registry](https://cloud.ibm.com/docs/Registry?topic=registry-getting-started).
|
||||
To install the IBM Cloud Container Registry CLI plug-in and create a namespace for your images, see [Getting started with IBM Cloud Container Registry](https://cloud.ibm.com/docs/services/Registry?topic=registry-getting-started).
|
||||
|
||||
If you are using the same account and region, you can deploy images that are stored in IBM Cloud Container Registry into the default namespace of your IBM Cloud Kubernetes Service cluster without any additional configuration, see [Building containers from images](https://cloud.ibm.com/docs/containers?topic=containers-images). For other configuration options, see [Understanding how to authorize your cluster to pull images from a registry](https://cloud.ibm.com/docs/containers?topic=containers-registry#cluster_registry_auth).
|
||||
You can use the IBM Cloud Container Registry to deploy containers from [IBM Cloud public images](https://cloud.ibm.com/docs/services/Registry?topic=registry-public_images) and your private images into the `default` namespace of your IBM Cloud Kubernetes Service cluster. To deploy a container into other namespaces, or to use an image from a different IBM Cloud Container Registry region or IBM Cloud account, create a Kubernetes `imagePullSecret`. For more information, see [Building containers from images](https://cloud.ibm.com/docs/containers?topic=containers-images).
|
||||
|
||||
### Configuring Nodes to Authenticate to a Private Registry
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- thockin
|
||||
title: Containers overview
|
||||
content_template: templates/concept
|
||||
weight: 1
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
Containers are a technnology for packaging the (compiled) code for an
|
||||
application along with the dependencies it needs at run time. Each
|
||||
container that you run is repeatable; the standardisation from having
|
||||
dependencies included means that you get the same behavior wherever you
|
||||
run it.
|
||||
|
||||
Containers decouple applications from underlying host infrastructure.
|
||||
This makes deployment easier in different cloud or OS environments.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Container images
|
||||
A [container image](/docs/concepts/containers/images/) is a ready-to-run
|
||||
software package, containing everything needed to run an application:
|
||||
the code and any runtime it requires, application and system libraries,
|
||||
and default values for any essential settings.
|
||||
|
||||
By design, a container is immutable: you cannot change the code of a
|
||||
container that is already running. If you have a containerized application
|
||||
and want to make changes, you need to build a new container that includes
|
||||
the change, then recreate the container to start from the updated image.
|
||||
|
||||
## Container runtimes
|
||||
|
||||
{{< glossary_definition term_id="container-runtime" length="all" >}}
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
* Read about [container images](/docs/concepts/containers/images/)
|
||||
* Read about [Pods](/docs/concepts/workloads/pods/)
|
||||
{{% /capture %}}
|
||||
@@ -13,14 +13,22 @@ weight: 20
|
||||
|
||||
This page describes the RuntimeClass resource and runtime selection mechanism.
|
||||
|
||||
RuntimeClass is a feature for selecting the container runtime configuration. The container runtime
|
||||
configuration is used to run a Pod's containers.
|
||||
{{< warning >}}
|
||||
RuntimeClass includes *breaking* changes in the beta upgrade in v1.14. If you were using
|
||||
RuntimeClass prior to v1.14, see [Upgrading RuntimeClass from Alpha to
|
||||
Beta](#upgrading-runtimeclass-from-alpha-to-beta).
|
||||
{{< /warning >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Runtime Class
|
||||
|
||||
RuntimeClass is a feature for selecting the container runtime configuration. The container runtime
|
||||
configuration is used to run a Pod's containers.
|
||||
|
||||
## Motivation
|
||||
|
||||
You can set a different RuntimeClass between different Pods to provide a balance of
|
||||
@@ -33,7 +41,7 @@ additional overhead.
|
||||
You can also use RuntimeClass to run different Pods with the same container runtime
|
||||
but with different settings.
|
||||
|
||||
## Setup
|
||||
### Set Up
|
||||
|
||||
Ensure the RuntimeClass feature gate is enabled (it is by default). See [Feature
|
||||
Gates](/docs/reference/command-line-tools-reference/feature-gates/) for an explanation of enabling
|
||||
@@ -42,7 +50,7 @@ feature gates. The `RuntimeClass` feature gate must be enabled on apiservers _an
|
||||
1. Configure the CRI implementation on nodes (runtime dependent)
|
||||
2. Create the corresponding RuntimeClass resources
|
||||
|
||||
### 1. Configure the CRI implementation on nodes
|
||||
#### 1. Configure the CRI implementation on nodes
|
||||
|
||||
The configurations available through RuntimeClass are Container Runtime Interface (CRI)
|
||||
implementation dependent. See the corresponding documentation ([below](#cri-configuration)) for your
|
||||
@@ -57,7 +65,7 @@ heterogenous node configurations, see [Scheduling](#scheduling) below.
|
||||
The configurations have a corresponding `handler` name, referenced by the RuntimeClass. The
|
||||
handler must be a valid DNS 1123 label (alpha-numeric + `-` characters).
|
||||
|
||||
### 2. Create the corresponding RuntimeClass resources
|
||||
#### 2. Create the corresponding RuntimeClass resources
|
||||
|
||||
The configurations setup in step 1 should each have an associated `handler` name, which identifies
|
||||
the configuration. For each handler, create a corresponding RuntimeClass object.
|
||||
@@ -74,16 +82,13 @@ metadata:
|
||||
handler: myconfiguration # The name of the corresponding CRI configuration
|
||||
```
|
||||
|
||||
The name of a RuntimeClass object must be a valid
|
||||
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||
|
||||
{{< note >}}
|
||||
It is recommended that RuntimeClass write operations (create/update/patch/delete) be
|
||||
restricted to the cluster administrator. This is typically the default. See [Authorization
|
||||
Overview](/docs/reference/access-authn-authz/authorization/) for more details.
|
||||
{{< /note >}}
|
||||
|
||||
## Usage
|
||||
### Usage
|
||||
|
||||
Once RuntimeClasses are configured for the cluster, using them is very simple. Specify a
|
||||
`runtimeClassName` in the Pod spec. For example:
|
||||
@@ -115,7 +120,7 @@ For more details on setting up CRI runtimes, see [CRI installation](/docs/setup/
|
||||
|
||||
Kubernetes built-in dockershim CRI does not support runtime handlers.
|
||||
|
||||
#### {{< glossary_tooltip term_id="containerd" >}}
|
||||
#### [containerd](https://containerd.io/)
|
||||
|
||||
Runtime handlers are configured through containerd's configuration at
|
||||
`/etc/containerd/config.toml`. Valid handlers are configured under the runtimes section:
|
||||
@@ -127,29 +132,28 @@ Runtime handlers are configured through containerd's configuration at
|
||||
See containerd's config documentation for more details:
|
||||
https://github.com/containerd/cri/blob/master/docs/config.md
|
||||
|
||||
#### {{< glossary_tooltip term_id="cri-o" >}}
|
||||
#### [cri-o](https://cri-o.io/)
|
||||
|
||||
Runtime handlers are configured through CRI-O's configuration at `/etc/crio/crio.conf`. Valid
|
||||
Runtime handlers are configured through cri-o's configuration at `/etc/crio/crio.conf`. Valid
|
||||
handlers are configured under the [crio.runtime
|
||||
table](https://github.com/cri-o/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table):
|
||||
table](https://github.com/kubernetes-sigs/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table):
|
||||
|
||||
```
|
||||
[crio.runtime.runtimes.${HANDLER_NAME}]
|
||||
runtime_path = "${PATH_TO_BINARY}"
|
||||
```
|
||||
|
||||
See CRI-O's [config documentation][100] for more details.
|
||||
See cri-o's config documentation for more details:
|
||||
https://github.com/kubernetes-sigs/cri-o/blob/master/cmd/crio/config.go
|
||||
|
||||
[100]: https://raw.githubusercontent.com/cri-o/cri-o/9f11d1d/docs/crio.conf.5.md
|
||||
|
||||
## Scheduling
|
||||
### Scheduling
|
||||
|
||||
{{< feature-state for_k8s_version="v1.16" state="beta" >}}
|
||||
|
||||
As of Kubernetes v1.16, RuntimeClass includes support for heterogenous clusters through its
|
||||
`scheduling` fields. Through the use of these fields, you can ensure that pods running with this
|
||||
RuntimeClass are scheduled to nodes that support it. To use the scheduling support, you must have
|
||||
the [RuntimeClass admission controller][] enabled (the default, as of 1.16).
|
||||
the RuntimeClass [admission controller][] enabled (the default, as of 1.16).
|
||||
|
||||
To ensure pods land on nodes supporting a specific RuntimeClass, that set of nodes should have a
|
||||
common label which is then selected by the `runtimeclass.scheduling.nodeSelector` field. The
|
||||
@@ -165,23 +169,50 @@ by each.
|
||||
To learn more about configuring the node selector and tolerations, see [Assigning Pods to
|
||||
Nodes](/docs/concepts/configuration/assign-pod-node/).
|
||||
|
||||
[RuntimeClass admission controller]: /docs/reference/access-authn-authz/admission-controllers/#runtimeclass
|
||||
[admission controller]: /docs/reference/access-authn-authz/admission-controllers/
|
||||
|
||||
### Pod Overhead
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
|
||||
|
||||
You can specify _overhead_ resources that are associated with running a Pod. Declaring overhead allows
|
||||
the cluster (including the scheduler) to account for it when making decisions about Pods and resources.
|
||||
To use Pod overhead, you must have the PodOverhead [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
enabled (it is on by default).
|
||||
As of Kubernetes v1.16, RuntimeClass includes support for specifying overhead associated with
|
||||
running a pod, as part of the [`PodOverhead`](/docs/concepts/configuration/pod-overhead/) feature.
|
||||
To use `PodOverhead`, you must have the PodOverhead [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
enabled (it is off by default).
|
||||
|
||||
Pod overhead is defined in RuntimeClass through the `overhead` fields. Through the use of these fields,
|
||||
|
||||
Pod overhead is defined in RuntimeClass through the `Overhead` fields. Through the use of these fields,
|
||||
you can specify the overhead of running pods utilizing this RuntimeClass and ensure these overheads
|
||||
are accounted for in Kubernetes.
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
### Upgrading RuntimeClass from Alpha to Beta
|
||||
|
||||
The RuntimeClass Beta feature includes the following changes:
|
||||
|
||||
- The `node.k8s.io` API group and `runtimeclasses.node.k8s.io` resource have been migrated to a
|
||||
built-in API from a CustomResourceDefinition.
|
||||
- The `spec` has been inlined in the RuntimeClass definition (i.e. there is no more
|
||||
RuntimeClassSpec).
|
||||
- The `runtimeHandler` field has been renamed `handler`.
|
||||
- The `handler` field is now required in all API versions. This means the `runtimeHandler` field in
|
||||
the Alpha API is also required.
|
||||
- The `handler` field must be a valid DNS label ([RFC 1123](https://tools.ietf.org/html/rfc1123)),
|
||||
meaning it can no longer contain `.` characters (in all versions). Valid handlers match the
|
||||
following regular expression: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`.
|
||||
|
||||
**Action Required:** The following actions are required to upgrade from the alpha version of the
|
||||
RuntimeClass feature to the beta version:
|
||||
|
||||
- RuntimeClass resources must be recreated *after* upgrading to v1.14, and the
|
||||
`runtimeclasses.node.k8s.io` CRD should be manually deleted:
|
||||
```
|
||||
kubectl delete customresourcedefinitions.apiextensions.k8s.io runtimeclasses.node.k8s.io
|
||||
```
|
||||
- Alpha RuntimeClasses with an unspecified or empty `runtimeHandler` or those using a `.` character
|
||||
in the handler are no longer valid, and must be migrated to a valid handler configuration (see
|
||||
above).
|
||||
|
||||
### Further Reading
|
||||
|
||||
- [RuntimeClass Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class.md)
|
||||
- [RuntimeClass Scheduling Design](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class-scheduling.md)
|
||||
|
||||
@@ -5,34 +5,30 @@ reviewers:
|
||||
- cheftako
|
||||
- chenopis
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
The aggregation layer allows Kubernetes to be extended with additional APIs, beyond what is offered by the core Kubernetes APIs.
|
||||
The additional APIs can either be ready-made solutions such as [service-catalog](/docs/concepts/extend-kubernetes/service-catalog/), or APIs that you develop yourself.
|
||||
|
||||
The aggregation layer is different from [Custom Resources](/docs/concepts/extend-kubernetes/api-extension/custom-resources/), which are a way to make the {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver" >}} recognise new kinds of object.
|
||||
The aggregation layer allows Kubernetes to be extended with additional APIs, beyond what is offered by the core Kubernetes APIs.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## Aggregation layer
|
||||
## Overview
|
||||
|
||||
The aggregation layer runs in-process with the kube-apiserver. Until an extension resource is registered, the aggregation layer will do nothing. To register an API, you add an _APIService_ object, which "claims" the URL path in the Kubernetes API. At that point, the aggregation layer will proxy anything sent to that API path (e.g. `/apis/myextension.mycompany.io/v1/…`) to the registered APIService.
|
||||
The aggregation layer enables installing additional Kubernetes-style APIs in your cluster. These can either be pre-built, existing 3rd party solutions, such as [service-catalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/README.md), or user-created APIs like [apiserver-builder](https://github.com/kubernetes-incubator/apiserver-builder/blob/master/README.md), which can get you started.
|
||||
|
||||
The most common way to implement the APIService is to run an *extension API server* in Pod(s) that run in your cluster. If you're using the extension API server to manage resources in your cluster, the extension API server (also written as "extension-apiserver") is typically paired with one or more {{< glossary_tooltip text="controllers" term_id="controller" >}}. The apiserver-builder library provides a skeleton for both extension API servers and the associated controller(s).
|
||||
The aggregation layer runs in-process with the kube-apiserver. Until an extension resource is registered, the aggregation layer will do nothing. To register an API, users must add an APIService object, which "claims" the URL path in the Kubernetes API. At that point, the aggregation layer will proxy anything sent to that API path (e.g. /apis/myextension.mycompany.io/v1/…) to the registered APIService.
|
||||
|
||||
### Response latency
|
||||
Ordinarily, the APIService will be implemented by an *extension-apiserver* in a pod running in the cluster. This extension-apiserver will normally need to be paired with one or more controllers if active management of the added resources is needed. As a result, the apiserver-builder will actually provide a skeleton for both. As another example, when the service-catalog is installed, it provides both the extension-apiserver and controller for the services it provides.
|
||||
|
||||
Extension API servers should have low latency networking to and from the kube-apiserver.
|
||||
Discovery requests are required to round-trip from the kube-apiserver in five seconds or less.
|
||||
|
||||
If your extension API server cannot achieve that latency requirement, consider making changes that let you meet it. You can also set the
|
||||
`EnableAggregatedDiscoveryTimeout=false` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) on the kube-apiserver
|
||||
to disable the timeout restriction. This deprecated feature gate will be removed in a future release.
|
||||
Extension-apiservers should have low latency connections to and from the kube-apiserver.
|
||||
In particular, discovery requests are required to round-trip from the kube-apiserver in five seconds or less.
|
||||
If your deployment cannot achieve this, you should consider how to change it. For now, setting the
|
||||
`EnableAggregatedDiscoveryTimeout=false` feature gate on the kube-apiserver
|
||||
will disable the timeout restriction. It will be removed in a future release.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -41,6 +37,7 @@ to disable the timeout restriction. This deprecated feature gate will be removed
|
||||
* To get the aggregator working in your environment, [configure the aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/).
|
||||
* Then, [setup an extension api-server](/docs/tasks/access-kubernetes-api/setup-extension-api-server/) to work with the aggregation layer.
|
||||
* Also, learn how to [extend the Kubernetes API using Custom Resource Definitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
|
||||
* Read the specification for [APIService](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#apiservice-v1-apiregistration-k8s-io)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ reviewers:
|
||||
- enisoc
|
||||
- deads2k
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
weight: 20
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
@@ -37,14 +37,14 @@ On their own, custom resources simply let you store and retrieve structured data
|
||||
When you combine a custom resource with a *custom controller*, custom resources
|
||||
provide a true _declarative API_.
|
||||
|
||||
A [declarative API](/docs/concepts/overview/kubernetes-api/)
|
||||
A [declarative API](/docs/concepts/overview/working-with-objects/kubernetes-objects/#understanding-kubernetes-objects)
|
||||
allows you to _declare_ or specify the desired state of your resource and tries to
|
||||
keep the current state of Kubernetes objects in sync with the desired state.
|
||||
The controller interprets the structured data as a record of the user's
|
||||
desired state, and continually maintains this state.
|
||||
|
||||
You can deploy and update a custom controller on a running cluster, independently
|
||||
of the cluster's lifecycle. Custom controllers can work with any kind of resource,
|
||||
of the cluster's own lifecycle. Custom controllers can work with any kind of resource,
|
||||
but they are especially effective when combined with custom resources. The
|
||||
[Operator pattern](https://coreos.com/blog/introducing-operators.html) combines custom
|
||||
resources and custom controllers. You can use custom controllers to encode domain knowledge
|
||||
@@ -61,7 +61,7 @@ When creating a new API, consider whether to [aggregate your API with the Kubern
|
||||
| You want to view your new types in a Kubernetes UI, such as dashboard, alongside built-in types. | Kubernetes UI support is not required. |
|
||||
| You are developing a new API. | You already have a program that serves your API and works well. |
|
||||
| You are willing to accept the format restriction that Kubernetes puts on REST resource paths, such as API Groups and Namespaces. (See the [API Overview](/docs/concepts/overview/kubernetes-api/).) | You need to have specific REST paths to be compatible with an already defined REST API. |
|
||||
| Your resources are naturally scoped to a cluster or namespaces of a cluster. | Cluster or namespace scoped resources are a poor fit; you need control over the specifics of resource paths. |
|
||||
| Your resources are naturally scoped to a cluster or to namespaces of a cluster. | Cluster or namespace scoped resources are a poor fit; you need control over the specifics of resource paths. |
|
||||
| You want to reuse [Kubernetes API support features](#common-features). | You don't need those features. |
|
||||
|
||||
### Declarative APIs
|
||||
@@ -83,7 +83,7 @@ Signs that your API might not be declarative include:
|
||||
- You talk about Remote Procedure Calls (RPCs).
|
||||
- Directly storing large amounts of data (e.g. > a few kB per object, or >1000s of objects).
|
||||
- High bandwidth access (10s of requests per second sustained) needed.
|
||||
- Store end-user data (such as images, PII, etc.) or other large-scale data processed by applications.
|
||||
- Store end-user data (such as images, PII, etc) or other large-scale data processed by applications.
|
||||
- The natural operations on the objects are not CRUD-y.
|
||||
- The API is not easily modeled as objects.
|
||||
- You chose to represent pending operations with an operation ID or an operation object.
|
||||
@@ -96,7 +96,7 @@ Use a ConfigMap if any of the following apply:
|
||||
* You want to put the entire config file into one key of a configMap.
|
||||
* The main use of the config file is for a program running in a Pod on your cluster to consume the file to configure itself.
|
||||
* Consumers of the file prefer to consume via file in a Pod or environment variable in a pod, rather than the Kubernetes API.
|
||||
* You want to perform rolling updates via Deployment, etc., when the file is updated.
|
||||
* You want to perform rolling updates via Deployment, etc, when the file is updated.
|
||||
|
||||
{{< note >}}
|
||||
Use a [secret](/docs/concepts/configuration/secret/) for sensitive data, which is similar to a configMap but more secure.
|
||||
@@ -128,12 +128,7 @@ Regardless of how they are installed, the new resources are referred to as Custo
|
||||
|
||||
## CustomResourceDefinitions
|
||||
|
||||
The [CustomResourceDefinition](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/)
|
||||
API resource allows you to define custom resources.
|
||||
Defining a CRD object creates a new custom resource with a name and schema that you specify.
|
||||
The Kubernetes API serves and handles the storage of your custom resource.
|
||||
The name of a CRD object must be a valid
|
||||
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||
The [CustomResourceDefinition](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/) API resource allows you to define custom resources. Defining a CRD object creates a new custom resource with a name and schema that you specify. The Kubernetes API serves and handles the storage of your custom resource.
|
||||
|
||||
This frees you from writing your own API server to handle the custom resource,
|
||||
but the generic nature of the implementation means you have less flexibility than with
|
||||
@@ -145,7 +140,7 @@ and use a controller to handle events.
|
||||
|
||||
## API server aggregation
|
||||
|
||||
Usually, each resource in the Kubernetes API requires code that handles REST requests and manages persistent storage of objects. The main Kubernetes API server handles built-in resources like *pods* and *services*, and can also generically handle custom resources through [CRDs](#customresourcedefinitions).
|
||||
Usually, each resource in the Kubernetes API requires code that handles REST requests and manages persistent storage of objects. The main Kubernetes API server handles built-in resources like *pods* and *services*, and can also handle custom resources in a generic way through [CRDs](#customresourcedefinitions).
|
||||
|
||||
The [aggregation layer](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) allows you to provide specialized
|
||||
implementations for your custom resources by writing and deploying your own standalone API server.
|
||||
@@ -167,7 +162,7 @@ CRDs are easier to create than Aggregated APIs.
|
||||
|
||||
| CRDs | Aggregated API |
|
||||
| --------------------------- | -------------- |
|
||||
| Do not require programming. Users can choose any language for a CRD controller. | Requires programming in Go and building binary and image. |
|
||||
| Do not require programming. Users can choose any language for a CRD controller. | Requires programming in Go and building binary and image. Users can choose any language for a CRD controller. |
|
||||
| No additional service to run; CRs are handled by API Server. | An additional service to create and that could fail. |
|
||||
| No ongoing support once the CRD is created. Any bug fixes are picked up as part of normal Kubernetes Master upgrades. | May need to periodically pickup bug fixes from upstream and rebuild and update the Aggregated APIserver. |
|
||||
| No need to handle multiple versions of your API. For example: when you control the client for this resource, you can upgrade it in sync with the API. | You need to handle multiple versions of your API, for example: when developing an extension to share with the world. |
|
||||
@@ -184,7 +179,7 @@ Aggregated APIs offer more advanced API features and customization of other feat
|
||||
| Custom Storage | If you need storage with a different performance mode (for example, time-series database instead of key-value store) or isolation for security (for example, encryption secrets or different | No | Yes |
|
||||
| Custom Business Logic | Perform arbitrary checks or actions when creating, reading, updating or deleting an object | Yes, using [Webhooks](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks). | Yes |
|
||||
| Scale Subresource | Allows systems like HorizontalPodAutoscaler and PodDisruptionBudget interact with your new resource | [Yes](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#scale-subresource) | Yes |
|
||||
| Status Subresource | Allows fine-grained access control where user writes the spec section and the controller writes the status section. Allows incrementing object Generation on custom resource data mutation (requires separate spec and status sections in the resource) | [Yes](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#status-subresource) | Yes |
|
||||
| Status Subresource | <ul><li>Finer-grained access control: user writes spec section, controller writes status section.</li><li>Allows incrementing object Generation on custom resource data mutation (requires separate spec and status sections in the resource)</li></ul> | [Yes](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#status-subresource) | Yes |
|
||||
| Other Subresources | Add operations other than CRUD, such as "logs" or "exec". | No | Yes |
|
||||
| strategic-merge-patch | The new endpoints support PATCH with `Content-Type: application/strategic-merge-patch+json`. Useful for updating objects that may be modified both locally, and by the server. For more information, see ["Update API Objects in Place Using kubectl patch"](/docs/tasks/run-application/update-api-object-kubectl-patch/) | No | Yes |
|
||||
| Protocol Buffers | The new resource supports clients that want to use Protocol Buffers | No | Yes |
|
||||
@@ -207,7 +202,7 @@ When you create a custom resource, either via a CRDs or an AA, you get many feat
|
||||
| Finalizers | Block deletion of extension resources until external cleanup happens. |
|
||||
| Admission Webhooks | Set default values and validate extension resources during any create/update/delete operation. |
|
||||
| UI/CLI Display | Kubectl, dashboard can display extension resources. |
|
||||
| Unset versus Empty | Clients can distinguish unset fields from zero-valued fields. |
|
||||
| Unset vs Empty | Clients can distinguish unset fields from zero-valued fields. |
|
||||
| Client Libraries Generation | Kubernetes provides generic client libraries, as well as tools to generate type-specific client libraries. |
|
||||
| Labels and annotations | Common metadata across objects that tools know how to edit for core and custom resources. |
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ weight: 10
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state state="alpha" >}}
|
||||
{{< caution >}}Alpha features can change rapidly. {{< /caution >}}
|
||||
{{< warning >}}Alpha features change rapidly. {{< /warning >}}
|
||||
|
||||
Network plugins in Kubernetes come in a few flavors:
|
||||
|
||||
@@ -154,7 +154,7 @@ most network plugins.
|
||||
|
||||
Where needed, you can specify the MTU explicitly with the `network-plugin-mtu` kubelet option. For example,
|
||||
on AWS the `eth0` MTU is typically 9001, so you might specify `--network-plugin-mtu=9001`. If you're using IPSEC you
|
||||
might reduce it to allow for encapsulation overhead; for example: `--network-plugin-mtu=8873`.
|
||||
might reduce it to allow for encapsulation overhead e.g. `--network-plugin-mtu=8873`.
|
||||
|
||||
This option is provided to the network-plugin; currently **only kubenet supports `network-plugin-mtu`**.
|
||||
|
||||
|
||||
+61
-55
@@ -1,111 +1,117 @@
|
||||
---
|
||||
title: Poseidon-Firmament Scheduler
|
||||
title: Poseidon-Firmament - An alternate scheduler
|
||||
content_template: templates/concept
|
||||
weight: 80
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.6" state="alpha" >}}
|
||||
**Current release of Poseidon-Firmament scheduler is an <code> alpha </code> release.**
|
||||
|
||||
The Poseidon-Firmament scheduler is an alternate scheduler that can be deployed alongside the default Kubernetes scheduler.
|
||||
Poseidon-Firmament scheduler is an alternate scheduler that can be deployed alongside the default Kubernetes scheduler.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
|
||||
## Introduction
|
||||
## Introduction
|
||||
|
||||
Poseidon is a service that acts as the integration glue between the [Firmament scheduler](https://github.com/Huawei-PaaS/firmament) and Kubernetes. Poseidon-Firmament augments the current Kubernetes scheduling capabilities. It incorporates novel flow network graph based scheduling capabilities alongside the default Kubernetes scheduler. The Firmament scheduler models workloads and clusters as flow networks and runs min-cost flow optimizations over these networks to make scheduling decisions.
|
||||
Poseidon is a service that acts as the integration glue for the [Firmament scheduler](https://github.com/Huawei-PaaS/firmament) with Kubernetes. Poseidon-Firmament scheduler augments the current Kubernetes scheduling capabilities. It incorporates novel flow network graph based scheduling capabilities alongside the default Kubernetes Scheduler. Firmament scheduler models workloads and clusters as flow networks and runs min-cost flow optimizations over these networks to make scheduling decisions.
|
||||
|
||||
Firmament models the scheduling problem as a constraint-based optimization over a flow network graph. This is achieved by reducing scheduling to a min-cost max-flow optimization problem. The Poseidon-Firmament scheduler dynamically refines the workload placements.
|
||||
It models the scheduling problem as a constraint-based optimization over a flow network graph. This is achieved by reducing scheduling to a min-cost max-flow optimization problem. The Poseidon-Firmament scheduler dynamically refines the workload placements.
|
||||
|
||||
Poseidon-Firmament scheduler runs alongside the default Kubernetes scheduler as an alternate scheduler. You can simultaneously run multiple, different schedulers.
|
||||
Poseidon-Firmament scheduler runs alongside the default Kubernetes Scheduler as an alternate scheduler, so multiple schedulers run simultaneously.
|
||||
|
||||
Flow graph scheduling with the Poseidon-Firmament scheduler provides the following advantages:
|
||||
## Key Advantages
|
||||
|
||||
- Workloads (Pods) are bulk scheduled to enable scheduling at massive scale.
|
||||
The Poseidon-Firmament scheduler outperforms the Kubernetes default scheduler by a wide margin when it comes to throughput performance for scenarios where compute resource requirements are somewhat uniform across your workload (Deployments, ReplicaSets, Jobs).
|
||||
- The Poseidon-Firmament's scheduler's end-to-end throughput performance and bind time improves as the number of nodes in a cluster increases. As you scale out, Poseidon-Firmament scheduler is able to amortize more and more work across workloads.
|
||||
- Scheduling in Poseidon-Firmament is dynamic; it keeps cluster resources in a global optimal state during every scheduling run.
|
||||
- The Poseidon-Firmament scheduler supports scheduling complex rule constraints.
|
||||
### Flow graph scheduling based Poseidon-Firmament scheduler provides the following key advantages:
|
||||
- Workloads (pods) are bulk scheduled to enable scheduling at massive scale..
|
||||
- Based on the extensive performance test results, Poseidon-Firmament scales much better than the Kubernetes default scheduler as the number of nodes increase in a cluster. This is due to the fact that Poseidon-Firmament is able to amortize more and more work across workloads.
|
||||
- Poseidon-Firmament Scheduler outperforms the Kubernetes default scheduler by a wide margin when it comes to throughput performance numbers for scenarios where compute resource requirements are somewhat uniform across jobs (Replicasets/Deployments/Jobs). Poseidon-Firmament scheduler end-to-end throughput performance numbers, including bind time, consistently get better as the number of nodes in a cluster increase. For example, for a 2,700 node cluster (shown in the graphs [here](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/benchmark/README.md)), Poseidon-Firmament scheduler achieves a 7X or greater end-to-end throughput than the Kubernetes default scheduler, which includes bind time.
|
||||
|
||||
## How the Poseidon-Firmament scheduler works
|
||||
- Availability of complex rule constraints.
|
||||
- Scheduling in Poseidon-Firmament is dynamic; it keeps cluster resources in a global optimal state during every scheduling run.
|
||||
- Highly efficient resource utilizations.
|
||||
|
||||
Kubernetes supports [using multiple schedulers](/docs/tasks/administer-cluster/configure-multiple-schedulers/). You can specify, for a particular Pod, that it is scheduled by a custom scheduler (“poseidon” for this case), by setting the `schedulerName` field in the PodSpec at the time of pod creation. The default scheduler will ignore that Pod and allow Poseidon-Firmament scheduler to schedule the Pod on a relevant node.
|
||||
## Poseidon-Firmament Scheduler - How it works
|
||||
|
||||
For example:
|
||||
As part of the Kubernetes multiple schedulers support, each new pod is typically scheduled by the default scheduler. Kubernetes can be instructed to use another scheduler by specifying the name of another custom scheduler (“poseidon” in our case) in the **schedulerName** field of the PodSpec at the time of pod creation. In this case, the default scheduler will ignore that Pod and allow Poseidon scheduler to schedule the Pod on a relevant node.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
|
||||
...
|
||||
spec:
|
||||
schedulerName: poseidon
|
||||
...
|
||||
```
|
||||
schedulerName: poseidon
|
||||
```
|
||||
|
||||
## Batch scheduling
|
||||
|
||||
{{< note >}}
|
||||
For details about the design of this project see the [design document](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/design/README.md).
|
||||
{{< /note >}}
|
||||
|
||||
## Possible Use Case Scenarios - When to use it
|
||||
|
||||
As mentioned earlier, Poseidon-Firmament scheduler enables an extremely high throughput scheduling environment at scale due to its bulk scheduling approach versus Kubernetes pod-at-a-time approach. In our extensive tests, we have observed substantial throughput benefits as long as resource requirements (CPU/Memory) for incoming Pods are uniform across jobs (Replicasets/Deployments/Jobs), mainly due to efficient amortization of work across jobs.
|
||||
|
||||
Although, Poseidon-Firmament scheduler is capable of scheduling various types of workloads, such as service, batch, etc., the following are a few use cases where it excels the most:
|
||||
|
||||
1. For “Big Data/AI” jobs consisting of large number of tasks, throughput benefits are tremendous.
|
||||
2. Service or batch jobs where workload resource requirements are uniform across jobs (Replicasets/Deployments/Jobs).
|
||||
1. For “Big Data/AI” jobs consisting of large number of tasks, throughput benefits are tremendous.
|
||||
2. Service or batch jobs where workload resource requirements are uniform across jobs (Replicasets/Deployments/Jobs).
|
||||
|
||||
## Feature state
|
||||
## Current Project Stage
|
||||
|
||||
Poseidon-Firmament is designed to work with Kubernetes release 1.6 and all subsequent releases.
|
||||
- **Alpha Release - Incubation repo.** at https://github.com/kubernetes-sigs/poseidon.
|
||||
- Currently, Poseidon-Firmament scheduler **does not provide support for high availability**, our implementation assumes that the scheduler cannot fail. The [design document](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/design/README.md) describes possible ways to enable high availability, but we leave this to future work.
|
||||
- We are **not aware of any production deployment** of Poseidon-Firmament scheduler at this time.
|
||||
- Poseidon-Firmament is supported from Kubernetes release 1.6 and works with all subsequent releases.
|
||||
- Release process for Poseidon and Firmament repos are in lock step. The current Poseidon release can be found [here](https://github.com/kubernetes-sigs/poseidon/releases) and the corresponding Firmament release can be found [here](https://github.com/Huawei-PaaS/firmament/releases).
|
||||
|
||||
{{< caution >}}
|
||||
Poseidon-Firmament scheduler does not provide support for high availability; its implementation assumes that the scheduler cannot fail.
|
||||
{{< /caution >}}
|
||||
## Features Comparison Matrix
|
||||
|
||||
## Feature comparison {#feature-comparison-matrix}
|
||||
|
||||
{{< table caption="Feature comparison of Kubernetes and Poseidon-Firmament schedulers." >}}
|
||||
|Feature|Kubernetes Default Scheduler|Poseidon-Firmament Scheduler|Notes|
|
||||
|--- |--- |--- |--- |
|
||||
|Node Affinity/Anti-Affinity|Y|Y||
|
||||
|Pod Affinity/Anti-Affinity - including support for pod anti-affinity symmetry|Y|Y|The default scheduler outperforms the Poseidon-Firmament scheduler pod affinity/anti-affinity functionality.|
|
||||
|Pod Affinity/Anti-Affinity - including support for pod anti-affinity symmetry|Y|Y|Currently, the default scheduler outperforms the Poseidon-Firmament scheduler pod affinity/anti-affinity functionality. We are working towards resolving this.|
|
||||
|Taints & Tolerations|Y|Y||
|
||||
|Baseline Scheduling capability in accordance to available compute resources (CPU & Memory) on a node|Y|Y†|**†** Not all Predicates & Priorities are supported with Poseidon-Firmament.|
|
||||
|Extreme Throughput at scale|Y†|Y|**†** Bulk scheduling approach scales or increases workload placement. Firmament scheduler offers high throughput when resource requirements (CPU/Memory) for incoming Pods are uniform across ReplicaSets/Deployments/Jobs.|
|
||||
|Colocation Interference Avoidance|N|N||
|
||||
|Priority Preemption|Y|N†|**†** Partially exists in Poseidon-Firmament versus extensive support in Kubernetes default scheduler.|
|
||||
|Inherent Rescheduling|N|Y†|**†** Poseidon-Firmament scheduler supports workload re-scheduling. In each scheduling run, Poseidon-Firmament considers all Pods, including running Pods, and as a result can migrate or evict Pods – a globally optimal scheduling environment.|
|
||||
|Baseline Scheduling capability in accordance to available compute resources (CPU & Memory) on a node|Y|Y**|Not all Predicates & Priorities are supported at this time.|
|
||||
|Extreme Throughput at scale|Y**|Y|Bulk scheduling approach scales or increases workload placement. Substantial throughput benefits using Firmament scheduler as long as resource requirements (CPU/Memory) for incoming Pods is uniform across Replicasets/Deployments/Jobs. This is mainly due to efficient amortization of work across Replicasets/Deployments/Jobs . 1) For “Big Data/AI” jobs consisting of large no. of tasks, throughput benefits are tremendous. 2) Substantial throughput benefits also for service or batch job scenarios where workload resource requirements are uniform across Replicasets/Deployments/Jobs.|
|
||||
|Optimal Scheduling|Pod-by-Pod scheduler, processes one pod at a time (may result into sub-optimal scheduling)|Bulk Scheduling (Optimal scheduling)|Pod-by-Pod Kubernetes default scheduler may assign tasks to a sub-optimal machine. By contrast, Firmament considers all unscheduled tasks at the same time together with their soft and hard constraints.|
|
||||
|Colocation Interference Avoidance|N|N**|Planned in Poseidon-Firmament.|
|
||||
|Priority Pre-emption|Y|N**|Partially exists in Poseidon-Firmament versus extensive support in Kubernetes default scheduler.|
|
||||
|Inherent Re-Scheduling|N|Y**|Poseidon-Firmament scheduler supports workload re-scheduling. In each scheduling run it considers all the pods, including running pods, and as a result can migrate or evict pods – a globally optimal scheduling environment.|
|
||||
|Gang Scheduling|N|Y||
|
||||
|Support for Pre-bound Persistence Volume Scheduling|Y|Y||
|
||||
|Support for Local Volume & Dynamic Persistence Volume Binding Scheduling|Y|N||
|
||||
|High Availability|Y|N||
|
||||
|Real-time metrics based scheduling|N|Y†|**†** Partially supported in Poseidon-Firmament using Heapster (now deprecated) for placing Pods using actual cluster utilization statistics rather than reservations.|
|
||||
|Support for Local Volume & Dynamic Persistence Volume Binding Scheduling|Y|N**|Planned.|
|
||||
|High Availability|Y|N**|Planned.|
|
||||
|Real-time metrics based scheduling|N|Y**|Initially supported using Heapster (now deprecated) for placing pods using actual cluster utilization statistics rather than reservations. Plans to switch over to "metric server".|
|
||||
|Support for Max-Pod per node|Y|Y|Poseidon-Firmament scheduler seamlessly co-exists with Kubernetes default scheduler.|
|
||||
|Support for Ephemeral Storage, in addition to CPU/Memory|Y|Y||
|
||||
{{< /table >}}
|
||||
|
||||
## Installation
|
||||
|
||||
The [Poseidon-Firmament installation guide](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/install/README.md#Installation) explains how to deploy Poseidon-Firmament to your cluster.
|
||||
## Installation
|
||||
|
||||
## Performance comparison
|
||||
For in-cluster installation of Poseidon, please start at the [Installation instructions](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/install/README.md).
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
For developers, please refer to the [Developer Setup instructions](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/devel/README.md).
|
||||
|
||||
## Latest Throughput Performance Testing Results
|
||||
|
||||
Pod-by-pod schedulers, such as the Kubernetes default scheduler, typically process one pod at a time. These schedulers have the following crucial drawbacks:
|
||||
|
||||
1. The scheduler commits to a pod placement early and restricts the choices for other pods that wait to be placed.
|
||||
2. There is limited opportunities for amortizing work across pods because they are considered for placement individually.
|
||||
|
||||
These downsides of pod-by-pod schedulers are addressed by batching or bulk scheduling in Poseidon-Firmament scheduler. Processing several pods in a batch allows the scheduler to jointly consider their placement, and thus to find the best trade-off for the whole batch instead of one pod. At the same time it amortizes work across pods resulting in much higher throughput.
|
||||
|
||||
{{< note >}}
|
||||
Please refer to the [latest benchmark results](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/benchmark/README.md) for detailed throughput performance comparison test results between Poseidon-Firmament scheduler and the Kubernetes default scheduler.
|
||||
{{< /note >}}
|
||||
|
||||
Pod-by-pod schedulers, such as the Kubernetes default scheduler, process Pods in small batches (typically one at a time). These schedulers have the following crucial drawbacks:
|
||||
|
||||
1. The scheduler commits to a pod placement early and restricts the choices for other pods that wait to be placed.
|
||||
2. There is limited opportunities for amortizing work across pods because they are considered for placement individually.
|
||||
|
||||
These downsides of pod-by-pod schedulers are addressed by batching or bulk scheduling in Poseidon-Firmament scheduler. Processing several pods in a batch allows the scheduler to jointly consider their placement, and thus to find the best trade-off for the whole batch instead of one pod. At the same time it amortizes work across pods resulting in much higher throughput.
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
* See [Poseidon-Firmament](https://github.com/kubernetes-sigs/poseidon#readme) on GitHub for more information.
|
||||
* See the [design document](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/design/README.md) for Poseidon.
|
||||
* Read [Firmament: Fast, Centralized Cluster Scheduling at Scale](https://www.usenix.org/system/files/conference/osdi16/osdi16-gog.pdf), the academic paper on the Firmament scheduling design.
|
||||
* If you'd like to contribute to Poseidon-Firmament, refer to the [developer setup instructions](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/devel/README.md).
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -11,7 +11,7 @@ card:
|
||||
|
||||
{{% capture overview %}}
|
||||
When you deploy Kubernetes, you get a cluster.
|
||||
{{< glossary_definition term_id="cluster" length="all" prepend="A Kubernetes cluster consists of">}}
|
||||
{{< glossary_definition term_id="cluster" length="all" prepend="A cluster is">}}
|
||||
|
||||
This document outlines the various components you need to have
|
||||
a complete and working Kubernetes cluster.
|
||||
@@ -23,12 +23,13 @@ Here's the diagram of a Kubernetes cluster with all the components tied together
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
## Control Plane Components
|
||||
## Master Components
|
||||
|
||||
The Control Plane's components make global decisions about the cluster (for example, scheduling), as well as detecting and responding to cluster events (for example, starting up a new {{< glossary_tooltip text="pod" term_id="pod">}} when a deployment's `replicas` field is unsatisfied).
|
||||
Master components provide the cluster's control plane. Master components make global decisions about the
|
||||
cluster (for example, scheduling), and they detect and respond to cluster events (for example, starting up a new {{< glossary_tooltip text="pod" term_id="pod">}} when a deployment's `replicas` field is unsatisfied).
|
||||
|
||||
Control Plane components can be run on any machine in the cluster. However,
|
||||
for simplicity, set up scripts typically start all Control Plane components on
|
||||
Master components can be run on any machine in the cluster. However,
|
||||
for simplicity, set up scripts typically start all master components on
|
||||
the same machine, and do not run user containers on this machine. See
|
||||
[Building High-Availability Clusters](/docs/admin/high-availability/) for an example multi-master-VM setup.
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ Kubernetes implements an alternative Protobuf based serialization format for the
|
||||
|
||||
Prior to 1.14, the Kubernetes apiserver also exposes an API that can be used to retrieve
|
||||
the [Swagger v1.2](http://swagger.io/) Kubernetes API spec at `/swaggerapi`.
|
||||
This endpoint is deprecated, and was removed in Kubernetes 1.14.
|
||||
This endpoint is deprecated, and will be removed in Kubernetes 1.14.
|
||||
|
||||
## API versioning
|
||||
|
||||
@@ -121,22 +121,21 @@ There are two supported paths to extending the API with [custom resources](/docs
|
||||
to make it seamless for clients.
|
||||
|
||||
|
||||
## Enabling or disabling API groups
|
||||
## Enabling API groups
|
||||
|
||||
Certain resources and API groups are enabled by default. They can be enabled or disabled by setting `--runtime-config`
|
||||
on apiserver. `--runtime-config` accepts comma separated values. For example: to disable batch/v1, set
|
||||
on apiserver. `--runtime-config` accepts comma separated values. For ex: to disable batch/v1, set
|
||||
`--runtime-config=batch/v1=false`, to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`.
|
||||
The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver.
|
||||
|
||||
{{< note >}}Enabling or disabling groups or resources requires restarting apiserver and controller-manager
|
||||
to pick up the `--runtime-config` changes.{{< /note >}}
|
||||
IMPORTANT: Enabling or disabling groups or resources requires restarting apiserver and controller-manager
|
||||
to pick up the `--runtime-config` changes.
|
||||
|
||||
## Enabling specific resources in the extensions/v1beta1 group
|
||||
## Enabling resources in the groups
|
||||
|
||||
DaemonSets, Deployments, StatefulSet, NetworkPolicies, PodSecurityPolicies and ReplicaSets in the `extensions/v1beta1` API group are disabled by default.
|
||||
For example: to enable deployments and daemonsets, set
|
||||
`--runtime-config=extensions/v1beta1/deployments=true,extensions/v1beta1/daemonsets=true`.
|
||||
|
||||
{{< note >}}Individual resource enablement/disablement is only supported in the `extensions/v1beta1` API group for legacy reasons.{{< /note >}}
|
||||
DaemonSets, Deployments, HorizontalPodAutoscalers, Ingresses, Jobs and ReplicaSets are enabled by default.
|
||||
Other extensions resources can be enabled by setting `--runtime-config` on
|
||||
apiserver. `--runtime-config` accepts comma separated values. For example: to disable deployments and ingress, set
|
||||
`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/ingresses=false`
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
reviewers:
|
||||
- bgrant0607
|
||||
- mikedanese
|
||||
title: What is Kubernetes?
|
||||
description: >
|
||||
Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
|
||||
title: What is Kubernetes
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
card:
|
||||
@@ -19,10 +17,9 @@ This page is an overview of Kubernetes.
|
||||
{{% capture body %}}
|
||||
Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
|
||||
|
||||
The name Kubernetes originates from Greek, meaning helmsman or pilot. Google open-sourced the Kubernetes project in 2014. Kubernetes combines [over 15 years of Google's experience](/blog/2015/04/borg-predecessor-to-kubernetes/) running production workloads at scale with best-of-breed ideas and practices from the community.
|
||||
The name Kubernetes originates from Greek, meaning helmsman or pilot. Google open-sourced the Kubernetes project in 2014. Kubernetes builds upon a [decade and a half of experience that Google has with running production workloads at scale](https://ai.google/research/pubs/pub43438), combined with best-of-breed ideas and practices from the community.
|
||||
|
||||
## Going back in time
|
||||
|
||||
Let's take a look at why Kubernetes is so useful by going back in time.
|
||||
|
||||

|
||||
@@ -45,13 +42,13 @@ Containers have become popular because they provide extra benefits, such as:
|
||||
* Dev and Ops separation of concerns: create application container images at build/release time rather than deployment time, thereby decoupling applications from infrastructure.
|
||||
* Observability not only surfaces OS-level information and metrics, but also application health and other signals.
|
||||
* Environmental consistency across development, testing, and production: Runs the same on a laptop as it does in the cloud.
|
||||
* Cloud and OS distribution portability: Runs on Ubuntu, RHEL, CoreOS, on-premises, on major public clouds, and anywhere else.
|
||||
* Cloud and OS distribution portability: Runs on Ubuntu, RHEL, CoreOS, on-prem, Google Kubernetes Engine, and anywhere else.
|
||||
* Application-centric management: Raises the level of abstraction from running an OS on virtual hardware to running an application on an OS using logical resources.
|
||||
* Loosely coupled, distributed, elastic, liberated micro-services: applications are broken into smaller, independent pieces and can be deployed and managed dynamically – not a monolithic stack running on one big single-purpose machine.
|
||||
* Resource isolation: predictable application performance.
|
||||
* Resource utilization: high efficiency and density.
|
||||
|
||||
## Why you need Kubernetes and what it can do {#why-you-need-kubernetes-and-what-can-it-do}
|
||||
## Why you need Kubernetes and what can it do
|
||||
|
||||
Containers are a good way to bundle and run your applications. In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime. For example, if a container goes down, another container needs to start. Wouldn't it be easier if this behavior was handled by a system?
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
image: nginx:1.7.9
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user