diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..42ff3294fd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +[*] +end_of_line = lf +insert_final_newline = false +charset = utf-8 +max_line_length = 80 +trim_trailing_whitespace = true + +[*.{html,js,json,sass,md,mmark,toml,yaml}] +indent_style = space +indent_size = 2 + +[*.{sh}] +indent_style = space +indent_size = 4 + +[Makefile] +indent_style = tab diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7c0810171f..85229c98ef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,11 @@ >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > Please delete this note before submitting the pull request. > -> For 1.13 Features: set Milestone to 1.13 and Base Branch to dev-1.13 +> For 1.14 Features: set Milestone to 1.14 and Base Branch to dev-1.14 +> +> For Chinese localization, base branch to release-1.12 +> +> For Korean Localization: set Base Branch to dev-1.13-ko. > > Help editing and submitting pull requests: > https://kubernetes.io/docs/contribute/start/#improve-existing-content. @@ -10,4 +14,3 @@ > https://kubernetes.io/docs/contribute/start#choose-which-git-branch-to-use. >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > - diff --git a/.gitignore b/.gitignore index ebf3b38926..50d954cf3d 100644 --- a/.gitignore +++ b/.gitignore @@ -31,9 +31,6 @@ nohup.out public/ resources/ -# User-specific editorconfig files -.editorconfig - # Netlify Functions build output package-lock.json functions/ diff --git a/.travis.yml b/.travis.yml index 750acaefd2..4f15008944 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: go go: - - 1.10.2 - -env: - - HUGO_VERSION=0.49 + - 1.11.5 jobs: include: - name: "Testing examples" + cache: + directories: + - $HOME/.cache/go-build # Don't want default ./... here: install: - export PATH=$GOPATH/bin:$PATH @@ -16,7 +16,7 @@ jobs: # Make sure we are testing against the correct branch - pushd $GOPATH/src/k8s.io && git clone https://github.com/kubernetes/kubernetes && popd - - pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.11 && popd + - pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.13 && make generated_files && popd - cp -L -R $GOPATH/src/k8s.io/kubernetes/vendor/ $GOPATH/src/ - rm -r $GOPATH/src/k8s.io/kubernetes/vendor/ @@ -26,9 +26,6 @@ jobs: - go test -v k8s.io/website/content/en/examples - name: "Hugo build" install: - - curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz - - mkdir -p ${TRAVIS_HOME}/bin - - mv hugo ${TRAVIS_HOME}/bin - - export PATH=${TRAVIS_HOME}/bin:$PATH + - make travis-hugo-build script: - hugo diff --git a/Dockerfile b/Dockerfile index 0e3f6d1099..d8a60ea07f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,11 +20,8 @@ ARG HUGO_VERSION RUN mkdir -p /usr/local/src && \ cd /usr/local/src && \ - #curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \ curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \ mv hugo /usr/local/bin/hugo && \ - #curl -L https://bin.equinox.io/c/dhgbqpS8Bvy/minify-stable-linux-amd64.tgz | tar -xz && \ - #mv minify /usr/local/bin && \ addgroup -Sg 1000 hugo && \ adduser -Sg hugo -u 1000 -h /src hugo diff --git a/Makefile b/Makefile index 666e54ef71..f44e04b46e 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ DOCKER = docker -HUGO_VERSION = 0.49 +HUGO_VERSION = 0.53 DOCKER_IMAGE = kubernetes-hugo DOCKER_RUN = $(DOCKER) run --rm --interactive --tty --volume $(CURDIR):/src NODE_BIN = node_modules/.bin @@ -13,10 +13,10 @@ help: ## Show this help. all: build ## Build site with production settings and put deliverables in ./public build: ## Build site with production settings and put deliverables in ./public - hugo + hugo --minify build-preview: ## Build site with drafts and future posts enabled - hugo -D -F + hugo --buildDrafts --buildFuture functions-build: $(NETLIFY_FUNC) build functions-src @@ -24,9 +24,9 @@ functions-build: 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 sass-build: @@ -36,7 +36,7 @@ sass-develop: scripts/sass.sh develop serve: ## Boot the development server. - hugo server --ignoreCache --disableFastRender --buildFuture + hugo server --buildFuture docker-image: $(DOCKER) build . --tag $(DOCKER_IMAGE) --build-arg HUGO_VERSION=$(HUGO_VERSION) @@ -46,3 +46,13 @@ docker-build: docker-serve: $(DOCKER_RUN) -p 1313:1313 $(DOCKER_IMAGE) hugo server --buildFuture --bind 0.0.0.0 + +# This command is used only by Travis CI; do not run this locally +travis-hugo-build: + curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz + mkdir -p ${TRAVIS_HOME}/bin + mv hugo ${TRAVIS_HOME}/bin + export PATH=${TRAVIS_HOME}/bin:$PATH + +check-hugo-versions: + scripts/hugo-version-check.sh $(HUGO_VERSION) diff --git a/OWNERS b/OWNERS index da9dee9771..82662b6c46 100644 --- a/OWNERS +++ b/OWNERS @@ -1,3 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + # Reviewers can /lgtm /approve but not sufficient for auto-merge without an # approver reviewers: diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 7aee5b8a70..8ee41f9a72 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -119,21 +119,58 @@ aliases: - chenopis - cody-clark - jaredbhatti + - jimangel - kbarnard10 - mistyhacks + - rajakavitha1 - ryanmcginnis - steveperry-53 - stewart-yu - tengqm - tfogo - zacharysarah + - zhangxiaoyu-zidif - zparnold sig-docs-en-reviews: #Team: Documentation; GH: sig-docs-pr-reviews - jimangel - rajakavitha1 - stewart-yu - xiangpengzhao - - zhangxiaoyu + - zhangxiaoyu-zidif + sig-docs-fr-owners: #Team: Documentation; GH: sig-docs-fr-owners + - sieben + - perriea + - rekcah78 + - lledru + - yastij + - smana + - rbenzair + - abuisine + - erickhun + - jygastaud + - awkif + - oussemos + sig-docs-fr-reviews: #Team: Documentation; GH: sig-docs-fr-reviews + - sieben + - perriea + - rekcah78 + - lledru + - yastij + - smana + - rbenzair + - abuisine + - erickhun + - jygastaud + - awkif + - oussemos + sig-docs-it-owners: #Team: Italian docs localization; GH: sig-docs-it-owners + - rlenferink + - lledru + - micheleberardi + sig-docs-it-reviews: #Team: Italian docs PR reviews; GH:sig-docs-it-reviews + - rlenferink + - lledru + - micheleberardi sig-docs-ja-owners: #Team: Japanese docs localization; GH: sig-docs-ja-owners - cstoku - nasa9084 @@ -148,9 +185,7 @@ aliases: sig-docs-ko-owners: #Team Korean docs localization; GH: sig-docs-ko-owners - ClaudiaJKang - gochist - - bradamant3 # Temporary for 1.13 release - - jimangel # Temporary for 1.13 release - - tfogo # Temporary for 1.13 release + - ianychoi - zacharysarah sig-docs-ko-reviews: #Team Korean docs reviews; GH: sig-docs-ko-reviews - ClaudiaJKang @@ -168,17 +203,16 @@ aliases: - markthink - tengqm - xiangpengzhao + - xichengliudui - zacharysarah - zhangxiaoyu-zidif - - bradamant3 # Temporary for 1.13 release - - jimangel # Temporary for 1.13 release - - tfogo # Temporary for 1.13 release sig-docs-zh-reviews: #Team Chinese docs reviews; GH: sig-docs-zh-reviews - chenrui333 - idealhack - markthink - tengqm - xiangpengzhao + - xichengliudui - zhangxiaoyu-zidif - pigletfly sig-federation: #Team: Federation; e.g. Federated Clusters @@ -291,3 +325,4 @@ aliases: - floreks sig-windows: - michmike + diff --git a/README-fr.md b/README-fr.md new file mode 100644 index 0000000000..cca46595ad --- /dev/null +++ b/README-fr.md @@ -0,0 +1,83 @@ +# Documentation de Kubernetes + +[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website) +[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest) + +Bienvenue ! +Ce référentiel contient toutes les informations nécessaires à la construction du site web et de la documentation de Kubernetes. +Nous sommes très heureux que vous vouliez contribuer ! + +## Contribuer à la rédaction des docs + +Vous pouvez cliquer sur le bouton **Fork** en haut à droite de l'écran pour créer une copie de ce dépôt dans votre compte GitHub. +Cette copie s'appelle un *fork*. +Faites tous les changements que vous voulez dans votre fork, et quand vous êtes prêt à nous envoyer ces changements, allez dans votre fork et créez une nouvelle pull request pour nous le faire savoir. + +Une fois votre pull request créée, un examinateur de Kubernetes se chargera de vous fournir une revue claire et exploitable. +En tant que propriétaire de la pull request, **il est de votre responsabilité de modifier votre pull request pour tenir compte des commentaires qui vous ont été fournis par l'examinateur de Kubernetes.** +Notez également que vous pourriez vous retrouver avec plus d'un examinateur de Kubernetes pour vous fournir des commentaires ou vous pourriez finir par recevoir des commentaires d'un autre examinateur que celui qui vous a été initialement affecté pour vous fournir ces commentaires. +De plus, dans certains cas, l'un de vos examinateur peut demander un examen technique à un [examinateur technique de Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) au besoin. +Les examinateurs feront de leur mieux pour fournir une revue rapidement, mais le temps de réponse peut varier selon les circonstances. + +Pour plus d'informations sur la contribution à la documentation Kubernetes, voir : + +* [Commencez à contribuer](https://kubernetes.io/docs/contribute/start/) +* [Apperçu des modifications apportées à votre documentation](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally) +* [Utilisation des modèles de page](http://kubernetes.io/docs/contribute/style/page-templates/) +* [Documentation Style Guide](http://kubernetes.io/docs/contribute/style/style-guide/) +* [Traduction de la documentation Kubernetes](https://kubernetes.io/docs/contribute/localization/) + +## Exécuter le site localement en utilisant Docker + +La façon recommandée d'exécuter le site web Kubernetes localement est d'utiliser une image spécialisée [Docker](https://docker.com) qui inclut le générateur de site statique [Hugo](https://gohugo.io). + +> 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](#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: + +```bash +make docker-image +``` + +Une fois l'image construite, vous pouvez exécuter le site localement : + +```bash +make docker-serve +``` + +Ouvrez votre navigateur à l'adresse: http://localhost:1313 pour voir le site. +Lorsque vous apportez des modifications aux fichiers sources, Hugo met à jour le site et force le navigateur à rafraîchir la page. + +## Exécuter le site localement en utilisant Hugo + +Voir la [documentation officielle Hugo](https://gohugo.io/getting-started/installing/) pour les instructions d'installation Hugo. +Assurez-vous d'installer la version Hugo spécifiée par la variable d'environnement `HUGO_VERSION` dans le fichier [`netlify.toml`](netlify.toml#L9). + +Pour exécuter le site localement lorsque vous avez Hugo installé : + +```bash +make serve +``` + +Le serveur Hugo local démarrera sur le port 1313. +Ouvrez votre navigateur à l'adresse: http://localhost:1313 pour voir le site. +Lorsque vous apportez des modifications aux fichiers sources, Hugo met à jour le site et force le navigateur à rafraîchir la page. + +## Communauté, discussion, contribution et assistance + +Apprenez comment vous engager avec la communauté Kubernetes sur la [page communauté](http://kubernetes.io/community/). + +Vous pouvez joindre les responsables de ce projet à l'adresse : + +- [Slack](https://kubernetes.slack.com/messages/sig-docs) +- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) + +### Code de conduite + +La participation à la communauté Kubernetes est régie par le [Code de conduite de Kubernetes](code-of-conduct.md). + +## Merci ! + +Kubernetes prospère grâce à la participation de la communauté, et nous apprécions vraiment vos contributions à notre site et à notre documentation ! diff --git a/README-ko.md b/README-ko.md new file mode 100644 index 0000000000..5ac8d1e617 --- /dev/null +++ b/README-ko.md @@ -0,0 +1,69 @@ +# 쿠버네티스 문서화 + +[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website) +[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest) + +환영합니다! 이 저장소는 쿠버네티스 웹사이트 및 문서화를 만드는 데 필요로 하는 모든 asset에 대한 공간을 제공합니다. 여러 분이 기여를 원한다는 사실에 매우 기쁩니다! + +## 문서에 기여하기 + +이 저장소에 대한 복제본을 여러분의 GitHub 계정에 생성하기 위해 화면 오른쪽 위 영역에 있는 **Fork** 버튼을 클릭 가능합니 다. 이 복제본은 *fork* 라고 부릅니다. 여러분의 fork에서 원하는 임의의 변경 사항을 만들고, 해당 변경 사항을 보낼 준비가 되었다면, 여러분의 fork로 이동하여 새로운 풀 리퀘스트를 만들어 우리에게 알려주시기 바랍니다. + +여러분의 풀 리퀘스트가 생생된 이후에는, 쿠버네티스 리뷰어가 명료하고 실행 가능한 피드백을 제공하는 책임을 담당할 것입니 다. 풀 리퀘스트의 오너로서, **쿠버네티스 리뷰어로부터 제공받은 피드백을 수용하기 위해 풀 리퀘스트를 수정하는 것은 여러분의 책임입니다.** 또한, 참고로 한 명 이상의 쿠버네티스 리뷰어가 여러분에게 피드백을 제공하는 상황에 처하거나, 또는 여러분에게 피드백을 제공하기로 원래 할당된 사람이 아닌 다른 쿠버네티스 리뷰어로부터 피드백을 받는 상황에 처할 수도 있습니다. 뿐만 아니라, 몇몇 상황에서는, 필요에 따라 리뷰어 중 한 명이 [쿠버네티스 기술 리뷰어](https://github.com/kubernetes/website/wiki/Tech-reviewers)로부터의 기술 리뷰를 요청할지도 모릅니다. 리뷰어는 제시간에 피드백을 제공하기 위해 최선을 다할 것이지만, 응답 시간은 상황에 따라 달라질 수도 있습니다. + +쿠버네티스 문서화에 기여하기와 관련된 보다 자세한 정보는, 다음을 살펴봅니다: + +* [기여 시작하기](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/) +* [쿠버네티스 문서화 로컬라이징](https://kubernetes.io/docs/contribute/localization/) + +## `README.md`에 대한 쿠버네티스 문서화 번역 + +### 한국어 + +`README.md` 번역 및 한국어 기여자를 위한 보다 자세한 가이드를 [한국어 README](README-ko.md) 페이지에서 살펴봅니다. + +한국어 번역 메인테이너에게 다음을 통해 연락 가능합니다: + +* 이덕준 ([GitHub - @gochist](https://github.com/gochist)) +* [Slack channel](https://kubernetes.slack.com/messages/kubernetes-docs-ko) + +## 도커를 사용하여 사이트를 로컬에서 실행하기 + +쿠버네티스 웹사이트를 로컬에서 실행하기 위한 추천하는 방식은 [Hugo](https://gohugo.io) 정적 사이트 생성기를 포함하는 특 별한 [도커](https://docker.com) 이미지를 실행하는 것입니다. + +> Windows에서 실행하는 경우, [Chocolatey](https://chocolatey.org)로 설치할 수 있는 명명 추가 도구를 필요로 할 것입니다. `choco install make` + +> 도커를 사용하지 않고 웹사이트를 로컬에서 실행하기를 선호하는 경우에는, 아래 [Hugo를 사용한 로컬 사이트 실행하기](#hugo를-사용한-로컬-사이트-실행하기)를 살펴봅니다. + +도커 [동작 및 실행](https://www.docker.com/get-started) 환경이 있는 경우, 로컬에서 `kubernetes-hugo` 도커 이미지를 빌드 합니다: + +```bash +make docker-image +``` + +해당 이미지가 빌드된 이후, 사이트를 로컬에서 실행할 수 있습니다: + +```bash +make docker-serve +``` + +브라우저에서 http://localhost:1313 를 열어 사이트를 살펴봅니다. 소스 파일에 변경 사항이 있을 때, Hugo는 사이트를 업데이 트하고 브라우저를 강제로 새로고침합니다. + +## Hugo를 사용한 로컬 사이트 실행하기 + +Hugo 설치 안내를 위해서는 [공식 Hugo 문서화](https://gohugo.io/getting-started/installing/)를 살펴봅니다. [`netlify.toml`](netlify.toml#L9) 파일에 있는 `HUGO_VERSION` 환경 변수에서 지정된 Hugo 버전이 설치되었는지를 확인합니다. + +Hugo가 설치되었을 때 로컬에서 사이트를 실행하기 위해 (다음을 실행합니다): + +```bash +make serve +``` + +이를 통해 로컬 Hugo 서버를 1313번 포트에 시작합니다. 브라우저에서 http://localhost:1313 를 열어 사이트를 살펴봅니다. 소 스 파일에 변경 사항이 있을 때, Hugo는 사이트를 업데이트하고 브라우저를 강제로 새로고침합니다. + +## 감사합니다! + +쿠버네티스는 커뮤니티 참여와 함께 생존하며, 우리는 사이트 및 문서화에 대한 여러분의 컨트리뷰션에 대해 정말 감사하게 생각합니다! diff --git a/README.md b/README.md index e27e13a492..fd22b3342c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # The Kubernetes documentation -Welcome! This repository houses all of the assets required to build the Kubernetes website and documentation. We're very pleased that you want to contribute! +[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website) +[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest) + +Welcome! This repository houses all of the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're very pleased that you want to contribute! ## Contributing to the docs @@ -16,6 +19,17 @@ For more information about contributing to the Kubernetes documentation, see: * [Documentation Style Guide](http://kubernetes.io/docs/contribute/style/style-guide/) * [Localizing Kubernetes Documentation](https://kubernetes.io/docs/contribute/localization/) +## `README.md`'s Localizing Kubernetes Documentation + +### Korean + +See translation of `README.md` and more detail guidance for Korean contributors on the [Korean README](README-ko.md) page. + +You can reach the maintainers of Korean localization at: + +* June Yi ([GitHub - @gochist](https://github.com/gochist)) +* [Slack channel](https://kubernetes.slack.com/messages/kubernetes-docs-ko) + ## Running the site locally using Docker The recommended way to run the Kubernetes website locally is to run a specialized [Docker](https://docker.com) image that includes the [Hugo](https://gohugo.io) static site generator. @@ -50,6 +64,19 @@ make serve This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the site. As you make changes to the source files, Hugo updates the site and forces a browser refresh. +## Community, discussion, contribution, and support + +Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). + +You can reach the maintainers of this project at: + +- [Slack](https://kubernetes.slack.com/messages/sig-docs) +- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) + +### Code of conduct + +Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). + ## Thank you! Kubernetes thrives on community participation, and we really appreciate your contributions to our site and our documentation! diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 0000000000..0d15c00cf3 --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,3 @@ +# Kubernetes Community Code of Conduct + +Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/config.toml b/config.toml index 65bdd3192c..071c527e98 100644 --- a/config.toml +++ b/config.toml @@ -4,6 +4,7 @@ title = "Kubernetes" defaultContentLanguage = "en" defaultContentLanguageInSubdir = false enableRobotsTXT = true +disableBrowserError = true disableKinds = ["taxonomy", "taxonomyTerm"] @@ -153,15 +154,49 @@ contentDir = "content/ko" time_format_blog = "2006.01.02" language_alternatives = ["en"] +[languages.ja] +title = "Kubernetes" +description = "Production-Grade Container Orchestration" +languageName = "日本語 Japanese" +weight = 4 +contentDir = "content/ja" + +[languages.ja.params] +time_format_blog = "2006.01.02" +language_alternatives = ["en"] + +[languages.fr] +title = "Kubernetes" +description = "Production-Grade Container Orchestration" +languageName ="Français" +weight = 5 +contentDir = "content/fr" + +[languages.fr.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"] + +[languages.it] +title = "Kubernetes" +description = "Production-Grade Container Orchestration" +languageName ="Italian" +weight = 6 +contentDir = "content/it" + +[languages.it.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"] + [languages.no] title = "Kubernetes" description = "Production-Grade Container Orchestration" languageName ="Norsk" -weight = 4 +weight = 7 contentDir = "content/no" [languages.no.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"] - diff --git a/content/en/OWNERS b/content/en/OWNERS index 52f02277d4..5c67ba358d 100644 --- a/content/en/OWNERS +++ b/content/en/OWNERS @@ -1,3 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + # This is the directory for English source content. # Teams and members are visible at https://github.com/orgs/kubernetes/teams. diff --git a/content/en/_index.html b/content/en/_index.html index 2cb16d2ccb..57a8b5b8ba 100644 --- a/content/en/_index.html +++ b/content/en/_index.html @@ -8,7 +8,7 @@ cid: home {{< blocks/section id="oceanNodes" >}} {{% blocks/feature image="flower" %}} -### [Kubernetes]({{< relref "/docs/concepts/overview/what-is-kubernetes" >}}) is an open-source system for automating deployment, scaling, and management of containerized applications. +### [Kubernetes (K8s)]({{< relref "/docs/concepts/overview/what-is-kubernetes" >}}) is an open-source system for automating deployment, scaling, and management of containerized applications. It groups containers that make up an application into logical units for easy management and discovery. Kubernetes builds upon [15 years of experience of running production workloads at Google](http://queue.acm.org/detail.cfm?id=2898444), combined with best-of-breed ideas and practices from the community. {{% /blocks/feature %}} @@ -44,12 +44,12 @@ Kubernetes is open source giving you the freedom to take advantage of on-premise


- Attend KubeCon in Shanghai on Nov. 13-15, 2018 + Attend KubeCon in Barcelona on May 20-23, 2019



- Attend KubeCon in Seattle on Dec. 11-13, 2018 + Attend KubeCon in Shanghai on June 24-26, 2019
diff --git a/content/en/blog/OWNERS b/content/en/blog/OWNERS index 73d6d59c1a..710299aa42 100644 --- a/content/en/blog/OWNERS +++ b/content/en/blog/OWNERS @@ -1,3 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + # Owned by Kubernetes Blog reviewers. options: no_parent_owners: false diff --git a/content/en/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout_18.md b/content/en/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout_18.md index 51ec30dbf1..5a8d7f4ec0 100644 --- a/content/en/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout_18.md +++ b/content/en/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout_18.md @@ -37,11 +37,11 @@ Every week the Kubernetes contributing community meet virtually over Google Hang * additional status - additive, backward compatible * elimination of phase - won't make it for v1 * Service discussion - Public IPs - * with public ips as it exists we can't go to v1 + * with public IPs as it exists we can't go to v1 * Tim has been developing a mitigation if we can't get Justin's overhaul in (but hopefully we will) * Justin's fix will describe public IPs in a much better way - * The general problem is it's too flexible and you can do things that are scary, the mitigation is to restrict public ip usage to specific use cases -- validated public ips would be copied to status, which is what kube-proxy would use - * public ips used for - + * The general problem is it's too flexible and you can do things that are scary, the mitigation is to restrict public ip usage to specific use cases -- validated public IPs would be copied to status, which is what kube-proxy would use + * public IPs used for - * binding to nodes / node * request a specific load balancer IP (GCE only) * emulate multi-port services -- now we support multi-port services, so no longer necessary diff --git a/content/en/blog/_posts/2015-06-00-Weekly-Kubernetes-Community-Hangout.md b/content/en/blog/_posts/2015-06-00-Weekly-Kubernetes-Community-Hangout.md index ec7f4ad846..a87fa5528f 100644 --- a/content/en/blog/_posts/2015-06-00-Weekly-Kubernetes-Community-Hangout.md +++ b/content/en/blog/_posts/2015-06-00-Weekly-Kubernetes-Community-Hangout.md @@ -27,7 +27,7 @@ E2E issues and LGTM process * Question/concern to work out is securing Jenkins. Short term conclusion: Will look at pushing Jenkins logs into GCS bucket. Lavalamp will follow up with Jeff Grafton. - * Longer term solution may be a merge queue, where e2e runs for each merge (as opposed to multiple merges). This exists in Openshift today. + * Longer term solution may be a merge queue, where e2e runs for each merge (as opposed to multiple merges). This exists in OpenShift today. Cluster Upgrades for Kubernetes as final v1 feature diff --git a/content/en/blog/_posts/2016-07-00-Kubernetes-In-Rancher-Further-Evolution.md b/content/en/blog/_posts/2016-07-00-Kubernetes-In-Rancher-Further-Evolution.md index a1c3c0295b..7ce90e5791 100644 --- a/content/en/blog/_posts/2016-07-00-Kubernetes-In-Rancher-Further-Evolution.md +++ b/content/en/blog/_posts/2016-07-00-Kubernetes-In-Rancher-Further-Evolution.md @@ -131,7 +131,7 @@ Cluster Federation is a control plane of cluster federation in Kubernetes. It of ![Screen Shot 2016-07-07 at 1.46.55 PM.png](https://lh6.googleusercontent.com/jJjQ6wbYYG1y7rS7SXFNj1dsLrTEBbiOB9TfrkJAqayHVzBZwLguxMB6HLObCgpVGLKF7xdPd3wfdvQzB2a7Cq6cuqqXRRl3L5OfVPwKB34BxdpRUc1g7EgOdEkILH9E4sAfzHyb) -Each Kubernetes cluster exposes an API endpoint and gets registered to Cluster Federation as a part of Federation object. Then using Cluster Federation API, you can create federated services. Those objects are comprised of multiple equivalent underlying Kubernetes resources. Assuming that the 3 clusters on the picture above belong to the same Federation object, each Service created via Cluster Federation, will get equivalent service created in each of the clusters. Besides that, a Cluster Federation service will get publicly resolvable DNS name resolvable to Kuberentes service’s public ip addresses (DNS record gets programmed to a one of the public DNS providers below): +Each Kubernetes cluster exposes an API endpoint and gets registered to Cluster Federation as a part of Federation object. Then using Cluster Federation API, you can create federated services. Those objects are comprised of multiple equivalent underlying Kubernetes resources. Assuming that the 3 clusters on the picture above belong to the same Federation object, each Service created via Cluster Federation, will get equivalent service created in each of the clusters. Besides that, a Cluster Federation service will get publicly resolvable DNS name resolvable to Kubernetes service’s public ip addresses (DNS record gets programmed to a one of the public DNS providers below): diff --git a/content/en/blog/_posts/2016-08-00-Security-Best-Practices-Kubernetes-Deployment.md b/content/en/blog/_posts/2016-08-00-Security-Best-Practices-Kubernetes-Deployment.md index 74bb85843a..28b9a2ccb7 100644 --- a/content/en/blog/_posts/2016-08-00-Security-Best-Practices-Kubernetes-Deployment.md +++ b/content/en/blog/_posts/2016-08-00-Security-Best-Practices-Kubernetes-Deployment.md @@ -4,6 +4,8 @@ date: 2016-08-31 slug: security-best-practices-kubernetes-deployment url: /blog/2016/08/Security-Best-Practices-Kubernetes-Deployment --- +_Note: some of the recommendations in this post are no longer current. Current cluster hardening options are described in this [documentation](https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/)._ + _Editor’s note: today’s post is by Amir Jerbi and Michael Cherny of Aqua Security, describing security best practices for Kubernetes deployments, based on data they’ve collected from various use-cases seen in both on-premises and cloud deployments._ Kubernetes provides many controls that can greatly improve your application security. Configuring them requires intimate knowledge with Kubernetes and the deployment’s security requirements. The best practices we highlight here are aligned to the container lifecycle: build, ship and run, and are specifically tailored to Kubernetes deployments. We adopted these best practices in [our own SaaS deployment](http://blog.aquasec.com/running-a-security-service-in-google-cloud-real-world-example) that runs Kubernetes on Google Cloud Platform. diff --git a/content/en/blog/_posts/2016-11-00-Kompose-Tool-Go-From-Docker-Compose-To-Kubernetes.md b/content/en/blog/_posts/2016-11-00-Kompose-Tool-Go-From-Docker-Compose-To-Kubernetes.md index 167a4aa4b6..2f88069daf 100644 --- a/content/en/blog/_posts/2016-11-00-Kompose-Tool-Go-From-Docker-Compose-To-Kubernetes.md +++ b/content/en/blog/_posts/2016-11-00-Kompose-Tool-Go-From-Docker-Compose-To-Kubernetes.md @@ -18,7 +18,7 @@ We see kompose as a terrific way to expose Kubernetes principles to Docker users Over the summer, Kompose has found a new gear with help from Tomas Kral and Suraj Deshmukh from Red Hat, and Janet Kuo from Google. Together with our own lead kompose developer Nguyen An-Tu they are making kompose even more exciting. We proposed Kompose to the Kubernetes Incubator within the SIG-apps and we received approval from the general Kubernetes community; you can now find kompose in the [Kubernetes Incubator](https://github.com/kubernetes-incubator/kompose). -Kompose now supports Docker-compose v2 format, persistent volume claims have been added recently, as well as multiple container per pods. It can also be used to target Openshift deployments, by specifying a different provider than the default Kubernetes. Kompose is also now available in Fedora packages and we look forward to see it in CentOS distributions in the coming weeks. +Kompose now supports Docker-compose v2 format, persistent volume claims have been added recently, as well as multiple container per pods. It can also be used to target OpenShift deployments, by specifying a different provider than the default Kubernetes. Kompose is also now available in Fedora packages and we look forward to see it in CentOS distributions in the coming weeks. kompose is a single Golang binary that you build or install from the [release on GitHub](https://github.com/kubernetes-incubator/kompose). Let’s skip the build instructions and dive straight into an example. diff --git a/content/en/blog/_posts/2017-07-00-How-Watson-Health-Cloud-Deploys.md b/content/en/blog/_posts/2017-07-00-How-Watson-Health-Cloud-Deploys.md index 2917f55e79..0d6e6481cd 100644 --- a/content/en/blog/_posts/2017-07-00-How-Watson-Health-Cloud-Deploys.md +++ b/content/en/blog/_posts/2017-07-00-How-Watson-Health-Cloud-Deploys.md @@ -19,7 +19,7 @@ I was able to run more processes on a single physical server than I could using -To orchestrate container deployment, we are using[Armada infrastructure](https://console.bluemix.net/containers-kubernetes/launch), a Kubernetes implementation by IBM for automating deployment, scaling, and operations of application containers across clusters of hosts, providing container-centric infrastructure. +To orchestrate container deployment, we are using [IBM Cloud Kubernetes Service infrastructure](https://cloud.ibm.com/containers-kubernetes/landing), a Kubernetes implementation by IBM for automating deployment, scaling, and operations of application containers across clusters of hosts, providing container-centric infrastructure. @@ -39,7 +39,7 @@ Here is a snapshot of Watson Care Manager, running inside a Kubernetes cluster: -Before deploying an app, a user must create a worker node cluster. I can create a cluster using the kubectl cli commands or create it from[a Bluemix](http://bluemix.net/) dashboard. +Before deploying an app, a user must create a worker node cluster. I can create a cluster using the kubectl cli commands or create it from the [IBM Cloud](https://cloud.ibm.com/) dashboard. @@ -107,16 +107,16 @@ If needed, run a rolling update to update the existing pod. -Deploying the application in Armada: +Deploying the application in IBM Cloud Kubernetes Service: -Provision a cluster in Armada with \ worker nodes. Create Kubernetes controllers for deploying the containers in worker nodes, the Armada infrastructure pulls the Docker images from IBM Bluemix Docker registry to create containers. We tried deploying an application container and running a logmet agent (see Reading and displaying logs using logmet container, below) inside the containers that forwards the application logs to an IBM cloud logging service. As part of the process, YAML files are used to create a controller resource for the UrbanCode Deploy (UCD). UCD agent is deployed as a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) controller, which is used to connect to the UCD server. The whole process of deployment of application happens in UCD. To support the application for public access, we created a service resource to interact between pods and access container services. For storage support, we created persistent volume claims and mounted the volume for the containers. +Provision a cluster in IBM Cloud Kubernetes Service with \ worker nodes. Create Kubernetes controllers for deploying the containers in worker nodes, the IBM Cloud Kubernetes Service infrastructure pulls the Docker images from IBM Cloud Container Registry to create containers. We tried deploying an application container and running a logmet agent (see Reading and displaying logs using logmet container, below) inside the containers that forwards the application logs to an IBM Cloud logging service. As part of the process, YAML files are used to create a controller resource for the UrbanCode Deploy (UCD). UCD agent is deployed as a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) controller, which is used to connect to the UCD server. The whole process of deployment of application happens in UCD. To support the application for public access, we created a service resource to interact between pods and access container services. For storage support, we created persistent volume claims and mounted the volume for the containers. | ![](https://lh6.googleusercontent.com/iFKlbBX8rjWTuygIfjImdxP8R7xXuvaaoDwldEIC3VRL03XIehxagz8uePpXllYMSxoyai5a6N-0NB4aTGK9fwwd8leFyfypxtbmaWBK-b2Kh9awcA76-_82F7ZZl7lgbf0gyFN7) | -| UCD: IBM UrbanCode Deploy is a tool for automating application deployments through your environments. Armada: Kubernetes implementation of IBM. WH Docker Registry: Docker Private image registry. Common agent containers: We expect to configure our services to use the WHC mandatory agents. We deployed all ion containers. | +| UCD: IBM UrbanCode Deploy is a tool for automating application deployments through your environments. IBM Cloud Kubernetes Service: Kubernetes implementation of IBM. WH Docker Registry: Docker Private image registry. Common agent containers: We expect to configure our services to use the WHC mandatory agents. We deployed all ion containers. | @@ -142,7 +142,7 @@ Exposing services with Ingress: -To expose our services to outside the cluster, we used Ingress. In Armada, if we create a paid cluster, an Ingress controller is automatically installed for us to use. We were able to access services through Ingress by creating a YAML resource file that specifies the service path. +To expose our services to outside the cluster, we used Ingress. In IBM Cloud Kubernetes Service, if we create a paid cluster, an Ingress controller is automatically installed for us to use. We were able to access services through Ingress by creating a YAML resource file that specifies the service path. diff --git a/content/en/blog/_posts/2018-05-04-Announcing-Kubeflow-0-1.md b/content/en/blog/_posts/2018-05-04-Announcing-Kubeflow-0-1.md index 2b23ac523b..9bc8ceb2c9 100644 --- a/content/en/blog/_posts/2018-05-04-Announcing-Kubeflow-0-1.md +++ b/content/en/blog/_posts/2018-05-04-Announcing-Kubeflow-0-1.md @@ -94,7 +94,7 @@ If you’d like to try out Kubeflow, we have a number of options for you: 1. You can use sample walkthroughs hosted on [Katacoda](https://www.katacoda.com/kubeflow) 2. You can follow a guided tutorial with existing models from the [examples repository](https://github.com/kubeflow/examples). These include the [Github Issue Summarization](https://github.com/kubeflow/examples/tree/master/github_issue_summarization), [MNIST](https://github.com/kubeflow/examples/tree/master/mnist) and [Reinforcement Learning with Agents](https://github.com/kubeflow/examples/tree/master/agents). -3. You can start a cluster on your own and try your own model. Any Kubernetes conformant cluster will support Kubeflow including those from contributors [Caicloud](https://www.prnewswire.com/news-releases/caicloud-releases-its-kubernetes-based-cluster-as-a-service-product-claas-20-and-the-first-tensorflow-as-a-service-taas-11-while-closing-6m-series-a-funding-300418071.html), [Canonical](https://jujucharms.com/canonical-kubernetes/), [Google](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-container-cluster), [Heptio](https://heptio.com/products/kubernetes-subscription/), [Mesosphere](https://github.com/mesosphere/dcos-kubernetes-quickstart), [Microsoft](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough), [IBM](https://console.bluemix.net/docs/containers/cs_tutorials.html#cs_cluster_tutorial), [Red Hat/Openshift ](https://docs.openshift.com/container-platform/3.3/install_config/install/quick_install.html#install-config-install-quick-install)and [Weaveworks](https://www.weave.works/product/cloud/). +3. You can start a cluster on your own and try your own model. Any Kubernetes conformant cluster will support Kubeflow including those from contributors [Caicloud](https://www.prnewswire.com/news-releases/caicloud-releases-its-kubernetes-based-cluster-as-a-service-product-claas-20-and-the-first-tensorflow-as-a-service-taas-11-while-closing-6m-series-a-funding-300418071.html), [Canonical](https://jujucharms.com/canonical-kubernetes/), [Google](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-container-cluster), [Heptio](https://heptio.com/products/kubernetes-subscription/), [Mesosphere](https://github.com/mesosphere/dcos-kubernetes-quickstart), [Microsoft](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough), [IBM](https://cloud.ibm.com/docs/containers?topic=containers-cs_cluster_tutorial#cs_cluster_tutorial), [Red Hat/Openshift ](https://docs.openshift.com/container-platform/3.3/install_config/install/quick_install.html#install-config-install-quick-install)and [Weaveworks](https://www.weave.works/product/cloud/). There were also a number of sessions at KubeCon + CloudNativeCon EU 2018 covering Kubeflow. The links to the talks are here; the associated videos will be posted in the coming days. diff --git a/content/en/blog/_posts/2018-05-24-kubernetes-containerd-integration-goes-ga.md b/content/en/blog/_posts/2018-05-24-kubernetes-containerd-integration-goes-ga.md index 205c7bcb5b..4336880154 100644 --- a/content/en/blog/_posts/2018-05-24-kubernetes-containerd-integration-goes-ga.md +++ b/content/en/blog/_posts/2018-05-24-kubernetes-containerd-integration-goes-ga.md @@ -109,7 +109,7 @@ For a detailed list of changes in the containerd 1.1 release, please see the rel To setup a Kubernetes cluster using containerd as the container runtime: * For a production quality cluster on GCE brought up with kube-up.sh, see [here](https://github.com/containerd/cri/blob/v1.0.0/docs/kube-up.md). -* For a multi-node cluster installer and bring up steps using ansible and kubeadm, see [here](https://github.com/containerd/cri/blob/v1.0.0/contrib/ansible/README.md). +* For a multi-node cluster installer and bring up steps using Ansible and kubeadm, see [here](https://github.com/containerd/cri/blob/v1.0.0/contrib/ansible/README.md). * For creating a cluster from scratch on Google Cloud, see [Kubernetes the Hard Way](https://github.com/kelseyhightower/kubernetes-the-hard-way). * For a custom installation from release tarball, see [here](https://github.com/containerd/cri/blob/v1.0.0/docs/installation.md). * To install using LinuxKit on a local VM, see [here](https://github.com/linuxkit/linuxkit/tree/master/projects/kubernetes). diff --git a/content/en/blog/_posts/2018-11-07-grpc-load-balancing-with-linkerd.md.md b/content/en/blog/_posts/2018-11-07-grpc-load-balancing-with-linkerd.md.md new file mode 100644 index 0000000000..d56074cc3b --- /dev/null +++ b/content/en/blog/_posts/2018-11-07-grpc-load-balancing-with-linkerd.md.md @@ -0,0 +1,172 @@ +--- +layout: blog +title: 'gRPC Load Balancing on Kubernetes without Tears' +date: 2018-11-07 +--- + +**Author**: William Morgan (Buoyant) + +Many new gRPC users are surprised to find that Kubernetes's default load +balancing often doesn't work out of the box with gRPC. For example, here's what +happens when you take a [simple gRPC Node.js microservices +app](https://github.com/sourishkrout/nodevoto) and deploy it on Kubernetes: + +![](/images/blog/grpc-load-balancing-with-linkerd/Screenshot2018-11-0116-c4d86100-afc1-4a08-a01c-16da391756dd.34.36.png) + +While the `voting` service displayed here has several pods, it's clear from +Kubernetes's CPU graphs that only one of the pods is actually doing any +work—because only one of the pods is receiving any traffic. Why? + +In this blog post, we describe why this happens, and how you can easily fix it +by adding gRPC load balancing to any Kubernetes app with +[Linkerd](https://linkerd.io), a [CNCF](https://cncf.io) service mesh and service sidecar. + +# Why does gRPC need special load balancing? + +First, let's understand why we need to do something special for gRPC. + +gRPC is an increasingly common choice for application developers. Compared to +alternative protocols such as JSON-over-HTTP, gRPC can provide some significant +benefits, including dramatically lower (de)serialization costs, automatic type +checking, formalized APIs, and less TCP management overhead. + +However, gRPC also breaks the standard connection-level load balancing, +including what's provided by Kubernetes. This is because gRPC is built on +HTTP/2, and HTTP/2 is designed to have a single long-lived TCP connection, +across which all requests are *multiplexed*—meaning multiple requests can be +active on the same connection at any point in time. Normally, this is great, as +it reduces the overhead of connection management. However, it also means that +(as you might imagine) connection-level balancing isn't very useful. Once the +connection is established, there's no more balancing to be done. All requests +will get pinned to a single destination pod, as shown below: + +![](/images/blog/grpc-load-balancing-with-linkerd/Mono-8d2e53ef-b133-4aa0-9551-7e36a880c553.png) + +# Why doesn't this affect HTTP/1.1? + +The reason why this problem doesn't occur in HTTP/1.1, which also has the +concept of long-lived connections, is because HTTP/1.1 has several features +that naturally result in cycling of TCP connections. Because of this, +connection-level balancing is "good enough", and for most HTTP/1.1 apps we +don't need to do anything more. + +To understand why, let's take a deeper look at HTTP/1.1. In contrast to HTTP/2, +HTTP/1.1 cannot multiplex requests. Only one HTTP request can be active at a +time per TCP connection. The client makes a request, e.g. `GET /foo`, and then +waits until the server responds. While that request-response cycle is +happening, no other requests can be issued on that connection. + +Usually, we want lots of requests happening in parallel. Therefore, to have +concurrent HTTP/1.1 requests, we need to make multiple HTTP/1.1 connections, +and issue our requests across all of them. Additionally, long-lived HTTP/1.1 +connections typically expire after some time, and are torn down by the client +(or server). These two factors combined mean that HTTP/1.1 requests typically +cycle across multiple TCP connections, and so connection-level balancing works. + +# So how do we load balance gRPC? + +Now back to gRPC. Since we can't balance at the connection level, in order to +do gRPC load balancing, we need to shift from connection balancing to *request* +balancing. In other words, we need to open an HTTP/2 connection to each +destination, and balance *requests* across these connections, as shown below: + +![](/images/blog/grpc-load-balancing-with-linkerd/Stereo-09aff9d7-1c98-4a0a-9184-9998ed83a531.png) + +In network terms, this means we need to make decisions at L5/L7 rather than +L3/L4, i.e. we need to understand the protocol sent over the TCP connections. + +How do we accomplish this? There are a couple options. First, our application +code could manually maintain its own load balancing pool of destinations, and +we could configure our gRPC client to [use this load balancing +pool](https://godoc.org/google.golang.org/grpc/balancer). This approach gives +us the most control, but it can be very complex in environments like Kubernetes +where the pool changes over time as Kubernetes reschedules pods. Our +application would have to watch the Kubernetes API and keep itself up to date +with the pods. + +Alternatively, in Kubernetes, we could deploy our app as [headless +services](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services). +In this case, Kubernetes [will create multiple A +records](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services) +in the DNS entry for the service. If our gRPC client is sufficiently advanced, +it can automatically maintain the load balancing pool from those DNS entries. +But this approach restricts us to certain gRPC clients, and it's rarely +possible to only use headless services. + +Finally, we can take a third approach: use a lightweight proxy. + +# gRPC load balancing on Kubernetes with Linkerd + +[Linkerd](https://linkerd.io) is a [CNCF](https://cncf.io)-hosted *service +mesh* for Kubernetes. Most relevant to our purposes, Linkerd also functions as +a *service sidecar*, where it can be applied to a single service—even without +cluster-wide permissions. What this means is that when we add Linkerd to our +service, it adds a tiny, ultra-fast proxy to each pod, and these proxies watch +the Kubernetes API and do gRPC load balancing automatically. Our deployment +then looks like this: + +![](/images/blog/grpc-load-balancing-with-linkerd/Linkerd-8df1031c-cdd1-4164-8e91-00f2d941e93f.io.png) + +Using Linkerd has a couple advantages. First, it works with services written in +any language, with any gRPC client, and any deployment model (headless or not). +Because Linkerd's proxies are completely transparent, they auto-detect HTTP/2 +and HTTP/1.x and do L7 load balancing, and they pass through all other traffic +as pure TCP. This means that everything will *just work.* + +Second, Linkerd's load balancing is very sophisticated. Not only does Linkerd +maintain a watch on the Kubernetes API and automatically update the load +balancing pool as pods get rescheduled, Linkerd uses an *exponentially-weighted +moving average* of response latencies to automatically send requests to the +fastest pods. If one pod is slowing down, even momentarily, Linkerd will shift +traffic away from it. This can reduce end-to-end tail latencies. + +Finally, Linkerd's Rust-based proxies are incredibly fast and small. They +introduce <1ms of p99 latency and require <10mb of RSS per pod, meaning that +the impact on system performance will be negligible. + +# gRPC Load Balancing in 60 seconds + +Linkerd is very easy to try. Just follow the steps in the [Linkerd Getting +Started Instructions](https://linkerd.io/2/getting-started/)—install the +CLI on your laptop, install the control plane on your cluster, and "mesh" your +service (inject the proxies into each pod). You'll have Linkerd running on your +service in no time, and should see proper gRPC balancing immediately. + +Let's take a look at our sample `voting` service again, this time after +installing Linkerd: + +![](/images/blog/grpc-load-balancing-with-linkerd/Screenshot2018-11-0116-24b8ee81-144c-4eac-b73d-871bbf0ea22e.57.42.png) + +As we can see, the CPU graphs for all pods are active, indicating that all pods +are now taking traffic—without having to change a line of code. Voila, +gRPC load balancing as if by magic! + +Linkerd also gives us built-in traffic-level dashboards, so we don't even need +to guess what's happening from CPU charts any more. Here's a Linkerd graph +that's showing the success rate, request volume, and latency percentiles of +each pod: + +![](/images/blog/grpc-load-balancing-with-linkerd/Screenshot2018-11-0212-15ed0448-5424-4e47-9828-20032de868b5.08.38.png) + +We can see that each pod is getting around 5 RPS. We can also see that, while +we've solved our load balancing problem, we still have some work to do on our +success rate for this service. (The demo app is built with an intentional +failure—as an exercise to the reader, see if you can figure it out by +using the Linkerd dashboard!) + +# Wrapping it up + +If you're interested in a dead simple way to add gRPC load balancing to your +Kubernetes services, regardless of what language it's written in, what gRPC +client you're using, or how it's deployed, you can use Linkerd to add gRPC load +balancing in a few commands. + +There's a lot more to Linkerd, including security, reliability, and debugging +and diagnostics features, but those are topics for future blog posts. + +Want to learn more? We’d love to have you join our rapidly-growing community! +Linkerd is a [CNCF](https://cncf.io) project, [hosted on +GitHub](https://github.com/linkerd/linkerd2), and has a thriving community +on [Slack](https://slack.linkerd.io), [Twitter](https://twitter.com/linkerd), +and the [mailing lists](https://lists.cncf.io/g/cncf-linkerd-users). Come and +join the fun! diff --git a/content/en/blog/_posts/2018-12-05-new-contributor-shanghai.md b/content/en/blog/_posts/2018-12-05-new-contributor-shanghai.md new file mode 100644 index 0000000000..23d955d064 --- /dev/null +++ b/content/en/blog/_posts/2018-12-05-new-contributor-shanghai.md @@ -0,0 +1,41 @@ +--- +layout: blog +title: 'New Contributor Workshop Shanghai' +date: 2018-12-05 +--- + +**Authors**: Josh Berkus (Red Hat), Yang Li (The Plant), Puja Abbassi (Giant Swarm), XiangPeng Zhao (ZTE) + +{{< figure src="/images/blog/2018-12-05-new-contributor-shanghai/attendees.png" caption="Kubecon Shanghai New Contributor Summit attendees. Photo by Jerry Zhang" >}} + +We recently completed our first New Contributor Summit in China, at the first KubeCon in China. It was very exciting to see all of the Chinese and Asian developers (plus a few folks from around the world) interested in becoming contributors. Over the course of a long day, they learned how, why, and where to contribute to Kubernetes, created pull requests, attended a panel of current contributors, and got their CLAs signed. + +This was our second New Contributor Workshop (NCW), building on the one created and led by SIG Contributor Experience members in Copenhagen. Because of the audience, it was held in both Chinese and English, taking advantage of the superb simultaneous interpretation services the CNCF sponsored. Likewise, the NCW team included both English and Chinese-speaking members of the community: Yang Li, XiangPeng Zhao, Puja Abbassi, Noah Abrahams, Tim Pepper, Zach Corleissen, Sen Lu, and Josh Berkus. In addition to presenting and helping students, the bilingual members of the team translated all of the slides into Chinese. Fifty-one students attended. + +{{< figure src="/images/blog/2018-12-05-new-contributor-shanghai/noahabrahams.png" caption="Noah Abrahams explains Kubernetes communications channels. Photo by Jerry Zhang" >}} + +The NCW takes participants through the stages of contributing to Kubernetes, starting from deciding where to contribute, followed by an introduction to the SIG system and our repository structure. We also have "guest speakers" from Docs and Test Infrastructure who cover contributing in those areas. We finally wind up with some hands-on exercises in filing issues and creating and approving PRs. + +Those hands-on exercises use a repository known as [the contributor playground](https://github.com/kubernetes-sigs/contributor-playground), created by SIG Contributor Experience as a place for new contributors to try out performing various actions on a Kubernetes repo. It has modified Prow and Tide automation, uses Owners files like in the real repositories. This lets students learn how the mechanics of contributing to our repositories work without disrupting normal development. + +{{< figure src="/images/blog/2018-12-05-new-contributor-shanghai/yangli.png" caption="Yang Li talks about getting your PRs reviewed. Photo by Josh Berkus" >}} + +Both the "Great Firewall" and the language barrier prevent contributing Kubernetes from China from being straightforward. What's more, because open source business models are not mature in China, the time for employees work on open source projects is limited. + +Chinese engineers are eager to participate in the development of Kubernetes, but many of them don't know where to start since Kubernetes is such a large project. With this workshop, we hope to help those who want to contribute, whether they wish to fix some bugs they encountered, improve or localize documentation, or they need to work with Kubernetes at their work. We are glad to see more and more Chinese contributors joining the community in the past few years, and we hope to see more of them in the future. + +"I have been participating in the Kubernetes community for about three years," said XiangPeng Zhao. "In the community, I notice that more and more Chinese developers are showing their interest in contributing to Kubernetes. However, it's not easy to start contributing to such a project. I tried my best to help those who I met in the community, but I think there might still be some new contributors leaving the community due to not knowing where to get help when in trouble. Fortunately, the community initiated NCW at KubeCon Copenhagen and held a second one at KubeCon Shanghai. I was so excited to be invited by Josh Berkus to help organize this workshop. During the workshop, I met community friends in person, mentored attendees in the exercises, and so on. All of this was a memorable experience for me. I also learned a lot as a contributor who already has years of contributing experience. I wish I had attended such a workshop when I started contributing to Kubernetes years ago." + +{{< figure src="/images/blog/2018-12-05-new-contributor-shanghai/panel.png" caption="Panel of contributors. Photo by Jerry Zhang" >}} + +The workshop ended with a panel of current contributors, featuring Lucas Käldström, Janet Kuo, Da Ma, Pengfei Ni, Zefeng Wang, and Chao Xu. The panel aimed to give both new and current contributors a look behind the scenes on the day-to-day of some of the most active contributors and maintainers, both from China and around the world. Panelists talked about where to begin your contributor's journey, but also how to interact with reviewers and maintainers. They further touched upon the main issues of contributing from China and gave attendees an outlook into exciting features they can look forward to in upcoming releases of Kubernetes. + +After the workshop, Xiang Peng Zhao chatted with some attendees on WeChat and Twitter about their experiences. They were very glad to have attended the NCW and had some suggestions on improving the workshop. One attendee, Mohammad, said, "I had a great time at the workshop and learned a lot about the entire process of k8s for a contributor." Another attendee, Jie Jia, said, "The workshop was wonderful. It systematically explained how to contribute to Kubernetes. The attendee could understand the process even if s/he knew nothing about that before. For those who were already contributors, they could also learn something new. Furthermore, I could make new friends from inside or outside of China in the workshop. It was awesome!" + +SIG Contributor Experience will continue to run New Contributor Workshops at each upcoming Kubecon, including Seattle, Barcelona, and the return to Shanghai in June 2019. If you failed to get into one this year, register for one at a future Kubecon. And, when you meet an NCW attendee, make sure to welcome them to the community. + +Links: + +* English versions of the slides: [PDF](https://gist.github.com/jberkus/889be25c234b01761ce44eccff816380#file-kubernetes-shanghai-english-pdf) or [Google Docs with speaker notes](https://docs.google.com/presentation/d/1l5f_iAFsKg50LFq3N80KbZKUIEL_tyCaUoWPzSxColo/edit?usp=sharing) +* Chinese version of the slides: [PDF](https://gist.github.com/jberkus/889be25c234b01761ce44eccff816380#file-kubernetes-shanghai-cihinese-pdf) +* [Contributor playground](https://github.com/kubernetes-sigs/contributor-playground) diff --git a/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md b/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md new file mode 100644 index 0000000000..02768fafd3 --- /dev/null +++ b/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md @@ -0,0 +1,95 @@ +--- +layout: blog +title: Kubernetes Federation Evolution +date: 2018-12-12 +--- + +**Authors**: Irfan Ur Rehman (Huawei), Paul Morie (RedHat) and Shashidhara T D (Huawei) + +Kubernetes provides great primitives for deploying applications to a cluster: it can be as simple as `kubectl create -f app.yaml`. Deploy apps across multiple clusters has never been that simple. How should app workloads be distributed? Should the app resources be replicated into all clusters, replicated into selected clusters, or partitioned into clusters? How is access to the clusters managed? What happens if some of the resources that a user wants to distribute pre-exist, in some or all of the clusters, in some form? + +In SIG Multicluster, our journey has revealed that there are multiple possible models to solve these problems and there probably is no single best-fit, all-scenario solution. [Federation](https://kubernetes.io/docs/concepts/cluster-administration/federation/), however, is the single biggest Kubernetes open source sub-project, and has seen the maximum interest and contribution from the community in this problem space. The project initially reused the Kubernetes API to do away with any added usage complexity for an existing Kubernetes user. This approach was not viable, because of the problems summarised below: + +* Difficulties in re-implementing the Kubernetes API at the cluster level, as federation-specific extensions were stored in annotations. +* Limited flexibility in federated types, placement and reconciliation, due to 1:1 emulation of the Kubernetes API. +* No settled path to GA, and general confusion on API maturity; for example, Deployments are GA in Kubernetes but not even Beta in Federation v1. + + +The ideas have evolved further with a federation-specific API architecture and a community effort which now continues as Federation v2. + +# Conceptual Overview +Because Federation attempts to address a complex set of problems, it pays to break the different parts of those problems down. Let’s take a look at the different high-level areas involved: +{{< figure src="/images/blog/2018-12-11-Kubernetes-Federation-Evolution/concepts.png" caption="Kubernetes Federation v2 Concepts" >}} + +## Federating arbitrary resources +One of the main goals of Federation is to be able to define the APIs and API groups which encompass basic tenets needed to federate any given Kubernetes resource. This is crucial, due to the popularity of CustomResourceDefinitions as a way to extend Kubernetes with new APIs. + +The workgroup arrived at a common definition of the federation API and API groups as _'a mechanism that distributes “normal” Kubernetes API resources into different clusters'_. The distribution in its most simple form could be imagined as ***simple propagation*** of this _'normal Kubernetes API resource'_ across the federated clusters. A thoughtful reader can certainly discern more complicated mechanisms, other than this simple propagation of the Kubernetes resources. + +During the journey of defining building blocks of the federation APIs, one of the near term goals also evolved as _'to be able to create a simple federation a.k.a. simple propagation of any Kubernetes resource or a CRD, writing almost zero code'_. What ensued further was a core API group defining the building blocks as a `Template` resource, a `Placement` resource and an `Override` resource per given Kubernetes resource, a `TypeConfig` to specify sync or no sync for the given resource and associated controller(s) to carry out the sync. More details follow [in the next section](#federating-resources-the-details). Further sections will also talk about being able to follow a layered behaviour with higher-level federation APIs consuming the behaviour of these core building blocks, and users being able to consume whole or part of the API and associated controllers. Lastly, this architecture also allows the users to write additional controllers or replace the available reference controllers with their own, to carry out desired behaviour. + +The ability to _'easily federate arbitrary Kubernetes resources'_, and a decoupled API, divided into building blocks APIs, higher level APIs and possible user intended types, presented such that different users can consume parts and write controllers composing solutions specific to them, makes a compelling case for Federation v2. + +## Federating resources: the details +Fundamentally, federation must be configured with two types of information: + +* Which API types federation should handle +* Which clusters federation should target for distributing those resources. + +For each API type that federation handles, different parts of the declared state live in different API resources: + +* A `Template` type holds the base specification of the resource - for example, a type called `FederatedReplicaSet` holds the base specification of a `ReplicaSet` that should be distributed to the targeted clusters +* A `Placement` type holds the specification of the clusters the resource should be distributed to - for example, a type called `FederatedReplicaSetPlacement` holds information about which clusters `FederatedReplicaSets` should be distributed to +* An optional `Overrides` type holds the specification of how the `Template` resource should be varied in some clusters - for example, a type called `FederatedReplicaSetOverrides` holds information about how a `FederatedReplicaSet` should be varied in certain clusters. + +These types are all associated by name - meaning that for a particular Template resource with name `foo`, the Placement and Override information for that resource are contained by the Override and Placement resources with the name `foo` and in the same namespace as the Template. + +## Higher-level behaviour +The architecture of the v2 API allows higher-level APIs to be constructed using the mechanics provided by the core API types (`Template`, `Placement` and `Override`), and associated controllers, for a given resource. In the community we uncovered a few use cases and implemented the higher-level APIs and associated controllers useful for those cases. Some of these types described in further sections also provide an useful reference to anybody interested in solving more complex use cases, building on top of the mechanics already available with the v2 API. + +### ReplicaSchedulingPreference +`ReplicaSchedulingPreference` provides an automated mechanism of distributing and maintaining total number of replicas for Deployment or ReplicaSet-based federated workloads into federated clusters. This is based on high-level user preferences given by the user. These preferences include the semantics of _weighted distribution_ and _limits_ (min and max) for distributing the replicas. These also include semantics to allow redistribution of replicas dynamically in case some replica Pods remain unscheduled in some clusters, for example due to insufficient resources in that cluster. +More details can be found at the [user guide for ReplicaSchedulingPreferences](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md#replicaschedulingpreference). + +### Federated services & cross-cluster service discovery +Kubernetes Services are very useful in constructing a microservices architecture. There is a clear desire to deploy services across cluster, zone, region and cloud boundaries. Services that span clusters provide geographic distribution, enable hybrid and multi-cloud scenarios and improve the level of high availability beyond single cluster deployments. Customers who want their services to span one or more (possibly remote) clusters, need them to be reachable in a consistent manner from both within and outside their clusters. + +Federated `Service`, at its core, contains a `Template` (a definition of a Kubernetes Service), a `Placement` (which clusters to be deployed into), an `Override` (optional variation in particular clusters) and a `ServiceDNSRecord` (specifying details on how to discover it). + +Note: The federated service has to be of type `LoadBalancer` in order for it to be discoverable across clusters. + +#### Discovering a federated service from Pods inside your federated clusters +By default, Kubernetes clusters come preconfigured with a cluster-local DNS server, as well as an intelligently constructed DNS search path, which together ensure that DNS queries like `myservice`, `myservice.mynamespace`, or `some-other-service.other-namespace`, issued by software running inside Pods, are automatically expanded and resolved correctly to the appropriate IP of Services running in the local cluster. + +With the introduction of federated services and cross-cluster service discovery, this concept is extended to cover Kubernetes Services running in any other cluster across your cluster federation, globally. To take advantage of this extended range, you use a slightly different DNS name (e.g. `myservice.mynamespace.myfederation`) to resolve federated services. Using a different DNS name also avoids having your existing applications accidentally traversing cross-zone or cross-region networks and you incurring perhaps unwanted network charges or latency, without you explicitly opting in to this behavior. + +Lets consider an example, using a service named `nginx`. + +A Pod in a cluster in the `us-central1-a` availability zone needs to contact our `nginx` service. Rather than use the service’s traditional cluster-local DNS name (`nginx.mynamespace`, which is automatically expanded to `nginx.mynamespace.svc.cluster.local`) it can now use the service’s federated DNS name, which is `nginx.mynamespace.myfederation`. This will be automatically expanded and resolved to the closest healthy shard of my `nginx` service, wherever in the world that may be. If a healthy shard exists in the local cluster, that service’s cluster-local IP address will be returned (by the cluster-local DNS). This is exactly equivalent to non-federated service resolution. + +If the Service does not exist in the local cluster (or it exists but has no healthy backend pods), the DNS query is automatically expanded to `nginx.mynamespace.myfederation.svc.us-central1-a.us-central1.example.com`. Behind the scenes, this finds the external IP of one of the shards closest to my availability zone. This expansion is performed automatically by the cluster-local DNS server, which returns the associated CNAME record. This results in a traversal of the hierarchy of DNS records, and ends up at one of the external IP’s of the federated service nearby. + +It is also possible to target service shards in availability zones and regions other than the ones local to a Pod by specifying the appropriate DNS names explicitly, and not relying on automatic DNS expansion. For example, `nginx.mynamespace.myfederation.svc.europe-west1.example.com`will resolve to all of the currently healthy service shards in Europe, even if the Pod issuing the lookup is located in the U.S., and irrespective of whether or not there are healthy shards of the service in the U.S. This is useful for remote monitoring and other similar applications. + +#### Discovering a federated service from other clients outside your federated clusters +For external clients, automatic DNS expansion described is not currently possible. External clients need to specify one of the fully qualified DNS names of the federated service, be that a zonal, regional or global name. For convenience reasons, it is often a good idea to manually configure additional static CNAME records in your service, for example: + +| SHORT NAME | CNAME | +|-------------------|-------------------------------------------------------------| +| eu.nginx.acme.com | nginx.mynamespace.myfederation.svc.europe-west1.example.com | +| us.nginx.acme.com | nginx.mynamespace.myfederation.svc.us-central1.example.com | +| nginx.acme.com | nginx.mynamespace.myfederation.svc.example.com | + +That way, your clients can always use the short form on the left, and always be automatically routed to the closest healthy shard on their home continent. All of the required failover is handled for you automatically by Kubernetes cluster federation. + +As further reading, a more elaborate example for users is available in the [Multi-Cluster Service DNS with ExternalDNS guide](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/servicedns-with-externaldns.md). + +# Try it yourself +To get started with Federation v2, please refer to the [user guide](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md). Deployment can be accomplished with a [Helm chart](https://github.com/kubernetes-sigs/federation-v2/blob/master/charts/federation-v2/README.md), and once the control plane is available, the [user guide’s example](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md#example) can be used to get some hands-on experience with using Federation V2. + +Federation v2 can be deployed in both _cluster-scoped_ and _namespace-scoped_ configurations. A cluster-scoped deployment will require cluster-admin privileges to both host and member clusters, and may be a good fit for evaluating federation on clusters that are not running critical workloads. Namespace-scoped deployment requires access to only a single namespace on host and member clusters, and is a better fit for evaluating federation on clusters running workloads. Most of the user guide refers to cluster-scoped deployment, with the [namespaced federation](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md#namespaced-federation) section documenting how use of a namespaced deployment differs. The same cluster can host multiple federations, and clusters can be part of multiple federations when using namespaced federation. + +# Next Steps +As we noted in the beginning of this post, the multicluster problem space is extremely broad. It can be difficult to know exactly how to handle such broad problem spaces without concrete pieces of software to frame those conversations around. Our hope in the Federation working group is that Federation v2 can be a concrete artifact to frame discussions around. We would love to know experiences that folks have had in this problem space, how they feel about Federation v2, and what use-cases they’re interested in exploring in the future. + +Please feel welcome to join us at the [sig-multicluster slack channel](https://kubernetes.slack.com/messages/C09R1PJR3) or at [Federation working group meetings](https://docs.google.com/document/d/1FQx0BPlkkl1Bn0c9ocVBxYIKojpmrS1CFP5h0DI68AE/edit) on Wednesdays at 07:30 PST. diff --git a/content/en/blog/_posts/2018-12-11-current-status-and-future-roadmap.md b/content/en/blog/_posts/2018-12-11-current-status-and-future-roadmap.md new file mode 100644 index 0000000000..fab15f369c --- /dev/null +++ b/content/en/blog/_posts/2018-12-11-current-status-and-future-roadmap.md @@ -0,0 +1,57 @@ +--- +layout: blog +title: 'etcd: Current status and future roadmap' +date: 2018-12-11 +--- + +**Author**: Gyuho Lee (Amazon Container OSS Team, @gyuho), Joe Betz (Google Cloud, @jpbetz) + +etcd is a distributed key value store that provides a reliable way to manage the coordination state of distributed systems. etcd was first announced in June 2013 by CoreOS (part of Red Hat as of 2018). Since its adoption in Kubernetes in 2014, etcd has become a fundamental part of the Kubernetes cluster management software design, and the etcd community has grown exponentially. etcd is now being used in production environments of multiple companies, including large cloud provider environments such as AWS, Google Cloud Platform, Azure, and other on-premises Kubernetes implementations. CNCF currently has [32 conformant Kubernetes platforms and distributions](https://www.cncf.io/announcement/2017/11/13/cloud-native-computing-foundation-launches-certified-kubernetes-program-32-conformant-distributions-platforms/), all of which use etcd as the datastore. + +In this blog post, we’ll review some of the milestones achieved in latest etcd releases, and go over the future roadmap for etcd. Share your thoughts and feedback on features you consider important on the mailing list: etcd-dev@googlegroups.com. + +## etcd, 2013 + +In June 2014, Kubernetes was released with etcd as a backing storage for all master states. Kubernetes v0.4 used etcd v0.2 API, which was in an alpha stage at the time. As Kubernetes reached the v1.0 milestone in 2015, etcd stabilized its v2.0 API. The widespread adoption of Kubernetes led to a dramatic increase in the scalability requirements for etcd. To handle large number of workloads and the growing requirements on scale, etcd released v3.0 API in June 2016. Kubernetes v1.13 finally [dropped support for etcd v2.0 API](https://github.com/kubernetes/enhancements/issues/622) and adopted the etcd v3.0 API. The table below gives a visual snapshot of the release cycles of etcd and Kubernetes. + +| | etcd | Kubernetes | +|---|---|---| +| Initial Commit | June 2, 2013 | June 1, 2014 | +| First Stable Release | January 28, 2015 (v2.0.0) | July 13, 2015 (v1.0.0) | +| Latest Release | October 10, 2018 (v3.3.10) | December 3, 2018 (v1.13.0) | + +## etcd v3.1, early 2017 + +etcd v3.1 features provide better read performance and better availability during version upgrades. Given the high use of etcd in production even to this day, these features were very useful for users. It implements Raft read index, which bypasses [Raft WAL](https://godoc.org/github.com/etcd-io/etcd/wal) disk writes for linearizable reads. The follower requests read index from the leader. Responses from the leader indicate whether a follower has advanced as much as the leader. When the follower's logs are up-to-date, quorum read is served locally without going through the full Raft protocol. Thus, no disk write is required for read requests. etcd v3.1 introduces automatic leadership transfer. When etcd leader receives an interrupt signal, it automatically transfers its leadership to a follower. This provides higher availability when the cluster adds or loses a member. + +## etcd v3.2 (summer 2017) + +etcd v3.2 focuses on stability. Its client was shipped in Kubernetes v1.10, v1.11, and v1.12. The etcd team still actively maintains the branch by backporting all the bug fixes. This release introduces gRPC proxy to support, watch, and coalesce all watch event broadcasts into one gRPC stream. These event broadcasts can go up to one million events per second. + +etcd v3.2 also introduces changes such as `“snapshot-count”` default value from 10,000 to 100,000. With higher snapshot count, etcd server holds Raft entries in-memory for longer periods before compacting the old ones. etcd v3.2 default configuration shows higher memory usage, while giving more time for slow followers to catch up. It is a trade-off between less frequent snapshot sends and higher memory usage. Users can employ lower `etcd --snapshot-count` value to reduce the memory usage or higher `“snapshot-count”` value to increase the availability of slow followers. + +Another new feature backported to etcd v3.2.19 was `etcd --initial-election-tick-advance` flag. By default, a rejoining follower fast-forwards election ticks to speed up its initial cluster bootstrap. For example, the starting follower node only waits 200ms instead of full election timeout 1-second before starting an election. Ideally, within the 200ms, it receives a leader heartbeat and immediately joins the cluster as a follower. However, if network partition happens, heartbeat may drop and thus leadership election will be triggered. A vote request from a partitioned node is quite disruptive. If it contains a higher Raft term, current leader is forced to step down. With “initial-election-tick-advance” set to false, a rejoining node has [more chance to receive leader heartbeats](https://github.com/etcd-io/etcd/pull/9591) before disrupting the cluster. + +## etcd v3.3 (early 2018) + +etcd v3.3 continues the theme of stability. Its client is included in [Kubernetes v1.13](https://github.com/kubernetes/kubernetes/pull/69322). Previously, etcd client carelessly retried on network disconnects without any backoff or failover logic. The client was often stuck with a partitioned node, [affecting several production users](https://github.com/etcd-io/etcd/issues/7321). v3.3 client balancer now maintains a list of unhealthy endpoints using gRPC health checking protocol, making more efficient retries and failover in the face of transient disconnects and [network partitions](https://github.com/etcd-io/etcd/issues/8711). This was backported to etcd v3.2 and also [included in Kubernetes v1.10 API server](https://github.com/kubernetes/kubernetes/pull/57480). etcd v3.3 also provides more predictable database size. etcd used to maintain a separate freelist DB to track pages that were no longer in use and freed after transactions, so that following transactions can reuse them. However, it turns out persisting freelist demands high disk space and introduces high latency for Kubernetes workloads. Especially when there were frequent snapshots with lots of read transactions, etcd database size quickly grew from 16 MB to 4 GB. etcd v3.3 disables freelist sync and rebuilds the freelist on restart. The overhead is so small that it is unnoticeable to most users. See ["database space exceeded" issue](https://github.com/etcd-io/etcd/issues/8009) for more information on this. + +## etcd v3.4 and beyond + +etcd v3.4 focuses on improving the operational experience. It adds [Raft pre-vote feature](https://github.com/etcd-io/etcd/pull/9352) to improve the robustness of leadership election. When a node becomes isolated (e.g. network partition), this member will start an election requesting votes with increased Raft terms. When a leader receives a vote request with a higher term, it steps down to a follower. With pre-vote, Raft runs an additional election phase to check if the candidate can get enough votes to win an election. The isolated follower's vote request is rejected because it does not contain the latest log entries. + +etcd v3.4 adds a [Raft learner](https://etcd.readthedocs.io/en/latest/server-learner.html#server-learner) that joins the cluster as a non-voting member that still receives all the updates from leader. Adding a learner node does not increase the size of quorum and hence improves the cluster availability during membership reconfiguration. It only serves as a standby node until it gets promoted to a voting member. Moreover, to handle unexpected upgrade failures, v3.4 introduces [etcd downgrade](https://groups.google.com/forum/?hl=en#!topic/etcd-dev/Hq6zru44L74) feature. + +etcd v3 storage uses multi-version concurrency control model to preserve key updates as event history. Kubernetes runs compaction to discard the event history that is no longer needed, and reclaims the storage space. etcd v3.4 will improve this storage compact operation, boost backend [concurrency for large read transactions](https://github.com/etcd-io/etcd/pull/9384), and [optimize storage commit interval](https://github.com/etcd-io/etcd/pull/10283) for Kubernetes use-case. + +To further improve etcd client load balancer, the v3.4 balancer was rewritten to leverage the newly introduced gRPC load balancing API. By leveraging gPRC, the etcd client load balancer codebase was substantially simplified while retaining feature parity with the v3.3 implementation and improving overall load balancing by round-robining requests across healthy endpoints. See [Client Architecture](https://etcd.readthedocs.io/en/latest/client-architecture.html#client-architecture) for more details. + +Additionally, etcd maintainers will continue to make improvements to Kubernetes test frameworks: kubemark integration for scalability tests, Kubernetes API server conformance tests with etcd to provide release recommends and version skew policy, specifying conformance testing requirements for each cloud provider, etc. + +## etcd Joins CNCF + +etcd now has a new home at [etcd-io](https://github.com/etcd-io) and [joined CNCF as an incubating project](https://www.cncf.io/blog/2018/12/11/cncf-to-host-etcd/). + +The synergistic efforts with Kubernetes have driven the evolution of etcd. Without community feedback and contribution, etcd could not have achieved its maturity and reliability. We’re looking forward to continuing the growth of etcd as an open source project and are excited to work with the Kubernetes and the wider CNCF community. + +Finally, we’d like to thank all contributors with special thanks to [Xiang Li](https://github.com/xiang90) for his leadership in etcd and Kubernetes. diff --git a/content/en/blog/_posts/2019-01-14-apiserver-dry-run-and-kubectl-diff.md b/content/en/blog/_posts/2019-01-14-apiserver-dry-run-and-kubectl-diff.md new file mode 100644 index 0000000000..bbaeb891c1 --- /dev/null +++ b/content/en/blog/_posts/2019-01-14-apiserver-dry-run-and-kubectl-diff.md @@ -0,0 +1,99 @@ +--- +layout: blog +title: 'APIServer dry-run and kubectl diff' +date: 2019-01-14 +--- + +**Author**: Antoine Pelisse (Google Cloud, @apelisse) + +Declarative configuration management, also known as configuration-as-code, is +one of the key strengths of Kubernetes. It allows users to commit the desired state of +the cluster, and to keep track of the different versions, improve auditing and +automation through CI/CD pipelines. The [Apply working-group](https://groups.google.com/forum/#!forum/kubernetes-wg-apply) +is working on fixing some of the gaps, and is happy to announce that Kubernetes +1.13 promoted server-side dry-run and `kubectl diff` to beta. These +two features are big improvements for the Kubernetes declarative model. + +## Challenges + +A few pieces are still missing in order to have a seamless declarative +experience with Kubernetes, and we tried to address some of these: + +- While compilers and linters do a good job to detect errors in pull-requests + for code, a good validation is missing for Kubernetes configuration files. + The existing solution is to run `kubectl apply --dry-run`, but this runs a + *local* dry-run that doesn't talk to the server: it doesn't have server + validation and doesn't go through validating admission controllers. As an + example, Custom resource names are only validated on the server so a local + dry-run won't help. +- It can be difficult to know how your object is going to be applied by the + server for multiple reasons: + - Defaulting will set some fields to potentially unexpected values, + - Mutating webhooks might set fields or clobber/change some values. + - Patch and merges can have surprising effects and result in unexpected + objects. For example, it can be hard to know how lists are going to be + ordered once merged. + +The working group has tried to address these problems. + +## APIServer dry-run + +[APIServer dry-run](https://kubernetes.io/docs/reference/using-api/api-concepts/#dry-run) was implemented to address these two problems: + +- it allows individual requests to the apiserver to be marked as "dry-run", +- the apiserver guarantees that dry-run requests won't be persisted to storage, +- the request is still processed as typical request: the fields are + defaulted, the object is validated, it goes through the validation admission + chain, and through the mutating admission chain, and then the final object is + returned to the user as it normally would, without being persisted. + +While dynamic admission controllers are not supposed to have side-effects on +each request, dry-run requests are only processed if all admission controllers +explicitly announce that they don't have any dry-run side-effects. + +### How to enable it + +Server-side dry-run is enabled through a feature-gate. Now that the feature is +Beta in 1.13, it should be enabled by default, but still can be enabled/disabled +using `kube-apiserver --feature-gates DryRun=true`. + +If you have dynamic admission controllers, you might have to fix them to: + +- Remove any side-effects when the dry-run parameter is specified on the webhook request, +- Specify in the [`sideEffects`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#webhook-v1beta1-admissionregistration) +field of the `admissionregistration.k8s.io/v1beta1.Webhook` object to indicate that the object doesn't +have side-effects on dry-run (or at all). + +### How to use it + +You can trigger the feature from kubectl by using `kubectl apply +--server-dry-run`, which will decorate the request with the dryRun flag +and return the object as it would have been applied, or an error if it would +have failed. + +## Kubectl diff + +APIServer dry-run is convenient because it lets you see how the object would be +processed, but it can be hard to identify exactly what changed if the object is +big. `kubectl diff` does exactly what you want by showing the differences between +the current "live" object and the new "dry-run" object. It makes it very +convenient to focus on only the changes that are made to the object, how the +server has merged these and how the mutating webhooks affects the output. + +### How to use it + +`kubectl diff` is meant to be as similar as possible to `kubectl apply`: +`kubectl diff -f some-resources.yaml` will show a diff for the resources in the yaml file. One can even use the diff program of their choice by using the KUBECTL_EXTERNAL_DIFF environment variable, for example: +``` +KUBECTL_EXTERNAL_DIFF=meld kubectl diff -f some-resources.yaml +``` + +## What's next + +The working group is still busy trying to improve some of these things: + +- Server-side apply is trying to improve the apply scenario, by adding owner +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! diff --git a/content/en/blog/_posts/2019-01-15-container-storage-interface-ga.md b/content/en/blog/_posts/2019-01-15-container-storage-interface-ga.md new file mode 100644 index 0000000000..05adbc3cb6 --- /dev/null +++ b/content/en/blog/_posts/2019-01-15-container-storage-interface-ga.md @@ -0,0 +1,208 @@ +--- +title: Container Storage Interface (CSI) for Kubernetes GA +date: 2019-01-15 +slug: container-storage-interface-ga +--- + +![Kubernetes Logo](/images/blog-logging/2018-04-10-container-storage-interface-beta/csi-kubernetes.png) +![CSI Logo](/images/blog-logging/2018-04-10-container-storage-interface-beta/csi-logo.png) + +**Author:** Saad Ali, Senior Software Engineer, Google + +The Kubernetes implementation of the [Container Storage Interface](https://github.com/container-storage-interface/spec/blob/master/spec.md) (CSI) has been promoted to GA in the Kubernetes v1.13 release. Support for CSI was [introduced as alpha](http://blog.kubernetes.io/2018/01/introducing-container-storage-interface.html) in Kubernetes v1.9 release, and [promoted to beta](https://kubernetes.io/blog/2018/04/10/container-storage-interface-beta/) in the Kubernetes v1.10 release. + +The GA milestone indicates that Kubernetes users may depend on the feature and its API without fear of backwards incompatible changes in future causing regressions. GA features are protected by the [Kubernetes deprecation policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/). + +## Why CSI? + +Although prior to CSI Kubernetes provided a powerful volume plugin system, it was challenging to add support for new volume plugins to Kubernetes: volume plugins were “in-tree” meaning their code was part of the core Kubernetes code and shipped with the core Kubernetes binaries—vendors wanting to add support for their storage system to Kubernetes (or even fix a bug in an existing volume plugin) were forced to align with the Kubernetes release process. In addition, third-party storage code caused reliability and security issues in core Kubernetes binaries and the code was often difficult (and in some cases impossible) for Kubernetes maintainers to test and maintain. + +CSI was developed as a standard for exposing arbitrary block and file storage storage systems to containerized workloads on Container Orchestration Systems (COs) like Kubernetes. With the adoption of the Container Storage Interface, the Kubernetes volume layer becomes truly extensible. Using CSI, third-party storage providers can write and deploy plugins exposing new storage systems in Kubernetes without ever having to touch the core Kubernetes code. This gives Kubernetes users more options for storage and makes the system more secure and reliable. + +## What’s new? + +With the promotion to GA, the Kubernetes implementation of CSI introduces the following changes: + +- Kubernetes is now compatible with CSI spec [v1.0](https://github.com/container-storage-interface/spec/releases/tag/v1.0.0) and [v0.3](https://github.com/container-storage-interface/spec/releases/tag/v0.3.0) (instead of CSI spec [v0.2](https://github.com/container-storage-interface/spec/releases/tag/v0.2.0)). + - There were breaking changes between CSI spec v0.3.0 and v1.0.0, but Kubernetes v1.13 supports both versions so either version will work with Kubernetes v1.13. + - Please note that with the release of the CSI 1.0 API, support for CSI drivers using 0.3 and older releases of the CSI API is deprecated, and is planned to be removed in Kubernetes v1.15. + - There were no breaking changes between CSI spec v0.2 and v0.3, so v0.2 drivers should also work with Kubernetes v1.10.0+. + - There were breaking changes between the CSI spec v0.1 and v0.2, so very old drivers implementing CSI 0.1 must be updated to be at least 0.2 compatible before use with Kubernetes v1.10.0+. +- The Kubernetes `VolumeAttachment` object (introduced in v1.9 in the storage v1alpha1 group, and added to the v1beta1 group in v1.10) has been added to the storage v1 group in v1.13. +- The Kubernetes `CSIPersistentVolumeSource` volume type has been promoted to GA. +- The [Kubelet device plugin registration mechanism](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#device-plugin-registration), which is the means by which kubelet discovers new CSI drivers, has been promoted to GA in Kubernetes v1.13. + +## How to deploy a CSI driver? + +Kubernetes users interested in how to deploy or manage an existing CSI driver on Kubernetes should look at the documentation provided by the author of the CSI driver. + +## How to use a CSI volume? + +Assuming a CSI storage plugin is already deployed on a Kubernetes cluster, users can use CSI volumes through the familiar Kubernetes storage API objects: `PersistentVolumeClaims`, `PersistentVolumes`, and `StorageClasses`. Documented [here](https://kubernetes.io/docs/concepts/storage/volumes/#csi). + +Although the Kubernetes implementation of CSI is a GA feature in Kubernetes v1.13, it may require the following flag: + +- API server binary and kubelet binaries: + - `--allow-privileged=true` + - Most CSI plugins will require bidirectional mount propagation, which can only be enabled for privileged pods. Privileged pods are only permitted on clusters where this flag has been set to true (this is the default in some environments like GCE, GKE, and kubeadm). + +### Dynamic Provisioning + +You can enable automatic creation/deletion of volumes for CSI Storage plugins that support dynamic provisioning by creating a `StorageClass` pointing to the CSI plugin. + +The following StorageClass, for example, enables dynamic creation of “`fast-storage`” volumes by a CSI volume plugin called “`csi-driver.example.com`”. + +``` +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast-storage +provisioner: csi-driver.example.com +parameters: + type: pd-ssd + csi.storage.k8s.io/provisioner-secret-name: mysecret + csi.storage.k8s.io/provisioner-secret-namespace: mynamespace +``` + +New for GA, the [CSI external-provisioner](https://github.com/kubernetes-csi/external-provisioner) (v1.0.1+) reserves the parameter keys prefixed with `csi.storage.k8s.io/`. If the keys do not correspond to a set of known keys the values are simply ignored (and not passed to the CSI driver). The older secret parameter keys (`csiProvisionerSecretName`, `csiProvisionerSecretNamespace`, etc.) are also supported by CSI external-provisioner v1.0.1 but are deprecated and may be removed in future releases of the CSI external-provisioner. + +Dynamic provisioning is triggered by the creation of a `PersistentVolumeClaim` object. The following `PersistentVolumeClaim`, for example, triggers dynamic provisioning using the `StorageClass` above. + +``` +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: my-request-for-storage +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: fast-storage +``` + +When volume provisioning is invoked, the parameter type: `pd-ssd` and the secret any referenced secret(s) are passed to the CSI plugin `csi-driver.example.com` via a `CreateVolume` call. In response, the external volume plugin provisions a new volume and then automatically create a `PersistentVolume` object to represent the new volume. Kubernetes then binds the new `PersistentVolume` object to the `PersistentVolumeClaim`, making it ready to use. + +If the `fast-storage StorageClass` is marked as “default”, there is no need to include the `storageClassName` in the `PersistentVolumeClaim`, it will be used by default. + +### Pre-Provisioned Volumes + +You can always expose a pre-existing volume in Kubernetes by manually creating a PersistentVolume object to represent the existing volume. The following `PersistentVolume`, for example, exposes a volume with the name “`existingVolumeName`” belonging to a CSI storage plugin called “`csi-driver.example.com`”. + +``` +apiVersion: v1 +kind: PersistentVolume +metadata: + name: my-manually-created-pv +spec: + capacity: + storage: 5Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + csi: + driver: csi-driver.example.com + volumeHandle: existingVolumeName + readOnly: false + fsType: ext4 + volumeAttributes: + foo: bar + controllerPublishSecretRef: + name: mysecret1 + namespace: mynamespace + nodeStageSecretRef: + name: mysecret2 + namespace: mynamespace + nodePublishSecretRef + name: mysecret3 + namespace: mynamespace +``` + +### Attaching and Mounting + +You can reference a `PersistentVolumeClaim` that is bound to a CSI volume in any pod or pod template. + +``` +kind: Pod +apiVersion: v1 +metadata: + name: my-pod +spec: + containers: + - name: my-frontend + image: nginx + volumeMounts: + - mountPath: "/var/www/html" + name: my-csi-volume + volumes: + - name: my-csi-volume + persistentVolumeClaim: + claimName: my-request-for-storage +``` + +When the pod referencing a CSI volume is scheduled, Kubernetes will trigger the appropriate operations against the external CSI plugin (`ControllerPublishVolume`, `NodeStageVolume`, `NodePublishVolume`, etc.) to ensure the specified volume is attached, mounted, and ready to use by the containers in the pod. + +For more details please see the CSI implementation [design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md) and [documentation](https://kubernetes.io/docs/concepts/storage/volumes/#csi). + +## How to write a CSI Driver? + +The [kubernetes-csi](https://kubernetes-csi.github.io/) site details how to develop, deploy, and test a CSI driver on Kubernetes. In general, CSI Drivers should be deployed on Kubernetes along with the following sidecar (helper) containers: + +- [external-attacher](https://github.com/kubernetes-csi/external-attacher) + - Watches Kubernetes `VolumeAttachment` objects and triggers `ControllerPublish` and `ControllerUnpublish` operations against a CSI endpoint. +- [external-provisioner](https://github.com/kubernetes-csi/external-provisioner) + - Watches Kubernetes `PersistentVolumeClaim` objects and triggers `CreateVolume` and `DeleteVolume` operations against a CSI endpoint. +- [node-driver-registrar](https://github.com/kubernetes-csi/node-driver-registrar) + - Registers the CSI driver with kubelet using the [Kubelet device plugin mechanism](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#device-plugin-registration). +- [cluster-driver-registrar](https://github.com/kubernetes-csi/cluster-driver-registrar) (Alpha) + - Registers a CSI Driver with the Kubernetes cluster by creating a `CSIDriver` object which enables the driver to customize how Kubernetes interacts with it. +- [external-snapshotter](https://github.com/kubernetes-csi/external-snapshotter) (Alpha) + - Watches Kubernetes `VolumeSnapshot` CRD objects and triggers `CreateSnapshot` and `DeleteSnapshot` operations against a CSI endpoint. +- [livenessprobe](https://github.com/kubernetes-csi/livenessprobe) + - May be included in a CSI plugin pod to enable the [Kubernetes Liveness Probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) mechanism. + +Storage vendors can build Kubernetes deployments for their plugins using these components, while leaving their CSI driver completely unaware of Kubernetes. + +## List of CSI Drivers + +CSI drivers are developed and maintained by third parties. You can find a non-definitive list of CSI drivers [here](https://kubernetes-csi.github.io/docs/Drivers.html). + +## What about in-tree volume plugins? + +There is a plan to migrate most of the persistent, remote in-tree volume plugins to CSI. For more details see [design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/csi-migration.md). + +## Limitations of GA + +The GA implementation of CSI has the following limitations: + +- Ephemeral local volumes must create a PVC (pod inline referencing of CSI volumes is not supported). + +## What’s next? + +- Work on moving Kubernetes CSI features that are still alpha to beta: + - Raw block volumes + - Topology awareness (the ability for Kubernetes to understand and influence where a CSI volume is provisioned (zone, regions, etc.). + - Features depending on CSI CRDs (e.g. “Skip attach” and “Pod info on mount”). + - Volume Snapshots +- Work on completing support for local ephemeral volumes. +- Work on migrating remote persistent in-tree volume plugins to CSI. + +## How to get involved? +The Kubernetes Slack channel [wg-csi](https://kubernetes.slack.com/messages/C8EJ01Z46/details/) and the Google group [kubernetes-sig-storage-wg-csi](https://groups.google.com/forum/#!forum/kubernetes-sig-storage-wg-csi) along with any of the standard [SIG storage communication channels](https://github.com/kubernetes/community/blob/master/sig-storage/README.md#contact) are all great mediums to reach out to the SIG Storage team. + +This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together. We offer a huge thank you to the new contributors who stepped up this quarter to help the project reach GA: + +- Saad Ali ([saad-ali](https://github.com/saad-ali)) +- Michelle Au ([msau42](https://github.com/msau42)) +- Serguei Bezverkhi ([sbezverk](https://github.com/sbezverk)) +- Masaki Kimura ([mkimuram](https://github.com/mkimuram)) +- Patrick Ohly ([pohly](https://github.com/pohly)) +- Luis Pabón ([lpabon](https://github.com/lpabon)) +- Jan Šafránek ([jsafrane](https://github.com/jsafrane)) +- Vladimir Vivien ([vladimirvivien](https://github.com/vladimirvivien)) +- Cheng Xing ([verult](https://github.com/verult)) +- Xing Yang ([xing-yang](https://github.com/xing-yang)) +- David Zhu ([davidz627](https://github.com/davidz627)) + +If you’re interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system, join the [Kubernetes Storage Special Interest Group](https://github.com/kubernetes/community/tree/master/sig-storage) (SIG). We’re rapidly growing and always welcome new contributors. diff --git a/content/en/blog/_posts/2019-01-17-update-volume-snapshot-alpha.md b/content/en/blog/_posts/2019-01-17-update-volume-snapshot-alpha.md new file mode 100644 index 0000000000..208a940ba6 --- /dev/null +++ b/content/en/blog/_posts/2019-01-17-update-volume-snapshot-alpha.md @@ -0,0 +1,170 @@ +--- +title: Update on Volume Snapshot Alpha for Kubernetes +date: 2019-01-17 +--- + +**Authors:** Jing Xu (Google), Xing Yang (Huawei), Saad Ali (Google) + +Volume snapshotting support was introduced in Kubernetes v1.12 as an alpha feature. In Kubernetes v1.13, it remains an alpha feature, but a few enhancements were added and some breaking changes were made. This post summarizes the changes. + +## Breaking Changes + +[CSI spec v1.0](https://github.com/container-storage-interface/spec/releases/tag/v1.0.0) introduced a few breaking changes to the volume snapshot feature. CSI driver maintainers should be aware of these changes as they upgrade their drivers to support v1.0. + +## SnapshotStatus replaced with Boolean ReadyToUse + +CSI v0.3.0, defined a `SnapshotStatus` enum in `CreateSnapshotResponse` which indicates whether the snapshot is `READY`, `UPLOADING`, or `ERROR_UPLOADING`. In CSI v1.0, `SnapshotStatus` has been removed from `CreateSnapshotResponse` and replaced with a `boolean ReadyToUse`. A `ReadyToUse` value of `true` indicates that post snapshot processing (such as uploading) is complete and the snapshot is ready to be used as a source to create a volume. + +Storage systems that need to do post snapshot processing (such as uploading after the snapshot is cut) should return a successful `CreateSnapshotResponse` with the `ReadyToUse` field set to `false` as soon as the snapshot has been taken. This indicates that the Container Orchestration System (CO) can resume any workload that was quiesced for the snapshot to be taken. The CO can then repeatedly call `CreateSnapshot` until the `ReadyToUse` field is set to `true` or the call returns an error indicating a problem in processing. The CSI `ListSnapshot` call could be used along with `snapshot_id` filtering to determine if the snapshot is ready to use, but is not recommended because it provides no way to detect errors during processing (the `ReadyToUse` field simply remains `false` indefinitely). + +The [v1.x.x releases](https://github.com/kubernetes-csi/external-snapshotter/releases/tag/v1.0.1) of the CSI external-snapshotter sidecar container already handle this change by calling `CreateSnapshot` instead of `ListSnapshots` to check if a snapshot is ready to use. When upgrading their drivers to CSI 1.0, driver maintainers should use the appropriate 1.0 compatible sidecar container. + +To be consistent with the change in the CSI spec, the `Ready` field in the `VolumeSnapshot` API object has been renamed to `ReadyToUse`. This change is visible to the user when running `kubectl describe volumesnapshot` to view the details of a snapshot. + +## Timestamp Data Type + +The creation time of a snapshot is available to Kubernetes admins as part of the `VolumeSnapshotContent` API object. This field is populated using the `creation_time` field in the CSI `CreateSnapshotResponse`. In CSI v1.0, this `creation_time` field type was changed to [`.google.protobuf.Timestamp`](https://godoc.org/github.com/golang/protobuf/ptypes/timestamp) instead of `int64`. When upgrading drivers to CSI 1.0, driver maintainers must make changes accordingly. The [v1.x.x releases](https://github.com/kubernetes-csi/external-snapshotter/releases/tag/v1.0.1) of the CSI external-snapshotter sidecar container has been updated to handle this change. + +## Deprecations + +The following `VolumeSnapshotClass` parameters are deprecated and will be removed in a future release. They will be replaced with parameters listed in the `Replacement` section below. + +Deprecated +Replacement +csiSnapshotterSecretName +csi.storage.k8s.io/snapshotter-secret-name +csiSnapshotterSecretNameSpace +csi.storage.k8s.io/snapshotter-secret-namespace + +## New Features + +### SnapshotContent Deletion/Retain Policy + +As described in the [initial blog post announcing the snapshot alpha](https://kubernetes.io/blog/2018/10/09/introducing-volume-snapshot-alpha-for-kubernetes/), the Kubernetes snapshot APIs are similar to the PV/PVC APIs: just like a volume is represented by a bound PVC and PV pair, a snapshot is represented by a bound `VolumeSnapshot` and `VolumeSnapshotContent` pair. + +With PV/PVC pairs, when a user is done with a volume, they can delete the PVC. And the reclaim policy on the PV determines what happens to the PV (whether it is also deleted or retained). + +In the initial alpha release, snapshots did not support the ability to specify a reclaim policy. Instead when a snapshot object was deleted it always resulted in the snapshot being deleted. In Kubernetes v1.13, a snapshot content `DeletionPolicy` was added. It enables an admin to configure what what happens to a `VolumeSnapshotContent` after the `VolumeSnapshot` object it is bound to is deleted. The `DeletionPolicy` of a volume snapshot can either be `Retain` or `Delete`. If the value is not specified, the default depends on whether the `SnapshotContent` object was created via static binding or dynamic provisioning. + +### Retain + +The `Retain` policy allows for manual reclamation of the resource. If a `VolumeSnapshotContent` is statically created and bound, the default `DeletionPolicy` is `Retain`. When the `VolumeSnapshot` is deleted, the `VolumeSnapshotContent` continues to exist and the `VolumeSnapshotContent` is considered “released”. But it is not available for binding to other `VolumeSnapshot` objects because it contains data. It is up to an administrator to decide how to handle the remaining API object and resource cleanup. + +### Delete + +A `Delete` policy enables automatic deletion of the bound `VolumeSnapshotContent` object from Kubernetes and the associated storage asset in the external infrastructure (such as an AWS EBS snapshot or GCE PD snapshot, etc.). Snapshots that are dynamically provisioned inherit the deletion policy of their [`VolumeSnapshotClass`](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/), which defaults to `Delete`. The administrator should configure the `VolumeSnapshotClass` with the desired retention policy. The policy may be changed for individual `VolumeSnapshotContent` after it is created by patching the object. + +The following example demonstrates how to check the deletion policy of a dynamically provisioned `VolumeSnapshotContent`. + +``` +$ kubectl create -f ./examples/kubernetes/demo-defaultsnapshotclass.yaml +$ kubectl create -f ./examples/kubernetes/demo-snapshot.yaml +$ kubectl get volumesnapshots demo-snapshot-podpvc -o yaml +apiVersion: snapshot.storage.k8s.io/v1alpha1 +kind: VolumeSnapshot +metadata: + creationTimestamp: "2018-11-27T23:57:09Z" +... +spec: + snapshotClassName: default-snapshot-class + snapshotContentName: snapcontent-26cd0db3-f2a0-11e8-8be6-42010a800002 + source: + apiGroup: null + kind: PersistentVolumeClaim + name: podpvc +status: +… +$ kubectl get volumesnapshotcontent snapcontent-26cd0db3-f2a0-11e8-8be6-42010a800002 -o yaml +apiVersion: snapshot.storage.k8s.io/v1alpha1 +kind: VolumeSnapshotContent +… +spec: + csiVolumeSnapshotSource: + creationTime: 1546469777852000000 + driver: pd.csi.storage.gke.io + restoreSize: 6442450944 + snapshotHandle: projects/jing-k8s-dev/global/snapshots/snapshot-26cd0db3-f2a0-11e8-8be6-42010a800002 + deletionPolicy: Delete + persistentVolumeRef: + apiVersion: v1 + kind: PersistentVolume + name: pvc-853622a4-f28b-11e8-8be6-42010a800002 + resourceVersion: "21117" + uid: ae400e9f-f28b-11e8-8be6-42010a800002 + snapshotClassName: default-snapshot-class + volumeSnapshotRef: + apiVersion: snapshot.storage.k8s.io/v1alpha1 + kind: VolumeSnapshot + name: demo-snapshot-podpvc + namespace: default + resourceVersion: "6948065" + uid: 26cd0db3-f2a0-11e8-8be6-42010a800002 +``` + +User can change the deletion policy by using patch: + +``` +$ kubectl patch volumesnapshotcontent snapcontent-26cd0db3-f2a0-11e8-8be6-42010a800002 -p '{"spec":{"deletionPolicy":"Retain"}}' --type=merge + +$ kubectl get volumesnapshotcontent snapcontent-26cd0db3-f2a0-11e8-8be6-42010a800002 -o yaml +apiVersion: snapshot.storage.k8s.io/v1alpha1 +kind: VolumeSnapshotContent +... +spec: + csiVolumeSnapshotSource: +... + deletionPolicy: Retain + persistentVolumeRef: + apiVersion: v1 + kind: PersistentVolume + name: pvc-853622a4-f28b-11e8-8be6-42010a800002 +... +``` + +## Snapshot Object in Use Protection + +The purpose of the Snapshot Object in Use Protection feature is to ensure that in-use snapshot API objects are not removed from the system (as this may result in data loss). There are two cases that require “in-use” protection: + +1. If a volume snapshot is in active use by a persistent volume claim as a source to create a volume. +2. If a `VolumeSnapshotContent` API object is bound to a VolumeSnapshot API object, the content object is considered in use. + +If a user deletes a `VolumeSnapshot` API object in active use by a PVC, the `VolumeSnapshot` object is not removed immediately. Instead, removal of the `VolumeSnapshot` object is postponed until the `VolumeSnapshot` is no longer actively used by any PVCs. Similarly, if an admin deletes a `VolumeSnapshotContent` that is bound to a `VolumeSnapshot`, the `VolumeSnapshotContent` is not removed immediately. Instead, the `VolumeSnapshotContent` removal is postponed until the `VolumeSnapshotContent` is not bound to the `VolumeSnapshot` object. + +## Which volume plugins support Kubernetes Snapshots? + +Snapshots are only supported for CSI drivers (not for in-tree or Flexvolume). To use the Kubernetes snapshots feature, ensure that a CSI Driver that implements snapshots is deployed on your cluster. + +As of the publishing of this blog post, the following CSI drivers support snapshots: + +- [GCE Persistent Disk CSI Driver](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver) +- [OpenSDS CSI Driver](https://github.com/opensds/nbp/tree/master/csi/server) +- [Ceph RBD CSI Driver](https://github.com/ceph/ceph-csi/tree/master/pkg/rbd) +- [Portworx CSI Driver](https://github.com/libopenstorage/openstorage/tree/master/csi) +- [GlusterFS CSI Driver](https://github.com/gluster/gluster-csi-driver) +- [Digital Ocean CSI Driver](https://github.com/digitalocean/csi-digitalocean) +- [Ember CSI Driver](https://github.com/embercsi/ember-csi) +- [Cinder CSI Driver](https://github.com/kubernetes/cloud-provider-openstack/tree/master/pkg/csi/cinder) +- [Datera CSI Driver](https://github.com/Datera/datera-csi) +- [NexentaStor CSI Driver](https://github.com/Nexenta/nexentastor-csi-driver) + +Snapshot support for other [drivers](https://kubernetes-csi.github.io/docs/Drivers.html) is pending, and should be available soon. Read the “Container Storage Interface (CSI) for Kubernetes GA” blog post to learn more about CSI and how to deploy CSI drivers. + +## What’s next? + +Depending on feedback and adoption, the Kubernetes team plans to push the CSI Snapshot implementation to beta in either 1.15 or 1.16. Some of the features we are interested in supporting include consistency groups, application consistent snapshots, workload quiescing, in-place restores, and more. + +## How can I learn more? + +The code repository for snapshot APIs and controller is here: https://github.com/kubernetes-csi/external-snapshotter + +Check out additional documentation on the snapshot feature here: http://k8s.io/docs/concepts/storage/volume-snapshots and https://kubernetes-csi.github.io/docs/ + +## How do I get involved? + +This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together. + +Special thanks to all the contributors that helped add CSI v1.0 support and improve the snapshot feature in this release, including Saad Ali ([saadali](https://github.com/saadali)), Michelle Au ([msau42](https://github.com/msau42)), Deep Debroy ([ddebroy](https://github.com/ddebroy)), James DeFelice ([jdef](https://github.com/jdef)), John Griffith ([j-griffith](https://github.com/j-griffith)), Julian Hjortshoj ([julian-hj](https://github.com/julian-hj)), Tim Hockin ([thockin](https://github.com/thockin)), Patrick Ohly ([pohly](https://github.com/pohly)), Luis Pabon ([lpabon](https://github.com/lpabon)), Cheng Xing ([verult](https://github.com/verult)), Jing Xu ([jingxu97](https://github.com/jingxu97)), Shiwei Xu ([wackxu](https://github.com/wackxu)), Xing Yang ([xing-yang](https://github.com/xing-yang)), Jie Yu ([jieyu](https://github.com/jieyu)), David Zhu ([davidz627](https://github.com/davidz627)). + +Those interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system, join the [Kubernetes Storage Special Interest Group](https://github.com/kubernetes/community/tree/master/sig-storage) (SIG). We’re rapidly growing and always welcome new contributors. + +We also hold regular [SIG-Storage Snapshot Working Group meetings](https://docs.google.com/document/d/1qdfvAj5O-tTAZzqJyz3B-yczLLxOiQd-XKpJmTEMazs/edit?usp=sharing). New attendees are welcome to join for design and development discussions. diff --git a/content/en/blog/_posts/2019-02-06-poseidon-firmament-scheduler-announcement.md b/content/en/blog/_posts/2019-02-06-poseidon-firmament-scheduler-announcement.md new file mode 100644 index 0000000000..12b3cf21af --- /dev/null +++ b/content/en/blog/_posts/2019-02-06-poseidon-firmament-scheduler-announcement.md @@ -0,0 +1,70 @@ +--- +title: Poseidon-Firmament Scheduler – Flow Network Graph Based Scheduler +date: 2019-02-06 +--- + +**Authors:** Deepak Vij (Huawei), Shivram Shrivastava (Huawei) + +## Introduction + +Cluster Management systems such as Mesos, Google Borg, Kubernetes etc. in a cloud scale datacenter environment (also termed as ***Datacenter-as-a-Computer*** or ***Warehouse-Scale Computing - WSC***) typically manage application workloads by performing tasks such as tracking machine live-ness, starting, monitoring, terminating workloads and more importantly using a **Cluster Scheduler** to decide on workload placements. + +A **Cluster Scheduler** essentially performs the scheduling of workloads to compute resources – combining the global placement of work across the WSC environment makes the “warehouse-scale computer” more efficient, increases utilization, and saves energy. **Cluster Scheduler** examples are Google Borg, Kubernetes, Firmament, Mesos, Tarcil, Quasar, Quincy, Swarm, YARN, Nomad, Sparrow, Apollo etc. + +In this blog post, we briefly describe the novel Firmament flow network graph based scheduling approach ([OSDI paper](https://www.usenix.org/conference/osdi16/technical-sessions/presentation/gog)) in Kubernetes. We specifically describe the Firmament Scheduler and how it integrates with the Kubernetes cluster manager using Poseidon as the integration glue. We have seen extremely impressive scheduling throughput performance benchmarking numbers with this novel scheduling approach. Originally, Firmament Scheduler was conceptualized, designed and implemented by University of Cambridge researchers, [Malte Schwarzkopf](http://www.malteschwarzkopf.de/) & [Ionel Gog](http://ionelgog.org/). + +## Poseidon-Firmament Scheduler – How It Works + +At a very high level, [Poseidon-Firmament scheduler](https://kubernetes.io/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler/) augments the current Kubernetes scheduling capabilities by incorporating novel flow network graph based scheduling capabilities alongside the default Kubernetes Scheduler. It models the scheduling problem as a constraint-based optimization over a flow network graph – by reducing scheduling to a min-cost max-flow optimization problem. Due to the inherent rescheduling capabilities, the new scheduler enables a globally optimal scheduling environment that constantly keeps refining the workloads placements dynamically. + +## Key Advantages + +Flow graph scheduling based [Poseidon-Firmament scheduler](https://kubernetes.io/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler/) provides the following key advantages: + + * Workloads (pods) are bulk scheduled to enable scheduling decisions at massive scale. + + * Based on the extensive performance test results, Poseidon-Firmament scales much better than 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. + + * Availability of complex rule constraints. + + * Scheduling in Poseidon-Firmament is very dynamic; it keeps cluster resources in a global optimal state during every scheduling run. + + * Highly efficient resource utilizations. + +## Firmament Flow Network Graph – An Overview + +Firmament scheduler runs a min-cost flow algorithm over the flow network to find an optimal flow, from which it extracts the implied workload (pod placements). A flow network is a directed graph whose arcs carry flow from source nodes (i.e. pod nodes) to a sink node. A cost and capacity associated with each arc constrain the flow, and specify preferential routes for it. + +Figure 1 below shows an example of a flow network for a cluster with two tasks (workloads or pods) and four machines (nodes) – each workload on the left hand side, is a source of one unit of flow. All such flow must be drained into the sink node (S) for a feasible solution to the optimization problem. + +{{
}} + + + +## Poseidon Mediation Layer – An Overview + +Poseidon is a service that acts as the integration glue for the Firmament scheduler with Kubernetes. It augments the current Kubernetes scheduling capabilities by incorporating new flow network graph based Firmament scheduling capabilities alongside the default Kubernetes Scheduler; multiple schedulers running simultaneously. Figure 2 below describes the high level overall design as far as how Poseidon integration glue works in conjunction with the underlying Firmament flow network graph based scheduler. + +{{
}} + +As part of the Kubernetes multiple schedulers support, each new pod is typically scheduled by the default scheduler, but Kubernetes can be instructed to use another scheduler by specifying the name of another custom scheduler (in our case, [Poseidon-Firmament](https://kubernetes.io/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler/)) at the time of pod deployment. In this case, the default scheduler will ignore that Pod and allow Poseidon scheduler to schedule the Pod to a relevant node. + +{{< 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 + +[Poseidon-Firmament scheduler](https://kubernetes.io/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler/) enables extremely high throughput scheduling environment at scale due to its bulk scheduling approach superiority versus K8s 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 is uniform across jobs (Replicasets/Deployments/Jobs), mainly due to efficient amortization of work across jobs. + +Although, [Poseidon-Firmament scheduler](https://kubernetes.io/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler/) is capable of scheduling various types of workloads (service, batch, etc.), following are the few use cases where it excels the most: + + 1. For “Big Data/AI” jobs consisting of a large number of tasks, throughput benefits are tremendous. + + 2. Substantial throughput benefits also for service or batch job scenarios where workload resource requirements are uniform across jobs (Replicasets/Deplyments/Jobs). + +## Current Project Stage + +Currently Poseidon-Firmament project is an incubation project. Alpha Release is available at https://github.com/kubernetes-sigs/poseidon. diff --git a/content/en/blog/_posts/2019-02-11-runc-CVE-2019-5736.md b/content/en/blog/_posts/2019-02-11-runc-CVE-2019-5736.md new file mode 100644 index 0000000000..84482daf79 --- /dev/null +++ b/content/en/blog/_posts/2019-02-11-runc-CVE-2019-5736.md @@ -0,0 +1,96 @@ +--- +title: Runc and CVE-2019-5736 +date: 2019-02-11 +--- + +This morning [a container escape vulnerability in runc was announced](https://www.openwall.com/lists/oss-security/2019/02/11/2). We wanted to provide some guidance to Kubernetes users to ensure everyone is safe and secure. + +## What Is Runc? + +Very briefly, runc is the low-level tool which does the heavy lifting of spawning a Linux container. Other tools like Docker, Containerd, and CRI-O sit on top of runc to deal with things like data formatting and serialization, but runc is at the heart of all of these systems. + +Kubernetes in turn sits on top of those tools, and so while no part of Kubernetes itself is vulnerable, most Kubernetes installations are using runc under the hood. + +### What Is The Vulnerability? + +While full details are still embargoed to give people time to patch, the rough version is that when running a process as root (UID 0) inside a container, that process can exploit a bug in runc to gain root privileges on the host running the container. This then allows them unlimited access to the server as well as any other containers on that server. + +If the process inside the container is either trusted (something you know is not hostile) or is not running as UID 0, then the vulnerability does not apply. It can also be prevented by SELinux, if an appropriate policy has been applied. RedHat Enterprise Linux and CentOS both include appropriate SELinux permissions with their packages and so are believed to be unaffected if SELinux is enabled. + +The most common source of risk is attacker-controller container images, such as unvetted images from public repositories. + +### What Should I Do? + +As with all security issues, the two main options are to mitigate the vulnerability or upgrade your version of runc to one that includes the fix. + +As the exploit requires UID 0 within the container, a direct mitigation is to ensure all your containers are running as a non-0 user. This can be set within the container image, or via your pod specification: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: run-as-uid-1000 +spec: + securityContext: + runAsUser: 1000 + # ... +``` + +This can also be enforced globally using a PodSecurityPolicy: + +```yaml +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: non-root +spec: + privileged: false + allowPrivilegeEscalation: false + runAsUser: + # Require the container to run without root privileges. + rule: 'MustRunAsNonRoot' +``` + +Setting a policy like this is highly encouraged given the overall risks of running as UID 0 inside a container. + +Another potential mitigation is to ensure all your container images are vetted and trusted. This can be accomplished by building all your images yourself, or by vetting the contents of an image and then pinning to the image version hash (`image: external/someimage@sha256:7832659873hacdef`). + +Upgrading runc can generally be accomplished by upgrading the package `runc` for your distribution or by upgrading your OS image if using immutable images. This is a list of known safe versions for various distributions and platforms: + +* Ubuntu - [`runc 1.0.0~rc4+dfsg1-6ubuntu0.18.10.1`](https://people.canonical.com/~ubuntu-security/cve/2019/CVE-2019-5736.html) +* Debian - [`runc 1.0.0~rc6+dfsg1-2`](https://security-tracker.debian.org/tracker/CVE-2019-5736) +* RedHat Enterprise Linux - [`docker 1.13.1-91.git07f3374.el7`](https://access.redhat.com/security/vulnerabilities/runcescape) (if SELinux is disabled) +* Amazon Linux - [`docker 18.06.1ce-7.25.amzn1.x86_64`](https://alas.aws.amazon.com/ALAS-2019-1156.html) +* CoreOS - Stable: [`1967.5.0`](https://coreos.com/releases/#1967.5.0) / Beta: [`2023.2.0`](https://coreos.com/releases/#2023.2.0) / Alpha: [`2051.0.0`](https://coreos.com/releases/#2051.0.0) +* Kops Debian - [in progress](https://github.com/kubernetes/kops/pull/6460) (see [advisory](https://github.com/kubernetes/kops/blob/master/docs/advisories/cve_2019_5736.md) for how to address until Kops Debian is patched) +* Docker - [`18.09.2`](https://github.com/docker/docker-ce/releases/tag/v18.09.2) + +Some platforms have also posted more specific instructions: + +#### Google Container Engine (GKE) + +Google has issued a [security bulletin](https://cloud.google.com/kubernetes-engine/docs/security-bulletins#february-11-2019-runc) with more detailed information but in short, if you are using the default GKE node image then you are safe. If you are using an Ubuntu node image then you will need to mitigate or upgrade to an image with a fixed version of runc. + +#### Amazon Elastic Container Service for Kubernetes (EKS) + +Amazon has also issued a [security bulletin](https://aws.amazon.com/security/security-bulletins/AWS-2019-002/) with more detailed information. All EKS users should mitigate the issue or upgrade to a new node image. + +#### Azure Kubernetes Service (AKS) + +Microsoft has issued a [security bulletin](https://azure.microsoft.com/en-us/updates/cve-2019-5736-and-runc-vulnerability/) with detailed information on mitigating the issue. Microsoft recommends all AKS users to upgrade their cluster to mitigate the issue. + +#### Kops + +Kops has issued an [advisory](https://github.com/kubernetes/kops/blob/master/docs/advisories/cve_2019_5736.md) with detailed information on mitigating this issue. + +### Docker + +We don't have specific confirmation that Docker for Mac and Docker for Windows are vulnerable, however it seems likely. Docker has released a fix in [version 18.09.2](https://github.com/docker/docker-ce/releases/tag/v18.09.2) and it is recommended you upgrade to it. This also applies to other deploy systems using Docker under the hood. + +If you are unable to upgrade Docker, the Rancher team has provided backports of the fix for many older versions at [github.com/rancher/runc-cve](https://github.com/rancher/runc-cve). + +## Getting More Information + +If you have any further questions about how this vulnerability impacts Kubernetes, please join us at [discuss.kubernetes.io](https://discuss.kubernetes.io/). + +If you would like to get in contact with the [runc team](https://github.com/opencontainers/org/blob/master/README.md#communications), you can reach them on [Google Groups](https://groups.google.com/a/opencontainers.org/forum/#!forum/dev) or `#opencontainers` on Freenode IRC. diff --git a/content/en/blog/_posts/2019-02-12-building-a-kubernetes-edge-control-plane-for-envoy-v2.md b/content/en/blog/_posts/2019-02-12-building-a-kubernetes-edge-control-plane-for-envoy-v2.md new file mode 100644 index 0000000000..7751712f0e --- /dev/null +++ b/content/en/blog/_posts/2019-02-12-building-a-kubernetes-edge-control-plane-for-envoy-v2.md @@ -0,0 +1,107 @@ +--- +title: Building a Kubernetes Edge (Ingress) Control Plane for Envoy v2 +date: 2019-02-12 +slug: building-a-kubernetes-edge-control-plane-for-envoy-v2 +--- + + +**Author:** +Daniel Bryant, Product Architect, Datawire; +Flynn, Ambassador Lead Developer, Datawire; +Richard Li, CEO and Co-founder, Datawire + + +Kubernetes has become the de facto runtime for container-based microservice applications, but this orchestration framework alone does not provide all of the infrastructure necessary for running a distributed system. Microservices typically communicate through Layer 7 protocols such as HTTP, gRPC, or WebSockets, and therefore having the ability to make routing decisions, manipulate protocol metadata, and observe at this layer is vital. However, traditional load balancers and edge proxies have predominantly focused on L3/4 traffic. This is where the [Envoy Proxy](https://www.envoyproxy.io/) comes into play. + +Envoy proxy was designed as a [universal data plane](https://blog.envoyproxy.io/the-universal-data-plane-api-d15cec7a) from the ground-up by the Lyft Engineering team for today's distributed, L7-centric world, with broad support for L7 protocols, a real-time API for managing its configuration, first-class observability, and high performance within a small memory footprint. However, Envoy's vast feature set and flexibility of operation also makes its configuration highly complicated -- this is evident from looking at its rich but verbose [control plane](https://blog.envoyproxy.io/service-mesh-data-plane-vs-control-plane-2774e720f7fc) syntax. + +With the open source [Ambassador API Gateway](https://www.getambassador.io), we wanted to tackle the challenge of creating a new control plane that focuses on the use case of deploying Envoy as an forward-facing edge proxy within a Kubernetes cluster, in a way that is idiomatic to Kubernetes operators. In this article, we'll walk through two major iterations of the Ambassador design, and how we integrated Ambassador with Kubernetes. + + +## Ambassador pre-2019: Envoy v1 APIs, Jinja Template Files, and Hot Restarts + +Ambassador itself is deployed within a container as a Kubernetes service, and uses annotations added to Kubernetes Services as its [core configuration model](https://www.getambassador.io/reference/configuration). This approach [enables application developers to manage routing](https://www.getambassador.io/concepts/developers) as part of the Kubernetes service definition. We explicitly decided to go down this route because of [limitations](https://blog.getambassador.io/kubernetes-ingress-nodeport-load-balancers-and-ingress-controllers-6e29f1c44f2d) in the current [Ingress API spec](https://kubernetes.io/docs/concepts/services-networking/ingress/), and we liked the simplicity of extending Kubernetes services, rather than introducing another custom resource type. An example of an Ambassador annotation can be seen here: + + +``` +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + getambassador.io/config: | + --- + apiVersion: ambassador/v0 + kind: Mapping + name: my_service_mapping + prefix: /my-service/ + service: my-service +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +``` + + +Translating this simple Ambassador annotation config into valid [Envoy v1](https://www.envoyproxy.io/docs/envoy/v1.6.0/configuration/overview/v1_overview) config was not a trivial task. By design, Ambassador's configuration isn't based on the same conceptual model as Envoy's configuration -- we deliberately wanted to aggregate and simplify operations and config. Therefore, translating between one set of concepts to the other involves a fair amount of logic within Ambassador. + +In this first iteration of Ambassador we created a Python-based service that watched the Kubernetes API for changes to Service objects. When new or updated Ambassador annotations were detected, these were translated from the Ambassador syntax into an intermediate representation (IR) which embodied our core configuration model and concepts. Next, Ambassador translated this IR into a representative Envoy configuration which was saved as a file within pods associated with the running Ambassador k8s Service. Ambassador then "hot-restarted" the Envoy process running within the Ambassador pods, which triggered the loading of the new configuration. + +There were many benefits with this initial implementation. The mechanics involved were fundamentally simple, the transformation of Ambassador config into Envoy config was reliable, and the file-based hot restart integration with Envoy was dependable. + +However, there were also notable challenges with this version of Ambassador. First, although the hot restart was effective for the majority of our customers' use cases, it was not very fast, and some customers (particularly those with huge application deployments) found it was limiting the frequency with which they could change their configuration. Hot restart can also drop connections, especially long-lived connections like WebSockets or gRPC streams. + +More crucially, though, the first implementation of the IR allowed rapid prototyping but was primitive enough that it proved very difficult to make substantial changes. While this was a pain point from the beginning, it became a critical issue as Envoy shifted to the [Envoy v2 API](https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/v2_overview). It was clear that the v2 API would offer Ambassador many benefits -- as Matt Klein outlined in his blog post, "[The universal data plane API](https://blog.envoyproxy.io/the-universal-data-plane-api-d15cec7a)" -- including access to new features and a solution to the connection-drop problem noted above, but it was also clear that the existing IR implementation was not capable of making the leap. + + +## Ambassador >= v0.50: Envoy v2 APIs (ADS), Testing with KAT, and Golang + +In consultation with the [Ambassador community](http://d6e.co/slack), the [Datawire](www.datawire.io) team undertook a redesign of the internals of Ambassador in 2018. This was driven by two key goals. First, we wanted to integrate Envoy's v2 configuration format, which would enable the support of features such as [SNI](https://www.getambassador.io/user-guide/sni/), [rate limiting](https://www.getambassador.io/user-guide/rate-limiting) and [gRPC authentication APIs](https://www.getambassador.io/user-guide/auth-tutorial). Second, we also wanted to do much more robust semantic validation of Envoy configuration due to its increasing complexity (particularly when operating with large-scale application deployments). + + +### Initial stages + +We started by restructuring the Ambassador internals more along the lines of a multipass compiler. The class hierarchy was made to more closely mirror the separation of concerns between the Ambassador configuration resources, the IR, and the Envoy configuration resources. Core parts of Ambassador were also redesigned to facilitate contributions from the community outside Datawire. We decided to take this approach for several reasons. First, Envoy Proxy is a very fast moving project, and we realized that we needed an approach where a seemingly minor Envoy configuration change didn't result in days of reengineering within Ambassador. In addition, we wanted to be able to provide semantic verification of configuration. + +As we started working more closely with Envoy v2, a testing challenge was quickly identified. As more and more features were being supported in Ambassador, more and more bugs appeared in Ambassador's handling of less common but completely valid combinations of features. This drove to creation of a new testing requirement that meant Ambassador's test suite needed to be reworked to automatically manage many combinations of features, rather than relying on humans to write each test individually. Moreover, we wanted the test suite to be fast in order to maximize engineering productivity. + +Thus, as part of the Ambassador rearchitecture, we introduced the [Kubernetes Acceptance Test (KAT)](https://github.com/datawire/ambassador/tree/master/kat) framework. KAT is an extensible test framework that: + + + +1. Deploys a bunch of services (along with Ambassador) to a Kubernetes cluster +1. Run a series of verification queries against the spun up APIs +1. Perform a bunch of assertions on those query results + +KAT is designed for performance -- it batches test setup upfront, and then runs all the queries in step 3 asynchronously with a high performance client. The traffic driver in KAT runs locally using [Telepresence](https://www.telepresence.io), which makes it easier to debug issues. + +### Introducing Golang to the Ambassador Stack + +With the KAT test framework in place, we quickly ran into some issues with Envoy v2 configuration and hot restart, which presented the opportunity to switch to use Envoy’s Aggregated Discovery Service (ADS) APIs instead of hot restart. This completely eliminated the requirement for restart on configuration changes, which we found could lead to dropped connection under high loads or long-lived connections. + +However, we faced an interesting question as we considered the move to the ADS. The ADS is not as simple as one might expect: there are explicit ordering dependencies when sending updates to Envoy. The Envoy project has reference implementations of the ordering logic, but only in Go and Java, where Ambassador was primarily in Python. We agonized a bit, and decided that the simplest way forward was to accept the polyglot nature of our world, and do our ADS implementation in Go. + +We also found, with KAT, that our testing had reached the point where Python’s performance with many network connections was a limitation, so we took advantage of Go here, as well, writing KAT’s querying and backend services primarily in Go. After all, what’s another Golang dependency when you’ve already taken the plunge? + +With a new test framework, new IR generating valid Envoy v2 configuration, and the ADS, we thought we were done with the major architectural changes in Ambassador 0.50. Alas, we hit one more issue. On the Azure Kubernetes Service, Ambassador annotation changes were no longer being detected. + +Working with the highly-responsive AKS engineering team, we were able to identify the issue -- namely, the Kubernetes API server in AKS is exposed through a chain of proxies, requiring clients to be updating to understand how to connect using the FQDN of the API server, which is provided through a mutating webhook in AKS. Unfortunately, support for this feature was not available in the official Kubernetes Python client, so this was the third spot where we chose to switch to Go instead of Python. + +This raises the interesting question of, “why not ditch all the Python code, and just rewrite Ambassador entirely in Go?” It’s a valid question. The main concern with a rewrite is that Ambassador and Envoy operate at different conceptual levels rather than simply expressing the same concepts with different syntax. Being certain that we’ve expressed the conceptual bridges in a new language is not a trivial challenge, and not something to undertake without already having really excellent test coverage in place + +At this point, we use Go to coverage very specific, well-contained functions that can be verified for correctness much more easily that we could verify a complete Golang rewrite. In the future, who knows? But for 0.50.0, this functional split let us both take advantage of Golang’s strengths, while letting us retain more confidence about all the changes already in 0.50. + +## Lessons Learned + +We've learned a lot in the process of building [Ambassador 0.50](https://blog.getambassador.io/ambassador-0-50-ga-release-notes-sni-new-authservice-and-envoy-v2-support-3b30a4d04c81). Some of our key takeaways: + +* Kubernetes and Envoy are very powerful frameworks, but they are also extremely fast moving targets -- there is sometimes no substitute for reading the source code and talking to the maintainers (who are fortunately all quite accessible!) +* The best supported libraries in the Kubernetes / Envoy ecosystem are written in Go. While we love Python, we have had to adopt Go so that we're not forced to maintain too many components ourselves. +* Redesigning a test harness is sometimes necessary to move your software forward. +* The real cost in redesigning a test harness is often in porting your old tests to the new harness implementation. +* Designing (and implementing) an effective control plane for the edge proxy use case has been challenging, and the feedback from the open source community around Kubernetes, Envoy and Ambassador has been extremely useful. + +Migrating Ambassador to the Envoy v2 configuration and ADS APIs was a long and difficult journey that required lots of architecture and design discussions and plenty of coding, but early feedback from results have been positive. [Ambassador 0.50 is available now](https://blog.getambassador.io/announcing-ambassador-0-50-8dffab5b05e0), so you can take it for a test run and share your feedback with the community on our [Slack channel](http://d6e.co/slack) or on [Twitter](https://www.twitter.com/getambassadorio). diff --git a/content/en/blog/_posts/2019-02-28-automate-operations-on-your-cluster-with-operatorhub.md b/content/en/blog/_posts/2019-02-28-automate-operations-on-your-cluster-with-operatorhub.md new file mode 100644 index 0000000000..a8f91716e7 --- /dev/null +++ b/content/en/blog/_posts/2019-02-28-automate-operations-on-your-cluster-with-operatorhub.md @@ -0,0 +1,67 @@ +--- +title: Automate Operations on your Cluster with OperatorHub.io +date: 2019-02-28 +--- + +**Author:** +Diane Mueller, Director of Community Development, Cloud Platforms, Red Hat + +One of the important challenges facing developers and Kubernetes administrators has been a lack of ability to quickly find common services that are operationally ready for Kubernetes. Typically, the presence of an Operator for a specific service - a pattern that was introduced in 2016 and has gained momentum - is a good signal for the operational readiness of the service on Kubernetes. However, there has to date not existed a registry of Operators to simplify the discovery of such services. + +To help address this challenge, today Red Hat is launching OperatorHub.io in collaboration with AWS, Google Cloud and Microsoft. OperatorHub.io enables developers and Kubernetes administrators to find and install curated Operator-backed services with a base level of documentation, active maintainership by communities or vendors, basic testing, and packaging for optimized life-cycle management on Kubernetes. + +The Operators currently in OperatorHub.io are just the start. We invite the Kubernetes community to join us in building a vibrant community for Operators by developing, packaging, and publishing Operators on OperatorHub.io. + +## What does OperatorHub.io provide? + +OperatorHub.io is designed to address the needs of both Kubernetes developers and users. For the former it provides a common registry where they can publish their Operators alongside with descriptions, relevant details like version, image, code repository and have them be readily packaged for installation. They can also update already published Operators to new versions when they are released. + + +Users get the ability to discover and download Operators at a central location, that has content which has been screened for the previously mentioned criteria and scanned for known vulnerabilities. In addition, developers can guide users of their Operators with prescriptive examples of the `CustomResources` that they introduce to interact with the application. + +## What is an Operator? + +Operators were first introduced in 2016 by CoreOS and have been used by Red Hat and the Kubernetes community as a way to package, deploy and manage a Kubernetes-native application. A Kubernetes-native application is an application that is both deployed on Kubernetes and managed using the Kubernetes APIs and well-known tooling, like kubectl. + +An Operator is implemented as a custom controller that watches for certain Kubernetes resources to appear, be modified or deleted. These are typically `CustomResourceDefinitions` that the Operator “owns.” In the spec properties of these objects the user declares the desired state of the application or the operation. The Operator’s reconciliation loop will pick these up and perform the required actions to achieve the desired state. For example, the intent to create a highly available etcd cluster could be expressed by creating an new resource of type `EtcdCluster`: + +``` +apiVersion: "etcd.database.coreos.com/v1beta2" +kind: "EtcdCluster" +metadata: + name: "my-etcd-cluster" +spec: + size: 3 + version: "3.3.12" +``` + +The `EtcdOperator` would be responsible for creating a 3-node etcd cluster running version v3.3.12 as a result. Similarly, an object of type `EtcdBackup` could be defined to express the intent to create a consistent backup of the etcd database to an S3 bucket. + +## How do I create and run an Operator? + +One way to get started is with the [Operator Framework](https://github.com/operator-framework), an open source toolkit that provides an SDK, lifecycle management, metering and monitoring capabilities. It enables developers to build, test, and package Operators. Operators can be implemented in several programming and automation languages, including Go, Helm, and Ansible, all three of which are supported directly by the SDK. + +If you are interested in creating your own Operator, we recommend checking out the Operator Framework to [get started](https://github.com/operator-framework/getting-started). + +Operators vary in where they fall along [the capability spectrum](https://github.com/operator-framework/operator-sdk/blob/master/doc/images/operator-maturity-model.png) ranging from basic functionality to having specific operational logic for an application to automate advanced scenarios like backup, restore or tuning. Beyond basic installation, advanced Operators are designed to handle upgrades more seamlessly and react to failures automatically. Currently, Operators on OperatorHub.io span the maturity spectrum, but we anticipate their continuing maturation over time. + +While Operators on OperatorHub.io don’t need to be implemented using the SDK, they are packaged for deployment through the [Operator Lifecycle Manager](https://github.com/operator-framework/operator-lifecycle-manager) (OLM). The format mainly consists of a YAML manifest referred to as `[ClusterServiceVersion]`(https://github.com/operator-framework/operator-lifecycle-manager/blob/master/Documentation/design/building-your-csv.md) which provides information about the `CustomResourceDefinitions` the Operator owns or requires, which RBAC definition it needs, where the image is stored, etc. This file is usually accompanied by additional YAML files which define the Operators’ own CRDs. This information is processed by OLM at the time a user requests to install an Operator to provide dependency resolution and automation. + +## What does listing of an Operator on OperatorHub.io mean? + +To be listed, Operators must successfully show cluster lifecycle features, be packaged as a CSV to be maintained through OLM, and have acceptable documentation for its intended users. + +Some examples of Operators that are currently listed on OperatorHub.io include: Amazon Web Services Operator, Couchbase Autonomous Operator, CrunchyData’s PostgreSQL, etcd Operator, Jaeger Operator for Kubernetes, Kubernetes Federation Operator, MongoDB Enterprise Operator, Percona MySQL Operator, PlanetScale’s Vitess Operator, Prometheus Operator, and Redis Operator. + +## Want to add your Operator to OperatorHub.io? Follow these steps + +If you have an existing Operator, follow the [contribution guide](https://www.operatorhub.io/contribute) using a fork of the [community-operators](https://github.com/operator-framework/community-operators/) repository. Each contribution contains the CSV, all of the `CustomResourceDefinitions`, access control rules and references to the container image needed to install and run your Operator, plus other info like a description of its features and supported Kubernetes versions. A complete example, including multiple versions of the Operator, can be found with the [EtcdOperator](https://github.com/operator-framework/community-operators/tree/master/community-operators/etcd). + +After testing out your Operator on your own cluster, submit a PR to the [community repository](https://github.com/operator-framework/community-operators) with all of YAML files following [this directory structure](https://github.com/operator-framework/community-operators#adding-your-operator). Subsequent versions of the Operator can be published in the same way. At first this will be reviewed manually, but automation is on the way. After it’s merged by the maintainers, it will show up on OperatorHub.io along with its documentation and a convenient installation method. + +## Want to learn more? + +- Attend one of the upcoming Kubernetes Operator Framework hands-on workshops at [ScaleX](https://www.socallinuxexpo.org/scale/17x/presentations/workshop-kubernetes-operator-framework) in Pasadena on March 7 and at the [OpenShift Commons Gathering on Operating at Scale in Santa Clara on March 11](https://commons.openshift.org/gatherings/Santa_Clara_2019.html) +- Listen to this [OpenShift Commons Briefing on “The State of Operators” with Daniel Messer and Diane Mueller](https://www.youtube.com/watch?v=GgEKEYH9MMM&feature=youtu.be) +- Join in on the online conversations in the community [Kubernetes-Operator Slack Channel](https://kubernetes.slack.com/messages/CAW0GV7A5) and the [Operator Framework Google Group](https://groups.google.com/forum/#!forum/operator-framework) +- Finally, read up on how to add your Operator to OperatorHub.io: https://operatorhub.io/contribute diff --git a/content/en/blog/_posts/2019-03-07-raw-block-volume-support-to-beta.md b/content/en/blog/_posts/2019-03-07-raw-block-volume-support-to-beta.md new file mode 100644 index 0000000000..fc08eadf83 --- /dev/null +++ b/content/en/blog/_posts/2019-03-07-raw-block-volume-support-to-beta.md @@ -0,0 +1,131 @@ +--- +title: Raw Block Volume support to Beta +date: 2019-03-07 +--- + +**Authors:** +Ben Swartzlander (NetApp), Saad Ali (Google) + +Kubernetes v1.13 moves raw block volume support to beta. This feature allows persistent volumes to be exposed inside containers as a block device instead of as a mounted file system. + +## What are block devices? + +Block devices enable random access to data in fixed-size blocks. Hard drives, SSDs, and CD-ROMs drives are all examples of block devices. + +Typically persistent storage is implemented in a layered maner with a file system (like ext4) on top of a block device (like a spinning disk or SSD). Applications then read and write files instead of operating on blocks. The operating systems take care of reading and writing files, using the specified filesystem, to the underlying device as blocks. + +It's worth noting that while whole disks are block devices, so are disk partitions, and so are LUNs from a storage area network (SAN) device. + +## Why add raw block volumes to kubernetes? + +There are some specialized applications that require direct access to a block device because, for example, the file system layer introduces unneeded overhead. The most common case is databases, which prefer to organize their data directly on the underlying storage. Raw block devices are also commonly used by any software which itself implements some kind of storage service (software defined storage systems). + +From a programmer's perspective, a block device is a very large array of bytes, usually with some minimum granularity for reads and writes, often 512 bytes, but frequently 4K or larger. + +As it becomes more common to run database software and storage infrastructure software inside of Kubernetes, the need for raw block device support in Kubernetes becomes more important. + +## Which volume plugins support raw blocks? + +As of the publishing of this blog, the following in-tree volumes types support raw blocks: + +- AWS EBS +- Azure Disk +- Cinder +- Fibre Channel +- GCE PD +- iSCSI +- Local volumes +- RBD (Ceph) +- Vsphere + +Out-of-tree [CSI volume drivers](https://kubernetes.io/blog/2019/01/15/container-storage-interface-ga/) may also support raw block volumes. Kubernetes CSI support for raw block volumes is currently alpha. See documentation [here](https://kubernetes-csi.github.io/docs/raw-block.html). + +## Kubernetes raw block volume API + +Raw block volumes share a lot in common with ordinary volumes. Both are requested by creating `PersistentVolumeClaim` objects which bind to `PersistentVolume` objects, and are attached to Pods in Kubernetes by including them in the volumes array of the `PodSpec`. + +There are 2 important differences however. First, to request a raw block `PersistentVolumeClaim`, you must set `volumeMode = "Block"` in the `PersistentVolumeClaimSpec`. Leaving `volumeMode` blank is the same as specifying `volumeMode = "Filesystem"` which results in the traditional behavior. `PersistentVolumes` also have a `volumeMode` field in their `PersistentVolumeSpec`, and `"Block"` type PVCs can only bind to `"Block"` type PVs and `"Filesystem"` PVCs can only bind to `"Filesystem"` PVs. + +Secondly, when using a raw block volume in your Pods, you must specify a `VolumeDevice` in the Container portion of the `PodSpec` rather than a `VolumeMount`. `VolumeDevices` have `devicePaths` instead of `mountPaths`, and inside the container, applications will see a device at that path instead of a mounted file system. + +Applications open, read, and write to the device node inside the container just like they would interact with any block device on a system in a non-containerized or virtualized context. + +## Creating a new raw block PVC + +First, ensure that the provisioner associated with the storage class you choose is one that support raw blocks. Then create the PVC. + +``` +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: my-pvc +spec: + accessModes: + - ReadWriteMany + volumeMode: Block + storageClassName: my-sc + resources: + requests: + storage: 1Gi +``` + +## Using a raw block PVC + +When you use the PVC in a pod definition, you get to choose the device path for the block device rather than the mount path for the file system. + +``` +apiVersion: v1 +kind: Pod +metadata: + name: my-pod +spec: + containers: + - name: my-container + image: busybox + command: + - sleep + - “3600” + volumeDevices: + - devicePath: /dev/block + name: my-volume + imagePullPolicy: IfNotPresent + volumes: + - name: my-volume + persistentVolumeClaim: + claimName: my-pvc +``` + +## As a storage vendor, how do I add support for raw block devices to my CSI plugin? + +Raw block support for CSI plugins is still alpha, but support can be added today. The [CSI specification](https://github.com/container-storage-interface/spec/blob/master/spec.md) details how to handle requests for volume that have the `BlockVolume` capability instead of the `MountVolume` capability. CSI plugins can support both kinds of volumes, or one or the other. For more details see [documentation here](https://kubernetes-csi.github.io/docs/raw-block.html). + + +## Issues/gotchas + +Because block devices are actually devices, it’s possible to do low-level actions on them from inside containers that wouldn’t be possible with file system volumes. For example, block devices that are actually SCSI disks support sending SCSI commands to the device using Linux ioctls. + +By default, Linux won’t allow containers to send SCSI commands to disks from inside containers though. In order to do so, you must grant the `SYS_RAWIO` capability to the container security context to allow this. See documentation [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container). + +Also, while Kubernetes is guaranteed to deliver a block device to the container, there’s no guarantee that it’s actually a SCSI disk or any other kind of disk for that matter. The user must either ensure that the desired disk type is used with his pods, or only deploy applications that can handle a variety of block device types. + +## How can I learn more? + +Check out additional documentation on the snapshot feature here: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#raw-block-volume-support + +How do I get involved? + +Join the Kubernetes storage SIG and the CSI community and help us add more great features and improve existing ones like raw block storage! + +https://github.com/kubernetes/community/tree/master/sig-storage +https://github.com/container-storage-interface/community/blob/master/README.md + +Special thanks to all the contributors who helped add block volume support to Kubernetes including: + +- Ben Swartzlander (https://github.com/bswartz) +- Brad Childs (https://github.com/childsb) +- Erin Boyd (https://github.com/erinboyd) +- Masaki Kimura (https://github.com/mkimuram) +- Matthew Wong (https://github.com/wongma7) +- Michelle Au (https://github.com/msau42) +- Mitsuhiro Tanino (https://github.com/mtanino) +- Saad Ali (https://github.com/saad-ali) diff --git a/content/en/blog/_posts/Kubernetes-setup-using-Ansible-and-Vagrant.md b/content/en/blog/_posts/Kubernetes-setup-using-Ansible-and-Vagrant.md new file mode 100644 index 0000000000..0ea0892d78 --- /dev/null +++ b/content/en/blog/_posts/Kubernetes-setup-using-Ansible-and-Vagrant.md @@ -0,0 +1,253 @@ +--- +layout: blog +title: Kubernetes Setup Using Ansible and Vagrant +date: 2019-03-15 +--- + +**Author:** Naresh L J (Infosys) + +## Objective +This blog post describes the steps required to setup a multi node Kubernetes cluster for development purposes. This setup provides a production-like cluster that can be setup on your local machine. + +## Why do we require multi node cluster setup? +Multi node Kubernetes clusters offer a production-like environment which has various advantages. Even though Minikube provides an excellent platform for getting started, it doesn't provide the opportunity to work with multi node clusters which can help solve problems or bugs that are related to application design and architecture. For instance, Ops can reproduce an issue in a multi node cluster environment, Testers can deploy multiple versions of an application for executing test cases and verifying changes. These benefits enable teams to resolve issues faster which make the more agile. + +## Why use Vagrant and Ansible? +Vagrant is a tool that will allow us to create a virtual environment easily and it eliminates pitfalls that cause the works-on-my-machine phenomenon. It can be used with multiple providers such as Oracle VirtualBox, VMware, Docker, and so on. It allows us to create a disposable environment by making use of configuration files. + +Ansible is an infrastructure automation engine that automates software configuration management. It is agentless and allows us to use SSH keys for connecting to remote machines. Ansible playbooks are written in yaml and offer inventory management in simple text files. + + +### Prerequisites +- Vagrant should be installed on your machine. Installation binaries can be found [here](https://www.vagrantup.com/downloads.html). +- Oracle VirtualBox can be used as a Vagrant provider or make use of similar providers as described in Vagrant's official [documentation](https://www.vagrantup.com/docs/providers/). +- Ansible should be installed in your machine. Refer to the [Ansible installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) for platform specific installation. + +## Setup overview +We will be setting up a Kubernetes cluster that will consist of one master and two worker nodes. All the nodes will run Ubuntu Xenial 64-bit OS and Ansible playbooks will be used for provisioning. + +#### Step 1: Creating a Vagrantfile +Use the text editor of your choice and create a file with named `Vagrantfile`, inserting the code below. The value of N denotes the number of nodes present in the cluster, it can be modified accordingly. In the below example, we are setting the value of N as 2. + +```ruby +IMAGE_NAME = "bento/ubuntu-16.04" +N = 2 + +Vagrant.configure("2") do |config| + config.ssh.insert_key = false + + config.vm.provider "virtualbox" do |v| + v.memory = 1024 + v.cpus = 2 + end + + config.vm.define "k8s-master" do |master| + master.vm.box = IMAGE_NAME + master.vm.network "private_network", ip: "192.168.50.10" + master.vm.hostname = "k8s-master" + master.vm.provision "ansible" do |ansible| + ansible.playbook = "kubernetes-setup/master-playbook.yml" + end + end + + (1..N).each do |i| + config.vm.define "node-#{i}" do |node| + node.vm.box = IMAGE_NAME + node.vm.network "private_network", ip: "192.168.50.#{i + 10}" + node.vm.hostname = "node-#{i}" + node.vm.provision "ansible" do |ansible| + ansible.playbook = "kubernetes-setup/node-playbook.yml" + end + end + end +``` + +### Step 2: Create an Ansible playbook for Kubernetes master. +Create a directory named `kubernetes-setup` in the same directory as the `Vagrantfile`. Create two files named `master-playbook.yml` and `node-playbook.yml` in the directory `kubernetes-setup`. + +In the file `master-playbook.yml`, add the code below. + +#### Step 2.1: Install Docker and its dependent components. + +We will be installing the following packages, and then adding a user named “vagrant” to the “docker” group. +- docker-ce +- docker-ce-cli +- containerd.io + +```yaml +--- +- hosts: all + become: true + tasks: + - name: Install packages that allow apt to be used over HTTPS + apt: + name: "{{ packages }}" + state: present + update_cache: yes + vars: + packages: + - apt-transport-https + - ca-certificates + - curl + - gnupg-agent + - software-properties-common + + - name: Add an apt signing key for Docker + apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + + - name: Add apt repository for stable version + apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable + state: present + + - name: Install docker and its dependecies + apt: + name: "{{ packages }}" + state: present + update_cache: yes + vars: + packages: + - docker-ce + - docker-ce-cli + - containerd.io + notify: + - docker status + + - name: Add vagrant user to docker group + user: + name: vagrant + group: docker +``` + +#### Step 2.2: Kubelet will not start if the system has swap enabled, so we are disabling swap using the below code. + +```yaml + - name: Remove swapfile from /etc/fstab + mount: + name: "{{ item }}" + fstype: swap + state: absent + with_items: + - swap + - none + + - name: Disable swap + command: swapoff -a + when: ansible_swaptotal_mb > 0 +``` + +#### Step 2.3: Installing kubelet, kubeadm and kubectl using the below code. + +```yaml + - name: Add an apt signing key for Kubernetes + apt_key: + url: https://packages.cloud.google.com/apt/doc/apt-key.gpg + state: present + + - name: Adding apt repository for Kubernetes + apt_repository: + repo: deb https://apt.kubernetes.io/ kubernetes-xenial main + state: present + filename: kubernetes.list + + - name: Install Kubernetes binaries + apt: + name: "{{ packages }}" + state: present + update_cache: yes + vars: + packages: + - kubelet + - kubeadm + - kubectl +``` + +#### Step 2.3: Initialize the Kubernetes cluster with kubeadm using the below code (applicable only on master node). + +```yaml + - name: Initialize the Kubernetes cluster using kubeadm + command: kubeadm init --apiserver-advertise-address="192.168.50.10" --apiserver-cert-extra-sans="192.168.50.10" --node-name k8s-master --pod-network-cidr=192.168.0.0/16 +``` + +#### Step 2.4: Setup the kube config file for the vagrant user to access the Kubernetes cluster using the below code. + +```yaml + - name: Setup kubeconfig for vagrant user + command: "{{ item }}" + with_items: + - mkdir -p /home/vagrant/.kube + - cp -i /etc/kubernetes/admin.conf /home/vagrant/.kube/config + - chown vagrant:vagrant /home/vagrant/.kube/config +``` + +#### Step 2.5: Setup the container networking provider and the network policy engine using the below code. + +```yaml + - name: Install calico pod network + become: false + command: kubectl create -f https://docs.projectcalico.org/v3.4/getting-started/kubernetes/installation/hosted/calico.yaml +``` + +#### Step 2.6: Generate kube join command for joining the node to the Kubernetes cluster and store the command in the file named `join-command`. + +```yaml + - name: Generate join command + command: kubeadm token create --print-join-command + register: join_command + + - name: Copy join command to local file + local_action: copy content="{{ join_command.stdout_lines[0] }}" dest="./join-command" +``` + +#### Step 2.7: Setup a handler for checking Docker daemon using the below code. + +```yaml + handlers: + - name: docker status + service: name=docker state=started +``` + +#### Step 3: Create the Ansible playbook for Kubernetes node. +Create a file named `node-playbook.yml` in the directory `kubernetes-setup`. + +Add the code below into `node-playbook.yml` + +#### Step 3.1: Start adding the code from Steps 2.1 till 2.3. + +#### Step 3.2: Join the nodes to the Kubernetes cluster using below code. + +```yaml + - name: Copy the join command to server location + copy: src=join-command dest=/tmp/join-command.sh mode=0777 + + - name: Join the node to cluster + command: sh /tmp/join-command.sh +``` + +#### Step 3.3: Add the code from step 2.7 to finish this playbook. + +#### Step 4: Upon completing the Vagrantfile and playbooks follow the below steps. + +```shell +$ cd /path/to/Vagrantfile +$ vagrant up +``` + +Upon completion of all the above steps, the Kubernetes cluster should be up and running. +We can login to the master or worker nodes using Vagrant as follows: + +```shell +$ ## Accessing master +$ vagrant ssh k8s-master +vagrant@k8s-master:~$ kubectl get nodes +NAME STATUS ROLES AGE VERSION +k8s-master Ready master 18m v1.13.3 +node-1 Ready 12m v1.13.3 +node-2 Ready 6m22s v1.13.3 + +$ ## Accessing nodes +$ vagrant ssh node-1 +$ vagrant ssh node-2 +``` diff --git a/content/en/case-studies/OWNERS b/content/en/case-studies/OWNERS index dd978fcd5a..e4131d339e 100644 --- a/content/en/case-studies/OWNERS +++ b/content/en/case-studies/OWNERS @@ -1,3 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + # Owned by Kubernetes Blog reviewers. options: no_parent_owners: false diff --git a/content/en/case-studies/adform/adform_featured_logo.png b/content/en/case-studies/adform/adform_featured_logo.png index 7e3be727e3..cd0fa7b6c9 100644 Binary files a/content/en/case-studies/adform/adform_featured_logo.png and b/content/en/case-studies/adform/adform_featured_logo.png differ diff --git a/content/en/case-studies/ibm/ibm_featured_logo.png b/content/en/case-studies/ibm/ibm_featured_logo.png index b819876bf7..adb07a8cdf 100644 Binary files a/content/en/case-studies/ibm/ibm_featured_logo.png and b/content/en/case-studies/ibm/ibm_featured_logo.png differ diff --git a/content/en/case-studies/netease/index.html b/content/en/case-studies/netease/index.html new file mode 100644 index 0000000000..4b699a1fcd --- /dev/null +++ b/content/en/case-studies/netease/index.html @@ -0,0 +1,86 @@ +--- +title: NetEase Case Study +case_study_styles: true +cid: caseStudies +css: /css/style_case_studies.css +--- + + +
+

CASE STUDY:
How NetEase Leverages Kubernetes to Support Internet Business Worldwide

+ +
+ +
+ Company  NetEase     Location  Hangzhou, China     Industry  Internet technology +
+ +
+
+
+
+

Challenge

+ Its gaming business is one of the largest in the world, but that’s not all that NetEase provides to Chinese consumers. The company also operates e-commerce, advertising, music streaming, online education, and email platforms; the last of which serves almost a billion users with free email services through sites like 163.com. In 2015, the NetEase Cloud team providing the infrastructure for all of these systems realized that their R&D process was slowing down developers. “Our users needed to prepare all of the infrastructure by themselves,” says Feng Changjian, Architect for NetEase Cloud and Container Service. “We were eager to provide the infrastructure and tools for our users automatically via serverless container service.” +

+

Solution

+ After considering building its own orchestration solution, NetEase decided to base its private cloud platform on Kubernetes. The fact that the technology came out of Google gave the team confidence that it could keep up with NetEase’s scale. “After our 2-to-3-month evaluation, we believed it could satisfy our needs,” says Feng. The team started working with Kubernetes in 2015, before it was even 1.0. Today, the NetEase internal cloud platform—which also leverages the CNCF projects Prometheus, Envoy, Harbor, gRPC, and Helm—runs 10,000 nodes in a production cluster and can support up to 30,000 nodes in a cluster. Based on its learnings from its internal platform, the company introduced a Kubernetes-based cloud and microservices-oriented PaaS product, NetEase Qingzhou Microservice, to outside customers. + + +

+

Impact

+ The NetEase team reports that Kubernetes has increased R&D efficiency by more than 100%. Deployment efficiency has improved by 280%. “In the past, if we wanted to do upgrades, we needed to work with other teams, even in other departments,” says Feng. “We needed special staff to prepare everything, so it took about half an hour. Now we can do it in only 5 minutes.” The new platform also allows for mixed deployments using GPU and CPU resources. “Before, if we put all the resources toward the GPU, we won’t have spare resources for the CPU. But now we have improvements thanks to the mixed deployments,” he says. Those improvements have also brought an increase in resource utilization. +
+
+ +
+
+
+ "The system can support 30,000 nodes in a single cluster. In production, we have gotten the data of 10,000 nodes in a single cluster. The whole internal system is using this system for development, test, and production."

— Zeng Yuxing, Architect, NetEase
+
+
+
+
+

Its gaming business is the fifth-largest in the world, but that’s not all that NetEase provides consumers.

The company also operates e-commerce, advertising, music streaming, online education, and email platforms in China; the last of which serves almost a billion users with free email services through popular sites like 163.com and 126.com. With that kind of scale, the NetEase Cloud team providing the infrastructure for all of these systems realized in 2015 that their R&D process was making it hard for developers to keep up with demand. “Our users needed to prepare all of the infrastructure by themselves,” says Feng Changjian, Architect for NetEase Cloud and Container Service. “We were eager to provide the infrastructure and tools for our users automatically via serverless container service.”

+ After considering building its own orchestration solution, NetEase decided to base its private cloud platform on Kubernetes. The fact that the technology came out of Google gave the team confidence that it could keep up with NetEase’s scale. “After our 2-to-3-month evaluation, we believed it could satisfy our needs,” says Feng. +
+
+
+
+ "We leveraged the programmability of Kubernetes so that we can build a platform to satisfy the needs of our internal customers for upgrades and deployment." +

- Feng Changjian, Architect for NetEase Cloud and Container Service, NetEase
+
+
+
+
+ The team started adopting Kubernetes in 2015, before it was even 1.0, because it was relatively easy to use and enabled DevOps at the company. “We abandoned some of the concepts of Kubernetes; we only wanted to use the standardized framework,” says Feng. “We leveraged the programmability of Kubernetes so that we can build a platform to satisfy the needs of our internal customers for upgrades and deployment.”

+ The team first focused on building the container platform to manage resources better, and then turned their attention to improving its support of microservices by adding internal systems such as monitoring. That has meant integrating the CNCF projects Prometheus, Envoy, Harbor, gRPC, and Helm. “We are trying to provide a simplified and standardized process, so our users and customers can leverage our best practices,” says Feng.

+ And the team is continuing to make improvements. For example, the e-commerce part of the business needs to leverage mixed deployments, which in the past required using two separate platforms: the infrastructure-as-a-service platform and the Kubernetes platform. More recently, NetEase has created a cross-platform application that enables using both with one-command deployment. +
+
+
+
+ "As long as a company has a mature team and enough developers, I think Kubernetes is a very good technology that can help them." +

- Li Lanqing, Kubernetes Developer, NetEase
+
+
+
+ +
+
+ Today, the NetEase internal cloud platform “can support 30,000 nodes in a single cluster,” says Architect Zeng Yuxing. “In production, we have gotten the data of 10,000 nodes in a single cluster. The whole internal system is using this system for development, test, and production.”

+ The NetEase team reports that Kubernetes has increased R&D efficiency by more than 100%. Deployment efficiency has improved by 280%. “In the past, if we wanted to do upgrades, we needed to work with other teams, even in other departments,” says Feng. “We needed special staff to prepare everything, so it took about half an hour. Now we can do it in only 5 minutes.” The new platform also allows for mixed deployments using GPU and CPU resources. “Before, if we put all the resources toward the GPU, we won’t have spare resources for the CPU. But now we have improvements thanks to the mixed deployments.” Those improvements have also brought an increase in resource utilization. + +
+ +
+
+ "By engaging with this community, we can gain some experience from it and we can also benefit from it. We can see what are the concerns and the challenges faced by the community, so we can get involved."

- Li Lanqing, Kubernetes Developer, NetEase
+ +
+
+
+ Based on the results and learnings from using its internal platform, the company introduced a Kubernetes-based cloud and microservices-oriented PaaS product, NetEase Qingzhou Microservice, to outside customers. “The idea is that we can find the problems encountered by our game and e-commerce and cloud music providers, so we can integrate their experiences and provide a platform to satisfy the needs of our users,” says Zeng.

+ With or without the use of the NetEase product, the team encourages other companies to try Kubernetes. “As long as a company has a mature team and enough developers, I think Kubernetes is a very good technology that can help them,” says Kubernetes developer Li Lanqing.

+ As an end user as well as a vendor, NetEase has become more involved in the community, learning from other companies and sharing what they’ve done. The team has been contributing to the Harbor and Envoy projects, providing feedback as the technologies are being tested at NetEase scale. “We are a team focusing on addressing the challenges of microservices architecture,” says Feng. “By engaging with this community, we can gain some experience from it and we can also benefit from it. We can see what are the concerns and the challenges faced by the community, so we can get involved.” +
+
diff --git a/content/en/case-studies/netease/netease_featured_logo.png b/content/en/case-studies/netease/netease_featured_logo.png new file mode 100644 index 0000000000..5700b940f3 Binary files /dev/null and b/content/en/case-studies/netease/netease_featured_logo.png differ diff --git a/content/en/community/code-of-conduct.md b/content/en/community/code-of-conduct.md index ec85a0cf75..09544efe48 100644 --- a/content/en/community/code-of-conduct.md +++ b/content/en/community/code-of-conduct.md @@ -17,12 +17,11 @@ If you notice that this is out of date, please If you notice a violation of the Code of Conduct at an event or meeting, in Slack, or in another communication mechanism, reach out to -the [Kubernetes Code of Conduct Committee](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct) . +the Kubernetes Code of Conduct Committee. +You can reach us by email at conduct@kubernetes.io. Your anonymity will be protected.
{{< include "/static/cncf-code-of-conduct.md" >}}
- - diff --git a/content/en/docs/concepts/architecture/cloud-controller.md b/content/en/docs/concepts/architecture/cloud-controller.md index 82f791ff1f..24f685539c 100644 --- a/content/en/docs/concepts/architecture/cloud-controller.md +++ b/content/en/docs/concepts/architecture/cloud-controller.md @@ -255,6 +255,8 @@ The following cloud providers have implemented CCMs: * [Azure](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/azure) * [GCE](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/gce) * [AWS](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/aws) +* [BaiduCloud](https://github.com/baidu/cloud-provider-baiducloud) +* [Linode](https://github.com/linode/linode-cloud-controller-manager) ## Cluster Administration diff --git a/content/en/docs/concepts/architecture/master-node-communication.md b/content/en/docs/concepts/architecture/master-node-communication.md index 7c6b3a9f1c..be327630fe 100644 --- a/content/en/docs/concepts/architecture/master-node-communication.md +++ b/content/en/docs/concepts/architecture/master-node-communication.md @@ -77,7 +77,7 @@ To verify this connection, use the `--kubelet-certificate-authority` flag to provide the apiserver with a root certificate bundle to use to verify the kubelet's serving certificate. -If that is not possible, use [SSH tunneling](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) +If that is not possible, use [SSH tunneling](/docs/concepts/architecture/master-node-communication/#ssh-tunnels) between the apiserver and kubelet if required to avoid connecting over an untrusted or public network. @@ -95,4 +95,15 @@ connection will be encrypted, it will not provide any guarantees of integrity. These connections **are not currently safe** to run over untrusted and/or public networks. +### SSH Tunnels + +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. A replacement for this communication channel is being designed. + {{% /capture %}} diff --git a/content/en/docs/concepts/architecture/nodes.md b/content/en/docs/concepts/architecture/nodes.md index f82c271345..c70b99fb87 100644 --- a/content/en/docs/concepts/architecture/nodes.md +++ b/content/en/docs/concepts/architecture/nodes.md @@ -74,7 +74,7 @@ the `Terminating` or `Unknown` state. In cases where Kubernetes cannot deduce fr permanently left a cluster, the cluster administrator may need to delete the node object by hand. Deleting the node object from Kubernetes causes all the Pod objects running on the node to be deleted from the apiserver, and frees up their names. -In version 1.12, `TaintNodesByCondition` feature is promoted to beta,so node lifecycle controller automatically creates +In version 1.12, `TaintNodesByCondition` feature is promoted to beta, so node lifecycle controller automatically creates [taints](/docs/concepts/configuration/taint-and-toleration/) that represent conditions. Similarly the scheduler ignores conditions when considering a Node; instead it looks at the Node's taints and a Pod's tolerations. @@ -272,27 +272,8 @@ The Kubernetes scheduler ensures that there are enough resources for all the pod checks that the sum of the requests of containers on the node is no greater than the node capacity. It includes all containers started by the kubelet, but not containers started directly by the [container runtime](/docs/concepts/overview/components/#node-components) nor any process running outside of the containers. -If you want to explicitly reserve resources for non-pod processes, you can create a placeholder -pod. Use the following template: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: resource-reserver -spec: - containers: - - name: sleep-forever - image: k8s.gcr.io/pause:0.8.0 - resources: - requests: - cpu: 100m - memory: 100Mi -``` - -Set the `cpu` and `memory` values to the amount of resources you want to reserve. -Place the file in the manifest directory (`--config=DIR` flag of kubelet). Do this -on each kubelet where you want to reserve resources. +If you want to explicitly reserve resources for non-Pod processes, follow this tutorial to +[reserve resources for system daemons](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved). ## API Object diff --git a/content/en/docs/concepts/cluster-administration/addons.md b/content/en/docs/concepts/cluster-administration/addons.md index dd12e76074..d0a8c3946c 100644 --- a/content/en/docs/concepts/cluster-administration/addons.md +++ b/content/en/docs/concepts/cluster-administration/addons.md @@ -26,10 +26,11 @@ Add-ons in each section are sorted alphabetically - the ordering does not imply * [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. * [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 a 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 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. +* [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. * [Romana](http://romana.io) is a Layer 3 networking solution for pod networks that also supports the [NetworkPolicy API](/docs/concepts/services-networking/network-policies/). Kubeadm add-on installation details available [here](https://github.com/romana/romana/tree/master/containerize). * [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) provides networking and network policy, will carry on working on both sides of a network partition, and does not require an external database. diff --git a/content/en/docs/concepts/cluster-administration/certificates.md b/content/en/docs/concepts/cluster-administration/certificates.md index 40e4fb922c..1a3ddf8263 100644 --- a/content/en/docs/concepts/cluster-administration/certificates.md +++ b/content/en/docs/concepts/cluster-administration/certificates.md @@ -183,7 +183,7 @@ Finally, add the same parameters into the API server start parameters. ../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca 1. Create a JSON config file for generating keys and certificates for the API - server as shown below. Be sure to replace the values in angle brackets with + server, for example, `server-csr.json`. Be sure to replace the values in angle brackets with real values you want to use. The `MASTER_CLUSTER_IP` is the service cluster IP for the API server as described in previous subsection. The sample below also assumes that you are using `cluster.local` as the default @@ -231,8 +231,11 @@ refresh the local list for valid certificates. On each client, perform the following operations: ```bash -$ sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt -$ sudo update-ca-certificates +sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt +sudo update-ca-certificates +``` + +``` Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d.... diff --git a/content/en/docs/concepts/cluster-administration/cloud-providers.md b/content/en/docs/concepts/cluster-administration/cloud-providers.md index 4f868a62ca..ff3df214b4 100644 --- a/content/en/docs/concepts/cluster-administration/cloud-providers.md +++ b/content/en/docs/concepts/cluster-administration/cloud-providers.md @@ -251,11 +251,11 @@ file: monitor for the Neutron load balancer. Valid values are `true` and `false`. The default is `false`. When `true` is specified then `monitor-delay`, `monitor-timeout`, and `monitor-max-retries` must also be set. -* `monitor-delay` (Optional): The time, in seconds, between sending probes to - members of the load balancer. -* `monitor-timeout` (Optional): Maximum number of seconds for a monitor to wait +* `monitor-delay` (Optional): The time between sending probes to + members of the load balancer. Ensure that you specify a valid time unit. The valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" +* `monitor-timeout` (Optional): Maximum time for a monitor to wait for a ping reply before it times out. The value must be less than the delay - value. + value. Ensure that you specify a valid time unit. The valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" * `monitor-max-retries` (Optional): Number of permissible ping failures before changing the load balancer member's status to INACTIVE. Must be a number between 1 and 10. @@ -367,14 +367,21 @@ The `--hostname-override` parameter is ignored by the VSphere cloud provider. ## IBM Cloud Kubernetes Service ### Compute nodes -By using the IBM Cloud Kubernetes Service provider, you can create clusters with a mixture of virtual and physical (bare metal) nodes in a single zone or across multiple zones in a region. For more information, see [Planning your cluster and worker node setup](https://console.bluemix.net/docs/containers/cs_clusters_planning.html#plan_clusters). +By using the IBM Cloud Kubernetes Service provider, you can create clusters with a mixture of virtual and physical (bare metal) nodes in a single zone or across multiple zones in a region. For more information, see [Planning your cluster and worker node setup](https://cloud.ibm.com/docs/containers?topic=containers-plan_clusters#plan_clusters). The name of the Kubernetes Node object is the private IP address of the IBM Cloud Kubernetes Service worker node instance. ### Networking -The IBM Cloud Kubernetes Service provider provides VLANs for quality network performance and network isolation for nodes. You can set up custom firewalls and Calico network policies to add an extra layer of security for your cluster, or connect your cluster to your on-prem data center via VPN. For more information, see [Planning in-cluster and private networking](https://console.bluemix.net/docs/containers/cs_network_cluster.html#planning). +The IBM Cloud Kubernetes Service provider provides VLANs for quality network performance and network isolation for nodes. You can set up custom firewalls and Calico network policies to add an extra layer of security for your cluster, or connect your cluster to your on-prem data center via VPN. For more information, see [Planning in-cluster and private networking](https://cloud.ibm.com/docs/containers?topic=containers-cs_network_cluster#cs_network_cluster). -To expose apps to the public or within the cluster, you can leverage NodePort, LoadBalancer, or Ingress services. You can also customize the Ingress application load balancer with annotations. For more information, see [Planning to expose your apps with external networking](https://console.bluemix.net/docs/containers/cs_network_planning.html#planning). +To expose apps to the public or within the cluster, you can leverage NodePort, LoadBalancer, or Ingress services. You can also customize the Ingress application load balancer with annotations. For more information, see [Planning to expose your apps with external networking](https://cloud.ibm.com/docs/containers?topic=containers-cs_network_planning#cs_network_planning). ### Storage -The IBM Cloud Kubernetes Service provider leverages Kubernetes-native persistent volumes to enable users to mount file, block, and cloud object storage to their apps. You can also use database-as-a-service and third-party add-ons for persistent storage of your data. For more information, see [Planning highly available persistent storage](https://console.bluemix.net/docs/containers/cs_storage_planning.html#storage_planning). +The IBM Cloud Kubernetes Service provider leverages Kubernetes-native persistent volumes to enable users to mount file, block, and cloud object storage to their apps. You can also use database-as-a-service and third-party add-ons for persistent storage of your data. For more information, see [Planning highly available persistent storage](https://cloud.ibm.com/docs/containers?topic=containers-storage_planning#storage_planning). + +## Baidu Cloud Container Engine + +### Node Name + +The Baidu cloud provider uses the private IP address of the node (as determined by the kubelet or overridden with `--hostname-override`) as the name of the Kubernetes Node object. +Note that the Kubernetes Node name must match the Baidu VM private IP. diff --git a/content/en/docs/concepts/cluster-administration/federation.md b/content/en/docs/concepts/cluster-administration/federation.md index 16fc92d1f7..501568531b 100644 --- a/content/en/docs/concepts/cluster-administration/federation.md +++ b/content/en/docs/concepts/cluster-administration/federation.md @@ -6,7 +6,9 @@ weight: 80 {{% capture overview %}} -{{< include "federation-current-state.md" >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This page explains why and how to manage multiple Kubernetes clusters using federation. diff --git a/content/en/docs/concepts/cluster-administration/logging.md b/content/en/docs/concepts/cluster-administration/logging.md index d6aa8c45de..1040fae424 100644 --- a/content/en/docs/concepts/cluster-administration/logging.md +++ b/content/en/docs/concepts/cluster-administration/logging.md @@ -35,14 +35,14 @@ a container that writes some text to standard output once per second. To run this pod, use the following command: ```shell -$ kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml +kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml pod/counter created ``` To fetch the logs, use the `kubectl logs` command, as follows: ```shell -$ kubectl logs counter +kubectl logs counter 0: Mon Jan 1 00:00:00 UTC 2001 1: Mon Jan 1 00:00:01 UTC 2001 2: Mon Jan 1 00:00:02 UTC 2001 @@ -76,8 +76,7 @@ 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. As an example, you can find detailed information about how `kube-up.sh` sets -up logging for COS image on GCP in the corresponding [script] -[cosConfigureHelper]. +up logging for COS image on GCP in the corresponding [script][cosConfigureHelper]. When you run [`kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs) as in the basic logging example, the kubelet on the node handles the request and @@ -89,9 +88,9 @@ only the contents of the latest log file will be available through `kubectl logs`. E.g. if there's a 10MB file, `logrotate` performs the rotation and there are two files, one 10MB in size and one empty, `kubectl logs` will return an empty response. +{{< /note >}} [cosConfigureHelper]: https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/cluster/gce/gci/configure-helper.sh -{{< /note >}} ### System component logs @@ -104,7 +103,7 @@ that do not run in a container. For example: On machines with systemd, the kubelet and container runtime write to journald. If systemd is not present, they write to `.log` files in the `/var/log` directory. System components inside containers always write to the `/var/log` directory, -bypassing the default logging mechanism. They use the [glog][glog] +bypassing the default logging mechanism. They use the [klog][klog] logging library. You can find the conventions for logging severity for those components in the [development docs on logging](https://git.k8s.io/community/contributors/devel/logging.md). @@ -113,7 +112,7 @@ directory should be rotated. In Kubernetes clusters brought up by the `kube-up.sh` script, those logs are configured to be rotated by the `logrotate` tool daily or once the size exceeds 100MB. -[glog]: https://godoc.org/github.com/golang/glog +[klog]: https://github.com/kubernetes/klog ## Cluster-level logging architectures @@ -179,7 +178,9 @@ Now when you run this pod, you can access each log stream separately by running the following commands: ```shell -$ kubectl logs counter count-log-1 +kubectl logs counter count-log-1 +``` +``` 0: Mon Jan 1 00:00:00 UTC 2001 1: Mon Jan 1 00:00:01 UTC 2001 2: Mon Jan 1 00:00:02 UTC 2001 @@ -187,7 +188,9 @@ $ kubectl logs counter count-log-1 ``` ```shell -$ kubectl logs counter count-log-2 +kubectl logs counter count-log-2 +``` +``` Mon Jan 1 00:00:00 UTC 2001 INFO 0 Mon Jan 1 00:00:01 UTC 2001 INFO 1 Mon Jan 1 00:00:02 UTC 2001 INFO 2 diff --git a/content/en/docs/concepts/cluster-administration/manage-deployment.md b/content/en/docs/concepts/cluster-administration/manage-deployment.md index 0288c73efa..b216f8c8ae 100644 --- a/content/en/docs/concepts/cluster-administration/manage-deployment.md +++ b/content/en/docs/concepts/cluster-administration/manage-deployment.md @@ -26,7 +26,10 @@ Many applications require multiple resources to be created, such as a Deployment Multiple resources can be created the same way as a single resource: ```shell -$ kubectl create -f https://k8s.io/examples/application/nginx-app.yaml +kubectl create -f https://k8s.io/examples/application/nginx-app.yaml +``` + +```shell service/my-nginx-svc created deployment.apps/my-nginx created ``` @@ -36,13 +39,13 @@ The resources will be created in the order they appear in the file. Therefore, i `kubectl create` also accepts multiple `-f` arguments: ```shell -$ kubectl create -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml +kubectl create -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml ``` And a directory can be specified rather than or in addition to individual files: ```shell -$ kubectl create -f https://k8s.io/examples/application/nginx/ +kubectl create -f https://k8s.io/examples/application/nginx/ ``` `kubectl` will read any files with suffixes `.yaml`, `.yml`, or `.json`. @@ -52,7 +55,10 @@ It is a recommended practice to put resources related to the same microservice o A URL can also be specified as a configuration source, which is handy for deploying directly from configuration files checked into github: ```shell -$ kubectl create -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml +kubectl create -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml +``` + +```shell deployment.apps/my-nginx created ``` @@ -61,7 +67,10 @@ deployment.apps/my-nginx created Resource creation isn't the only operation that `kubectl` can perform in bulk. It can also extract resource names from configuration files in order to perform other operations, in particular to delete the same resources you created: ```shell -$ kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml +kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml +``` + +```shell deployment.apps "my-nginx" deleted service "my-nginx-svc" deleted ``` @@ -69,13 +78,16 @@ service "my-nginx-svc" deleted In the case of just two resources, it's also easy to specify both on the command line using the resource/name syntax: ```shell -$ kubectl delete deployments/my-nginx services/my-nginx-svc +kubectl delete deployments/my-nginx services/my-nginx-svc ``` For larger numbers of resources, you'll find it easier to specify the selector (label query) specified using `-l` or `--selector`, to filter resources by their labels: ```shell -$ kubectl delete deployment,services -l app=nginx +kubectl delete deployment,services -l app=nginx +``` + +```shell deployment.apps "my-nginx" deleted service "my-nginx-svc" deleted ``` @@ -83,7 +95,10 @@ service "my-nginx-svc" deleted Because `kubectl` outputs resource names in the same syntax it accepts, it's easy to chain operations using `$()` or `xargs`: ```shell -$ kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service) +kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service) +``` + +```shell NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx-svc LoadBalancer 10.0.0.208 80/TCP 0s ``` @@ -108,14 +123,20 @@ project/k8s/development By default, performing a bulk operation on `project/k8s/development` will stop at the first level of the directory, not processing any subdirectories. If we had tried to create the resources in this directory using the following command, we would have encountered an error: ```shell -$ kubectl create -f project/k8s/development +kubectl create -f project/k8s/development +``` + +```shell error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin) ``` Instead, specify the `--recursive` or `-R` flag with the `--filename,-f` flag as such: ```shell -$ kubectl create -f project/k8s/development --recursive +kubectl create -f project/k8s/development --recursive +``` + +```shell configmap/my-config created deployment.apps/my-deployment created persistentvolumeclaim/my-pvc created @@ -126,7 +147,10 @@ The `--recursive` flag works with any operation that accepts the `--filename,-f` The `--recursive` flag also works when multiple `-f` arguments are provided: ```shell -$ kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive +kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive +``` + +```shell namespace/development created namespace/staging created configmap/my-config created @@ -169,8 +193,11 @@ and The labels allow us to slice and dice our resources along any dimension specified by a label: ```shell -$ kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml -$ kubectl get pods -Lapp -Ltier -Lrole +kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml +kubectl get pods -Lapp -Ltier -Lrole +``` + +```shell NAME READY STATUS RESTARTS AGE APP TIER ROLE guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend @@ -180,7 +207,12 @@ guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestboo guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave my-nginx-divi2 1/1 Running 0 29m nginx my-nginx-o0ef1 1/1 Running 0 29m nginx -$ kubectl get pods -lapp=guestbook,role=slave +``` + +```shell +kubectl get pods -lapp=guestbook,role=slave +``` +```shell NAME READY STATUS RESTARTS AGE guestbook-redis-slave-2q2yf 1/1 Running 0 3m guestbook-redis-slave-qgazl 1/1 Running 0 3m @@ -240,7 +272,10 @@ Sometimes existing pods and other resources need to be relabeled before creating For example, if you want to label all your nginx pods as frontend tier, simply run: ```shell -$ kubectl label pods -l app=nginx tier=fe +kubectl label pods -l app=nginx tier=fe +``` + +```shell pod/my-nginx-2035384211-j5fhi labeled pod/my-nginx-2035384211-u2c7e labeled pod/my-nginx-2035384211-u3t6x labeled @@ -250,7 +285,9 @@ This first filters all pods with the label "app=nginx", and then labels them wit To see the pods you just labeled, run: ```shell -$ kubectl get pods -l app=nginx -L tier +kubectl get pods -l app=nginx -L tier +``` +```shell NAME READY STATUS RESTARTS AGE TIER my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe @@ -266,8 +303,10 @@ For more information, please see [labels](/docs/concepts/overview/working-with-o Sometimes you would want to attach annotations to resources. Annotations are arbitrary non-identifying metadata for retrieval by API clients such as tools, libraries, etc. This can be done with `kubectl annotate`. For example: ```shell -$ kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx' -$ kubectl get pods my-nginx-v4-9gw19 -o yaml +kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx' +kubectl get pods my-nginx-v4-9gw19 -o yaml +``` +```shell apiversion: v1 kind: pod metadata: @@ -283,14 +322,18 @@ For more information, please see [annotations](/docs/concepts/overview/working-w When load on your application grows or shrinks, it's easy to scale with `kubectl`. For instance, to decrease the number of nginx replicas from 3 to 1, do: ```shell -$ kubectl scale deployment/my-nginx --replicas=1 +kubectl scale deployment/my-nginx --replicas=1 +``` +```shell deployment.extensions/my-nginx scaled ``` Now you only have one pod managed by the deployment. ```shell -$ kubectl get pods -l app=nginx +kubectl get pods -l app=nginx +``` +```shell NAME READY STATUS RESTARTS AGE my-nginx-2035384211-j5fhi 1/1 Running 0 30m ``` @@ -298,7 +341,9 @@ my-nginx-2035384211-j5fhi 1/1 Running 0 30m To have the system automatically choose the number of nginx replicas as needed, ranging from 1 to 3, do: ```shell -$ kubectl autoscale deployment/my-nginx --min=1 --max=3 +kubectl autoscale deployment/my-nginx --min=1 --max=3 +``` +```shell horizontalpodautoscaler.autoscaling/my-nginx autoscaled ``` @@ -320,7 +365,9 @@ Then, you can use [`kubectl apply`](/docs/reference/generated/kubectl/kubectl-co This command will compare the version of the configuration that you're pushing with the previous version and apply the changes you've made, without overwriting any automated changes to properties you haven't specified. ```shell -$ kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml +kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml +``` +```shell deployment.apps/my-nginx configured ``` @@ -339,18 +386,20 @@ To use apply, always create resource initially with either `kubectl apply` or `k Alternatively, you may also update resources with `kubectl edit`: ```shell -$ kubectl edit deployment/my-nginx +kubectl edit deployment/my-nginx ``` This is equivalent to first `get` the resource, edit it in text editor, and then `apply` the resource with the updated version: ```shell -$ kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml -$ vi /tmp/nginx.yaml +kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml +vi /tmp/nginx.yaml # do some edit, and then save the file -$ kubectl apply -f /tmp/nginx.yaml + +kubectl apply -f /tmp/nginx.yaml deployment.apps/my-nginx configured -$ rm /tmp/nginx.yaml + +rm /tmp/nginx.yaml ``` This allows you to do more significant changes more easily. Note that you can specify the editor with your `EDITOR` or `KUBE_EDITOR` environment variables. @@ -370,7 +419,9 @@ and In some cases, you may need to update resource fields that cannot be updated once initialized, or you may just want to make a recursive change immediately, such as to fix broken pods created by a Deployment. To change such fields, use `replace --force`, which deletes and re-creates the resource. In this case, you can simply modify your original configuration file: ```shell -$ kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force +kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force +``` +```shell deployment.apps/my-nginx deleted deployment.apps/my-nginx replaced ``` @@ -385,14 +436,16 @@ you should read [how to use `kubectl rolling-update`](/docs/tasks/run-applicatio Let's say you were running version 1.7.9 of nginx: ```shell -$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3 +kubectl run my-nginx --image=nginx:1.7.9 --replicas=3 +``` +```shell deployment.apps/my-nginx created ``` 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 +kubectl edit deployment/my-nginx ``` That's it! The Deployment will declaratively update the deployed nginx application progressively behind the scene. It ensures that only a certain number of old replicas may be down while they are being updated, and only a certain number of new replicas may be created above the desired number of pods. To learn more details about it, visit [Deployment page](/docs/concepts/workloads/controllers/deployment/). diff --git a/content/en/docs/concepts/cluster-administration/networking.md b/content/en/docs/concepts/cluster-administration/networking.md index e0d7281d26..bbd223e9de 100644 --- a/content/en/docs/concepts/cluster-administration/networking.md +++ b/content/en/docs/concepts/cluster-administration/networking.md @@ -7,8 +7,9 @@ weight: 50 --- {{% capture overview %}} -Kubernetes approaches networking somewhat differently than Docker does by -default. There are 4 distinct networking problems to solve: +Networking is a central part of Kubernetes, but it can be challenging to +understand exactly how it is expected to work. There are 4 distinct networking +problems to address: 1. Highly-coupled container-to-container communications: this is solved by [pods](/docs/concepts/workloads/pods/pod/) and `localhost` communications. @@ -21,80 +22,56 @@ default. There are 4 distinct networking problems to solve: {{% capture body %}} -Kubernetes assumes that pods can communicate with other pods, regardless of -which host they land on. Every pod gets its own IP address so you do not -need to explicitly create links between pods and you almost never need to deal -with mapping container ports to host ports. This creates a clean, -backwards-compatible model where pods can be treated much like VMs or physical -hosts from the perspectives of port allocation, naming, service discovery, load -balancing, application configuration, and migration. +Kubernetes is all about sharing machines between applications. Typically, +sharing machines requires ensuring that two applications do not try to use the +same ports. Coordinating ports across multiple developers is very difficult to +do at scale and exposes users to cluster-level issues outside of their control. -There are requirements imposed on how you set up your cluster networking to -achieve this. - -## Docker model - -Before discussing the Kubernetes approach to networking, it is worthwhile to -review the "normal" way that networking works with Docker. By default, Docker -uses host-private networking. It creates a virtual bridge, called `docker0` by -default, and allocates a subnet from one of the private address blocks defined -in [RFC1918](https://tools.ietf.org/html/rfc1918) for that bridge. For each -container that Docker creates, it allocates a virtual Ethernet device (called -`veth`) which is attached to the bridge. The veth is mapped to appear as `eth0` -in the container, using Linux namespaces. The in-container `eth0` interface is -given an IP address from the bridge's address range. - -The result is that Docker containers can talk to other containers only if they -are on the same machine (and thus the same virtual bridge). Containers on -different machines can not reach each other - in fact they may end up with the -exact same network ranges and IP addresses. - -In order for Docker containers to communicate across nodes, there must -be allocated ports on the machine’s own IP address, which are then -forwarded or proxied to the containers. This obviously means that -containers must either coordinate which ports they use very carefully -or ports must be allocated dynamically. - -## Kubernetes model - -Coordinating ports across multiple developers is very difficult to do at -scale and exposes users to cluster-level issues outside of their control. Dynamic port allocation brings a lot of complications to the system - every application has to take ports as flags, the API servers have to know how to insert dynamic port numbers into configuration blocks, services have to know how to find each other, etc. Rather than deal with this, Kubernetes takes a different approach. +## The Kubernetes network model + +Every `Pod` gets its own IP address. This means you do not need to explicitly +create links between `Pods` and you almost never need to deal with mapping +container ports to host ports. This creates a clean, backwards-compatible +model where `Pods` can be treated much like VMs or physical hosts from the +perspectives of port allocation, naming, service discovery, load balancing, +application configuration, and migration. + Kubernetes imposes the following fundamental requirements on any networking implementation (barring any intentional network segmentation policies): - * all containers can communicate with all other containers without NAT - * all nodes can communicate with all containers (and vice-versa) without NAT - * the IP that a container sees itself as is the same IP that others see it as + * pods on a node can communicate with all pods on all nodes without NAT + * agents on a node (e.g. system daemons, kubelet) can communicate with all + pods on that node -What this means in practice is that you can not just take two computers -running Docker and expect Kubernetes to work. You must ensure that the -fundamental requirements are met. +Note: For those platforms that support `Pods` running in the host network (e.g. +Linux): + + * pods in the host network of a node can communicate with all pods on all + nodes without NAT This model is not only less complex overall, but it is principally compatible with the desire for Kubernetes to enable low-friction porting of apps from VMs to containers. If your job previously ran in a VM, your VM had an IP and could talk to other VMs in your project. This is the same basic model. -Until now this document has talked about containers. In reality, Kubernetes -applies IP addresses at the `Pod` scope - containers within a `Pod` share their -network namespaces - including their IP address. This means that containers -within a `Pod` can all reach each other's ports on `localhost`. This does imply -that containers within a `Pod` must coordinate port usage, but this is no -different than processes in a VM. This is called the "IP-per-pod" model. This -is implemented, using Docker, as a "pod container" which holds the network namespace -open while "app containers" (the things the user specified) join that namespace -with Docker's `--net=container:` function. +Kubernetes IP addresses exist at the `Pod` scope - containers within a `Pod` +share their network namespaces - including their IP address. This means that +containers within a `Pod` can all reach each other's ports on `localhost`. This +also means that containers within a `Pod` must coordinate port usage, but this +is no different than processes in a VM. This is called the "IP-per-pod" model. -As with Docker, it is possible to request host ports, but this is reduced to a -very niche operation. In this case a port will be allocated on the host `Node` -and traffic will be forwarded to the `Pod`. The `Pod` itself is blind to the -existence or non-existence of host ports. +How this is implemented is a detail of the particular container runtime in use. + +It is possible to request ports on the `Node` itself which forward to your `Pod` +(called host ports), but this is a very niche operation. How that forwarding is +implemented is also a detail of the container runtime. The `Pod` itself is +blind to the existence or non-existence of host ports. ## How to implement the Kubernetes networking model @@ -125,7 +102,7 @@ Details on how the AOS system works can be accessed here: http://www.apstra.com/ [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. -With the help of the Big Cloud Fabric's virtual pod multi-tenant architecture, container orchestration systems such as Kubernetes, RedHat Openshift, Mesosphere DC/OS & Docker Swarm will be natively integrated along side with VM orchestration systems such as VMware, OpenStack & Nutanix. Customers will be able to securely inter-connect any number of these clusters and enable inter-tenant communication between them if needed. +With the help of the Big Cloud Fabric's virtual pod multi-tenant architecture, container orchestration systems such as Kubernetes, RedHat OpenShift, Mesosphere DC/OS & Docker Swarm will be natively integrated along side with VM orchestration systems such as VMware, OpenStack & Nutanix. Customers will be able to securely inter-connect any number of these clusters and enable inter-tenant communication between them if needed. BCF was recognized by Gartner as a visionary in the latest [Magic Quadrant](http://go.bigswitch.com/17GatedDocuments-MagicQuadrantforDataCenterNetworking_Reg.html). One of the BCF Kubernetes on-premises deployments (which includes Kubernetes, DC/OS & VMware running on multiple DCs across different geographic regions) is also referenced [here](https://portworx.com/architects-corner-kubernetes-satya-komala-nio/). @@ -143,13 +120,29 @@ addressing. CNI-Genie also supports [assigning multiple IP addresses to a pod](https://github.com/Huawei-PaaS/CNI-Genie/blob/master/docs/multiple-ips/README.md#feature-2-extension-cni-genie-multiple-ip-addresses-per-pod), each from a different CNI plugin. +### cni-ipvlan-vpc-k8s +[cni-ipvlan-vpc-k8s](https://github.com/lyft/cni-ipvlan-vpc-k8s) contains a set +of CNI and IPAM plugins to provide a simple, host-local, low latency, high +throughput, and compliant networking stack for Kubernetes within Amazon Virtual +Private Cloud (VPC) environments by making use of Amazon Elastic Network +Interfaces (ENI) and binding AWS-managed IPs into Pods using the Linux kernel's +IPvlan driver in L2 mode. + +The plugins are designed to be straightforward to configure and deploy within a +VPC. Kubelets boot and then self-configure and scale their IP usage as needed +without requiring the often recommended complexities of administering overlay +networks, BGP, disabling source/destination checks, or adjusting VPC route +tables to provide per-instance subnets to each host (which is limited to 50-100 +entries per VPC). In short, cni-ipvlan-vpc-k8s significantly reduces the +network complexity required to deploy Kubernetes at scale within AWS. + ### Contiv [Contiv](https://github.com/contiv/netplugin) provides configurable networking (native l3 using BGP, overlay using vxlan, classic l2, or Cisco-SDN/ACI) for various use cases. [Contiv](http://contiv.io) is all open sourced. -### Contrail +### Contrail / Tungsten Fabric -[Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), based on [OpenContrail](http://www.opencontrail.org), is a truly open, multi-cloud network virtualization and policy management platform. Contrail / OpenContrail is integrated with various orchestration systems such as Kubernetes, OpenShift, OpenStack and Mesos, and provides different isolation modes for virtual machines, containers/pods and bare metal workloads. +[Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), based on [Tungsten Fabric](https://tungsten.io), is a truly open, multi-cloud network virtualization and policy management platform. Contrail and Tungsten Fabric are integrated with various orchestration systems such as Kubernetes, OpenShift, OpenStack and Mesos, and provide different isolation modes for virtual machines, containers/pods and bare metal workloads. ### DANM @@ -246,7 +239,7 @@ Multus supports all [reference plugins](https://github.com/containernetworking/p [VMware NSX-T](https://docs.vmware.com/en/VMware-NSX-T/index.html) is a network virtualization and security platform. NSX-T can provide network virtualization for a multi-cloud and multi-hypervisor environment and is focused on emerging application frameworks and architectures that have heterogeneous endpoints and technology stacks. In addition to vSphere hypervisors, these environments include other hypervisors such as KVM, containers, and bare metal. -[NSX-T Container Plug-in (NCP)](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) provides integration between 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. +[NSX-T Container Plug-in (NCP)](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) provides integration between 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 Networks VCS (Virtualized Cloud Services) @@ -272,9 +265,9 @@ at [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes). [Project Calico](http://docs.projectcalico.org/) is an open source container networking provider and network policy engine. -Calico provides a highly scalable networking and network policy solution for connecting Kubernetes pods based on the same IP networking principles as the internet. Calico can be deployed without encapsulation or overlays to provide high-performance, high-scale data center networking. Calico also provides fine-grained, intent based network security policy for Kubernetes pods via its distributed firewall. +Calico provides a highly scalable networking and network policy solution for connecting Kubernetes pods based on the same IP networking principles as the internet, for both Linux (open source) and Windows (proprietary - available from [Tigera](https://www.tigera.io/essentials/)). Calico can be deployed without encapsulation or overlays to provide high-performance, high-scale data center networking. Calico also provides fine-grained, intent based network security policy for Kubernetes pods via its distributed firewall. -Calico can also be run in policy enforcement mode in conjunction with other networking solutions such as Flannel, aka [canal](https://github.com/tigera/canal), or native GCE networking. +Calico can also be run in policy enforcement mode in conjunction with other networking solutions such as Flannel, aka [canal](https://github.com/tigera/canal), or native GCE, AWS or Azure networking. ### Romana diff --git a/content/en/docs/concepts/configuration/assign-pod-node.md b/content/en/docs/concepts/configuration/assign-pod-node.md index 468ca73303..70ec7f2938 100644 --- a/content/en/docs/concepts/configuration/assign-pod-node.md +++ b/content/en/docs/concepts/configuration/assign-pod-node.md @@ -12,7 +12,7 @@ weight: 30 {{% capture overview %}} You can constrain a [pod](/docs/concepts/workloads/pods/pod/) to only be able to run on particular [nodes](/docs/concepts/architecture/nodes/) or to prefer to -run on particular nodes. There are several ways to do this, and they all use +run on particular nodes. 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.) @@ -29,7 +29,7 @@ repo here](https://github.com/kubernetes/website/tree/{{< param "docsbranch" >}} ## nodeSelector -`nodeSelector` is the simplest form of constraint. +`nodeSelector` is the simplest recommended form of node selection constraint. `nodeSelector` is a field of PodSpec. It specifies a map of key-value pairs. For the pod to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels (it can have additional labels as well). The most common usage is one key-value pair. @@ -46,7 +46,7 @@ Run `kubectl get nodes` to get the names of your cluster's nodes. Pick out the o If this fails with an "invalid command" error, you're likely using an older version of kubectl that doesn't have the `label` command. In that case, see the [previous version](https://github.com/kubernetes/kubernetes/blob/a053dbc313572ed60d89dae9821ecab8bfd676dc/examples/node-selection/README.md) of this guide for instructions on how to manually set labels on a node. -You can verify that it worked by re-running `kubectl get nodes --show-labels` and checking that the node now has a label. +You can verify that it worked by re-running `kubectl get nodes --show-labels` and checking that the node now has a label. You can also use `kubectl describe node "nodename"` to see the full list of labels of the given node. ### Step Two: Add a nodeSelector field to your pod configuration @@ -362,6 +362,41 @@ For more information on inter-pod affinity/anti-affinity, see the You may want to check [Taints](/docs/concepts/configuration/taint-and-toleration/) as well, which allow a *node* to *repel* a set of pods. +## nodeName + +`nodeName` is the simplest form of node selection constraint, but due +to its limitations it is typically not used. `nodeName` is a field of +PodSpec. If it is non-empty, the scheduler ignores the pod and the +kubelet running on the named node tries to run the pod. Thus, if +`nodeName` is provided in the PodSpec, it takes precedence over the +above methods for node selection. + +Some of the limitations of using `nodeName` to select nodes are: + +- If the named node does not exist, the pod will not be run, and in + 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, + e.g. OutOfmemory or OutOfcpu. +- Node names in cloud environments are not always predictable or + stable. + +Here is an example of a pod config file using the `nodeName` field: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + containers: + - name: nginx + image: nginx + nodeName: kube-01 +``` + +The above pod will run on the node kube-01. + {{% /capture %}} {{% capture whatsnext %}} diff --git a/content/en/docs/concepts/configuration/manage-compute-resources-container.md b/content/en/docs/concepts/configuration/manage-compute-resources-container.md index b05b2e508d..34f3320893 100644 --- a/content/en/docs/concepts/configuration/manage-compute-resources-container.md +++ b/content/en/docs/concepts/configuration/manage-compute-resources-container.md @@ -189,7 +189,9 @@ unscheduled until a place can be found. An event is produced each time the scheduler fails to find a place for the Pod, like this: ```shell -$ kubectl describe pod frontend | grep -A 3 Events +kubectl describe pod frontend | grep -A 3 Events +``` +``` Events: FirstSeen LastSeen Count From Subobject PathReason Message 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others @@ -210,7 +212,9 @@ You can check node capacities and amounts allocated with the `kubectl describe nodes` command. For example: ```shell -$ kubectl describe nodes e2e-test-minion-group-4lw4 +kubectl describe nodes e2e-test-minion-group-4lw4 +``` +``` Name: e2e-test-minion-group-4lw4 [ ... lines removed for clarity ...] Capacity: @@ -260,7 +264,9 @@ whether a Container is being killed because it is hitting a resource limit, call `kubectl describe pod` on the Pod of interest: ```shell -[12:54:41] $ kubectl describe pod simmemleak-hra99 +kubectl describe pod simmemleak-hra99 +``` +``` Name: simmemleak-hra99 Namespace: default Image(s): saadali/simmemleak @@ -304,7 +310,9 @@ You can call `kubectl get pod` with the `-o go-template=...` option to fetch the of previously terminated Containers: ```shell -[13:59:01] $ kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99 +kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99 +``` +``` Container Name: simmemleak LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]] ``` diff --git a/content/en/docs/concepts/configuration/organize-cluster-access-kubeconfig.md b/content/en/docs/concepts/configuration/organize-cluster-access-kubeconfig.md index 8a77e153df..480b708018 100644 --- a/content/en/docs/concepts/configuration/organize-cluster-access-kubeconfig.md +++ b/content/en/docs/concepts/configuration/organize-cluster-access-kubeconfig.md @@ -103,7 +103,7 @@ Here are the rules that `kubectl` uses when it merges kubeconfig files: 1. Determine the context to use based on the first hit in this chain: - 1. Use the `--context` command-line flag if it exits. + 1. Use the `--context` command-line flag if it exists. 1. Use the `current-context` from the merged kubeconfig files. An empty context is allowed at this point. diff --git a/content/en/docs/concepts/configuration/pod-priority-preemption.md b/content/en/docs/concepts/configuration/pod-priority-preemption.md index 909b5c01ab..bcb1fab197 100644 --- a/content/en/docs/concepts/configuration/pod-priority-preemption.md +++ b/content/en/docs/concepts/configuration/pod-priority-preemption.md @@ -202,7 +202,7 @@ Node is found that satisfies all the specified requirements of the Pod, preemption logic is triggered for the pending Pod. Let's call the pending Pod P. Preemption logic tries to find a Node where removal of one or more Pods with lower priority than P would enable P to be scheduled on that Node. If such a -Node is found, one or more lower priority Pods get deleted from the Node. After +Node is found, one or more lower priority Pods get evicted from the Node. After the Pods are gone, P can be scheduled on the Node. ### User exposed information @@ -322,7 +322,7 @@ 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 a Pod. In such cases, preemption happens only when the priority of the pending 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 higher priority +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 @@ -364,11 +364,11 @@ 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 consider QoS when choosing preemption targets. Preemption -considers Pod priority and attempts to choose a set of targets with the lowest -priority. Higher-priority Pods are considered for preemption only if the removal -of the lowest priority Pods is not sufficient to allow the scheduler to schedule -the preemptor Pod, or if the lowest priority Pods are protected by +preemption logic does not consider QoS when choosing preemption targets. +Preemption considers Pod priority and attempts to choose a set of targets with +the lowest priority. Higher-priority Pods are considered for preemption only if +the removal of the lowest priority Pods is not sufficient to allow the scheduler +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 diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index cac58727d7..b6911c5fd9 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -13,10 +13,10 @@ weight: 50 {{% capture overview %}} -Objects of type `secret` are intended to hold sensitive information, such as -passwords, OAuth tokens, and ssh keys. Putting this information in a `secret` -is safer and more flexible than putting it verbatim in a `pod` definition or in -a docker image. See [Secrets design document](https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md) for more information. +Kubernetes `secret` objects let you store and manage sensitive information, such +as passwords, OAuth tokens, and ssh keys. Putting this information in a `secret` +is safer and more flexible than putting it verbatim in a +{{< glossary_tooltip term_id="pod" >}} definition or in a {{< glossary_tooltip text="container image" term_id="image" >}}. See [Secrets design document](https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md) for more information. {{% /capture %}} @@ -32,7 +32,8 @@ more control over how it is used, and reduces the risk of accidental exposure. Users can create secrets, and the system also creates some secrets. To use a secret, a pod needs to reference the secret. -A secret can be used with a pod in two ways: as files in a [volume](/docs/concepts/storage/volumes/) mounted on one or more of +A secret can be used with a pod in two ways: as files in a +{{< glossary_tooltip text="volume" term_id="volume" >}} mounted on one or more of its containers, or used by kubelet when pulling images for the pod. ### Built-in Secrets @@ -60,8 +61,8 @@ username and password that the pods should use is in the files ```shell # Create files needed for rest of example. -$ echo -n 'admin' > ./username.txt -$ echo -n '1f2d1e2e67df' > ./password.txt +echo -n 'admin' > ./username.txt +echo -n '1f2d1e2e67df' > ./password.txt ``` The `kubectl create secret` command @@ -69,18 +70,25 @@ packages these files into a Secret and creates the object on the Apiserver. ```shell -$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt +kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt +``` +``` secret "db-user-pass" created ``` You can check that the secret was created like this: ```shell -$ kubectl get secrets +kubectl get secrets +``` +``` NAME TYPE DATA AGE db-user-pass Opaque 2 51s - -$ kubectl describe secrets/db-user-pass +``` +```shell +kubectl describe secrets/db-user-pass +``` +``` Name: db-user-pass Namespace: default Labels: @@ -94,11 +102,14 @@ password.txt: 12 bytes username.txt: 5 bytes ``` -Note that neither `get` nor `describe` shows the contents of the file by default. -This is to protect the secret from being exposed accidentally to someone looking +{{< note >}} +`kubectl get` and `kubectl describe` avoid showing the contents of a secret by +default. +This is to protect the secret from being exposed accidentally to an onlooker, or from being stored in a terminal log. +{{< /note >}} -See [decoding a secret](#decoding-a-secret) for how to see the contents. +See [decoding a secret](#decoding-a-secret) for how to see the contents of a secret. #### Creating a Secret Manually @@ -135,7 +146,9 @@ data: Now create the Secret using [`kubectl create`](/docs/reference/generated/kubectl/kubectl-commands#create): ```shell -$ kubectl create -f ./secret.yaml +kubectl create -f ./secret.yaml +``` +``` secret "mysecret" created ``` @@ -246,7 +259,9 @@ the option `-w 0` to `base64` commands or the pipeline `base64 | tr -d '\n'` if Secrets can be retrieved via the `kubectl get secret` command. For example, to retrieve the secret created in the previous section: ```shell -$ kubectl get secret mysecret -o yaml +kubectl get secret mysecret -o yaml +``` +``` apiVersion: v1 data: username: YWRtaW4= @@ -265,14 +280,17 @@ type: Opaque Decode the password field: ```shell -$ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode +echo 'MWYyZDFlMmU2N2Rm' | base64 --decode +``` +``` 1f2d1e2e67df ``` ### Using Secrets -Secrets can be mounted as data volumes or be exposed as environment variables to -be used by a container in a pod. They can also be used by other parts of the +Secrets can be mounted as data volumes or be exposed as +{{< glossary_tooltip text="environment variables" term_id="container-env-variables" >}} +to be used by a container in a pod. They can also be used by other parts of the system, without being directly exposed to the pod. For example, they can hold credentials that other parts of the system should use to interact with external systems on your behalf. @@ -424,12 +442,22 @@ This is the result of commands executed inside the container from the example above: ```shell -$ ls /etc/foo/ +ls /etc/foo/ +``` +``` username password -$ cat /etc/foo/username +``` +```shell +cat /etc/foo/username +``` +``` admin -$ cat /etc/foo/password +``` +```shell +cat /etc/foo/password +``` +``` 1f2d1e2e67df ``` @@ -458,7 +486,8 @@ Secret updates. #### Using Secrets as Environment Variables -To use a secret in an environment variable in a pod: +To use a secret in an {{< glossary_tooltip text="environment variable" term_id="container-env-variables" >}} +in a pod: 1. Create a secret or use an existing one. Multiple pods can reference the same secret. 1. Modify your Pod definition in each container that you wish to consume the value of a secret key to add an environment variable for each secret key you wish to consume. The environment variable that consumes the secret key should populate the secret's name and key in `env[].valueFrom.secretKeyRef`. @@ -496,9 +525,15 @@ normal environment variables containing the base-64 decoded values of the secret This is the result of commands executed inside the container from the example above: ```shell -$ echo $SECRET_USERNAME +echo $SECRET_USERNAME +``` +``` admin -$ echo $SECRET_PASSWORD +``` +```shell +echo $SECRET_PASSWORD +``` +``` 1f2d1e2e67df ``` @@ -534,10 +569,10 @@ Secret volume sources are validated to ensure that the specified object reference actually points to an object of type `Secret`. Therefore, a secret needs to be created before any pods that depend on it. -Secret API objects reside in a namespace. They can only be referenced by pods -in that same namespace. +Secret API objects reside in a {{< glossary_tooltip text="namespace" term_id="namespace" >}}. +They can only be referenced by pods in that same namespace. -Individual secrets are limited to 1MB in size. This is to discourage creation +Individual secrets are limited to 1MiB in size. This is to discourage creation of very large secrets which would exhaust apiserver and kubelet memory. However, creation of many smaller secrets could also exhaust memory. More comprehensive limits on memory usage due to secrets is a planned feature. @@ -549,8 +584,8 @@ controller. It does not include pods created via the kubelets not common ways to create pods.) Secrets must be created before they are consumed in pods as environment -variables unless they are marked as optional. References to Secrets that do not exist will prevent -the pod from starting. +variables unless they are marked as optional. References to Secrets that do +not exist will prevent the pod from starting. References via `secretKeyRef` to keys that do not exist in a named Secret will prevent the pod from starting. @@ -563,7 +598,9 @@ invalid keys that were skipped. The example shows a pod which refers to the default/mysecret that contains 2 invalid keys, 1badkey and 2alsobad. ```shell -$ kubectl get events +kubectl get events +``` +``` LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names. ``` @@ -586,7 +623,10 @@ start until all the pod's volumes are mounted. Create a secret containing some ssh keys: ```shell -$ kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub +kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa +``` +``` +--from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub ``` {{< caution >}} @@ -636,9 +676,18 @@ credentials. Make the secrets: ```shell -$ kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11 +kubectl create secret generic prod-db-secret --from-literal=username=produser +--from-literal=password=Y4nys7f11 +``` + +``` secret "prod-db-secret" created -$ kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests +``` + +```shell +kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests +``` +``` secret "test-db-secret" created ``` {{< note >}} @@ -821,6 +870,7 @@ be available in future releases of Kubernetes. ## Security Properties + ### Protections Because `secret` objects can be created independently of the `pods` that use @@ -829,51 +879,52 @@ creating, viewing, and editing pods. The system can also take additional precautions with `secret` objects, such as avoiding writing them to disk where possible. -A secret is only sent to a node if a pod on that node requires it. It is not -written to disk. It is stored in a tmpfs. It is deleted once the pod that -depends on it is deleted. - -On most Kubernetes-project-maintained distributions, communication between user -to the apiserver, and from apiserver to the kubelets, is protected by SSL/TLS. -Secrets are protected when transmitted over these channels. - -Secret data on nodes is stored in tmpfs volumes and thus does not come to rest -on the node. +A secret is only sent to a node if a pod on that node requires it. +Kubelet stores the secret into a `tmpfs` so that the secret is not written +to disk storage. Once the Pod that depends on the secret is deleted, kubelet +will delete its local copy of the secret data as well. There may be secrets for several pods on the same node. However, only the secrets that a pod requests are potentially visible within its containers. -Therefore, one Pod does not have access to the secrets of another pod. +Therefore, one Pod does not have access to the secrets of another Pod. There may be several containers in a pod. However, each container in a pod has to request the secret volume in its `volumeMounts` for it to be visible within the container. This can be used to construct useful [security partitions at the Pod level](#use-case-secret-visible-to-one-container-in-a-pod). +On most Kubernetes-project-maintained distributions, communication between user +to the apiserver, and from apiserver to the kubelets, is protected by SSL/TLS. +Secrets are protected when transmitted over these channels. + +{{< feature-state for_k8s_version="v1.13" state="beta" >}} + +You can enable [encryption at rest](/docs/tasks/administer-cluster/encrypt-data/) +for secret data, so that the secrets are not stored in the clear into {{< glossary_tooltip term_id="etcd" >}}. + ### Risks - - In the API server secret data is stored as plaintext in etcd; therefore: + - In the API server secret data is stored in {{< glossary_tooltip term_id="etcd" >}}; + therefore: + - Administrators should enable encryption at rest for cluster data (requires v1.13 or later) - Administrators should limit access to etcd to admin users - - Secret data in the API server is at rest on the disk that etcd uses; admins may want to wipe/shred disks - used by etcd when no longer in use + - Administrators may want to wipe/shred disks used by etcd when no longer in use + - If running etcd in a cluster, administrators should make sure to use SSL/TLS + for etcd peer-to-peer communication. - If you configure the secret through a manifest (JSON or YAML) file which has the secret data encoded as base64, sharing this file or checking it in to a - source repository means the secret is compromised. Base64 encoding is not an + source repository means the secret is compromised. Base64 encoding is _not_ an encryption method and is considered the same as plain text. - Applications still need to protect the value of secret after reading it from the volume, such as not accidentally logging it or transmitting it to an untrusted party. - A user who can create a pod that uses a secret can also see the value of that secret. Even if apiserver policy does not allow that user to read the secret object, the user could run a pod which exposes the secret. - - If multiple replicas of etcd are run, then the secrets will be shared between them. - By default, etcd does not secure peer-to-peer communication with SSL/TLS, though this can be configured. - - Currently, anyone with root on any node can read any secret from the apiserver, + - Currently, anyone with root on any node can read _any_ secret from the apiserver, by impersonating the kubelet. It is a planned feature to only send secrets to nodes that actually require them, to restrict the impact of a root exploit on a single node. -{{< note >}} -As of 1.7 [encryption of secret data at rest is supported](/docs/tasks/administer-cluster/encrypt-data/). -{{< /note >}} {{% capture whatsnext %}} diff --git a/content/en/docs/concepts/configuration/taint-and-toleration.md b/content/en/docs/concepts/configuration/taint-and-toleration.md index a66b4f4a43..8757386c10 100644 --- a/content/en/docs/concepts/configuration/taint-and-toleration.md +++ b/content/en/docs/concepts/configuration/taint-and-toleration.md @@ -191,7 +191,7 @@ 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 (alpha feature)**: 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 @@ -279,7 +279,7 @@ which matches the behavior when this feature is disabled. In version 1.12, `TaintNodesByCondition` feature is promoted to beta, so node lifecycle controller automatically creates taints corresponding to 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 an alpha feature and disabled by default. +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 diff --git a/content/en/docs/concepts/containers/container-lifecycle-hooks.md b/content/en/docs/concepts/containers/container-lifecycle-hooks.md index f85569032b..08d855732f 100644 --- a/content/en/docs/concepts/containers/container-lifecycle-hooks.md +++ b/content/en/docs/concepts/containers/container-lifecycle-hooks.md @@ -36,7 +36,7 @@ No parameters are passed to the handler. `PreStop` -This hook is called immediately before a container is terminated. +This hook is called immediately before a container is terminated due to an API request or management event such as liveness probe failure, preemption, resource contention and others. A call to the preStop hook fails if the container is already in terminated or completed state. It is blocking, meaning it is synchronous, so it must complete before the call to delete the container can be sent. No parameters are passed to the handler. @@ -99,17 +99,17 @@ Here is some example output of events from running this command: ``` Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0" - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined] - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0" - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567 - 38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1 - 37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1 - 38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1" - 1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0" + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined] + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0" + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567 + 38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1 + 37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1 + 38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1" + 1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook ``` {{% /capture %}} diff --git a/content/en/docs/concepts/containers/images.md b/content/en/docs/concepts/containers/images.md index ed590b50d3..ab6206925f 100644 --- a/content/en/docs/concepts/containers/images.md +++ b/content/en/docs/concepts/containers/images.md @@ -149,9 +149,9 @@ Once you have those variables filled in you can ### 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 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://console.bluemix.net/docs/services/Registry/index.html#index). +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-index#index). -You can use the IBM Cloud Container Registry to deploy containers from [IBM Cloud public images](https://console.bluemix.net/docs/services/RegistryImages/index.html#ibm_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://console.bluemix.net/docs/containers/cs_images.html#images). +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#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#images). ### Configuring Nodes to Authenticate to a Private Registry @@ -170,6 +170,11 @@ will not work reliably on GCE, and any other cloud provider that does automatic node replacement. {{< /note >}} +{{< note >}} +Kubernetes as of now only supports the `auths` and `HttpHeaders` section of docker config. This means credential helpers (`credHelpers` or `credsStore`) are not supported. +{{< /note >}} + + Docker stores keys for private registries in the `$HOME/.dockercfg` or `$HOME/.docker/config.json` file. If you put the same file in the search paths list below, kubelet uses it as the credential provider when pulling images. @@ -278,42 +283,17 @@ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGIS secret/myregistrykey created. ``` -If you need access to multiple registries, you can create one secret for each registry. -Kubelet will merge any `imagePullSecrets` into a single virtual `.docker/config.json` -when pulling images for your Pods. +If you already have a Docker credentials file then, rather than using the above +command, you can import the credentials file as a Kubernetes secret. +[Create a Secret based on existing Docker credentials](/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials) explains how to set this up. +This is particularly useful if you are using multiple private container +registries, as `kubectl create secret docker-registry` creates a Secret that will +only work with a single private registry. +{{< note >}} Pods can only reference image pull secrets in their own namespace, so this process needs to be done one time per namespace. - -##### Bypassing kubectl create secrets - -If for some reason you need multiple items in a single `.docker/config.json` or need -control not given by the above command, then you can [create a secret using -json or yaml](/docs/user-guide/secrets/#creating-a-secret-manually). - -Be sure to: - -- set the name of the data item to `.dockerconfigjson` -- base64 encode the docker file and paste that string, unbroken - as the value for field `data[".dockerconfigjson"]` -- set `type` to `kubernetes.io/dockerconfigjson` - -Example: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: myregistrykey - namespace: awesomeapps -data: - .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== -type: kubernetes.io/dockerconfigjson -``` - -If you get the error message `error: no objects passed to create`, it may mean the base64 encoded string is invalid. -If you get an error message like `Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...`, it means -the data was successfully un-base64 encoded, but could not be parsed as a `.docker/config.json` file. +{{< /note >}} #### Referring to an imagePullSecrets on a Pod @@ -355,7 +335,7 @@ common use cases and suggested solutions. 1. Cluster running some proprietary images which should be hidden to those outside the company, but visible to all cluster users. - Use a hosted private [Docker registry](https://docs.docker.com/registry/). - - It may be hosted on the [Docker Hub](https://hub.docker.com/account/signup/), or elsewhere. + - It may be hosted on the [Docker Hub](https://hub.docker.com/signup), or elsewhere. - Manually configure .docker/config.json on each node as described above. - Or, run an internal private registry behind your firewall with open read access. - No Kubernetes configuration is required. @@ -372,3 +352,6 @@ common use cases and suggested solutions. - The tenant adds that secret to imagePullSecrets of each namespace. {{% /capture %}} + +If you need access to multiple registries, you can create one secret for each registry. +Kubelet will merge any `imagePullSecrets` into a single virtual `.docker/config.json` diff --git a/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md b/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md index e069d491c4..84f3c70209 100644 --- a/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md +++ b/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md @@ -9,40 +9,48 @@ weight: 20 {{% capture overview %}} -This page explains *custom resources*, which are extensions of the Kubernetes -API, including when to add a custom resource to your Kubernetes cluster and when -to use a standalone service. It describes the two methods for adding custom -resources and how to choose between them. +*Custom resources* are extensions of the Kubernetes API. This page discusses when to add a custom +resource to your Kubernetes cluster and when to use a standalone service. It describes the two +methods for adding custom resources and how to choose between them. {{% /capture %}} {{% capture body %}} ## Custom resources -A *resource* is an endpoint in the [Kubernetes API](/docs/reference/using-api/api-overview/) that stores a collection of [API objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/) of a certain kind. For example, the built-in *pods* resource contains a collection of Pod objects. +A *resource* is an endpoint in the [Kubernetes API](/docs/reference/using-api/api-overview/) that stores a collection of +[API objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/) of a certain kind. For example, the built-in *pods* resource contains a collection of Pod objects. -A *custom resource* is an extension of the Kubernetes API that is not necessarily available on every -Kubernetes cluster. -In other words, it represents a customization of a particular Kubernetes installation. +A *custom resource* is an extension of the Kubernetes API that is not necessarily available in a default +Kubernetes installation. It represents a customization of a particular Kubernetes installation. However, +many core Kubernetes functions are now built using custom resources, making Kubernetes more modular. Custom resources can appear and disappear in a running cluster through dynamic registration, and cluster admins can update custom resources independently of the cluster itself. -Once a custom resource is installed, users can create and access its objects with -[kubectl](/docs/user-guide/kubectl-overview/), just as they do for built-in resources like *pods*. +Once a custom resource is installed, users can create and access its objects using +[kubectl](/docs/user-guide/kubectl-overview/), just as they do for built-in resources like +*Pods*. -### Custom controllers +## Custom controllers On their own, custom resources simply let you store and retrieve structured data. -It is only when combined with a *controller* that they become a true declarative API. +When you combine a custom resource with a *custom controller*, custom resources +provide a true _declarative 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 match the actual state to this desired state. -Here, the controller interprets the structured data as a record of the user's -desired state, and continually takes action to achieve and maintain this state. +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. -A *custom controller* is a controller that users can deploy and update on a running cluster, independently 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](https://coreos.com/blog/introducing-operators.html) pattern is one example of such a combination. It allows developers to encode domain knowledge for specific applications into an extension of the Kubernetes API. +You can deploy and update a custom controller on a running cluster, independently +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 +for specific applications into an extension of the Kubernetes API. -### Should I add a custom resource to my Kubernetes Cluster? +## Should I add a custom resource to my Kubernetes Cluster? When creating a new API, consider whether to [aggregate your API with the Kubernetes cluster APIs](/docs/concepts/api-extension/apiserver-aggregation/) or let your API stand alone. @@ -56,7 +64,7 @@ When creating a new API, consider whether to [aggregate your API with the Kubern | 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 +### Declarative APIs In a Declarative API, typically: @@ -80,7 +88,7 @@ Signs that your API might not be declarative include: - The API is not easily modeled as objects. - You chose to represent pending operations with an operation ID or an operation object. -### Should I use a configMap or a custom resource? +## Should I use a configMap or a custom resource? Use a ConfigMap if any of the following apply: @@ -126,13 +134,9 @@ 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 [API server aggregation](#api-server-aggregation). -Refer to the [Custom Controller example, which uses Custom Resources](https://github.com/kubernetes/sample-controller) -for a demonstration of how to register a new custom resource, work with instances of your new resource type, -and setup a controller to handle events. - -{{< note >}} -CRD is the successor to the deprecated *ThirdPartyResource* (TPR) API, and is available as of Kubernetes 1.7. -{{< /note >}} +Refer to the [custom controller example](https://github.com/kubernetes/sample-controller) +for an example of how to register a new custom resource, work with instances of your new resource type, +and use a controller to handle events. ## API server aggregation @@ -143,7 +147,7 @@ implementations for your custom resources by writing and deploying your own stan The main API server delegates requests to you for the custom resources that you handle, making them available to all of its clients. -### Choosing a method for adding custom resources +## Choosing a method for adding custom resources CRDs are easier to use. Aggregated APIs are more flexible. Choose the method that best meets your needs. @@ -152,7 +156,7 @@ Typically, CRDs are a good fit if: * You have a handful of fields * You are using the resource within your company, or as part of a small open-source project (as opposed to a commercial product) -#### Comparing ease of use +### Comparing ease of use CRDs are easier to create than Aggregated APIs. @@ -181,7 +185,7 @@ Aggregated APIs offer more advanced API features and customization of other feat | Protocol Buffers | The new resource supports clients that want to use Protocol Buffers | No | Yes | | OpenAPI Schema | Is there an OpenAPI (swagger) schema for the types that can be dynamically fetched from the server? Is the user protected from misspelling field names by ensuring only allowed fields are set? Are types enforced (in other words, don't put an `int` in a `string` field?) | No, but planned | Yes | -#### Common Features +### Common Features When you create a custom resource, either via a CRDs or an AA, you get many features for your API, compared to implementing it outside the Kubernetes platform: diff --git a/content/en/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler.md b/content/en/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler.md new file mode 100644 index 0000000000..1afbc17c09 --- /dev/null +++ b/content/en/docs/concepts/extend-kubernetes/poseidon-firmament-alternate-scheduler.md @@ -0,0 +1,117 @@ +--- +title: Poseidon-Firmament - An alternate scheduler +content_template: templates/concept +weight: 80 +--- + +{{% capture overview %}} + +**Current release of Poseidon-Firmament scheduler is an alpha release.** + +Poseidon-Firmament scheduler is an alternate scheduler that can be deployed alongside the default Kubernetes scheduler. + +{{% /capture %}} + +{{% capture body %}} + + +## Introduction + +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. + +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, so multiple schedulers run simultaneously. + +## Key Advantages + +### 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. + +- 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. + +## Poseidon-Firmament Scheduler - How it works + +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 +``` + + +{{< 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). + +## Current Project Stage + +- **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). + +## Features Comparison Matrix + + +|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|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 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**|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|| + + +## Installation + +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 >}} + +{{% /capture %}} diff --git a/content/en/docs/concepts/overview/components.md b/content/en/docs/concepts/overview/components.md index 590e0598ba..4373482ffc 100644 --- a/content/en/docs/concepts/overview/components.md +++ b/content/en/docs/concepts/overview/components.md @@ -4,6 +4,9 @@ reviewers: title: Kubernetes Components content_template: templates/concept weight: 20 +card: + name: concepts + weight: 20 --- {{% capture overview %}} @@ -52,7 +55,7 @@ These controllers include: cloud-controller-manager runs cloud-provider-specific controller loops only. You must disable these controller loops in the kube-controller-manager. You can disable the controller loops by setting the `--cloud-provider` flag to `external` when starting the kube-controller-manager. -cloud-controller-manager allows cloud vendors code and the Kubernetes core to evolve independent of each other. In prior releases, the core Kubernetes code was dependent upon cloud-provider-specific code for functionality. In future releases, code specific to cloud vendors should be maintained by the cloud vendor themselves, and linked to cloud-controller-manager while running Kubernetes. +cloud-controller-manager allows cloud vendors code and the Kubernetes code to evolve independent of each other. In prior releases, the core Kubernetes code was dependent upon cloud-provider-specific code for functionality. In future releases, code specific to cloud vendors should be maintained by the cloud vendor themselves, and linked to cloud-controller-manager while running Kubernetes. The following controllers have cloud provider dependencies: @@ -76,7 +79,8 @@ network rules on the host and performing connection forwarding. ### Container Runtime -The container runtime is the software that is responsible for running containers. Kubernetes supports several runtimes: [Docker](http://www.docker.com), [rkt](https://coreos.com/rkt/), [runc](https://github.com/opencontainers/runc) and any OCI [runtime-spec](https://github.com/opencontainers/runtime-spec) implementation. +The container runtime is the software that is responsible for running containers. +Kubernetes supports several runtimes: [Docker](http://www.docker.com), [containerd](https://containerd.io), [cri-o](https://cri-o.io/), [rktlet](https://github.com/kubernetes-incubator/rktlet) and any implementation of the [Kubernetes CRI (Container Runtime Interface)](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md). ## Addons diff --git a/content/en/docs/concepts/overview/kubernetes-api.md b/content/en/docs/concepts/overview/kubernetes-api.md index 8bf6b92bfa..2ef08ade26 100644 --- a/content/en/docs/concepts/overview/kubernetes-api.md +++ b/content/en/docs/concepts/overview/kubernetes-api.md @@ -4,6 +4,9 @@ reviewers: title: The Kubernetes API content_template: templates/concept weight: 30 +card: + name: concepts + weight: 30 --- {{% capture overview %}} @@ -33,17 +36,19 @@ What constitutes a compatible change and how to change the API are detailed by t ## OpenAPI and Swagger definitions -Complete API details are documented using [Swagger v1.2](http://swagger.io/) and [OpenAPI](https://www.openapis.org/). The Kubernetes apiserver (aka "master") exposes an API that can be used to retrieve the Swagger v1.2 Kubernetes API spec located at `/swaggerapi`. +Complete API details are documented using [OpenAPI](https://www.openapis.org/). -Starting with Kubernetes 1.10, OpenAPI spec is served in a single `/openapi/v2` endpoint. The format-separated endpoints (`/swagger.json`, `/swagger-2.0.0.json`, `/swagger-2.0.0.pb-v1`, `/swagger-2.0.0.pb-v1.gz`) are deprecated and will get removed in Kubernetes 1.14. - -Requested format is specified by setting HTTP headers: +Starting with Kubernetes 1.10, the Kubernetes API server serves an OpenAPI spec via the `/openapi/v2` endpoint. +The requested format is specified by setting HTTP headers: Header | Possible Values ------ | --------------- Accept | `application/json`, `application/com.github.proto-openapi.spec.v2@v1.0+protobuf` (the default content-type is `application/json` for `*/*` or not passing this header) Accept-Encoding | `gzip` (not passing this header is acceptable) +Prior to 1.14, format-separated endpoints (`/swagger.json`, `/swagger-2.0.0.json`, `/swagger-2.0.0.pb-v1`, `/swagger-2.0.0.pb-v1.gz`) +serve the OpenAPI spec in different formats. These endpoints are deprecated, and will be removed in Kubernetes 1.14. + **Examples of getting OpenAPI spec**: Before 1.10 | Starting with Kubernetes 1.10 @@ -52,9 +57,12 @@ GET /swagger.json | GET /openapi/v2 **Accept**: application/json GET /swagger-2.0.0.pb-v1 | GET /openapi/v2 **Accept**: application/com.github.proto-openapi.spec.v2@v1.0+protobuf GET /swagger-2.0.0.pb-v1.gz | GET /openapi/v2 **Accept**: application/com.github.proto-openapi.spec.v2@v1.0+protobuf **Accept-Encoding**: gzip - Kubernetes implements an alternative Protobuf based serialization format for the API that is primarily intended for intra-cluster communication, documented in the [design proposal](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/protobuf.md) and the IDL files for each schema are located in the Go packages that define the API objects. +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 will be removed in Kubernetes 1.14. + ## API versioning To make it easier to eliminate fields or restructure resource representations, Kubernetes supports @@ -125,9 +133,9 @@ to pick up the `--runtime-config` changes. ## Enabling resources in the groups -DaemonSets, Deployments, HorizontalPodAutoscalers, Ingress, Jobs and ReplicaSets are enabled by default. +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/ingress=false` +`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/ingresses=false` {{% /capture %}} diff --git a/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md b/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md index 70fc566dfc..2887bee6b8 100644 --- a/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md +++ b/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md @@ -73,7 +73,7 @@ Run `kubectl diff` to print the object that will be created: kubectl diff -f https://k8s.io/examples/application/simple_deployment.yaml ``` {{< note >}} -**Note:** `diff` uses [server-side dry-run](/docs/reference/using-api/api-concepts/#dry-run), which needs to be enabled on `kube-apiserver`. +`diff` uses [server-side dry-run](/docs/reference/using-api/api-concepts/#dry-run), which needs to be enabled on `kube-apiserver`. {{< /note >}} Create the object using `kubectl apply`: @@ -625,7 +625,7 @@ Add, delete, or update individual elements. This does not preserve ordering. This merge strategy uses a special tag on each field called a `patchMergeKey`. The `patchMergeKey` is defined for each field in the Kubernetes source code: -[types.go](https://git.k8s.io/api/core/v1/types.go#L2565) +[types.go](https://github.com/kubernetes/api/blob/d04500c8c3dda9c980b668c57abc2ca61efcf5c4/core/v1/types.go#L2747) When merging a list of maps, the field specified as the `patchMergeKey` for a given element is used like a map key for that element. @@ -700,7 +700,7 @@ As of Kubernetes 1.5, merging lists of primitive elements is not supported. {{< note >}} Which of the above strategies is chosen for a given field is controlled by -the `patchStrategy` tag in [types.go](https://git.k8s.io/api/core/v1/types.go#L2565) +the `patchStrategy` tag in [types.go](https://github.com/kubernetes/api/blob/d04500c8c3dda9c980b668c57abc2ca61efcf5c4/core/v1/types.go#L2748) If no `patchStrategy` is specified for a field of type list, then the list is replaced. {{< /note >}} diff --git a/content/en/docs/concepts/overview/object-management-kubectl/imperative-command.md b/content/en/docs/concepts/overview/object-management-kubectl/imperative-command.md index 38b194d2a4..bc83bd6b03 100644 --- a/content/en/docs/concepts/overview/object-management-kubectl/imperative-command.md +++ b/content/en/docs/concepts/overview/object-management-kubectl/imperative-command.md @@ -73,7 +73,7 @@ that must be set: The `kubectl` command also supports update commands driven by an aspect of the object. Setting this aspect may set different fields for different object types: -- `set` : Set an aspect of an object. +- `set` ``: Set an aspect of an object. {{< note >}} In Kubernetes version 1.5, not every verb-driven command has an associated aspect-driven command. @@ -160,5 +160,3 @@ kubectl create --edit -f /tmp/srv.yaml - [Kubectl Command Reference](/docs/reference/generated/kubectl/kubectl/) - [Kubernetes API Reference](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) {{% /capture %}} - - diff --git a/content/en/docs/concepts/overview/what-is-kubernetes.md b/content/en/docs/concepts/overview/what-is-kubernetes.md index 014d4945c0..6bfd4404f0 100644 --- a/content/en/docs/concepts/overview/what-is-kubernetes.md +++ b/content/en/docs/concepts/overview/what-is-kubernetes.md @@ -5,6 +5,9 @@ reviewers: title: What is Kubernetes? content_template: templates/concept weight: 10 +card: + name: concepts + weight: 10 --- {{% capture overview %}} diff --git a/content/en/docs/concepts/overview/working-with-objects/annotations.md b/content/en/docs/concepts/overview/working-with-objects/annotations.md index 328a93fa1d..cfd08be919 100644 --- a/content/en/docs/concepts/overview/working-with-objects/annotations.md +++ b/content/en/docs/concepts/overview/working-with-objects/annotations.md @@ -53,11 +53,22 @@ Here are some examples of information that could be recorded in annotations: * Phone or pager numbers of persons responsible, or directory entries that specify where that information can be found, such as a team web site. +* Directives from the end-user to the implementations to modify behavior or + engage non-standard features. + Instead of using annotations, you could store this type of information in an external database or directory, but that would make it much harder to produce shared client libraries and tools for deployment, management, introspection, and the like. +## Syntax and character set + +_Annotations_ are key/value pairs. Valid annotation keys have two segments: an optional prefix and name, separated by a slash (`/`). The name segment is required and must be 63 characters or less, beginning and ending with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain: a series of DNS labels separated by dots (`.`), not longer than 253 characters in total, followed by a slash (`/`). + +If the prefix is omitted, the annotation Key is presumed to be private to the user. Automated system components (e.g. `kube-scheduler`, `kube-controller-manager`, `kube-apiserver`, `kubectl`, or other third-party automation) which add annotations to end-user objects must specify a prefix. + +The `kubernetes.io/` and `k8s.io/` prefixes are reserved for Kubernetes core components. + {{% /capture %}} {{% capture whatsnext %}} diff --git a/content/en/docs/concepts/overview/working-with-objects/field-selectors.md b/content/en/docs/concepts/overview/working-with-objects/field-selectors.md index 243eecce24..637af3ad92 100644 --- a/content/en/docs/concepts/overview/working-with-objects/field-selectors.md +++ b/content/en/docs/concepts/overview/working-with-objects/field-selectors.md @@ -12,15 +12,15 @@ _Field selectors_ let you [select Kubernetes resources](/docs/concepts/overview/ This `kubectl` command selects all Pods for which the value of the [`status.phase`](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase) field is `Running`: ```shell -$ kubectl get pods --field-selector status.phase=Running +kubectl get pods --field-selector status.phase=Running ``` {{< note >}} Field selectors are essentially resource *filters*. By default, no selectors/filters are applied, meaning that all resources of the specified type are selected. This makes the following `kubectl` queries equivalent: ```shell -$ kubectl get pods -$ kubectl get pods --field-selector "" +kubectl get pods +kubectl get pods --field-selector "" ``` {{< /note >}} @@ -29,7 +29,9 @@ $ kubectl get pods --field-selector "" Supported field selectors vary by Kubernetes resource type. All resource types support the `metadata.name` and `metadata.namespace` fields. Using unsupported field selectors produces an error. For example: ```shell -$ kubectl get ingress --field-selector foo.bar=baz +kubectl get ingress --field-selector foo.bar=baz +``` +``` Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace" ``` @@ -38,7 +40,7 @@ Error from server (BadRequest): Unable to find "ingresses" that match label sele You can use the `=`, `==`, and `!=` operators with field selectors (`=` and `==` mean the same thing). This `kubectl` command, for example, selects all Kubernetes Services that aren't in the `default` namespace: ```shell -$ kubectl get services --field-selector metadata.namespace!=default +kubectl get services --field-selector metadata.namespace!=default ``` ## Chained selectors @@ -46,7 +48,7 @@ $ kubectl get services --field-selector metadata.namespace!=default As with [label](/docs/concepts/overview/working-with-objects/labels) and other selectors, field selectors can be chained together as a comma-separated list. This `kubectl` command selects all Pods for which the `status.phase` does not equal `Running` and the `spec.restartPolicy` field equals `Always`: ```shell -$ kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always +kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always ``` ## Multiple resource types @@ -54,5 +56,5 @@ $ kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Alw You use field selectors across multiple resource types. This `kubectl` command selects all Statefulsets and Services that are not in the `default` namespace: ```shell -$ kubectl get statefulsets,services --field-selector metadata.namespace!=default +kubectl get statefulsets,services --field-selector metadata.namespace!=default ``` diff --git a/content/en/docs/concepts/overview/working-with-objects/kubernetes-objects.md b/content/en/docs/concepts/overview/working-with-objects/kubernetes-objects.md index ae529e39bc..57d65343d0 100644 --- a/content/en/docs/concepts/overview/working-with-objects/kubernetes-objects.md +++ b/content/en/docs/concepts/overview/working-with-objects/kubernetes-objects.md @@ -2,6 +2,9 @@ title: Understanding Kubernetes Objects content_template: templates/concept weight: 10 +card: + name: concepts + weight: 40 --- {{% capture overview %}} @@ -28,7 +31,7 @@ Every Kubernetes object includes two nested object fields that govern the object For example, a Kubernetes Deployment is an object that can represent an application running on your cluster. When you create the Deployment, you might set the Deployment spec to specify that you want three replicas of the application to be running. The Kubernetes system reads the Deployment spec and starts three instances of your desired application--updating the status to match your spec. If any of those instances should fail (a status change), the Kubernetes system responds to the difference between spec and status by making a correction--in this case, starting a replacement instance. -For more information on the object spec, status, and metadata, see the [Kubernetes API Conventions](https://git.k8s.io/community/contributors/devel/api-conventions.md). +For more information on the object spec, status, and metadata, see the [Kubernetes API Conventions](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md). ### Describing a Kubernetes Object @@ -43,7 +46,7 @@ One way to create a Deployment using a `.yaml` file like the one above is to use in the `kubectl` command-line interface, passing the `.yaml` file as an argument. Here's an example: ```shell -$ kubectl create -f https://k8s.io/examples/application/deployment.yaml --record +kubectl create -f https://k8s.io/examples/application/deployment.yaml --record ``` The output is similar to this: diff --git a/content/en/docs/concepts/overview/working-with-objects/labels.md b/content/en/docs/concepts/overview/working-with-objects/labels.md index 46535ab44e..d2858af8db 100644 --- a/content/en/docs/concepts/overview/working-with-objects/labels.md +++ b/content/en/docs/concepts/overview/working-with-objects/labels.md @@ -10,8 +10,8 @@ weight: 40 _Labels_ are key/value pairs that are attached to objects, such as pods. Labels are intended to be used to specify identifying attributes of objects that are meaningful and relevant to users, but do not directly imply semantics to the core system. -Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. -Each object can have a set of key/value labels defined. Each Key must be unique for a given object. +Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and subsequently added and modified at any time. +Each object can have a set of key/value labels defined. Each Key must be unique for a given object. ```json "metadata": { @@ -22,7 +22,7 @@ Each object can have a set of key/value labels defined. Each Key must be unique } ``` -We'll eventually index and reverse-index labels for efficient queries and watches, use them to sort and group in UIs and CLIs, etc. We don't want to pollute labels with non-identifying, especially large and/or structured, data. Non-identifying information should be recorded using [annotations](/docs/concepts/overview/working-with-objects/annotations/). +Labels allow for efficient queries and watches and are ideal for use in UIs and CLIs. Non-identifying information should be recorded using [annotations](/docs/concepts/overview/working-with-objects/annotations/). {{% /capture %}} @@ -47,8 +47,11 @@ These are just examples of commonly used labels; you are free to develop your ow ## Syntax and character set -_Labels_ are key/value pairs. Valid label keys have two segments: an optional prefix and name, separated by a slash (`/`). The name segment is required and must be 63 characters or less, beginning and ending with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain: a series of DNS labels separated by dots (`.`), not longer than 253 characters in total, followed by a slash (`/`). -If the prefix is omitted, the label Key is presumed to be private to the user. Automated system components (e.g. `kube-scheduler`, `kube-controller-manager`, `kube-apiserver`, `kubectl`, or other third-party automation) which add labels to end-user objects must specify a prefix. The `kubernetes.io/` prefix is reserved for Kubernetes core components. +_Labels_ are key/value pairs. Valid label keys have two segments: an optional prefix and name, separated by a slash (`/`). The name segment is required and must be 63 characters or less, beginning and ending with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain: a series of DNS labels separated by dots (`.`), not longer than 253 characters in total, followed by a slash (`/`). + +If the prefix is omitted, the label Key is presumed to be private to the user. Automated system components (e.g. `kube-scheduler`, `kube-controller-manager`, `kube-apiserver`, `kubectl`, or other third-party automation) which add labels to end-user objects must specify a prefix. + +The `kubernetes.io/` and `k8s.io/` prefixes are reserved for Kubernetes core components. Valid label values must be 63 characters or less and must be empty or begin and end with an alphanumeric character (`[a-z0-9A-Z]`) with dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. @@ -61,12 +64,12 @@ Via a _label selector_, the client/user can identify a set of objects. The label The API currently supports two types of selectors: _equality-based_ and _set-based_. A label selector can be made of multiple _requirements_ which are comma-separated. In the case of multiple requirements, all must be satisfied so the comma separator acts as a logical _AND_ (`&&`) operator. -An empty label selector (that is, one with zero requirements) selects every object in the collection. - -A null label selector (which is only possible for optional selector fields) selects no objects. +The semantics of empty or non-specified selectors are dependent on the context, +and API types that use selectors should document the validity and meaning of +them. {{< note >}} -The label selectors of two controllers must not overlap within a namespace, otherwise they will fight with each other. +For some API types, such as ReplicaSets, the label selectors of two instances must not overlap within a namespace, or the controller can see that as conflicting instructions and fail to determine how many replicas should be present. {{< /note >}} ### _Equality-based_ requirement @@ -136,25 +139,25 @@ LIST and WATCH operations may specify label selectors to filter the sets of obje Both label selector styles can be used to list or watch resources via a REST client. For example, targeting `apiserver` with `kubectl` and using _equality-based_ one may write: ```shell -$ kubectl get pods -l environment=production,tier=frontend +kubectl get pods -l environment=production,tier=frontend ``` or using _set-based_ requirements: ```shell -$ kubectl get pods -l 'environment in (production),tier in (frontend)' +kubectl get pods -l 'environment in (production),tier in (frontend)' ``` As already mentioned _set-based_ requirements are more expressive.  For instance, they can implement the _OR_ operator on values: ```shell -$ kubectl get pods -l 'environment in (production, qa)' +kubectl get pods -l 'environment in (production, qa)' ``` or restricting negative matching via _exists_ operator: ```shell -$ kubectl get pods -l 'environment,environment notin (frontend)' +kubectl get pods -l 'environment,environment notin (frontend)' ``` ### Set references in API objects diff --git a/content/en/docs/concepts/overview/working-with-objects/namespaces.md b/content/en/docs/concepts/overview/working-with-objects/namespaces.md index eb10f1067b..862ae2adc6 100644 --- a/content/en/docs/concepts/overview/working-with-objects/namespaces.md +++ b/content/en/docs/concepts/overview/working-with-objects/namespaces.md @@ -46,7 +46,9 @@ for namespaces](/docs/admin/namespaces). You can list the current namespaces in a cluster using: ```shell -$ kubectl get namespaces +kubectl get namespaces +``` +``` NAME STATUS AGE default Active 1d kube-system Active 1d @@ -66,8 +68,8 @@ To temporarily set the namespace for a request, use the `--namespace` flag. For example: ```shell -$ kubectl --namespace= run nginx --image=nginx -$ kubectl --namespace= get pods +kubectl --namespace= run nginx --image=nginx +kubectl --namespace= get pods ``` ### Setting the namespace preference @@ -76,9 +78,9 @@ You can permanently save the namespace for all subsequent kubectl commands in th context. ```shell -$ kubectl config set-context $(kubectl config current-context) --namespace= +kubectl config set-context $(kubectl config current-context) --namespace= # Validate it -$ kubectl config view | grep namespace: +kubectl config view | grep namespace: ``` ## Namespaces and DNS @@ -101,10 +103,10 @@ To see which Kubernetes resources are and aren't in a namespace: ```shell # In a namespace -$ kubectl api-resources --namespaced=true +kubectl api-resources --namespaced=true # Not in a namespace -$ kubectl api-resources --namespaced=false +kubectl api-resources --namespaced=false ``` {{% /capture %}} diff --git a/content/en/docs/concepts/policy/pod-security-policy.md b/content/en/docs/concepts/policy/pod-security-policy.md index 4f1c658aa8..1e796586ac 100644 --- a/content/en/docs/concepts/policy/pod-security-policy.md +++ b/content/en/docs/concepts/policy/pod-security-policy.md @@ -41,7 +41,7 @@ administrator to control the following: | Restricting escalation to root privileges | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) | | Linux capabilities | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) | | The SELinux context of the container | [`seLinux`](#selinux) | -| The Allowed Proc Mount types for the container | [`allowedProcMountTypes`](#allowedProcMountTypes) | +| The Allowed Proc Mount types for the container | [`allowedProcMountTypes`](#allowedprocmounttypes) | | The AppArmor profile used by containers | [annotations](#apparmor) | | The seccomp profile used by containers | [annotations](#seccomp) | | The sysctl profile used by containers | [annotations](#sysctl) | @@ -336,7 +336,6 @@ pause-7774d79b5-qrgcb 0/1 Pending 0 1s pause-7774d79b5-qrgcb 0/1 Pending 0 1s pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s pause-7774d79b5-qrgcb 1/1 Running 0 2s -^C ``` ### Clean up @@ -465,7 +464,7 @@ Please make sure [`volumes`](#volumes-and-file-systems) field contains the For example: ```yaml -apiVersion: extensions/v1beta1 +apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: allow-flex-volumes @@ -610,6 +609,6 @@ default cannot be changed. ### Sysctl Controlled via annotations on the PodSecurityPolicy. Refer to the [Sysctl documentation]( -/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy-annotations). +/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy). {{% /capture %}} diff --git a/content/en/docs/concepts/policy/resource-quotas.md b/content/en/docs/concepts/policy/resource-quotas.md index e3be95b50c..40c813e00c 100644 --- a/content/en/docs/concepts/policy/resource-quotas.md +++ b/content/en/docs/concepts/policy/resource-quotas.md @@ -551,10 +551,10 @@ plugins: kind: Configuration limitedResources: - resource: pods - matchScopes: - - operator : In - scopeName: PriorityClass - values: ["cluster-services"] + matchScopes: + - scopeName: PriorityClass + operator: In + values: ["cluster-services"] ``` Now, "cluster-services" pods will be allowed in only those namespaces where a quota object with a matching `scopeSelector` is present. @@ -562,8 +562,8 @@ For example: ```yaml scopeSelector: matchExpressions: - - operator : In - scopeName: PriorityClass + - scopeName: PriorityClass + operator: In values: ["cluster-services"] ``` diff --git a/content/en/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md b/content/en/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md index d472665b07..e67cd841c9 100644 --- a/content/en/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md +++ b/content/en/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md @@ -19,7 +19,7 @@ Modification not using HostAliases is not suggested because the file is managed ## Default Hosts File Content -Lets start an Nginx Pod which is assigned a Pod IP: +Let's start an Nginx Pod which is assigned a Pod IP: ```shell kubectl run nginx --image nginx --generator=run-pod/v1 @@ -107,10 +107,8 @@ fe00::2 ip6-allrouters 10.200.0.5 hostaliases-pod # Entries added by HostAliases. -127.0.0.1 foo.local -127.0.0.1 bar.local -10.1.2.3 foo.remote -10.1.2.3 bar.remote +127.0.0.1 foo.local bar.local +10.1.2.3 foo.remote bar.remote ``` With the additional entries specified at the bottom. diff --git a/content/en/docs/concepts/services-networking/connect-applications-service.md b/content/en/docs/concepts/services-networking/connect-applications-service.md index ae0160ad9f..a37f9d8b7c 100644 --- a/content/en/docs/concepts/services-networking/connect-applications-service.md +++ b/content/en/docs/concepts/services-networking/connect-applications-service.md @@ -17,7 +17,7 @@ Now that you have a continuously running, replicated application you can expose By default, Docker uses host-private networking, so containers can talk to other containers only if they are on the same machine. In order for Docker containers to communicate across nodes, there must be allocated ports on the machine’s own IP address, which are then forwarded or proxied to the containers. This obviously means that containers must either coordinate which ports they use very carefully or ports must be allocated dynamically. -Coordinating ports across multiple developers is very difficult to do at scale and exposes users to cluster-level issues outside of their control. Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. We give every pod its own cluster-private-IP address so you do not need to explicitly create links between pods or mapping container ports to host ports. This means that containers within a Pod can all reach each other's ports on localhost, and all pods in a cluster can see each other without NAT. The rest of this document will elaborate on how you can run reliable services on such a networking model. +Coordinating ports across multiple developers is very difficult to do at scale and exposes users to cluster-level issues outside of their control. Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. We give every pod its own cluster-private-IP address so you do not need to explicitly create links between pods or map container ports to host ports. This means that containers within a Pod can all reach each other's ports on localhost, and all pods in a cluster can see each other without NAT. The rest of this document will elaborate on how you can run reliable services on such a networking model. This guide uses a simple nginx server to demonstrate proof of concept. The same principles are embodied in a more complete [Jenkins CI application](https://kubernetes.io/blog/2015/07/strong-simple-ssl-for-kubernetes). @@ -35,8 +35,10 @@ Create an nginx Pod, and note that it has a container port specification: This makes it accessible from any node in your cluster. Check the nodes the Pod is running on: ```shell -$ kubectl create -f ./run-my-nginx.yaml -$ kubectl get pods -l run=my-nginx -o wide +kubectl create -f ./run-my-nginx.yaml +kubectl get pods -l run=my-nginx -o wide +``` +``` NAME READY STATUS RESTARTS AGE IP NODE my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd @@ -45,7 +47,7 @@ my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 Check your pods' IPs: ```shell -$ kubectl get pods -l run=my-nginx -o yaml | grep podIP +kubectl get pods -l run=my-nginx -o yaml | grep podIP podIP: 10.244.3.4 podIP: 10.244.2.5 ``` @@ -63,7 +65,9 @@ A Kubernetes Service is an abstraction which defines a logical set of Pods runni You can create a Service for your 2 nginx replicas with `kubectl expose`: ```shell -$ kubectl expose deployment/my-nginx +kubectl expose deployment/my-nginx +``` +``` service/my-nginx exposed ``` @@ -81,7 +85,9 @@ API object to see the list of supported fields in service definition. Check your Service: ```shell -$ kubectl get svc my-nginx +kubectl get svc my-nginx +``` +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx ClusterIP 10.0.162.149 80/TCP 21s ``` @@ -95,7 +101,9 @@ Check the endpoints, and note that the IPs are the same as the Pods created in the first step: ```shell -$ kubectl describe svc my-nginx +kubectl describe svc my-nginx +``` +``` Name: my-nginx Namespace: default Labels: run=my-nginx @@ -107,8 +115,11 @@ Port: 80/TCP Endpoints: 10.244.2.5:80,10.244.3.4:80 Session Affinity: None Events: - -$ kubectl get ep my-nginx +``` +```shell +kubectl get ep my-nginx +``` +``` NAME ENDPOINTS AGE my-nginx 10.244.2.5:80,10.244.3.4:80 1m ``` @@ -131,7 +142,9 @@ each active Service. This introduces an ordering problem. To see why, inspect the environment of your running nginx Pods (your Pod name will be different): ```shell -$ kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE +kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE +``` +``` KUBERNETES_SERVICE_HOST=10.0.0.1 KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT_HTTPS=443 @@ -147,9 +160,11 @@ replicas. This will give you scheduler-level Service spreading of your Pods variables: ```shell -$ kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2; +kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2; -$ kubectl get pods -l run=my-nginx -o wide +kubectl get pods -l run=my-nginx -o wide +``` +``` NAME READY STATUS RESTARTS AGE IP NODE my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m @@ -158,7 +173,9 @@ my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 You may notice that the pods have different names, since they are killed and recreated. ```shell -$ kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE +kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE +``` +``` KUBERNETES_SERVICE_PORT=443 MY_NGINX_SERVICE_HOST=10.0.162.149 KUBERNETES_SERVICE_HOST=10.0.0.1 @@ -171,19 +188,23 @@ KUBERNETES_SERVICE_PORT_HTTPS=443 Kubernetes offers a DNS cluster addon Service that automatically assigns dns names to other Services. You can check if it's running on your cluster: ```shell -$ kubectl get services kube-dns --namespace=kube-system +kubectl get services kube-dns --namespace=kube-system +``` +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.0.0.10 53/UDP,53/TCP 8m ``` -If it isn't running, you can [enable it](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md#how-do-i-configure-it). +If it isn't running, you can [enable it](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md#how-do-i-configure-it). The rest of this section will assume you have a Service with a long lived IP (my-nginx), and a DNS server that has assigned a name to that IP (the CoreDNS cluster addon), so you can talk to the Service from any pod in your cluster using standard methods (e.g. gethostbyname). Let's run another curl application to test this: ```shell -$ kubectl run curl --image=radial/busyboxplus:curl -i --tty +kubectl run curl --image=radial/busyboxplus:curl -i --tty +``` +``` Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false Hit enter for command prompt ``` @@ -210,10 +231,16 @@ Till now we have only accessed the nginx server from within the cluster. Before You can acquire all these from the [nginx https example](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/). This requires having go and make tools installed. If you don't want to install those, then follow the manual steps later. In short: ```shell -$ make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json -$ kubectl create -f /tmp/secret.json +make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json +kubectl create -f /tmp/secret.json +``` +``` secret/nginxsecret created -$ kubectl get secrets +``` +```shell +kubectl get secrets +``` +``` NAME TYPE DATA AGE default-token-il9rc kubernetes.io/service-account-token 1 1d nginxsecret Opaque 2 1m @@ -242,8 +269,10 @@ data: Now create the secrets using the file: ```shell -$ kubectl create -f nginxsecrets.yaml -$ kubectl get secrets +kubectl create -f nginxsecrets.yaml +kubectl get secrets +``` +``` NAME TYPE DATA AGE default-token-il9rc kubernetes.io/service-account-token 1 1d nginxsecret Opaque 2 1m @@ -263,13 +292,13 @@ Noteworthy points about the nginx-secure-app manifest: This is setup *before* the nginx server is started. ```shell -$ kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml +kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml ``` At this point you can reach the nginx server from any node. ```shell -$ kubectl get pods -o yaml | grep -i podip +kubectl get pods -o yaml | grep -i podip podIP: 10.244.3.5 node $ curl -k https://10.244.3.5 ... @@ -283,11 +312,15 @@ Let's test this from a pod (the same secret is being reused for simplicity, the {{< codenew file="service/networking/curlpod.yaml" >}} ```shell -$ kubectl create -f ./curlpod.yaml -$ kubectl get pods -l app=curlpod +kubectl create -f ./curlpod.yaml +kubectl get pods -l app=curlpod +``` +``` NAME READY STATUS RESTARTS AGE curl-deployment-1515033274-1410r 1/1 Running 0 1m -$ kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt +``` +```shell +kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt ... Welcome to nginx! ... @@ -302,7 +335,7 @@ so your nginx HTTPS replica is ready to serve traffic on the internet if your node has a public IP. ```shell -$ kubectl get svc my-nginx -o yaml | grep nodePort -C 5 +kubectl get svc my-nginx -o yaml | grep nodePort -C 5 uid: 07191fb3-f61a-11e5-8ae5-42010af00002 spec: clusterIP: 10.0.162.149 @@ -319,8 +352,9 @@ spec: targetPort: 443 selector: run: my-nginx - -$ kubectl get nodes -o yaml | grep ExternalIP -C 1 +``` +```shell +kubectl get nodes -o yaml | grep ExternalIP -C 1 - address: 104.197.41.11 type: ExternalIP allocatable: @@ -338,12 +372,15 @@ $ curl https://: -k Let's now recreate the Service to use a cloud load balancer, just change the `Type` of `my-nginx` Service from `NodePort` to `LoadBalancer`: ```shell -$ kubectl edit svc my-nginx -$ kubectl get svc my-nginx +kubectl edit svc my-nginx +kubectl get svc my-nginx +``` +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx ClusterIP 10.0.162.149 162.222.184.144 80/TCP,81/TCP,82/TCP 21s - -$ curl https:// -k +``` +``` +curl https:// -k ... Welcome to nginx! ``` @@ -357,7 +394,7 @@ output, in fact, so you'll need to do `kubectl describe service my-nginx` to see it. You'll see something like this: ```shell -$ kubectl describe service my-nginx +kubectl describe service my-nginx ... LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com ... diff --git a/content/en/docs/concepts/services-networking/dns-pod-service.md b/content/en/docs/concepts/services-networking/dns-pod-service.md index 268519e833..5c519d479a 100644 --- a/content/en/docs/concepts/services-networking/dns-pod-service.md +++ b/content/en/docs/concepts/services-networking/dns-pod-service.md @@ -251,7 +251,7 @@ options ndots:2 edns0 For IPv6 setup, search path and name server should be setup like this: ``` -$ kubectl exec -it busybox -- cat /etc/resolv.conf +$ kubectl exec -it dns-example -- cat /etc/resolv.conf nameserver fd00:79:30::a search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5 diff --git a/content/en/docs/concepts/services-networking/ingress-controllers.md b/content/en/docs/concepts/services-networking/ingress-controllers.md new file mode 100644 index 0000000000..57af46a01a --- /dev/null +++ b/content/en/docs/concepts/services-networking/ingress-controllers.md @@ -0,0 +1,74 @@ +--- +title: Ingress Controllers +reviewers: +content_template: templates/concept +weight: 40 +--- + +{{% capture overview %}} + +In order for the Ingress resource to work, the cluster must have an ingress controller running. + +Unlike other types of controllers which run as part of the `kube-controller-manager` binary, Ingress controllers +are not started automatically with a cluster. Use this page to choose the ingress controller implementation +that best fits your cluster. + +Kubernetes as a project currently supports and maintains [GCE](https://git.k8s.io/ingress-gce/README.md) and + [nginx](https://git.k8s.io/ingress-nginx/README.md) controllers. + +{{% /capture %}} + +{{% capture body %}} + +## Additional controllers + +* [Ambassador](https://www.getambassador.io/) API Gateway is an [Envoy](https://www.envoyproxy.io) based ingress + controller with [community](https://www.getambassador.io/docs) or + [commercial](https://www.getambassador.io/pro/) support from [Datawire](https://www.datawire.io/). +* [AppsCode Inc.](https://appscode.com) offers support and maintenance for the most widely used [HAProxy](http://www.haproxy.org/) based ingress controller [Voyager](https://appscode.com/products/voyager). +* [Contour](https://github.com/heptio/contour) is an [Envoy](https://www.envoyproxy.io) based ingress controller + provided and supported by Heptio. +* Citrix provides an [Ingress Controller](https://github.com/citrix/citrix-k8s-ingress-controller) for its hardware (MPX), virtualized (VPX) and [free containerized (CPX) ADC](https://www.citrix.com/products/citrix-adc/cpx-express.html) for [baremetal](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment/baremetal) and [cloud](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment) deployments. +* F5 Networks provides [support and maintenance](https://support.f5.com/csp/article/K86859508) + for the [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest). +* [Gloo](https://gloo.solo.io) is an open-source ingress controller based on [Envoy](https://www.envoyproxy.io) which offers API Gateway functionality with enterprise support from [solo.io](https://www.solo.io). +* [HAProxy](http://www.haproxy.org/) based ingress controller + [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) which is mentioned on the blog post + [HAProxy Ingress Controller for Kubernetes](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/). + [HAProxy Technologies](https://www.haproxy.com/) offers support and maintenance for HAProxy Enterprise and + the ingress controller [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress). +* [Istio](https://istio.io/) based ingress controller + [Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/). +* [Kong](https://konghq.com/) offers [community](https://discuss.konghq.com/c/kubernetes) or + [commercial](https://konghq.com/kong-enterprise/) support and maintenance for the + [Kong Ingress Controller for Kubernetes](https://github.com/Kong/kubernetes-ingress-controller). +* [NGINX, Inc.](https://www.nginx.com/) offers support and maintenance for the + [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller). +* [Traefik](https://github.com/containous/traefik) is a fully featured ingress controller + ([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket), and it also comes with commercial + support by [Containous](https://containo.us/services). + +## Using multiple Ingress controllers + +You may deploy [any number of ingress controllers](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) +within a cluster. When you create an ingress, you should annotate each ingress with the appropriate +[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster) +to indicate which ingress controller should be used if more than one exists within your cluster. + +If you do not define a class, your cloud provider may use a default ingress provider. + +Ideally, all ingress controllers should fulfill this specification, but the various ingress +controllers operate slightly differently. + +{{< note >}} +Make sure you review your ingress controller's documentation to understand the caveats of choosing it. +{{< /note >}} + +{{% /capture %}} + +{{% capture whatsnext %}} + +* Learn more about [Ingress](/docs/concepts/services-networking/ingress/). +* [Set up Ingress on Minikube with the NGINX Controller](/docs/tasks/access-application-cluster/ingress-minikube). + +{{% /capture %}} diff --git a/content/en/docs/concepts/services-networking/ingress.md b/content/en/docs/concepts/services-networking/ingress.md index 8b5638939c..10cf95e295 100644 --- a/content/en/docs/concepts/services-networking/ingress.md +++ b/content/en/docs/concepts/services-networking/ingress.md @@ -25,7 +25,7 @@ For the sake of clarity, this guide defines the following terms: Ingress, added in Kubernetes v1.1, exposes HTTP and HTTPS routes from outside the cluster to {{< link text="services" url="/docs/concepts/services-networking/service/" >}} within the cluster. -Traffic routing is controlled by rules defined on the ingress resource. +Traffic routing is controlled by rules defined on the Ingress resource. ```none internet @@ -35,9 +35,9 @@ Traffic routing is controlled by rules defined on the ingress resource. [ Services ] ``` -An ingress can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, and offer name based virtual hosting. An [ingress controller](#ingress-controllers) is responsible for fulfilling the ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic. +An Ingress can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, and offer name based virtual hosting. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers) is responsible for fulfilling the Ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic. -An ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically +An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) or [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer). @@ -45,50 +45,19 @@ uses a service of type [Service.Type=NodePort](/docs/concepts/services-networkin {{< feature-state for_k8s_version="v1.1" state="beta" >}} -Before you start using an ingress, there are a few things you should understand. The ingress is a beta resource. You will need an ingress controller to satisfy an ingress, simply creating the resource will have no effect. +Before you start using an Ingress, there are a few things you should understand. The Ingress is a beta resource. -GCE/Google Kubernetes Engine deploys an [ingress controller](#ingress-controllers) on the master. Review the +{{< note >}} +You must have an [Ingress controller](/docs/concepts/services-networking/ingress-controllers) to satisfy an Ingress. Only creating an Ingress resource has no effect. +{{< /note >}} + +GCE/Google Kubernetes Engine deploys an Ingress controller on the master. Review the [beta limitations](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations) of this controller if you are using GCE/GKE. In environments other than GCE/Google Kubernetes Engine, you may need to [deploy an ingress controller](https://kubernetes.github.io/ingress-nginx/deploy/). There are a number of -[ingress controller](#ingress-controllers) you may choose from. - -## Ingress controllers - -In order for the ingress resource to work, the cluster must have an ingress controller running. This is unlike other types of controllers, which run as part of the `kube-controller-manager` binary, and are typically started automatically with a cluster. Choose the ingress controller implementation that best fits your cluster. - -* Kubernetes as a project currently supports and maintains [GCE](https://git.k8s.io/ingress-gce/README.md) and - [nginx](https://git.k8s.io/ingress-nginx/README.md) controllers. - -Additional controllers include: - -* [Contour](https://github.com/heptio/contour) is an [Envoy](https://www.envoyproxy.io) based ingress controller - provided and supported by Heptio. -* F5 Networks provides [support and maintenance](https://support.f5.com/csp/article/K86859508) - for the [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest). -* [HAProxy](http://www.haproxy.org/) based ingress controller - [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) which is mentioned on the blog post - [HAProxy Ingress Controller for Kubernetes](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/). - [HAProxy Technologies](https://www.haproxy.com/) offers support and maintenance for HAProxy Enterprise and - the ingress controller [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress). -* [Istio](https://istio.io/) based ingress controller - [Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/). -* [Kong](https://konghq.com/) offers [community](https://discuss.konghq.com/c/kubernetes) or - [commercial](https://konghq.com/api-customer-success/) support and maintenance for the - [Kong Ingress Controllerfor Kubernetes](https://konghq.com/blog/kubernetes-ingress-controller-for-kong/). -* [NGINX, Inc.](https://www.nginx.com/) offers support and maintenance for the - [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller). -* [Traefik](https://github.com/containous/traefik) is a fully featured ingress controller - ([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket), and it also comes with commercial - support by [Containous](https://containo.us/services). - -You may deploy [any number of ingress controllers](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) within a cluster. -When you create an ingress, you should annotate each ingress with the appropriate -[`ingress-class`](https://git.k8s.io/ingress-gce/examples/PREREQUISITES.md#ingress-class) to indicate which ingress -controller should be used if more than one exists within your cluster. -If you do not define a class, your cloud provider may use a default ingress provider. +[ingress controllers](/docs/concepts/services-networking/ingress-controllers) you may choose from. ### Before you begin @@ -120,14 +89,14 @@ spec: servicePort: 80 ``` - As with all other Kubernetes resources, an ingress needs `apiVersion`, `kind`, and `metadata` fields. + As with all other Kubernetes resources, an Ingress needs `apiVersion`, `kind`, and `metadata` fields. For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configure-pod-configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/). - Ingress frequently uses annotations to configure some options depending on the ingress controller, an example of which + Ingress frequently uses annotations to configure some options depending on the Ingress controller, an example of which is the [rewrite-target annotation](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md). - Different [ingress controller](#ingress-controllers) support different annotations. Review the documentation for - your choice of ingress controller to learn which annotations are supported. + Different [Ingress controller](/docs/concepts/services-networking/ingress-controllers) support different annotations. Review the documentation for + your choice of Ingress controller to learn which annotations are supported. -The ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) +The Ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) has all the information needed to configure a loadbalancer or proxy server. Most importantly, it contains a list of rules matched against all incoming requests. Ingress resource only supports rules for directing HTTP traffic. @@ -144,18 +113,17 @@ Each http rule contains the following information: loadbalancer will direct traffic to the referenced service. * A backend is a combination of service and port names as described in the [services doc](/docs/concepts/services-networking/service/). HTTP (and HTTPS) requests to the - ingress matching the host and path of the rule will be sent to the listed backend. + Ingress matching the host and path of the rule will be sent to the listed backend. -A default backend is often configured in an ingress controller that will service any requests that do not +A default backend is often configured in an Ingress controller that will service any requests that do not match a path in the spec. ### Default Backend -An ingress with no rules sends all traffic to a single default backend. The default -backend is typically a configuration option of the [ingress controller](#ingress-controllers) -and is not specified in your ingress resources. +An Ingress with no rules sends all traffic to a single default backend. The default +backend is typically a configuration option of the [Ingress controller](/docs/concepts/services-networking/ingress-controllers) and is not specified in your Ingress resources. -If none of the hosts or paths match the HTTP request in the ingress objects, the traffic is +If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic is routed to your default backend. ## Types of Ingress @@ -163,7 +131,7 @@ routed to your default backend. ### Single Service Ingress There are existing Kubernetes concepts that allow you to expose a single Service -(see [alternatives](#alternatives)). You can also do this with an ingress by specifying a +(see [alternatives](#alternatives)). You can also do this with an Ingress by specifying a *default backend* with no rules. {{< codenew file="service/networking/ingress.yaml" >}} @@ -179,8 +147,8 @@ NAME HOSTS ADDRESS PORTS AGE test-ingress * 107.178.254.228 80 59s ``` -Where `107.178.254.228` is the IP allocated by the ingress controller to satisfy -this ingress. +Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy +this Ingress. {{< note >}} Ingress controllers and load balancers may take a minute or two to allocate an IP address. @@ -190,7 +158,7 @@ Until that time you will often see the address listed as ``. ### Simple fanout A fanout configuration routes traffic from a single IP address to more than one service, -based on the HTTP URI being requested. An ingress allows you to keep the number of loadbalancers +based on the HTTP URI being requested. An Ingress allows you to keep the number of loadbalancers down to a minimum. For example, a setup like: ```shell @@ -198,7 +166,7 @@ foo.bar.com -> 178.91.123.132 -> / foo service1:4200 / bar service2:8080 ``` -would require an ingress such as: +would require an Ingress such as: ```yaml apiVersion: extensions/v1beta1 @@ -222,7 +190,7 @@ spec: servicePort: 8080 ``` -When you create the ingress with `kubectl create -f`: +When you create the Ingress with `kubectl create -f`: ```shell kubectl describe ingress simple-fanout-example @@ -247,13 +215,13 @@ Events: Normal ADD 22s loadbalancer-controller default/test ``` -The ingress controller will provision an implementation specific loadbalancer -that satisfies the ingress, as long as the services (`s1`, `s2`) exist. -When it has done so, you will see the address of the loadbalancer at the +The Ingress controller provisions an implementation specific loadbalancer +that satisfies the Ingress, as long as the services (`s1`, `s2`) exist. +When it has done so, you can see the address of the loadbalancer at the Address field. {{< note >}} -Depending on the [ingress controller](#ingress-controllers) you are using, you may need to +Depending on the [Ingress controller](/docs/concepts/services-networking/ingress-controllers) you are using, you may need to create a default-http-backend [Service](/docs/concepts/services-networking/service/). {{< /note >}} @@ -267,7 +235,7 @@ foo.bar.com --| |-> foo.bar.com s1:80 bar.foo.com --| |-> bar.foo.com s2:80 ``` -The following ingress tells the backing loadbalancer to route requests based on +The following Ingress tells the backing loadbalancer to route requests based on the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4). ```yaml @@ -291,10 +259,10 @@ spec: servicePort: 80 ``` -If you create an ingress resource without any hosts defined in the rules, then any -web traffic to the IP address of your ingress controller can be matched without a name based -virtual host being required. For example, the following ingress resource will route traffic -requested for `first.bar.com` to `service1`, `second.bar.com` to `service2`, and any traffic +If you create an Ingress resource without any hosts defined in the rules, then any +web traffic to the IP address of your Ingress controller can be matched without a name based +virtual host being required. For example, the following Ingress resource will route traffic +requested for `first.bar.com` to `service1`, `second.foo.com` to `service2`, and any traffic to the IP address without a hostname defined in request (that is, without a request header being presented) to `service3`. @@ -326,12 +294,12 @@ spec: ### TLS -You can secure an ingress by specifying a [secret](/docs/concepts/configuration/secret) -that contains a TLS private key and certificate. Currently the ingress only +You can secure an Ingress by specifying a [secret](/docs/concepts/configuration/secret) +that contains a TLS private key and certificate. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If the TLS -configuration section in an ingress specifies different hosts, they will be +configuration section in an Ingress specifies different hosts, they will be multiplexed on the same port according to the hostname specified through the -SNI TLS extension (provided the ingress controller supports SNI). The TLS secret +SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, e.g.: @@ -344,10 +312,10 @@ kind: Secret metadata: name: testsecret-tls namespace: default -type: Opaque +type: kubernetes.io/tls ``` -Referencing this secret in an ingress will tell the ingress controller to +Referencing this secret in an Ingress will tell the Ingress controller to secure the channel from the client to the loadbalancer using TLS. You need to make sure the TLS secret you created came from a certificate that contains a CN for `sslexample.foo.com`. @@ -373,24 +341,24 @@ spec: ``` {{< note >}} -There is a gap between TLS features supported by various ingress +There is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on [nginx](https://git.k8s.io/ingress-nginx/README.md#https), [GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https), or any other -platform specific ingress controller to understand how TLS works in your environment. +platform specific Ingress controller to understand how TLS works in your environment. {{< /note >}} ### Loadbalancing -An ingress controller is bootstrapped with some load balancing policy settings -that it applies to all ingress, such as the load balancing algorithm, backend +An Ingress controller is bootstrapped with some load balancing policy settings +that it applies to all Ingress, such as the load balancing algorithm, backend weight scheme, and others. More advanced load balancing concepts (e.g. persistent sessions, dynamic weights) are not yet exposed through the -ingress. You can still get these features through the +Ingress. You can still get these features through the [service loadbalancer](https://github.com/kubernetes/ingress-nginx). It's also worth noting that even though health checks are not exposed directly -through the ingress, there exist parallel concepts in Kubernetes such as +through the Ingress, there exist parallel concepts in Kubernetes such as [readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) which allow you to achieve the same end result. Please review the controller specific docs to see how they handle health checks ( @@ -399,7 +367,7 @@ specific docs to see how they handle health checks ( ## Updating an Ingress -To update an existing ingress to add a new Host, you can update it by editing the resource: +To update an existing Ingress to add a new Host, you can update it by editing the resource: ```shell kubectl describe ingress test @@ -450,7 +418,7 @@ spec: ``` Saving the yaml will update the resource in the API server, which should tell the -ingress controller to reconfigure the loadbalancer. +Ingress controller to reconfigure the loadbalancer. ```shell kubectl describe ingress test @@ -476,25 +444,24 @@ Events: Normal ADD 45s loadbalancer-controller default/test ``` -You can achieve the same by invoking `kubectl replace -f` on a modified ingress yaml file. +You can achieve the same by invoking `kubectl replace -f` on a modified Ingress yaml file. ## Failing across availability zones Techniques for spreading traffic across failure domains differs between cloud providers. -Please check the documentation of the relevant [ingress controller](#ingress-controllers) for -details. You can also refer to the [federation documentation](/docs/concepts/cluster-administration/federation/) -for details on deploying ingress in a federated cluster. +Please check the documentation of the relevant [Ingress controller](/docs/concepts/services-networking/ingress-controllers) for details. You can also refer to the [federation documentation](/docs/concepts/cluster-administration/federation/) +for details on deploying Ingress in a federated cluster. ## Future Work Track [SIG Network](https://github.com/kubernetes/community/tree/master/sig-network) for more details on the evolution of the ingress and related resources. You may also track the -[ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the -evolution of various ingress controllers. +[Ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the +evolution of various Ingress controllers. ## Alternatives -You can expose a Service in multiple ways that don't directly involve the ingress resource: +You can expose a Service in multiple ways that don't directly involve the Ingress resource: * Use [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer) * Use [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) @@ -503,6 +470,5 @@ You can expose a Service in multiple ways that don't directly involve the ingres {{% /capture %}} {{% capture whatsnext %}} - +* [Set up Ingress on Minikube with the NGINX Controller](/docs/tasks/access-application-cluster/ingress-minikube) {{% /capture %}} - diff --git a/content/en/docs/concepts/services-networking/network-policies.md b/content/en/docs/concepts/services-networking/network-policies.md index 45f68088c5..cd18e6ecaa 100644 --- a/content/en/docs/concepts/services-networking/network-policies.md +++ b/content/en/docs/concepts/services-networking/network-policies.md @@ -92,11 +92,12 @@ __egress__: Each `NetworkPolicy` may include a list of whitelist `egress` rules. So, the example NetworkPolicy: 1. isolates "role=db" pods in the "default" namespace for both ingress and egress traffic (if they weren't already isolated) -2. allows connections to TCP port 6379 of "role=db" pods in the "default" namespace from: +2. (Ingress rules) allows connections to all pods in the “default” namespace with the label “role=db” on TCP port 6379 from: + * any pod in the "default" namespace with the label "role=frontend" * any pod in a namespace with the label "project=myproject" * IP addresses in the ranges 172.17.0.0–172.17.0.255 and 172.17.2.0–172.17.255.255 (ie, all of 172.17.0.0/16 except 172.17.1.0/24) -3. allows connections from any pod in the "default" namespace with the label "role=db" to CIDR 10.0.0.0/24 on TCP port 5978 +3. (Egress rules) allows connections from any pod in the "default" namespace with the label "role=db" to CIDR 10.0.0.0/24 on TCP port 5978 See the [Declare Network Policy](/docs/tasks/administer-cluster/declare-network-policy/) walkthrough for further examples. @@ -191,6 +192,8 @@ spec: podSelector: {} ingress: - {} + policyTypes: + - Ingress ``` ### Default deny all egress traffic @@ -264,4 +267,3 @@ The CNI plugin has to support SCTP as `protocol` value in `NetworkPolicy`. - See more [Recipes](https://github.com/ahmetb/kubernetes-network-policy-recipes) for common scenarios enabled by the NetworkPolicy resource. {{% /capture %}} - diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index 37cc723539..3723ca6bbe 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -83,12 +83,9 @@ deploying and evolving your `Services`. For example, you can change the port number that pods expose in the next version of your backend software, without breaking clients. -Kubernetes `Services` support `TCP`, `UDP` and `SCTP` for protocols. The default -is `TCP`. - -{{< note >}} -SCTP support is an alpha feature since Kubernetes 1.12 -{{< /note >}} +`TCP` is the default protocol for services, and you can also use any other +[supported protocol](#protocol-support). At the moment, you can only set a +single `port` and `protocol` for a Service. ### Services without selectors @@ -519,6 +516,16 @@ metadata: [...] ``` {{% /tab %}} +{{% tab name="Baidu Cloud" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/cce-load-balancer-internal-vpc: "true" +[...] +``` +{{% /tab %}} {{< /tabs >}} @@ -758,13 +765,10 @@ for supported instance types. ### Type ExternalName {#externalname} -{{< note >}} -ExternalName Services are available only with `kube-dns` version 1.7 and later. -{{< /note >}} +Services of type ExternalName map a service to a DNS name, not to a typical selector such as +`my-service` or `cassandra`. You specify these services with the `spec.externalName` parameter. -Services of type ExternalName map a service to a DNS name (specified using -the `spec.externalName` parameter) rather than to a typical selector like -`my-service` or `cassandra`. This Service definition, for example, would map +This Service definition, for example, maps the `my-service` Service in the `prod` namespace to `my.database.example.com`: ```yaml @@ -777,6 +781,10 @@ spec: type: ExternalName externalName: my.database.example.com ``` +{{< note >}} +ExternalName accepts an IPv4 address string, but as a DNS name comprised of digits, not as an IP address. ExternalNames that resemble IPv4 addresses are not resolved by CoreDNS or ingress-nginx because ExternalName +is intended to specify a canonical DNS name. To hardcode an IP address, consider headless services. +{{< /note >}} When looking up the host `my-service.prod.svc.cluster.local`, the cluster DNS service will return a `CNAME` record with the value `my.database.example.com`. Accessing @@ -933,29 +941,74 @@ Service is a top-level resource in the Kubernetes REST API. More details about t API object can be found at: [Service API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core). -## SCTP support +## Supported protocols {#protocol-support} + +### TCP + +{{< feature-state for_k8s_version="v1.0" state="stable" >}} + +You can use TCP for any kind of service, and it's the default network protocol. + +### UDP + +{{< feature-state for_k8s_version="v1.0" state="stable" >}} + +You can use UDP for most services. For type=LoadBalancer services, UDP support +depends on the cloud provider offering this facility. + +### HTTP + +{{< feature-state for_k8s_version="v1.1" state="stable" >}} + +If your cloud provider supports it, you can use a Service in LoadBalancer mode +to set up external HTTP / HTTPS reverse proxying, forwarded to the Endpoints +of the Service. + +{{< note >}} +You can also use {{< glossary_tooltip term_id="ingress" >}} in place of Service +to expose HTTP / HTTPS services. +{{< /note >}} + +### PROXY protocol + +{{< feature-state for_k8s_version="v1.1" state="stable" >}} + +If your cloud provider supports it (eg, [AWS](https://kubernetes.io/docs/concepts/cluster-administration/cloud-providers/#aws)), +you can use a Service in LoadBalancer mode to configure a load balancer outside +of Kubernetes itself, that will forward connections prefixed with +[PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt). + +The load balancer will send an initial series of octets describing the +incoming connection, similar to this example + +``` +PROXY TCP4 192.0.2.202 10.0.42.7 12345 7\r\n +``` +followed by the data from the client. + +### SCTP {{< feature-state for_k8s_version="v1.12" state="alpha" >}} Kubernetes supports SCTP as a `protocol` value in `Service`, `Endpoint`, `NetworkPolicy` and `Pod` definitions as an alpha feature. To enable this feature, the cluster administrator needs to enable the `SCTPSupport` feature gate on the apiserver, for example, `“--feature-gates=SCTPSupport=true,...”`. When the feature gate is enabled, users can set the `protocol` field of a `Service`, `Endpoint`, `NetworkPolicy` and `Pod` to `SCTP`. Kubernetes sets up the network accordingly for the SCTP associations, just like it does for TCP connections. -### Warnings +#### Warnings {#caveat-sctp-overview} -#### The support of multihomed SCTP associations +##### Support for multihomed SCTP associations {#caveat-sctp-multihomed} The support of multihomed SCTP associations requires that the CNI plugin can support the assignment of multiple interfaces and IP addresses to a `Pod`. NAT for multihomed SCTP associations requires special logic in the corresponding kernel modules. -#### Service with type=LoadBalancer +##### Service with type=LoadBalancer {#caveat-sctp-loadbalancer-service-type} A `Service` with `type` LoadBalancer and `protocol` SCTP can be created only if the cloud provider's load balancer implementation supports SCTP as a protocol. Otherwise the `Service` creation request is rejected. The current set of cloud load balancer providers (`Azure`, `AWS`, `CloudStack`, `GCE`, `OpenStack`) do not support SCTP. -#### Windows +##### Windows {#caveat-sctp-windows-os} SCTP is not supported on Windows based nodes. -#### Userspace kube-proxy +##### Userspace kube-proxy {#caveat-sctp-kube-proxy-userspace} The kube-proxy does not support the management of SCTP associations when it is in userspace mode. diff --git a/content/en/docs/concepts/storage/persistent-volumes.md b/content/en/docs/concepts/storage/persistent-volumes.md index f9f4df2615..ee66fdd81c 100644 --- a/content/en/docs/concepts/storage/persistent-volumes.md +++ b/content/en/docs/concepts/storage/persistent-volumes.md @@ -309,9 +309,7 @@ Currently, storage size is the only resource that can be set or requested. Futu ### Volume Mode -{{< feature-state for_k8s_version="v1.9" state="alpha" >}} - -To enable this feature, enable the `BlockVolume` feature gate on the apiserver, controller-manager and the kubelet. +{{< feature-state for_k8s_version="v1.13" state="beta" >}} Prior to Kubernetes 1.9, all volume plugins created a filesystem on the persistent volume. Now, you can set the value of `volumeMode` to `raw` to use a raw block device, or `filesystem` @@ -461,7 +459,7 @@ Claims use the same conventions as volumes when requesting storage with specific ### Volume Modes -Claims use the same convention as volumes to indicates the consumption of the volume as either a filesystem or block device. +Claims use the same convention as volumes to indicate the consumption of the volume as either a filesystem or block device. ### Resources @@ -548,10 +546,7 @@ spec: ## Raw Block Volume Support -{{< feature-state for_k8s_version="v1.9" state="alpha" >}} - -To enable support for raw block volumes, enable the `BlockVolume` feature gate on the -apiserver, controller-manager and the kubelet. +{{< feature-state for_k8s_version="v1.13" state="beta" >}} The following volume plugins support raw block volumes, including dynamic provisioning where applicable. diff --git a/content/en/docs/concepts/storage/storage-classes.md b/content/en/docs/concepts/storage/storage-classes.md index 798c409db4..fe817d1aac 100644 --- a/content/en/docs/concepts/storage/storage-classes.md +++ b/content/en/docs/concepts/storage/storage-classes.md @@ -153,7 +153,7 @@ The following plugins support `WaitForFirstConsumer` with pre-created Persistent ### Allowed Topologies -When a cluster operactor specifies the `WaitForFirstConsumer` volume binding mode, it is no longer necessary +When a cluster operator specifies the `WaitForFirstConsumer` volume binding mode, it is no longer necessary to restrict provisioning to specific topologies in most situations. However, if still required, `allowedTopologies` can be specified. @@ -627,13 +627,13 @@ parameters: ``` -* `fs`: filesystem to be laid out: [none/xfs/ext4] (default: `ext4`). +* `fs`: filesystem to be laid out: `none/xfs/ext4` (default: `ext4`). * `block_size`: block size in Kbytes (default: `32`). * `repl`: number of synchronous replicas to be provided in the form of - replication factor [1..3] (default: `1`) A string is expected here i.e. + replication factor `1..3` (default: `1`) A string is expected here i.e. `"1"` and not `1`. * `io_priority`: determines whether the volume will be created from higher - performance or a lower priority storage [high/medium/low] (default: `low`). + performance or a lower priority storage `high/medium/low` (default: `low`). * `snap_interval`: clock/time interval in minutes for when to trigger snapshots. Snapshots are incremental based on difference with the prior snapshot, 0 disables snaps (default: `0`). A string is expected here i.e. @@ -644,7 +644,7 @@ parameters: * `ephemeral`: specifies whether the volume should be cleaned-up after unmount or should be persistent. `emptyDir` use case can set this value to true and `persistent volumes` use case such as for databases like Cassandra should set - to false, [true/false] (default `false`). A string is expected here i.e. + to false, `true/false` (default `false`). A string is expected here i.e. `"true"` and not `true`. ### ScaleIO diff --git a/content/en/docs/concepts/storage/volumes.md b/content/en/docs/concepts/storage/volumes.md index 4c35d92678..a479c9ebde 100644 --- a/content/en/docs/concepts/storage/volumes.md +++ b/content/en/docs/concepts/storage/volumes.md @@ -75,6 +75,7 @@ Kubernetes supports several types of Volumes: * [downwardAPI](#downwardapi) * [emptyDir](#emptydir) * [fc (fibre channel)](#fc) + * [flexVolume](#flexVolume) * [flocker](#flocker) * [gcePersistentDisk](#gcepersistentdisk) * [gitRepo (deprecated)](#gitrepo) @@ -789,9 +790,8 @@ receive updates for those volume sources. ### portworxVolume {#portworxvolume} A `portworxVolume` is an elastic block storage layer that runs hyperconverged with -Kubernetes. Portworx fingerprints storage in a server, tiers based on capabilities, -and aggregates capacity across multiple servers. Portworx runs in-guest in virtual -machines or on bare metal Linux nodes. +Kubernetes. [Portworx](https://portworx.com/use-case/kubernetes-storage/) fingerprints storage in a server, tiers based on capabilities, +and aggregates capacity across multiple servers. Portworx runs in-guest in virtual machines or on bare metal Linux nodes. A `portworxVolume` can be dynamically created through Kubernetes or it can also be pre-provisioned and referenced inside a Kubernetes Pod. @@ -834,7 +834,9 @@ You must have your own Quobyte setup running with the volumes created before you can use it. {{< /caution >}} -See the [Quobyte example](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/quobyte) for more details. +Quobyte supports the {{< glossary_tooltip text="Container Storage Interface" term_id="csi" >}}. +CSI is the recommended plugin to use Quobyte volumes inside Kubernetes. Quobyte's +GitHub project has [instructions](https://github.com/quobyte/quobyte-csi#quobyte-csi) for deploying Quobyte using CSI, along with examples. ### rbd {#rbd} @@ -1149,12 +1151,12 @@ CSI support was introduced as alpha in Kubernetes v1.9, moved to beta in Kubernetes v1.10, and is GA in Kubernetes v1.13. {{< note >}} -**Note:** Support for CSI spec versions 0.2 and 0.3 are deprecated in Kubernetes +Support for CSI spec versions 0.2 and 0.3 are deprecated in Kubernetes v1.13 and will be removed in a future release. {{< /note >}} {{< note >}} -**Note:** CSI drivers may not be compatible across all Kubernetes releases. +CSI drivers may not be compatible across all Kubernetes releases. Please check the specific CSI driver's documentation for supported deployments steps for each Kubernetes release and a compatibility matrix. {{< /note >}} @@ -1237,7 +1239,7 @@ Learn how to For more information on how to develop a CSI driver, refer to the [kubernetes-csi documentation](https://kubernetes-csi.github.io/docs/) -### Flexvolume +### Flexvolume {#flexVolume} Flexvolume is an out-of-tree plugin interface that has existed in Kubernetes since version 1.2 (before CSI). It uses an exec-based model to interface with @@ -1305,8 +1307,8 @@ MountFlags=shared ``` Or, remove `MountFlags=slave` if present. Then restart the Docker daemon: ```shell -$ sudo systemctl daemon-reload -$ sudo systemctl restart docker +sudo systemctl daemon-reload +sudo systemctl restart docker ``` diff --git a/content/en/docs/concepts/workloads/controllers/cron-jobs.md b/content/en/docs/concepts/workloads/controllers/cron-jobs.md index 602bf0d581..339cb81f78 100644 --- a/content/en/docs/concepts/workloads/controllers/cron-jobs.md +++ b/content/en/docs/concepts/workloads/controllers/cron-jobs.md @@ -16,7 +16,7 @@ One CronJob object is like one line of a _crontab_ (cron table) file. It runs a on a given schedule, written in [Cron](https://en.wikipedia.org/wiki/Cron) format. {{< note >}} -All **CronJob** `schedule:` times are denoted in UTC. +All **CronJob** `schedule:` times are based the timezone of the master where the job is initiated. {{< /note >}} For instructions on creating and working with cron jobs, and for an example of a spec file for a cron job, see [Running automated tasks with cron jobs](/docs/tasks/job/automated-tasks-with-cron-jobs). @@ -46,11 +46,13 @@ It is important to note that if the `startingDeadlineSeconds` field is set (not A CronJob is counted as missed if it has failed to be created at its scheduled time. For example, If `concurrencyPolicy` is set to `Forbid` and a CronJob was attempted to be scheduled when there was a previous schedule still running, then it would count as missed. -For example, suppose a cron job is set to start at exactly `08:30:00` and its -`startingDeadlineSeconds` is set to 10, if the CronJob controller happens to -be down from `08:29:00` to `08:42:00`, the job will not start. -Set a longer `startingDeadlineSeconds` if starting later is better than not -starting at all. +For example, suppose a CronJob is set to schedule a new Job every one minute beginning at `08:30:00`, and its +`startingDeadlineSeconds` field is not set. The default for this field is `100` seconds. If the CronJob controller happens to +be down from `08:29:00` to `10:21:00`, the job will not start as the number of missed jobs which missed their schedule is greater than 100. + +To illustrate this concept further, suppose a CronJob is set to schedule a new Job every one minute beginning at `08:30:00`, and its +`startingDeadlineSeconds` is set to 200 seconds. If the CronJob controller happens to +be down for the same period as the previous example (`08:29:00` to `10:21:00`,) the Job will still start at 10:22:00. This happens as the controller now checks how many missed schedules happened in the last 200 seconds (ie, 3 missed schedules), rather than from the last scheduled time until now. The Cronjob is only responsible for creating Jobs that match its schedule, and the Job in turn is responsible for the management of the Pods it represents. diff --git a/content/en/docs/concepts/workloads/controllers/daemonset.md b/content/en/docs/concepts/workloads/controllers/daemonset.md index 3a205a2f79..33fd8af370 100644 --- a/content/en/docs/concepts/workloads/controllers/daemonset.md +++ b/content/en/docs/concepts/workloads/controllers/daemonset.md @@ -21,7 +21,7 @@ Some typical uses of a DaemonSet are: - running a cluster storage daemon, such as `glusterd`, `ceph`, on each node. - running a logs collection daemon on every node, such as `fluentd` or `logstash`. - running a node monitoring daemon on every node, such as [Prometheus Node Exporter]( - https://github.com/prometheus/node_exporter), `collectd`, [Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/), Datadog agent, New Relic agent, Ganglia `gmond` or Instana agent. + https://github.com/prometheus/node_exporter), `collectd`, [Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/), [AppDynamics Agent](https://docs.appdynamics.com/display/CLOUD/Container+Visibility+with+Kubernetes), [Datadog agent](https://docs.datadoghq.com/agent/kubernetes/daemonset_setup/), [New Relic agent](https://docs.newrelic.com/docs/integrations/kubernetes-integration/installation/kubernetes-installation-configuration), Ganglia `gmond` or Instana agent. In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon. A more complex setup might use multiple DaemonSets for a single type of daemon, but with diff --git a/content/en/docs/concepts/workloads/controllers/deployment.md b/content/en/docs/concepts/workloads/controllers/deployment.md index 80c81863c4..0910dfbdd1 100644 --- a/content/en/docs/concepts/workloads/controllers/deployment.md +++ b/content/en/docs/concepts/workloads/controllers/deployment.md @@ -40,7 +40,6 @@ The following are typical use cases for Deployments: * [Use the status of the Deployment](#deployment-status) as an indicator that a rollout has stuck. * [Clean up older ReplicaSets](#clean-up-policy) that you don't need anymore. - ## Creating a Deployment The following is an example of a Deployment. It creates a ReplicaSet to bring up three `nginx` Pods: @@ -55,9 +54,9 @@ In this example: In this case, you simply select a label that is defined in the Pod template (`app: nginx`). However, more sophisticated selection rules are possible, as long as the Pod template itself satisfies the rule. - + {{< note >}} - `matchLabels` is a map of {key,value} pairs. A single {key,value} in the `matchLabels` map + `matchLabels` is a map of {key,value} pairs. A single {key,value} in the `matchLabels` map is equivalent to an element of `matchExpressions`, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. {{< /note >}} @@ -66,9 +65,9 @@ In this example: * The Pods are labeled `app: nginx`using the `labels` field. * The Pod template's specification, or `.template.spec` field, indicates that the Pods run one container, `nginx`, which runs the `nginx` - [Docker Hub](https://hub.docker.com/) image at version 1.15.4. + [Docker Hub](https://hub.docker.com/) image at version 1.7.9. * Create one container and name it `nginx` using the `name` field. - * Run the `nginx` image at version `1.15.4`. + * Run the `nginx` image at version `1.7.9`. * Open port `80` so that the container can send and accept traffic. To create this Deployment, run the following command: @@ -128,18 +127,19 @@ To see the ReplicaSet (`rs`) created by the deployment, run `kubectl get rs`: ```shell NAME DESIRED CURRENT READY AGE -nginx-deployment-2035384211 3 3 3 18s +nginx-deployment-75675f5897 3 3 3 18s ``` -Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]`. The hash value is automatically generated when the Deployment is created. +Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[RANDOM-STRING]`. The random string is +randomly generated and uses the pod-template-hash as a seed. To see the labels automatically generated for each pod, run `kubectl get pods --show-labels`. The following output is returned: ```shell NAME READY STATUS RESTARTS AGE LABELS -nginx-deployment-2035384211-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 -nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 -nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 +nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 +nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 +nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 ``` The created ReplicaSet ensures that there are three `nginx` Pods running at all times. @@ -171,21 +171,27 @@ Suppose that you now want to update the nginx Pods to use the `nginx:1.9.1` imag instead of the `nginx:1.7.9` image. ```shell -$ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record -deployment.apps/nginx-deployment image updated +kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 +``` +``` +image updated ``` Alternatively, you can `edit` the Deployment and change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`: ```shell -$ kubectl edit deployment.v1.apps/nginx-deployment +kubectl edit deployment.v1.apps/nginx-deployment +``` +``` deployment.apps/nginx-deployment edited ``` To see the rollout status, run: ```shell -$ kubectl rollout status deployment.v1.apps/nginx-deployment +kubectl rollout status deployment.v1.apps/nginx-deployment +``` +``` Waiting for rollout to finish: 2 out of 3 new replicas have been updated... deployment.apps/nginx-deployment successfully rolled out ``` @@ -193,7 +199,9 @@ deployment.apps/nginx-deployment successfully rolled out After the rollout succeeds, you may want to `get` the Deployment: ```shell -$ kubectl get deployments +kubectl get deployments +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 36s ``` @@ -206,7 +214,9 @@ You can run `kubectl get rs` to see that the Deployment updated the Pods by crea up to 3 replicas, as well as scaling down the old ReplicaSet to 0 replicas. ```shell -$ kubectl get rs +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 6s nginx-deployment-2035384211 0 0 0 36s @@ -215,7 +225,9 @@ nginx-deployment-2035384211 0 0 0 36s Running `get pods` should now show only the new Pods: ```shell -$ kubectl get pods +kubectl get pods +``` +``` NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-khku8 1/1 Running 0 14s nginx-deployment-1564180365-nacti 1/1 Running 0 14s @@ -236,7 +248,9 @@ new Pods have come up, and does not create new Pods until a sufficient number of It makes sure that number of available Pods is at least 2 and the number of total Pods is at most 4. ```shell -$ kubectl describe deployments +kubectl describe deployments +``` +``` Name: nginx-deployment Namespace: default CreationTimestamp: Thu, 30 Nov 2017 10:56:25 +0000 @@ -337,14 +351,18 @@ rolled back. Suppose that you made a typo while updating the Deployment, by putting the image name as `nginx:1.91` instead of `nginx:1.9.1`: ```shell -$ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true +kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true +``` +``` deployment.apps/nginx-deployment image updated ``` The rollout will be stuck. ```shell -$ kubectl rollout status deployment.v1.apps/nginx-deployment +kubectl rollout status deployment.v1.apps/nginx-deployment +``` +``` Waiting for rollout to finish: 1 out of 3 new replicas have been updated... ``` @@ -354,7 +372,9 @@ Press Ctrl-C to stop the above rollout status watch. For more information on stu You will see that the number of old replicas (nginx-deployment-1564180365 and nginx-deployment-2035384211) is 2, and new replicas (nginx-deployment-3066724191) is 1. ```shell -$ kubectl get rs +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 25s nginx-deployment-2035384211 0 0 0 36s @@ -364,7 +384,9 @@ nginx-deployment-3066724191 1 1 0 6s Looking at the Pods created, you will see that 1 Pod created by new ReplicaSet is stuck in an image pull loop. ```shell -$ kubectl get pods +kubectl get pods +``` +``` NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-70iae 1/1 Running 0 25s nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s @@ -379,7 +401,9 @@ Kubernetes by default sets the value to 25%. {{< /note >}} ```shell -$ kubectl describe deployment +kubectl describe deployment +``` +``` Name: nginx-deployment Namespace: default CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 @@ -426,7 +450,9 @@ To fix this, you need to rollback to a previous revision of Deployment that is s First, check the revisions of this deployment: ```shell -$ kubectl rollout history deployment.v1.apps/nginx-deployment +kubectl rollout history deployment.v1.apps/nginx-deployment +``` +``` deployments "nginx-deployment" REVISION CHANGE-CAUSE 1 kubectl create --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true @@ -442,7 +468,9 @@ REVISION CHANGE-CAUSE To further see the details of each revision, run: ```shell -$ kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2 +kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2 +``` +``` deployments "nginx-deployment" revision 2 Labels: app=nginx pod-template-hash=1159050644 @@ -463,14 +491,18 @@ deployments "nginx-deployment" revision 2 Now you've decided to undo the current rollout and rollback to the previous revision: ```shell -$ kubectl rollout undo deployment.v1.apps/nginx-deployment +kubectl rollout undo deployment.v1.apps/nginx-deployment +``` +``` deployment.apps/nginx-deployment ``` -Alternatively, you can rollback to a specific revision by specify that in `--to-revision`: +Alternatively, you can rollback to a specific revision by specifying it with `--to-revision`: ```shell -$ kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2 +kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2 +``` +``` deployment.apps/nginx-deployment ``` @@ -480,11 +512,17 @@ The Deployment is now rolled back to a previous stable revision. As you can see, for rolling back to revision 2 is generated from Deployment controller. ```shell -$ kubectl get deployment nginx-deployment +kubectl get deployment nginx-deployment +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 30m +``` -$ kubectl describe deployment nginx-deployment +```shell +kubectl describe deployment nginx-deployment +``` +``` Name: nginx-deployment Namespace: default CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500 @@ -533,7 +571,9 @@ Events: You can scale a Deployment by using the following command: ```shell -$ kubectl scale deployment.v1.apps/nginx-deployment --replicas=10 +kubectl scale deployment.v1.apps/nginx-deployment --replicas=10 +``` +``` deployment.apps/nginx-deployment scaled ``` @@ -542,7 +582,9 @@ in your cluster, you can setup an autoscaler for your Deployment and choose the Pods you want to run based on the CPU utilization of your existing Pods. ```shell -$ kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80 +kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80 +``` +``` deployment.apps/nginx-deployment scaled ``` @@ -556,7 +598,9 @@ ReplicaSets (ReplicaSets with Pods) in order to mitigate risk. This is called *p For example, you are running a Deployment with 10 replicas, [maxSurge](#max-surge)=3, and [maxUnavailable](#max-unavailable)=2. ```shell -$ kubectl get deploy +kubectl get deploy +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 10 10 10 10 50s ``` @@ -564,7 +608,9 @@ nginx-deployment 10 10 10 10 50s You update to a new image which happens to be unresolvable from inside the cluster. ```shell -$ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag +kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag +``` +``` deployment.apps/nginx-deployment image updated ``` @@ -572,7 +618,9 @@ The image update starts a new rollout with ReplicaSet nginx-deployment-198919819 `maxUnavailable` requirement that you mentioned above. ```shell -$ kubectl get rs +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-deployment-1989198191 5 5 0 9s nginx-deployment-618515232 8 8 8 1m @@ -590,10 +638,17 @@ new ReplicaSet. The rollout process should eventually move all replicas to the n the new replicas become healthy. ```shell -$ kubectl get deploy +kubectl get deploy +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 15 18 7 8 7m -$ kubectl get rs +``` + +```shell +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-deployment-1989198191 7 7 0 7m nginx-deployment-618515232 11 11 11 7m @@ -607,10 +662,16 @@ apply multiple fixes in between pausing and resuming without triggering unnecess For example, with a Deployment that was just created: ```shell -$ kubectl get deploy +kubectl get deploy +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 3 3 3 3 1m -$ kubectl get rs +``` +```shell +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-2142116321 3 3 3 1m ``` @@ -618,26 +679,36 @@ nginx-2142116321 3 3 3 1m Pause by running the following command: ```shell -$ kubectl rollout pause deployment.v1.apps/nginx-deployment +kubectl rollout pause deployment.v1.apps/nginx-deployment +``` +``` deployment.apps/nginx-deployment paused ``` Then update the image of the Deployment: ```shell -$ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 +kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 +``` +``` deployment.apps/nginx-deployment image updated ``` Notice that no new rollout started: ```shell -$ kubectl rollout history deployment.v1.apps/nginx-deployment +kubectl rollout history deployment.v1.apps/nginx-deployment +``` +``` deployments "nginx" REVISION CHANGE-CAUSE 1 +``` -$ kubectl get rs +```shell +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-2142116321 3 3 3 2m ``` @@ -645,7 +716,9 @@ nginx-2142116321 3 3 3 2m You can make as many updates as you wish, for example, update the resources that will be used: ```shell -$ kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi +kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi +``` +``` deployment.apps/nginx-deployment resource requirements updated ``` @@ -655,9 +728,18 @@ the Deployment will not have any effect as long as the Deployment is paused. Eventually, resume the Deployment and observe a new ReplicaSet coming up with all the new updates: ```shell -$ kubectl rollout resume deployment.v1.apps/nginx-deployment +kubectl rollout resume deployment.v1.apps/nginx-deployment +``` + +``` deployment.apps/nginx-deployment resumed -$ kubectl get rs -w +``` + +```shell +kubectl get rs -w +``` + +``` NAME DESIRED CURRENT READY AGE nginx-2142116321 2 2 2 2m nginx-3926361531 2 2 0 6s @@ -673,8 +755,12 @@ nginx-2142116321 0 1 1 2m nginx-2142116321 0 1 1 2m nginx-2142116321 0 0 0 2m nginx-3926361531 3 3 3 20s -^C -$ kubectl get rs + +``` +```shell +kubectl get rs +``` +``` NAME DESIRED CURRENT READY AGE nginx-2142116321 0 0 0 2m nginx-3926361531 3 3 3 28s @@ -713,7 +799,9 @@ You can check if a Deployment has completed by using `kubectl rollout status`. I successfully, `kubectl rollout status` returns a zero exit code. ```shell -$ kubectl rollout status deployment.v1.apps/nginx-deployment +kubectl rollout status deployment.v1.apps/nginx-deployment +``` +``` Waiting for rollout to finish: 2 of 3 updated replicas are available... deployment.apps/nginx-deployment successfully rolled out $ echo $? @@ -741,7 +829,9 @@ The following `kubectl` command sets the spec with `progressDeadlineSeconds` to lack of progress for a Deployment after 10 minutes: ```shell -$ kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}' +kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}' +``` +``` deployment.apps/nginx-deployment patched ``` Once the deadline has been exceeded, the Deployment controller adds a DeploymentCondition with the following @@ -770,7 +860,9 @@ due to any other kind of error that can be treated as transient. For example, le insufficient quota. If you describe the Deployment you will notice the following section: ```shell -$ kubectl describe deployment nginx-deployment +kubectl describe deployment nginx-deployment +``` +``` <...> Conditions: Type Status Reason @@ -846,7 +938,9 @@ You can check if a Deployment has failed to progress by using `kubectl rollout s returns a non-zero exit code if the Deployment has exceeded the progression deadline. ```shell -$ kubectl rollout status deployment.v1.apps/nginx-deployment +kubectl rollout status deployment.v1.apps/nginx-deployment +``` +``` Waiting for rollout to finish: 2 out of 3 new replicas have been updated... error: deployment "nginx" exceeded its progress deadline $ echo $? @@ -988,15 +1082,12 @@ Field `.spec.rollbackTo` has been deprecated in API versions `extensions/v1beta1 ### Revision History Limit -A Deployment's revision history is stored in the replica sets it controls. +A Deployment's revision history is stored in the ReplicaSets it controls. `.spec.revisionHistoryLimit` is an optional field that specifies the number of old ReplicaSets to retain -to allow rollback. Its ideal value depends on the frequency and stability of new Deployments. All old -ReplicaSets will be kept by default, consuming resources in `etcd` and crowding the output of `kubectl get rs`, -if this field is not set. The configuration of each Deployment revision is stored in its ReplicaSets; -therefore, once an old ReplicaSet is deleted, you lose the ability to rollback to that revision of Deployment. +to allow rollback. These old ReplicaSets consume resources in `etcd` and crowd the output of `kubectl get rs`. The configuration of each Deployment revision is stored in its ReplicaSets; therefore, once an old ReplicaSet is deleted, you lose the ability to rollback to that revision of Deployment. By default, 10 old ReplicaSets will be kept, however its ideal value depends on the frequency and stability of new Deployments. -More specifically, setting this field to zero means that all old ReplicaSets with 0 replica will be cleaned up. +More specifically, setting this field to zero means that all old ReplicaSets with 0 replicas will be cleaned up. In this case, a new Deployment rollout cannot be undone, since its revision history is cleaned up. ### Paused @@ -1015,5 +1106,3 @@ in a similar fashion. But Deployments are recommended, since they are declarativ additional features, such as rolling back to any previous revision even after the rolling update is done. {{% /capture %}} - - diff --git a/content/en/docs/concepts/workloads/controllers/garbage-collection.md b/content/en/docs/concepts/workloads/controllers/garbage-collection.md index a2b8517afa..ee3fb1fcd5 100644 --- a/content/en/docs/concepts/workloads/controllers/garbage-collection.md +++ b/content/en/docs/concepts/workloads/controllers/garbage-collection.md @@ -60,6 +60,14 @@ metadata: ... ``` +{{< note >}} +Cross-namespace owner references is disallowed by design. This means: +1) Namespace-scoped dependents can only specify owners in the same namespace, +and owners that are cluster-scoped. +2) Cluster-scoped dependents can only specify cluster-scoped owners, but not +namespace-scoped owners. +{{< /note >}} + ## Controlling how the garbage collector deletes dependents When you delete an object, you can specify whether the object's dependents are diff --git a/content/en/docs/concepts/workloads/controllers/jobs-run-to-completion.md b/content/en/docs/concepts/workloads/controllers/jobs-run-to-completion.md index 0dbbfaabf0..4c22be980c 100644 --- a/content/en/docs/concepts/workloads/controllers/jobs-run-to-completion.md +++ b/content/en/docs/concepts/workloads/controllers/jobs-run-to-completion.md @@ -13,16 +13,16 @@ weight: 70 {{% capture overview %}} -A _job_ creates one or more pods and ensures that a specified number of them successfully terminate. -As pods successfully complete, the _job_ tracks the successful completions. When a specified number -of successful completions is reached, the job itself is complete. Deleting a Job will cleanup the -pods it created. +A Job creates one or more Pods and ensures that a specified number of them successfully terminate. +As pods successfully complete, the Job tracks the successful completions. When a specified number +of successful completions is reached, the task (ie, Job) is complete. Deleting a Job will clean up +the Pods it created. A simple case is to create one Job object in order to reliably run one Pod to completion. -The Job object will start a new Pod if the first pod fails or is deleted (for example +The Job object will start a new Pod if the first Pod fails or is deleted (for example due to a node hardware failure or a node reboot). -A Job can also be used to run multiple pods in parallel. +You can also use a Job to run multiple Pods in parallel. {{% /capture %}} @@ -36,17 +36,21 @@ It takes around 10s to complete. {{< codenew file="controllers/job.yaml" >}} -Run the example job by downloading the example file and then running this command: +You can run the example with this command: ```shell -$ kubectl create -f https://k8s.io/examples/controllers/job.yaml +kubectl create -f https://k8s.io/examples/controllers/job.yaml +``` +``` job "pi" created ``` -Check on the status of the job using this command: +Check on the status of the Job with `kubectl`: ```shell -$ kubectl describe jobs/pi +kubectl describe jobs/pi +``` +``` Name: pi Namespace: default Selector: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495 @@ -78,18 +82,20 @@ Events: 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: pi-dtn4q ``` -To view completed pods of a job, use `kubectl get pods`. +To view completed Pods of a Job, use `kubectl get pods`. -To list all the pods that belong to a job in a machine readable form, you can use a command like this: +To list all the Pods that belong to a Job in a machine readable form, you can use a command like this: ```shell -$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name}) -$ echo $pods +pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}') +echo $pods +``` +``` pi-aiw0a ``` -Here, the selector is the same as the selector for the job. The `--output=jsonpath` option specifies an expression -that just gets the name from each pod in the returned list. +Here, the selector is the same as the selector for the Job. The `--output=jsonpath` option specifies an expression +that just gets the name from each Pod in the returned list. View the standard output of one of the pods: @@ -102,7 +108,7 @@ $ kubectl logs $pods As with all other Kubernetes config, a Job needs `apiVersion`, `kind`, and `metadata` fields. -A Job also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status). +A Job also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status). ### Pod Template @@ -110,7 +116,7 @@ The `.spec.template` is the only required field of the `.spec`. The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [pod](/docs/user-guide/pods), except it is nested and does not have an `apiVersion` or `kind`. -In addition to required fields for a Pod, a pod template in a job must specify appropriate +In addition to required fields for a Pod, a pod template in a Job must specify appropriate labels (see [pod selector](#pod-selector)) and an appropriate restart policy. Only a [`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) equal to `Never` or `OnFailure` is allowed. @@ -123,31 +129,30 @@ See section [specifying your own pod selector](#specifying-your-own-pod-selector ### Parallel Jobs -There are three main types of jobs: +There are three main types of task suitable to run as a Job: 1. Non-parallel Jobs - - normally only one pod is started, unless the pod fails. - - job is complete as soon as Pod terminates successfully. + - normally, only one Pod is started, unless the Pod fails. + - the Job is complete as soon as its Pod terminates successfully. 1. Parallel Jobs with a *fixed completion count*: - specify a non-zero positive value for `.spec.completions`. - - the job is complete when there is one successful pod for each value in the range 1 to `.spec.completions`. - - **not implemented yet:** Each pod passed a different index in the range 1 to `.spec.completions`. + - the Job represents the overall task, and is complete when there is one successful Pod for each value in the range 1 to `.spec.completions`. + - **not implemented yet:** Each Pod is passed a different index in the range 1 to `.spec.completions`. 1. Parallel Jobs with a *work queue*: -  - do not specify `.spec.completions`, default to `.spec.parallelism`. -  - the pods must coordinate with themselves or an external service to determine what each should work on. - - each pod is independently capable of determining whether or not all its peers are done, thus the entire Job is done. - - when _any_ pod terminates with success, no new pods are created. - - once at least one pod has terminated with success and all pods are terminated, then the job is completed with success. - - once any pod has exited with success, no other pod should still be doing any work or writing any output. They should all be - in the process of exiting. + - do not specify `.spec.completions`, default to `.spec.parallelism`. + - the Pods must coordinate amongst themselves or an external service to determine what each should work on. For example, a Pod might fetch a batch of up to N items from the work queue. + - each Pod is independently capable of determining whether or not all its peers are done, and thus that the entire Job is done. + - when _any_ Pod from the Job terminates with success, no new Pods are created. + - once at least one Pod has terminated with success and all Pods are terminated, then the Job is completed with success. + - once any Pod has exited with success, no other Pod should still be doing any work for this task or writing any output. They should all be in the process of exiting. -For a Non-parallel job, you can leave both `.spec.completions` and `.spec.parallelism` unset. When both are +For a _non-parallel_ Job, you can leave both `.spec.completions` and `.spec.parallelism` unset. When both are unset, both are defaulted to 1. -For a Fixed Completion Count job, you should set `.spec.completions` to the number of completions needed. +For a _fixed completion count_ Job, you should set `.spec.completions` to the number of completions needed. You can set `.spec.parallelism`, or leave it unset and it will default to 1. -For a Work Queue Job, you must leave `.spec.completions` unset, and set `.spec.parallelism` to +For a _work queue_ Job, you must leave `.spec.completions` unset, and set `.spec.parallelism` to a non-negative integer. For more information about how to make use of the different types of job, see the [job patterns](#job-patterns) section. @@ -162,28 +167,28 @@ If it is specified as 0, then the Job is effectively paused until it is increase Actual parallelism (number of pods running at any instant) may be more or less than requested parallelism, for a variety of reasons: -- For Fixed Completion Count jobs, the actual number of pods running in parallel will not exceed the number of +- For _fixed completion count_ Jobs, the actual number of pods running in parallel will not exceed the number of remaining completions. Higher values of `.spec.parallelism` are effectively ignored. -- For work queue jobs, no new pods are started after any pod has succeeded -- remaining pods are allowed to complete, however. +- For _work queue_ Jobs, no new Pods are started after any Pod has succeeded -- remaining Pods are allowed to complete, however. - If the controller has not had time to react. -- If the controller failed to create pods for any reason (lack of ResourceQuota, lack of permission, etc.), +- If the controller failed to create Pods for any reason (lack of `ResourceQuota`, lack of permission, etc.), then there may be fewer pods than requested. -- The controller may throttle new pod creation due to excessive previous pod failures in the same Job. -- When a pod is gracefully shutdown, it takes time to stop. +- The controller may throttle new Pod creation due to excessive previous pod failures in the same Job. +- When a Pod is gracefully shut down, it takes time to stop. ## Handling Pod and Container Failures -A Container in a Pod may fail for a number of reasons, such as because the process in it exited with -a non-zero exit code, or the Container was killed for exceeding a memory limit, etc. If this +A container in a Pod may fail for a number of reasons, such as because the process in it exited with +a non-zero exit code, or the container was killed for exceeding a memory limit, etc. If this happens, and the `.spec.template.spec.restartPolicy = "OnFailure"`, then the Pod stays -on the node, but the Container is re-run. Therefore, your program needs to handle the case when it is +on the node, but the container is re-run. Therefore, your program needs to handle the case when it is restarted locally, or else specify `.spec.template.spec.restartPolicy = "Never"`. -See [pods-states](/docs/concepts/workloads/pods/pod-lifecycle/#example-states) for more information on `restartPolicy`. +See [pod lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/#example-states) for more information on `restartPolicy`. An entire Pod can also fail, for a number of reasons, such as when the pod is kicked off the node (node is upgraded, rebooted, deleted, etc.), or if a container of the Pod fails and the `.spec.template.spec.restartPolicy = "Never"`. When a Pod fails, then the Job controller -starts a new Pod. Therefore, your program needs to handle the case when it is restarted in a new +starts a new Pod. This means that your application needs to handle the case when it is restarted in a new pod. In particular, it needs to handle temporary files, locks, incomplete output and the like caused by previous runs. @@ -194,7 +199,7 @@ sometimes be started twice. If you do specify `.spec.parallelism` and `.spec.completions` both greater than 1, then there may be multiple pods running at once. Therefore, your pods must also be tolerant of concurrency. -### Pod Backoff failure policy +### Pod backoff failure policy There are situations where you want to fail a Job after some amount of retries due to a logical error in configuration etc. @@ -221,8 +226,7 @@ By default, a Job will run uninterrupted unless a Pod fails, at which point the Do this by setting the `.spec.activeDeadlineSeconds` field of the Job to a number of seconds. The `activeDeadlineSeconds` applies to the duration of the job, no matter how many Pods are created. -Once a Job reaches `activeDeadlineSeconds`, the Job and all of its Pods are terminated. -The result is that the job has a status with `reason: DeadlineExceeded`. +Once a Job reaches `activeDeadlineSeconds`, all of its Pods are terminated and the Job status will become `type: Failed` with `reason: DeadlineExceeded`. Note that a Job's `.spec.activeDeadlineSeconds` takes precedence over its `.spec.backoffLimit`. Therefore, a Job that is retrying one or more failed Pods will not deploy additional Pods once it reaches the time limit specified by `activeDeadlineSeconds`, even if the `backoffLimit` is not yet reached. @@ -245,7 +249,7 @@ spec: restartPolicy: Never ``` -Note that both the Job Spec and the [Pod Template Spec](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#detailed-behavior) within the Job have an `activeDeadlineSeconds` field. Ensure that you set this field at the proper level. +Note that both the Job spec and the [Pod template spec](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#detailed-behavior) within the Job have an `activeDeadlineSeconds` field. Ensure that you set this field at the proper level. ## Clean Up Finished Jobs Automatically @@ -317,7 +321,7 @@ The tradeoffs are: - One Job object for each work item, vs. a single Job object for all work items. The latter is better for large numbers of work items. The former creates some overhead for the user and for the system to manage large numbers of Job objects. -- Number of pods created equals number of work items, vs. each pod can process multiple work items. +- Number of pods created equals number of work items, vs. each Pod can process multiple work items. The former typically requires less modification to existing code and containers. The latter is better for large numbers of work items, for similar reasons to the previous bullet. - Several approaches use a work queue. This requires running a queue service, @@ -337,7 +341,7 @@ The pattern names are also links to examples and more detailed description. When you specify completions with `.spec.completions`, each Pod created by the Job controller has an identical [`spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status). This means that -all pods will have the same command line and the same +all pods for a task will have the same command line and the same image, the same volumes, and (almost) the same environment variables. These patterns are different ways to arrange for pods to work on different things. @@ -356,29 +360,29 @@ Here, `W` is the number of work items. ### Specifying your own pod selector -Normally, when you create a job object, you do not specify `.spec.selector`. -The system defaulting logic adds this field when the job is created. +Normally, when you create a Job object, you do not specify `.spec.selector`. +The system defaulting logic adds this field when the Job is created. It picks a selector value that will not overlap with any other jobs. However, in some cases, you might need to override this automatically set selector. -To do this, you can specify the `.spec.selector` of the job. +To do this, you can specify the `.spec.selector` of the Job. Be very careful when doing this. If you specify a label selector which is not -unique to the pods of that job, and which matches unrelated pods, then pods of the unrelated -job may be deleted, or this job may count other pods as completing it, or one or both -of the jobs may refuse to create pods or run to completion. If a non-unique selector is -chosen, then other controllers (e.g. ReplicationController) and their pods may behave +unique to the pods of that Job, and which matches unrelated Pods, then pods of the unrelated +job may be deleted, or this Job may count other Pods as completing it, or one or both +Jobs may refuse to create Pods or run to completion. If a non-unique selector is +chosen, then other controllers (e.g. ReplicationController) and their Pods may behave in unpredictable ways too. Kubernetes will not stop you from making a mistake when specifying `.spec.selector`. Here is an example of a case when you might want to use this feature. -Say job `old` is already running. You want existing pods -to keep running, but you want the rest of the pods it creates -to use a different pod template and for the job to have a new name. -You cannot update the job because these fields are not updatable. -Therefore, you delete job `old` but leave its pods -running, using `kubectl delete jobs/old --cascade=false`. +Say Job `old` is already running. You want existing Pods +to keep running, but you want the rest of the Pods it creates +to use a different pod template and for the Job to have a new name. +You cannot update the Job because these fields are not updatable. +Therefore, you delete Job `old` but _leave its pods +running_, using `kubectl delete jobs/old --cascade=false`. Before deleting it, you make a note of what selector it uses: ``` @@ -393,11 +397,11 @@ spec: ... ``` -Then you create a new job with name `new` and you explicitly specify the same selector. -Since the existing pods have label `job-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`, -they are controlled by job `new` as well. +Then you create a new Job with name `new` and you explicitly specify the same selector. +Since the existing Pods have label `job-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`, +they are controlled by Job `new` as well. -You need to specify `manualSelector: true` in the new job since you are not using +You need to specify `manualSelector: true` in the new Job since you are not using the selector that the system normally generates for you automatically. ``` @@ -421,25 +425,25 @@ mismatch. ### Bare Pods -When the node that a pod is running on reboots or fails, the pod is terminated -and will not be restarted. However, a Job will create new pods to replace terminated ones. -For this reason, we recommend that you use a job rather than a bare pod, even if your application -requires only a single pod. +When the node that a Pod is running on reboots or fails, the pod is terminated +and will not be restarted. However, a Job will create new Pods to replace terminated ones. +For this reason, we recommend that you use a Job rather than a bare Pod, even if your application +requires only a single Pod. ### Replication Controller Jobs are complementary to [Replication Controllers](/docs/user-guide/replication-controller). -A Replication Controller manages pods which are not expected to terminate (e.g. web servers), and a Job -manages pods that are expected to terminate (e.g. batch jobs). +A Replication Controller manages Pods which are not expected to terminate (e.g. web servers), and a Job +manages Pods that are expected to terminate (e.g. batch tasks). -As discussed in [Pod Lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/), `Job` is *only* appropriate for pods with -`RestartPolicy` equal to `OnFailure` or `Never`. (Note: If `RestartPolicy` is not set, the default -value is `Always`.) +As discussed in [Pod Lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/), `Job` is *only* appropriate +for pods with `RestartPolicy` equal to `OnFailure` or `Never`. +(Note: If `RestartPolicy` is not set, the default value is `Always`.) ### Single Job starts Controller Pod -Another pattern is for a single Job to create a pod which then creates other pods, acting as a sort -of custom controller for those pods. This allows the most flexibility, but may be somewhat +Another pattern is for a single Job to create a Pod which then creates other Pods, acting as a sort +of custom controller for those Pods. This allows the most flexibility, but may be somewhat complicated to get started with and offers less integration with Kubernetes. One example of this pattern would be a Job which starts a Pod which runs a script that in turn @@ -447,10 +451,10 @@ starts a Spark master controller (see [spark example](https://github.com/kuberne driver, and then cleans up. An advantage of this approach is that the overall process gets the completion guarantee of a Job -object, but complete control over what pods are created and how work is assigned to them. +object, but complete control over what Pods are created and how work is assigned to them. -## Cron Jobs +## Cron Jobs {#cron-jobs} -Support for creating Jobs at specified times/dates (i.e. cron) is available in Kubernetes [1.4](https://github.com/kubernetes/kubernetes/pull/11980). More information is available in the [cron job documents](/docs/concepts/workloads/controllers/cron-jobs/) +You can use a [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/) to create a Job that will run at specified times/dates, similar to the Unix tool `cron`. {{% /capture %}} diff --git a/content/en/docs/concepts/workloads/controllers/replicaset.md b/content/en/docs/concepts/workloads/controllers/replicaset.md index fd72b58149..9ca82477fe 100644 --- a/content/en/docs/concepts/workloads/controllers/replicaset.md +++ b/content/en/docs/concepts/workloads/controllers/replicaset.md @@ -10,39 +10,36 @@ weight: 10 {{% capture overview %}} -ReplicaSet is the next-generation Replication Controller. The only difference -between a _ReplicaSet_ and a -[_Replication Controller_](/docs/concepts/workloads/controllers/replicationcontroller/) right now is -the selector support. ReplicaSet supports the new set-based selector requirements -as described in the [labels user guide](/docs/concepts/overview/working-with-objects/labels/#label-selectors) -whereas a Replication Controller only supports equality-based selector requirements. +A ReplicaSet's purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often +used to guarantee the availability of a specified number of identical Pods. + {{% /capture %}} {{% capture body %}} -## How to use a ReplicaSet +## How a ReplicaSet works -Most [`kubectl`](/docs/user-guide/kubectl/) commands that support -Replication Controllers also support ReplicaSets. One exception is the -[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) command. If -you want the rolling update functionality please consider using Deployments -instead. Also, the -[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) command is -imperative whereas Deployments are declarative, so we recommend using Deployments -through the [`rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout) command. +A ReplicaSet is defined with fields, including a selector that specifies how to identify Pods it can acquire, a number +of replicas indicating how many Pods it should be maintaining, and a pod template specifying the data of new Pods +it should create to meet the number of replicas criteria. A ReplicaSet then fulfills its purpose by creating +and deleting Pods as needed to reach the desired number. When a ReplicaSet needs to create new Pods, it uses its Pod +template. -While ReplicaSets can be used independently, today it's mainly used by -[Deployments](/docs/concepts/workloads/controllers/deployment/) as a mechanism to orchestrate pod -creation, deletion and updates. When you use Deployments you don't have to worry -about managing the ReplicaSets that they create. Deployments own and manage -their ReplicaSets. +The link a ReplicaSet has to its Pods is via the Pods' [metadata.ownerReferences](/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) +field, which specifies what resource the current object is owned by. All Pods acquired by a ReplicaSet have their owning +ReplicaSet's identifying information within their ownerReferences field. It's through this link that the ReplicaSet +knows of the state of the Pods it is maintaining and plans accordingly. + +A ReplicaSet identifies new Pods to acquire by using its selector. If there is a Pod that has no OwnerReference or the +OwnerReference is not a controller and it matches a ReplicaSet's selector, it will be immediately acquired by said +ReplicaSet. ## When to use a ReplicaSet A ReplicaSet ensures that a specified number of pod replicas are running at any given time. However, a Deployment is a higher-level concept that manages ReplicaSets and -provides declarative updates to pods along with a lot of other useful features. +provides declarative updates to Pods along with a lot of other useful features. Therefore, we recommend using Deployments instead of directly using ReplicaSets, unless you require custom update orchestration or don't require updates at all. @@ -53,13 +50,31 @@ use a Deployment instead, and define your application in the spec section. {{< codenew file="controllers/frontend.yaml" >}} -Saving this manifest into `frontend.yaml` and submitting it to a Kubernetes cluster should -create the defined ReplicaSet and the pods that it manages. +Saving this manifest into `frontend.yaml` and submitting it to a Kubernetes cluster will +create the defined ReplicaSet and the Pods that it manages. ```shell -$ kubectl create -f http://k8s.io/examples/controllers/frontend.yaml -replicaset.apps/frontend created -$ kubectl describe rs/frontend +kubectl create -f http://k8s.io/examples/controllers/frontend.yaml +``` + +You can then get the current ReplicaSets deployed: +```shell +kubectl get rs +``` + +And see the frontend one you created: +```shell +NAME DESIRED CURRENT READY AGE +frontend 3 3 3 6s +``` + +You can also check on the state of the replicaset: +```shell +kubectl describe rs/frontend +``` + +And you will see output similar to: +```shell Name: frontend Namespace: default Selector: tier=frontend,tier in (frontend) @@ -88,66 +103,150 @@ Events: 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l -$ kubectl get pods +``` + +And lastly you can check for the Pods brought up: +```shell +kubectl get Pods +``` + +You should see Pod information similar to: +```shell NAME READY STATUS RESTARTS AGE frontend-9si5l 1/1 Running 0 1m frontend-dnjpy 1/1 Running 0 1m frontend-qhloh 1/1 Running 0 1m ``` -## Writing a ReplicaSet Spec +You can also verify that the owner reference of these pods is set to the frontend ReplicaSet. +To do this, get the yaml of one of the Pods running: +```shell +kubectl get pods frontend-9si5l -o yaml +``` -As with all other Kubernetes API objects, a ReplicaSet needs the `apiVersion`, `kind`, and `metadata` fields. For -general information about working with manifests, see [object management using kubectl](/docs/concepts/overview/object-management-kubectl/overview/). +The output will look similar to this, with the frontend ReplicaSet's info set in the metadata's ownerReferences field: +```shell +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: 2019-01-31T17:20:41Z + generateName: frontend- + labels: + tier: frontend + name: frontend-9si5l + namespace: default + ownerReferences: + - apiVersion: extensions/v1beta1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: frontend + uid: 892a2330-257c-11e9-aecd-025000000001 +... +``` + +## Non-Template Pod acquisitions + +While you can create bare Pods with no problems, it is strongly recommended to make sure that the bare Pods do not have +labels which match the selector of one of your ReplicaSets. The reason for this is because a ReplicaSet is not limited +to owning Pods specified by its template-- it can acquire other Pods in the manner specified in the previous sections. + +Take the previous frontend ReplicaSet example, and the Pods specified in the following manifest: + +{{< codenew file="pods/pod-rs.yaml" >}} + +As those Pods do not have a Controller (or any object) as their owner reference and match the selector of the frontend +ReplicaSet, they will immediately be acquired by it. + +Suppose you create the Pods after the frontend ReplicaSet has been deployed and has set up its initial Pod replicas to +fulfill its replica count requirement: + +```shell +kubectl create -f http://k8s.io/examples/pods/pod-rs.yaml +``` + +The new Pods will be acquired by the ReplicaSet, and then immediately terminated as the ReplicaSet would be over +its desired count. + +Fetching the Pods: +```shell +kubectl get Pods +``` + +The output shows that the new Pods are either already terminated, or in the process of being terminated: +```shell +NAME READY STATUS RESTARTS AGE +frontend-9si5l 1/1 Running 0 1m +frontend-dnjpy 1/1 Running 0 1m +frontend-qhloh 1/1 Running 0 1m +pod2 0/1 Terminating 0 4s +``` + +If you create the Pods first: +```shell +kubectl create -f http://k8s.io/examples/pods/pod-rs.yaml +``` + +And then create the ReplicaSet however: +```shell +kubectl create -f http://k8s.io/examples/controllers/frontend.yaml +``` + +You shall see that the ReplicaSet has acquired the Pods and has only created new ones according to its spec until the +number of its new Pods and the original matches its desired count. As fetching the Pods: +```shell +kubectl get Pods +``` + +Will reveal in its output: +```shell +NAME READY STATUS RESTARTS AGE +frontend-pxj4r 1/1 Running 0 5s +pod1 1/1 Running 0 13s +pod2 1/1 Running 0 13s +``` + +In this manner, a ReplicaSet can own a non-homogenous set of Pods + +## Writing a ReplicaSet manifest + +As with all other Kubernetes API objects, a ReplicaSet needs the `apiVersion`, `kind`, and `metadata` fields. +For ReplicaSets, the kind is always just ReplicaSet. +In Kubernetes 1.9 the API version `apps/v1` on the ReplicaSet kind is the current version and is enabled by default. The API version `apps/v1beta2` is deprecated. +Refer to the first lines of the `frontend.yaml` example for guidance. A ReplicaSet also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status). ### Pod Template -The `.spec.template` is the only required field of the `.spec`. The `.spec.template` is a -[pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a -[pod](/docs/concepts/workloads/pods/pod/), except that it is nested and does not have an `apiVersion` or `kind`. +The `.spec.template` is a [pod template](/docs/concepts/workloads/Pods/pod-overview/#pod-templates) which is also +required to have labels in place. In our `frontend.yaml` example we had one label: `tier: frontend`. +Be careful not to overlap with the selectors of other controllers, lest they try to adopt this Pod. -In addition to required fields of a pod, a pod template in a ReplicaSet must specify appropriate -labels and an appropriate restart policy. - -For labels, make sure to not overlap with other controllers. For more information, see [pod selector](#pod-selector). - -For [restart policy](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy), the only allowed value for `.spec.template.spec.restartPolicy` is `Always`, which is the default. - -For local container restarts, ReplicaSet delegates to an agent on the node, -for example the [Kubelet](/docs/admin/kubelet/) or Docker. +For the template's [restart policy](/docs/concepts/workloads/Pods/pod-lifecycle/#restart-policy) field, +`.spec.template.spec.restartPolicy`, the only allowed value is `Always`, which is the default. ### Pod Selector -The `.spec.selector` field is a [label selector](/docs/concepts/overview/working-with-objects/labels/). A ReplicaSet -manages all the pods with labels that match the selector. It does not distinguish -between pods that it created or deleted and pods that another person or process created or -deleted. This allows the ReplicaSet to be replaced without affecting the running pods. +The `.spec.selector` field is a [label selector](/docs/concepts/overview/working-with-objects/labels/). As discussed +[earlier](#how-a-replicaset-works) these are the labels used to identify potential Pods to acquire. In our +`frontend.yaml` example, the selector was: +```shell +matchLabels: + tier: frontend +``` -The `.spec.template.metadata.labels` must match the `.spec.selector`, or it will +In the ReplicaSet, `.spec.template.metadata.labels` must match `spec.selector`, or it will be rejected by the API. -In Kubernetes 1.9 the API version `apps/v1` on the ReplicaSet kind is the current version and is enabled by default. The API version `apps/v1beta2` is deprecated. - -Also you should not normally create any pods whose labels match this selector, either directly, with -another ReplicaSet, or with another controller such as a Deployment. If you do so, the ReplicaSet thinks that it -created the other pods. Kubernetes does not stop you from doing this. - -If you do end up with multiple controllers that have overlapping selectors, you -will have to manage the deletion yourself. - -### Labels on a ReplicaSet - -The ReplicaSet can itself have labels (`.metadata.labels`). Typically, you -would set these the same as the `.spec.template.metadata.labels`. However, they are allowed to be -different, and the `.metadata.labels` do not affect the behavior of the ReplicaSet. +{{< note >}} +For 2 ReplicaSets specifying the same `.spec.selector` but different `.spec.template.metadata.labels` and `.spec.template.spec` fields, each ReplicaSet ignores the Pods created by the other ReplicaSet. +{{< /note >}} ### Replicas -You can specify how many pods should run concurrently by setting `.spec.replicas`. The number running at any time may be higher -or lower, such as if the replicas were just increased or decreased, or if a pod is gracefully -shut down, and a replacement starts early. +You can specify how many Pods should run concurrently by setting `.spec.replicas`. The ReplicaSet will create/delete +its Pods to match this number. If you do not specify `.spec.replicas`, then it defaults to 1. @@ -157,7 +256,9 @@ If you do not specify `.spec.replicas`, then it defaults to 1. To delete a ReplicaSet and all of its Pods, use [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete). The [Garbage collector](/docs/concepts/workloads/controllers/garbage-collection/) automatically deletes all of the dependent Pods by default. -When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Background` or `Foreground` in delete option. e.g. : +When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Background` or `Foreground` in +the -d option. +For example: ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \ @@ -167,8 +268,9 @@ curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/repli ### Deleting just a ReplicaSet -You can delete a ReplicaSet without affecting any of its pods using [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) with the `--cascade=false` option. -When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Orphan`, e.g. : +You can delete a ReplicaSet without affecting any of its Pods using [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) with the `--cascade=false` option. +When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Orphan`. +For example: ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \ @@ -177,22 +279,22 @@ curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/repli ``` Once the original is deleted, you can create a new ReplicaSet to replace it. As long -as the old and new `.spec.selector` are the same, then the new one will adopt the old pods. -However, it will not make any effort to make existing pods match a new, different pod template. -To update pods to a new spec in a controlled way, use a [rolling update](#rolling-updates). +as the old and new `.spec.selector` are the same, then the new one will adopt the old Pods. +However, it will not make any effort to make existing Pods match a new, different pod template. +To update Pods to a new spec in a controlled way, use a [rolling update](#rolling-updates). -### Isolating pods from a ReplicaSet +### Isolating Pods from a ReplicaSet -Pods may be removed from a ReplicaSet's target set by changing their labels. This technique may be used to remove pods +You can remove Pods from a ReplicaSet by changing their labels. This technique may be used to remove Pods from service for debugging, data recovery, etc. Pods that are removed in this way will be replaced automatically ( - assuming that the number of replicas is not also changed). +assuming that the number of replicas is not also changed). ### Scaling a ReplicaSet A ReplicaSet can be easily scaled up or down by simply updating the `.spec.replicas` field. The ReplicaSet controller -ensures that a desired number of pods with a matching label selector are available and operational. +ensures that a desired number of Pods with a matching label selector are available and operational. -### ReplicaSet as an Horizontal Pod Autoscaler Target +### ReplicaSet as a Horizontal Pod Autoscaler Target A ReplicaSet can also be a target for [Horizontal Pod Autoscalers (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/). That is, @@ -203,7 +305,7 @@ the ReplicaSet we created in the previous example. Saving this manifest into `hpa-rs.yaml` and submitting it to a Kubernetes cluster should create the defined HPA that autoscales the target ReplicaSet depending on the CPU usage -of the replicated pods. +of the replicated Pods. ```shell kubectl create -f https://k8s.io/examples/controllers/hpa-rs.yaml @@ -213,34 +315,40 @@ Alternatively, you can use the `kubectl autoscale` command to accomplish the sam (and it's easier!) ```shell -kubectl autoscale rs frontend +kubectl autoscale rs frontend --max=10 ``` ## Alternatives to ReplicaSet -### Deployment (Recommended) +### Deployment (recommended) -[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying ReplicaSets and their Pods -in a similar fashion as `kubectl rolling-update`. Deployments are recommended if you want this rolling update functionality, -because unlike `kubectl rolling-update`, they are declarative, server-side, and have additional features. For more information on running a stateless -application using a Deployment, please read [Run a Stateless Application Using a Deployment](/docs/tasks/run-application/run-stateless-application-deployment/). +[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is an object which can own ReplicaSets and update +them and their Pods via declarative, server-side rolling updates. +While ReplicaSets can be used independently, today they're mainly used by Deployments as a mechanism to orchestrate Pod +creation, deletion and updates. When you use Deployments you don’t have to worry about managing the ReplicaSets that +they create. Deployments own and manage their ReplicaSets. +As such, it is recommended to use Deployments when you want ReplicaSets. ### Bare Pods -Unlike the case where a user directly created pods, a ReplicaSet replaces pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicaSet even if your application requires only a single pod. Think of it similarly to a process supervisor, only it supervises multiple pods across multiple nodes instead of individual processes on a single node. A ReplicaSet delegates local container restarts to some agent on the node (for example, Kubelet or Docker). +Unlike the case where a user directly created Pods, a ReplicaSet replaces Pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicaSet even if your application requires only a single Pod. Think of it similarly to a process supervisor, only it supervises multiple Pods across multiple nodes instead of individual processes on a single node. A ReplicaSet delegates local container restarts to some agent on the node (for example, Kubelet or Docker). ### Job -Use a [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) instead of a ReplicaSet for pods that are expected to terminate on their own +Use a [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) instead of a ReplicaSet for Pods that are expected to terminate on their own (that is, batch jobs). ### DaemonSet -Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicaSet for pods that provide a -machine-level function, such as machine monitoring or machine logging. These pods have a lifetime that is tied -to a machine lifetime: the pod needs to be running on the machine before other pods start, and are +Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicaSet for Pods that provide a +machine-level function, such as machine monitoring or machine logging. These Pods have a lifetime that is tied +to a machine lifetime: the Pod needs to be running on the machine before other Pods start, and are safe to terminate when the machine is otherwise ready to be rebooted/shutdown. +### ReplicationController +ReplicaSets are the successors to [_ReplicationControllers_](/docs/concepts/workloads/controllers/replicationcontroller/). +The two serve the same purpose, and behave similarly, except that a ReplicationController does not support set-based +selector requirements as described in the [labels user guide](/docs/concepts/overview/working-with-objects/labels/#label-selectors). +As such, ReplicaSets are preferred over ReplicationControllers + {{% /capture %}} - - diff --git a/content/en/docs/concepts/workloads/controllers/replicationcontroller.md b/content/en/docs/concepts/workloads/controllers/replicationcontroller.md index daf0dfd59a..c77b2fee28 100644 --- a/content/en/docs/concepts/workloads/controllers/replicationcontroller.md +++ b/content/en/docs/concepts/workloads/controllers/replicationcontroller.md @@ -55,14 +55,18 @@ This example ReplicationController config runs three copies of the nginx web ser Run the example job by downloading the example file and then running this command: ```shell -$ kubectl create -f https://k8s.io/examples/controllers/replication.yaml +kubectl create -f https://k8s.io/examples/controllers/replication.yaml +``` +``` replicationcontroller/nginx created ``` Check on the status of the ReplicationController using this command: ```shell -$ kubectl describe replicationcontrollers/nginx +kubectl describe replicationcontrollers/nginx +``` +``` Name: nginx Namespace: default Selector: app=nginx @@ -97,8 +101,10 @@ Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed To list all the pods that belong to the ReplicationController in a machine readable form, you can use a command like this: ```shell -$ pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name}) +pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name}) echo $pods +``` +``` nginx-3ntk0 nginx-4ok8v nginx-qrm3m ``` diff --git a/content/en/docs/concepts/workloads/controllers/statefulset.md b/content/en/docs/concepts/workloads/controllers/statefulset.md index 0e3a4e8569..e83a4f3c8b 100644 --- a/content/en/docs/concepts/workloads/controllers/statefulset.md +++ b/content/en/docs/concepts/workloads/controllers/statefulset.md @@ -134,6 +134,10 @@ As each Pod is created, it gets a matching DNS subdomain, taking the form: `$(podname).$(governing service domain)`, where the governing service is defined by the `serviceName` field on the StatefulSet. +As mentioned in the [limitations](#limitations) section, you are responsible for +creating the [Headless Service](/docs/concepts/services-networking/service/#headless-services) +responsible for the network identity of the pods. + Here are some examples of choices for Cluster Domain, Service name, StatefulSet name, and how that affects the DNS names for the StatefulSet's Pods. diff --git a/content/en/docs/concepts/workloads/pods/disruptions.md b/content/en/docs/concepts/workloads/pods/disruptions.md index 3a3ecb36cf..6725c887f4 100644 --- a/content/en/docs/concepts/workloads/pods/disruptions.md +++ b/content/en/docs/concepts/workloads/pods/disruptions.md @@ -63,6 +63,11 @@ Ask your cluster administrator or consult your cloud provider or distribution do to determine if any sources of voluntary disruptions are enabled for your cluster. If none are enabled, you can skip creating Pod Disruption Budgets. +{{< caution >}} +Not all voluntary disruptions are constrained by Pod Disruption Budgets. For example, +deleting deployments or pods bypasses Pod Disruption Budgets. +{{< /caution >}} + ## Dealing with Disruptions Here are some ways to mitigate involuntary disruptions: @@ -102,7 +107,7 @@ percentage of the total. Cluster managers and hosting providers should use tools which respect Pod Disruption Budgets by calling the [Eviction API](/docs/tasks/administer-cluster/safely-drain-node/#the-eviction-api) -instead of directly deleting pods. Examples are the `kubectl drain` command +instead of directly deleting pods or deployments. Examples are the `kubectl drain` command and the Kubernetes-on-GCE cluster upgrade script (`cluster/gce/upgrade.sh`). When a cluster administrator wants to drain a node diff --git a/content/en/docs/concepts/workloads/pods/init-containers.md b/content/en/docs/concepts/workloads/pods/init-containers.md index 6ee6dd45ce..d4592138de 100644 --- a/content/en/docs/concepts/workloads/pods/init-containers.md +++ b/content/en/docs/concepts/workloads/pods/init-containers.md @@ -83,7 +83,7 @@ Here are some ideas for how to use Init Containers: * Register this Pod with a remote server from the downward API with a command like: - curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$()&ip=$()' + `curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$()&ip=$()'` * Wait for some time before starting the app Container with a command like `sleep 60`. * Clone a git repository into a volume. @@ -180,12 +180,24 @@ spec: This Pod can be started and debugged with the following commands: ```shell -$ kubectl create -f myapp.yaml +kubectl create -f myapp.yaml +``` +``` pod/myapp-pod created -$ kubectl get -f myapp.yaml +``` + +```shell +kubectl get -f myapp.yaml +``` +``` NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 6m -$ kubectl describe -f myapp.yaml +``` + +```shell +kubectl describe -f myapp.yaml +``` +``` Name: myapp-pod Namespace: default [...] @@ -218,18 +230,25 @@ Events: 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox" 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined] 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634 -$ kubectl logs myapp-pod -c init-myservice # Inspect the first init container -$ kubectl logs myapp-pod -c init-mydb # Inspect the second init container +``` +```shell +kubectl logs myapp-pod -c init-myservice # Inspect the first init container +kubectl logs myapp-pod -c init-mydb # Inspect the second init container ``` Once we start the `mydb` and `myservice` services, we can see the Init Containers complete and the `myapp-pod` is created: ```shell -$ kubectl create -f services.yaml +kubectl create -f services.yaml +``` +``` service/myservice created service/mydb created -$ kubectl get -f myapp.yaml +``` + +```shell +kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 9m ``` diff --git a/content/en/docs/concepts/workloads/pods/pod-lifecycle.md b/content/en/docs/concepts/workloads/pods/pod-lifecycle.md index 2b559bd6a2..707a3d1658 100644 --- a/content/en/docs/concepts/workloads/pods/pod-lifecycle.md +++ b/content/en/docs/concepts/workloads/pods/pod-lifecycle.md @@ -39,6 +39,9 @@ Value | Description `Succeeded` | All Containers in the Pod have terminated in success, and will not be restarted. `Failed` | All Containers in the Pod have terminated, and at least one Container has terminated in failure. That is, the Container either exited with non-zero status or was terminated by the system. `Unknown` | For some reason the state of the Pod could not be obtained, typically due to an error in communicating with the host of the Pod. +`Completed` | The pod has run to completion as there's nothing to keep it running eg. Completed Jobs. +`CrashLoopBackOff` | This means that one of the containers in the pod has exited unexpectedly, and perhaps with a non-zero error code even after restarting due to [restart policy](#restart-policy). + ## Pod conditions @@ -130,7 +133,6 @@ specify a readiness probe. In this case, the readiness probe might be the same as the liveness probe, but the existence of the readiness probe in the spec means that the Pod will start without receiving any traffic and only start receiving traffic after the probe starts succeeding. - If your Container needs to work on loading large data, configuration files, or migrations during startup, specify a readiness probe. If you want your Container to be able to take itself down for maintenance, you @@ -155,13 +157,47 @@ and Note that the information reported as Pod status depends on the current [ContainerState](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#containerstatus-v1-core). +## Container States + +Once Pod is assigned to a node by scheduler, kubelet starts creating containers using container runtime.There are three possible states of containers: Waiting, Running and Terminated. To check state of container, you can use `kubectl describe pod [POD_NAME]`. State is displayed for each container within that Pod. + +* `Waiting`: Default state of container. If container is not in either Running or Terminated state, it is in Waiting state. A container in Waiting state still runs its required operations, like pulling images, applying Secrets, etc. Along with this state, a message and reason about the state are displayed to provide more information. + + ```yaml + ... + State: Waiting + Reason: ErrImagePull + ... + ``` + +* `Running`: Indicates that the container is executing without issues. Once a container enters into Running, `postStart` hook (if any) is executed. This state also displays the time when the container entered Running state. + + ```yaml + ... + State: Running + Started: Wed, 30 Jan 2019 16:46:38 +0530 + ... + ``` + +* `Terminated`: Indicates that the container completed its execution and has stopped running.A container enters into this when it has successfully completed execution or when it has failed for some reason. Regardless, a reason and exit code is displayed, as well as the container's start and finish time. Before a container enters into Terminated, `preStop` hook (if any) is executed. + + ```yaml + ... + State: Terminated + Reason: Completed + Exit Code: 0 + Started: Wed, 30 Jan 2019 11:45:26 +0530 + Finished: Wed, 30 Jan 2019 11:45:26 +0530 + ... + ``` + ## Pod readiness gate {{< feature-state for_k8s_version="v1.12" state="beta" >}} In order to add extensibility to Pod readiness by enabling the injection of extra feedbacks or signals into `PodStatus`, Kubernetes 1.11 introduced a -feature named [Pod ready++](https://github.com/kubernetes/community/blob/master/keps/sig-network/0007-pod-ready%2B%2B.md). +feature named [Pod ready++](https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/0007-pod-ready%2B%2B.md). You can use the new field `ReadinessGate` in the `PodSpec` to specify additional conditions to be evaluated for Pod readiness. If Kubernetes cannot find such a condition in the `status.conditions` field of a Pod, the status of the condition diff --git a/content/en/docs/concepts/workloads/pods/pod-overview.md b/content/en/docs/concepts/workloads/pods/pod-overview.md index 8bb3f68504..4e5d8109a7 100644 --- a/content/en/docs/concepts/workloads/pods/pod-overview.md +++ b/content/en/docs/concepts/workloads/pods/pod-overview.md @@ -4,6 +4,9 @@ reviewers: title: Pod Overview content_template: templates/concept weight: 10 +card: + name: concepts + weight: 60 --- {{% capture overview %}} @@ -101,5 +104,5 @@ Rather than specifying the current desired state of all replicas, pod templates {{% capture whatsnext %}} * Learn more about Pod behavior: * [Pod Termination](/docs/concepts/workloads/pods/pod/#termination-of-pods) - * Other Pod Topics + * [Pod Lifecycle](../pod-lifecycle) {{% /capture %}} diff --git a/content/en/docs/concepts/workloads/pods/pod.md b/content/en/docs/concepts/workloads/pods/pod.md index d468102304..45783625fd 100644 --- a/content/en/docs/concepts/workloads/pods/pod.md +++ b/content/en/docs/concepts/workloads/pods/pod.md @@ -173,8 +173,8 @@ An example flow: 1. The Pod in the API server is updated with the time beyond which the Pod is considered "dead" along with the grace period. 1. Pod shows up as "Terminating" when listed in client commands 1. (simultaneous with 3) When the Kubelet sees that a Pod has been marked as terminating because the time in 2 has been set, it begins the pod shutdown process. - 1. If the pod has defined a [preStop hook](/docs/concepts/containers/container-lifecycle-hooks/#hook-details), it is invoked inside of the pod. If the `preStop` hook is still running after the grace period expires, step 2 is then invoked with a small (2 second) extended grace period. - 1. The processes in the Pod are sent the TERM signal. + 1. If one of the Pod's containers has defined a [preStop hook](/docs/concepts/containers/container-lifecycle-hooks/#hook-details), it is invoked inside of the container. If the `preStop` hook is still running after the grace period expires, step 2 is then invoked with a small (2 second) extended grace period. + 1. The container is sent the TERM signal. Note that not all containers in the Pod will receive the TERM signal at the same time and may each require a `preStop` hook if the order in which they shut down matters. 1. (simultaneous with 3) Pod is removed from endpoints list for service, and are no longer considered part of the set of running pods for replication controllers. Pods that shutdown slowly cannot continue to serve traffic as load balancers (like the service proxy) remove them from their rotations. 1. When the grace period expires, any processes still running in the Pod are killed with SIGKILL. 1. The Kubelet will finish deleting the Pod on the API server by setting grace period 0 (immediate deletion). The Pod disappears from the API and is no longer visible from the client. @@ -191,7 +191,7 @@ Force deletions can be potentially dangerous for some pods and should be perform From Kubernetes v1.1, any container in a pod can enable privileged mode, using the `privileged` flag on the `SecurityContext` of the container spec. This is useful for containers that want to use linux capabilities like manipulating the network stack and accessing devices. Processes within the container get almost the same privileges that are available to processes outside a container. With privileged mode, it should be easier to write network and volume plugins as separate pods that don't need to be compiled into the kubelet. -If the master is running Kubernetes v1.1 or higher, and the nodes are running a version lower than v1.1, then new privileged pods will be accepted by api-server, but will not be launched. They will be pending state. +If the master is running Kubernetes v1.1 or higher, and the nodes are running a version lower than v1.1, then new privileged pods will be accepted by api-server, but will not be launched. They will be in pending state. If user calls `kubectl describe pod FooPodName`, user can see the reason why the pod is in pending state. The events table in the describe command output will say: `Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'` diff --git a/content/en/docs/concepts/workloads/pods/podpreset.md b/content/en/docs/concepts/workloads/pods/podpreset.md index dfae21fd4f..5d7ab78c46 100644 --- a/content/en/docs/concepts/workloads/pods/podpreset.md +++ b/content/en/docs/concepts/workloads/pods/podpreset.md @@ -68,10 +68,14 @@ In order to use Pod Presets in your cluster you must ensure the following: 1. You have enabled the API type `settings.k8s.io/v1alpha1/podpreset`. For example, this can be done by including `settings.k8s.io/v1alpha1=true` in - the `--runtime-config` option for the API server. + the `--runtime-config` option for the API server. In minikube add this flag + `--extra-config=apiserver.runtime-config=settings.k8s.io/v1alpha1=true` while + starting the cluster. 1. You have enabled the admission controller `PodPreset`. One way to doing this is to include `PodPreset` in the `--enable-admission-plugins` option value specified - for the API server. + for the API server. In minikube add this flag + `--extra-config=apiserver.enable-admission-plugins=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodPreset` + while starting the cluster. 1. You have defined your Pod Presets by creating `PodPreset` objects in the namespace you will use. diff --git a/content/en/docs/contribute/advanced.md b/content/en/docs/contribute/advanced.md index 3b55e78a61..619d022f6d 100644 --- a/content/en/docs/contribute/advanced.md +++ b/content/en/docs/contribute/advanced.md @@ -38,6 +38,24 @@ for weekly rotations. The PR wrangler's duties include: [Intermediate contributing](/docs/contribute/intermediate/) for guidelines about how SIG Docs uses metadata. +### Helpful Github queries for wranglers + +The following queries are helpful when wrangling. After working through these three queries, the remaining list of PRs to be +reviewed is usually small. These queries specifically exclude localization PRs, and only include the `master` branch (except for the last one). + +- [No CLA, not eligible to merge](https://github.com/kubernetes/website/pulls?q=is%3Aopen+is%3Apr+label%3A%22cncf-cla%3A+no%22+-label%3Ado-not-merge+label%3Alanguage%2Fen): + Remind the contributor to sign the CLA. If they've already been reminded by both the bot and a human, close + the PR and remind them that they can open it after signing the CLA. + **We can't even review PRs whose authors have not signed the CLA!** +- [Needs LGTM](https://github.com/kubernetes/website/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+-label%3Ado-not-merge+label%3Alanguage%2Fen+-label%3Algtm+): + If it needs technical review, loop in one of the reviewers suggested by the bot. If it needs docs review + or copy-editing, either suggest changes or add a copyedit commit to the PR to move it along. +- [Has LGTM, needs docs approval](https://github.com/kubernetes/website/pulls?q=is%3Aopen+is%3Apr+-label%3Ado-not-merge+label%3Alanguage%2Fen+label%3Algtm): + See if you can figure out what needs to happen for the PR to be merged. +- [Not against master](https://github.com/kubernetes/website/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+-label%3Ado-not-merge+label%3Alanguage%2Fen+-base%3Amaster): If it's against a `dev-` branch, it's for an upcoming release. + Make sure the [release meister](https://github.com/kubernetes/sig-release/tree/master/release-team) knows about it. + If it's against an old branch, help the PR author figure out whether it's targeted against the best branch. + ## Propose improvements SIG Docs diff --git a/content/en/docs/contribute/intermediate.md b/content/en/docs/contribute/intermediate.md index 0a21ae1ddc..2ef7278621 100644 --- a/content/en/docs/contribute/intermediate.md +++ b/content/en/docs/contribute/intermediate.md @@ -3,6 +3,9 @@ title: Intermediate contributing slug: intermediate content_template: templates/concept weight: 20 +card: + name: contribute + weight: 50 --- {{% capture overview %}} @@ -487,23 +490,8 @@ Slack channel or the ### View your changes locally If you aren't ready to create a pull request but you want to see what your -changes look like, you can use the `hugo` command to stage the changes locally. - -1. Install Hugo version {{< hugoVersion >}} or later. - -2. In a terminal, go to the root directory of your clone of the Kubernetes - docs, and enter this command: - - ```bash - hugo server - ``` - -3. In your browser’s address bar, enter `localhost:1313`. - -4. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C` - or just close the terminal window. - -Alternatively, you can build the Kubernetes docs using Docker. +changes look like, you can build and run a docker image to generate all the documentation and +serve it locally. 1. Build the image locally: @@ -518,7 +506,26 @@ Alternatively, you can build the Kubernetes docs using Docker. ``` 3. In your browser's address bar, enter `localhost:1313`. Hugo will watch the -filesystem for changes and rebuild the site as needed. + filesystem for changes and rebuild the site as needed. + +4. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C` + or just close the terminal window. + +Alternatively, you can install and use the `hugo` command on your development machine: + +1. [Install Hugo](https://gohugo.io/getting-started/installing/) version {{< hugoVersion >}} or later. + +2. In a terminal, go to the root directory of your clone of the Kubernetes + docs, and enter this command: + + ```bash + hugo server + ``` + +3. In your browser’s address bar, enter `localhost:1313`. + +4. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C` + or just close the terminal window. ## Triage and categorize issues diff --git a/content/en/docs/contribute/localization.md b/content/en/docs/contribute/localization.md index 6e73492a14..db3ef4e980 100644 --- a/content/en/docs/contribute/localization.md +++ b/content/en/docs/contribute/localization.md @@ -5,29 +5,25 @@ approvers: - chenopis - zacharysarah - zparnold +card: + name: contribute + weight: 30 + title: Translating the docs --- {{% capture overview %}} -Documentation for Kubernetes is available in multiple languages: - -- English -- Chinese -- Japanese -- Korean - -We encourage you to add new [localizations](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/)! +Documentation for Kubernetes is available in multiple languages. We encourage you to add new [localizations](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/)! {{% /capture %}} - {{% capture body %}} ## Getting started -Localizations must meet some requirements for workflow (*how* to localize) and output (*what* to localize). +Localizations must meet some requirements for workflow (*how* to localize) and output (*what* to localize) before publishing. -To add a new localization of the Kubernetes documentation, you'll need to update the website by modifying the [site configuration](#modify-the-site-configuration) and [directory structure](#add-a-new-localization-directory). Then you can start [translating documents](#translating-documents)! +To add a new localization of the Kubernetes documentation, you'll need to update the website by modifying the [site configuration](#modify-the-site-configuration) and [directory structure](#add-a-new-localization-directory). Then you can start [translating documents](#translating-documents)! {{< note >}} For an example localization-related [pull request](../create-pull-request), see [this pull request](https://github.com/kubernetes/website/pull/8636) to the [Kubernetes website repo](https://github.com/kubernetes/website) adding Korean localization to the Kubernetes docs. @@ -209,7 +205,7 @@ SIG Docs welcomes [upstream contributions and corrections](/docs/contribute/inte {{% capture whatsnext %}} -Once a l10n meets requirements for workflow and minimum output, SIG docs will: +Once a localization meets requirements for workflow and minimum output, SIG docs will: - Enable language selection on the website - Publicize the localization's availability through [Cloud Native Computing Foundation](https://www.cncf.io/) (CNCF) channels, including the [Kubernetes blog](https://kubernetes.io/blog/). diff --git a/content/en/docs/contribute/participating.md b/content/en/docs/contribute/participating.md index 029f3bf746..ca3be91d7d 100644 --- a/content/en/docs/contribute/participating.md +++ b/content/en/docs/contribute/participating.md @@ -1,6 +1,9 @@ --- title: Participating in SIG Docs content_template: templates/concept +card: + name: contribute + weight: 40 --- {{% capture overview %}} diff --git a/content/en/docs/contribute/start.md b/content/en/docs/contribute/start.md index ee49c00022..b106b1666a 100644 --- a/content/en/docs/contribute/start.md +++ b/content/en/docs/contribute/start.md @@ -3,6 +3,9 @@ title: Start contributing slug: start content_template: templates/concept weight: 10 +card: + name: contribute + weight: 10 --- {{% capture overview %}} @@ -79,7 +82,7 @@ Anyone with a Github account can file an issue (bug report) against the Kubernetes documentation. If you see something wrong, even if you have no idea how to fix it, [file an issue](#how-to-file-an-issue). The exception to this rule is a tiny bug like a typo that you intend to fix yourself. In that case, -you can instead [fix it](#fix-it) without filing a bug first. +you can instead [fix it](#improve-existing-content) without filing a bug first. ### How to file an issue @@ -133,10 +136,11 @@ The SIG Docs team communicates using the following mechanisms: introduce yourself! - [Join the `kubernetes-sig-docs` mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-docs), where broader discussions take place and official decisions are recorded. -- Participate in the weekly SIG Docs video meeting, which is announced on the - Slack channel and the mailing list. Currently, these meetings take place on - Zoom, so you'll need to download the [Zoom client](https://zoom.us/download) - or dial in using a phone. +- Participate in the [weekly SIG Docs](https://github.com/kubernetes/community/tree/master/sig-docs) video meeting, which is announced on the Slack channel and the mailing list. Currently, these meetings take place on Zoom, so you'll need to download the [Zoom client](https://zoom.us/download) or dial in using a phone. + +{{< note >}} +You can also check the SIG Docs weekly meeting on the [Kubernetes community meetings calendar](https://calendar.google.com/calendar/embed?src=cgnt364vd8s86hr2phapfjc6uk%40group.calendar.google.com&ctz=America/Los_Angeles). +{{< /note >}} ## Improve existing content diff --git a/content/en/docs/contribute/style/content-organization.md b/content/en/docs/contribute/style/content-organization.md index a89e686ac9..e954c98118 100644 --- a/content/en/docs/contribute/style/content-organization.md +++ b/content/en/docs/contribute/style/content-organization.md @@ -108,7 +108,6 @@ Another widely used example is the `includes` bundle. It sets `headless: true` i en/includes ├── default-storage-class-prereqs.md ├── federated-task-tutorial-prereqs.md -├── federation-content-moved.md ├── index.md ├── partner-script.js ├── partner-style.css diff --git a/content/en/docs/contribute/style/page-templates.md b/content/en/docs/contribute/style/page-templates.md index 7c2229ad99..033ddf6223 100644 --- a/content/en/docs/contribute/style/page-templates.md +++ b/content/en/docs/contribute/style/page-templates.md @@ -2,6 +2,9 @@ title: Using Page Templates content_template: templates/concept weight: 30 +card: + name: contribute + weight: 30 --- {{% capture overview %}} @@ -65,17 +68,13 @@ To write a new concept page, create a Markdown file in a subdirectory of the {{%/* /capture */%}} ``` -- Within each section, write your content. Use the following guidelines: - - Use a minimum of H2 headings (with two leading `#` characters). The sections - themselves are titled automatically by the template. - - For `overview`, use a paragraph to set context for the entire topic. - - For `body`, explain the concept using free-form Markdown. - - For `whatsnext`, give a bullet list of up to 5 topics the reader might be - interested in reading next. +- Fill each section with content. Follow these guidelines: + - Organize content with H2 and H3 headings. + - For `overview`, set the topic's context with a single paragraph. + - For `body`, explain the concept. + - For `whatsnext`, provide a bulleted list of topics (5 maximum) to learn more about the concept. -An example of a published topic that uses the concept template is -[Annotations](/docs/concepts/overview/working-with-objects/annotations/). The -page you are currently reading also uses the concept template. +[Annotations](/docs/concepts/overview/working-with-objects/annotations/) is a published example of the concept template. This page also uses the concept template. ## Task template diff --git a/content/en/docs/contribute/style/style-guide.md b/content/en/docs/contribute/style/style-guide.md index 8cd5e14337..e0cc3f17d4 100644 --- a/content/en/docs/contribute/style/style-guide.md +++ b/content/en/docs/contribute/style/style-guide.md @@ -3,6 +3,10 @@ title: Documentation Style Guide linktitle: Style guide content_template: templates/concept weight: 10 +card: + name: contribute + weight: 20 + title: Documentation Style Guide --- {{% capture overview %}} @@ -106,8 +110,13 @@ document, use the backtick (`). DoDon't The kubectl run command creates a Deployment.The "kubectl run" command creates a Deployment. For declarative management, use kubectl apply.For declarative management, use "kubectl apply". + Enclose code samples with triple backticks. (```)Enclose code samples with any other syntax. +{{< note >}} +The website supports syntax highlighting for code samples, but specifying a language is optional. +{{< /note >}} + ### Use code style for object field names @@ -318,7 +327,7 @@ Shortcodes inside include statements will break the build. You must insert them ``` {{}} -{{}} +{{}} {{}} ``` diff --git a/content/en/docs/doc-contributor-tools/snippets/atom-snippets.cson b/content/en/docs/doc-contributor-tools/snippets/atom-snippets.cson index 5d4573938b..878ccc4ed7 100644 --- a/content/en/docs/doc-contributor-tools/snippets/atom-snippets.cson +++ b/content/en/docs/doc-contributor-tools/snippets/atom-snippets.cson @@ -116,7 +116,7 @@ 'body': '{{< toc >}}' 'Insert code from file': 'prefix': 'codefile' - 'body': '{{< code file="$1" >}}' + 'body': '{{< codenew file="$1" >}}' 'Insert feature state': 'prefix': 'fstate' 'body': '{{< feature-state for_k8s_version="$1" state="$2" >}}' @@ -223,4 +223,4 @@ ${7:"next-steps-or-delete"} {{% /capture %}} """ - \ No newline at end of file + diff --git a/content/en/docs/getting-started-guides/OWNERS b/content/en/docs/getting-started-guides/OWNERS index 329dc6583e..fecf081d73 100644 --- a/content/en/docs/getting-started-guides/OWNERS +++ b/content/en/docs/getting-started-guides/OWNERS @@ -1,3 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + reviewers: - errordeveloper diff --git a/content/en/docs/getting-started-guides/fedora/OWNERS b/content/en/docs/getting-started-guides/fedora/OWNERS index a385021cf9..67c11df3a5 100644 --- a/content/en/docs/getting-started-guides/fedora/OWNERS +++ b/content/en/docs/getting-started-guides/fedora/OWNERS @@ -1,3 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + reviewers: - aveshagarwal - eparis diff --git a/content/en/docs/getting-started-guides/fedora/fedora_manual_config.md b/content/en/docs/getting-started-guides/fedora/fedora_manual_config.md index 7a338b1abc..385ecc190a 100644 --- a/content/en/docs/getting-started-guides/fedora/fedora_manual_config.md +++ b/content/en/docs/getting-started-guides/fedora/fedora_manual_config.md @@ -65,8 +65,7 @@ KUBE_MASTER="--master=http://fed-master:8080" systemctl mask firewalld.service systemctl stop firewalld.service -systemctl disable iptables.service -systemctl stop iptables.service +systemctl disable --now iptables.service ``` **Configure the Kubernetes services on the master.** @@ -97,8 +96,7 @@ ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ```shell for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do - systemctl restart $SERVICES - systemctl enable $SERVICES + systemctl enable --now $SERVICES systemctl status $SERVICES done ``` @@ -146,8 +144,7 @@ current-context: kubelet-context ```shell for SERVICES in kube-proxy kubelet docker; do - systemctl restart $SERVICES - systemctl enable $SERVICES + systemctl enable --now $SERVICES systemctl status $SERVICES done ``` diff --git a/content/en/docs/getting-started-guides/ubuntu/_index.md b/content/en/docs/getting-started-guides/ubuntu/_index.md index 1b1eced189..ed60790b67 100644 --- a/content/en/docs/getting-started-guides/ubuntu/_index.md +++ b/content/en/docs/getting-started-guides/ubuntu/_index.md @@ -51,7 +51,7 @@ These are more in-depth guides for users choosing to run Kubernetes in productio - [Decommissioning](/docs/getting-started-guides/ubuntu/decommissioning/) - [Operational Considerations](/docs/getting-started-guides/ubuntu/operational-considerations/) - [Glossary](/docs/getting-started-guides/ubuntu/glossary/) - + - [Authenticating with LDAP](https://www.ubuntu.com/kubernetes/docs/ldap) ## Third-party Product Integrations @@ -73,5 +73,3 @@ We're normally following the following Slack channels: and we monitor the Kubernetes mailing lists. {{% /capture %}} - - diff --git a/content/en/docs/getting-started-guides/ubuntu/local.md b/content/en/docs/getting-started-guides/ubuntu/local.md index b8aaaf9d5d..49e5e64f74 100644 --- a/content/en/docs/getting-started-guides/ubuntu/local.md +++ b/content/en/docs/getting-started-guides/ubuntu/local.md @@ -18,6 +18,15 @@ sudo snap install conjure-up --classic sudo usermod -a -G lxd $(whoami) ``` +If you have never run or configured lxd before, you will need to run the following +command to set up the default storage pool and the network bridge required: + +``` +sudo lxd init +``` + +If a bridge named `lxdbr0` already exists, you can tell the init config tool to use it. + Note: If conjure-up asks you to "Setup an IPv6 subnet" with LXD, answer NO. IPv6 with Juju/LXD is currently unsupported. If you already have a bridge configured, e.g. `lxdbr0`, [disable IPv6 on the bridge](https://docs.conjure-up.io/stable/en/troubleshoot#common-problems), otherwise you won't be able to choose it. {{% /capture %}} diff --git a/content/en/docs/getting-started-guides/ubuntu/networking.md b/content/en/docs/getting-started-guides/ubuntu/networking.md index e3afca9e87..41c43cc7b1 100644 --- a/content/en/docs/getting-started-guides/ubuntu/networking.md +++ b/content/en/docs/getting-started-guides/ubuntu/networking.md @@ -48,7 +48,7 @@ empty string or undefined the code will attempt to find the default network adapter similar to the following command: ```bash -$ route | grep default | head -n 1 | awk {'print $8'} +route | grep default | head -n 1 | awk {'print $8'} ``` **cidr** The network range to configure the flannel or canal SDN to declare when diff --git a/content/en/docs/getting-started-guides/ubuntu/operational-considerations.md b/content/en/docs/getting-started-guides/ubuntu/operational-considerations.md index 8970df854c..18c0f12264 100644 --- a/content/en/docs/getting-started-guides/ubuntu/operational-considerations.md +++ b/content/en/docs/getting-started-guides/ubuntu/operational-considerations.md @@ -127,7 +127,7 @@ juju config kubernetes-worker allow-privileged=true ### Private registry -With the registry action, you can easily create a private docker registry that +With the registry action, you can easily create a private Docker registry that uses TLS authentication. However, note that a registry deployed with that action is not HA; it uses storage tied to the kubernetes node where the pod is running. Consequently, if the registry pod is migrated from one node to another, you will diff --git a/content/en/docs/getting-started-guides/ubuntu/scaling.md b/content/en/docs/getting-started-guides/ubuntu/scaling.md index aab81330b6..45dd80044e 100644 --- a/content/en/docs/getting-started-guides/ubuntu/scaling.md +++ b/content/en/docs/getting-started-guides/ubuntu/scaling.md @@ -65,7 +65,7 @@ For quorum reasons it is recommended to keep an odd number of etcd nodes. 3, 5, [optimal cluster size](https://coreos.com/etcd/docs/latest/admin_guide.html#optimal-cluster-size) to determine fault tolerance. -To add an etcd unit: +To add an etcd unit: ``` juju add-unit etcd @@ -80,9 +80,8 @@ on each machine that manage Kubernetes; it is called the controller node. For production deployments it is recommended to enable HA of the controller node: juju enable-ha - -Enabling HA results in 3 controller nodes, this should be sufficient for most use cases. 5 and 7 controller nodes are also supported for extra large deployments. - -Refer to the [Juju HA controller documentation](https://jujucharms.com/docs/2.2/controllers-ha) for more information. -{{% /capture %}} +Enabling HA results in 3 controller nodes, this should be sufficient for most use cases. 5 and 7 controller nodes are also supported for extra large deployments. + +For more information, see "Controller high availability" topic in [Juju documentation](https://docs.jujucharms.com). +{{% /capture %}} diff --git a/content/en/docs/getting-started-guides/ubuntu/upgrades.md b/content/en/docs/getting-started-guides/ubuntu/upgrades.md index b34108c2c0..5f87c0b3c8 100644 --- a/content/en/docs/getting-started-guides/ubuntu/upgrades.md +++ b/content/en/docs/getting-started-guides/ubuntu/upgrades.md @@ -107,15 +107,15 @@ but is a safer upgrade route. #### Blue/green worker upgrade -Given a deployment where the workers are named kubernetes-alpha. +Given a deployment where the workers are named kubernetes-blue. Deploy new workers: - juju deploy kubernetes-alpha + juju deploy kubernetes-green Pause the old workers so your workload migrates: - juju run-action kubernetes-alpha/# pause + juju run-action kubernetes-blue/# pause Verify old workloads have migrated with: @@ -123,7 +123,7 @@ Verify old workloads have migrated with: Tear down old workers with: - juju remove-application kubernetes-alpha + juju remove-application kubernetes-blue #### In place worker upgrade diff --git a/content/en/docs/getting-started-guides/windows/_index.md b/content/en/docs/getting-started-guides/windows/_index.md index 71107fe827..5d0ca0d122 100644 --- a/content/en/docs/getting-started-guides/windows/_index.md +++ b/content/en/docs/getting-started-guides/windows/_index.md @@ -354,13 +354,13 @@ This means that you can now register them as Windows services via `sc` command. To create the service: ``` -PS > sc.exe create binPath= " --service " -CMD > sc create binPath= " --service " +PS > sc.exe create binPath= " --windows-service " +CMD > sc create binPath= " --windows-service " ``` Please note that if the arguments contain spaces, it must be escaped. Example: ``` -PS > sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' " -CMD > sc create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' " +PS > sc.exe create kubelet binPath= "C:\kubelet.exe --windows-service --hostname-override 'minion' " +CMD > sc create kubelet binPath= "C:\kubelet.exe --windows-service --hostname-override 'minion' " ``` To start the service: ``` diff --git a/content/en/docs/home/_index.md b/content/en/docs/home/_index.md index c385c17780..31f37880ff 100644 --- a/content/en/docs/home/_index.md +++ b/content/en/docs/home/_index.md @@ -2,12 +2,10 @@ approvers: - chenopis title: Kubernetes Documentation -layout: docsportal_home noedit: true -cid: userJourneys -css: /css/style_user_journeys.css -js: /js/user-journeys/home.js, https://use.fontawesome.com/4bcc658a89.js -display_browse_numbers: true +cid: docsHome +layout: docsportal_home +class: gridPage linkTitle: "Home" main_menu: true weight: 10 @@ -17,5 +15,44 @@ menu: title: "Documentation" weight: 20 post: > -

Learn how to use Kubernetes with the use of walkthroughs, samples, and reference documentation. You can even help contribute to the docs!

+

Learn how to use Kubernetes with conceptual, tutorial, and reference documentation. You can even help contribute to the docs!

+overview: > + Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications. The open source project is hosted by the Cloud Native Computing Foundation (CNCF). +cards: +- name: concepts + title: "Understand the basics" + description: "Learn about Kubernetes and its fundamental concepts." + button: "Learn Concepts" + button_path: "/docs/concepts" +- name: tutorials + title: "Try Kubernetes" + description: "Follow tutorials to learn how to deploy applications in Kubernetes." + button: "View Tutorials" + button_path: "/docs/tutorials" +- name: setup + title: "Set up a cluster" + description: "Get Kubernetes running based on your resources and needs." + button: "Set up Kubernetes" + button_path: "/docs/setup" +- name: tasks + title: "Learn how to use Kubernetes" + description: "Look up common tasks and how to perform them using a short sequence of steps." + button: "View Tasks" + button_path: "/docs/tasks" +- name: reference + title: Look up reference information + description: Browse terminology, command line syntax, API resource types, and setup tool documentation. + button: View Reference + button_path: /docs/reference +- name: contribute + title: Contribute to the docs + description: Anyone can contribute, whether you’re new to the project or you’ve been around a long time. + button: Contribute to the docs + button_path: /docs/contribute +- name: download + title: Download Kubernetes + description: If you are installing Kubernetes or upgrading to the newest version, refer to the current release notes. +- name: about + title: About the documentation + description: This website contains documentation for the current and previous 4 versions of Kubernetes. --- diff --git a/content/en/docs/home/supported-doc-versions.md b/content/en/docs/home/supported-doc-versions.md index 7747ea2b76..45a6012eaa 100644 --- a/content/en/docs/home/supported-doc-versions.md +++ b/content/en/docs/home/supported-doc-versions.md @@ -1,6 +1,10 @@ --- title: Supported Versions of the Kubernetes Documentation content_template: templates/concept +card: + name: about + weight: 10 + title: Supported Versions of the Documentation --- {{% capture overview %}} diff --git a/content/en/docs/reference/_index.md b/content/en/docs/reference/_index.md index 1ebaf37cca..468dcf2924 100644 --- a/content/en/docs/reference/_index.md +++ b/content/en/docs/reference/_index.md @@ -25,8 +25,6 @@ This section of the Kubernetes documentation contains references. * [1.11](/docs/reference/generated/kubernetes-api/v1.11/) * [1.10](https://v1-10.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/) * [1.9](https://v1-9.docs.kubernetes.io/docs/api-reference/v1.9/) - * [1.8](https://v1-8.docs.kubernetes.io/docs/api-reference/v1.8/) - * [1.7](https://v1-7.docs.kubernetes.io/docs/api-reference/v1.7/) ## API Client Libraries diff --git a/content/en/docs/reference/access-authn-authz/abac.md b/content/en/docs/reference/access-authn-authz/abac.md index 9174027776..40c56a985c 100644 --- a/content/en/docs/reference/access-authn-authz/abac.md +++ b/content/en/docs/reference/access-authn-authz/abac.md @@ -82,10 +82,9 @@ resource, and nonResourcePath properties set to `"*"`. ## Kubectl -Kubectl uses the `/api` and `/apis` endpoints of api-server to negotiate -client/server versions. To validate objects sent to the API by create/update -operations, kubectl queries certain swagger resources. For API version `v1` -those would be `/swaggerapi/api/v1` & `/swaggerapi/experimental/v1`. +Kubectl uses the `/api` and `/apis` endpoints of api-server to discover +served resource types, and validates objects sent to the API by create/update +operations using schema information located at `/openapi/v2`. When using ABAC authorization, those special resources have to be explicitly exposed via the `nonResourcePath` property in a policy (see [examples](#examples) below): diff --git a/content/en/docs/reference/access-authn-authz/admission-controllers.md b/content/en/docs/reference/access-authn-authz/admission-controllers.md index 5dc9f2c311..7051356b1a 100644 --- a/content/en/docs/reference/access-authn-authz/admission-controllers.md +++ b/content/en/docs/reference/access-authn-authz/admission-controllers.md @@ -89,17 +89,17 @@ To see which admission plugins are enabled: kube-apiserver -h | grep enable-admission-plugins ``` -In 1.11, they are: +In 1.13, they are: ```shell -NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,Priority +NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeClaimResize,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,Priority ``` ## What does each admission controller do? -### AlwaysAdmit (DEPRECATED) {#alwaysadmit} +### AlwaysAdmit {#alwaysadmit} {{< feature-state for_k8s_version="v1.13" state="deprecated" >}} -Use this admission controller by itself to pass-through all requests. AlwaysAdmit is DEPRECATED as no real meaning. +This admission controller allows all pods into the cluster. It is deprecated because its behavior is the same as if there were no admission controller at all. ### AlwaysPullImages {#alwayspullimages} @@ -111,7 +111,7 @@ scheduled onto the right node), without any authorization check against the imag is enabled, images are always pulled prior to starting containers, which means valid credentials are required. -### AlwaysDeny (DEPRECATED) {#alwaysdeny} +### AlwaysDeny {#alwaysdeny} {{< feature-state for_k8s_version="v1.13" state="deprecated" >}} Rejects all requests. AlwaysDeny is DEPRECATED as no real meaning. @@ -138,26 +138,30 @@ if the pods don't already have toleration for taints `node.kubernetes.io/not-ready:NoExecute` or `node.alpha.kubernetes.io/unreachable:NoExecute`. -### DenyExecOnPrivileged (deprecated) {#denyexeconprivileged} +### DenyExecOnPrivileged {#denyexeconprivileged} {{< feature-state for_k8s_version="v1.13" state="deprecated" >}} This admission controller will intercept all requests to exec a command in a pod if that pod has a privileged container. -If your cluster supports privileged containers, and you want to restrict the ability of end-users to exec -commands in those containers, we strongly encourage enabling this admission controller. - This functionality has been merged into [DenyEscalatingExec](#denyescalatingexec). +The DenyExecOnPrivileged admission plugin is deprecated and will be removed in v1.18. -### DenyEscalatingExec {#denyescalatingexec} +Use of a policy-based admission plugin (like [PodSecurityPolicy](#podsecuritypolicy) or a custom admission plugin) +which can be targeted at specific users or Namespaces and also protects against creation of overly privileged Pods +is recommended instead. + +### DenyEscalatingExec {#denyescalatingexec} {{< feature-state for_k8s_version="v1.13" state="deprecated" >}} This admission controller will deny exec and attach commands to pods that run with escalated privileges that allow host access. This includes pods that run as privileged, have access to the host IPC namespace, and have access to the host PID namespace. -If your cluster supports containers that run with escalated privileges, and you want to -restrict the ability of end-users to exec commands in those containers, we strongly encourage -enabling this admission controller. +The DenyEscalatingExec admission plugin is deprecated and will be removed in v1.18. -### EventRateLimit (alpha) {#eventratelimit} +Use of a policy-based admission plugin (like [PodSecurityPolicy](#podsecuritypolicy) or a custom admission plugin) +which can be targeted at specific users or Namespaces and also protects against creation of overly privileged Pods +is recommended instead. + +### EventRateLimit {#eventratelimit} {{< feature-state for_k8s_version="v1.13" state="alpha" >}} This admission controller mitigates the problem where the API server gets flooded by event requests. The cluster admin can specify event rate limits by: @@ -227,7 +231,7 @@ imagePolicy: # time in s to cache approval allowTTL: 50 # time in s to cache denial - denyTTL: 50 + denyTTL: 50 # time in ms to wait between retries retryBackoff: 500 # determines behavior if the webhook backend fails @@ -264,6 +268,7 @@ users: client-certificate: /path/to/cert.pem # cert for the webhook admission controller to use client-key: /path/to/key.pem # key matching the cert ``` + For additional HTTP configuration, refer to the [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/) documentation. #### Request Payloads @@ -274,7 +279,7 @@ Note that webhook API objects are subject to the same versioning compatibility r An example request body: -``` +```json { "apiVersion":"imagepolicy.k8s.io/v1alpha1", "kind":"ImageReview", @@ -297,7 +302,7 @@ An example request body: The remote service is expected to fill the ImageReviewStatus field of the request and respond to either allow or disallow access. The response body's "spec" field is ignored and may be omitted. A permissive response would return: -``` +```json { "apiVersion": "imagepolicy.k8s.io/v1alpha1", "kind": "ImageReview", @@ -309,7 +314,7 @@ The remote service is expected to fill the ImageReviewStatus field of the reques To disallow access, the service would return: -``` +```json { "apiVersion": "imagepolicy.k8s.io/v1alpha1", "kind": "ImageReview", @@ -334,7 +339,7 @@ Examples of information you might put here are: In any case, the annotations are provided by the user and are not validated by Kubernetes in any way. In the future, if an annotation is determined to be widely useful, it may be promoted to a named field of ImageReviewSpec. -### Initializers (alpha) {#initializers} +### Initializers {#initializers} {{< feature-state for_k8s_version="v1.13" state="alpha" >}} The admission controller determines the initializers of a resource based on the existing `InitializerConfiguration`s. It sets the pending initializers by modifying the @@ -356,7 +361,7 @@ applies a 0.1 CPU requirement to all Pods in the `default` namespace. See the [limitRange design doc](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md) and the [example of Limit Range](/docs/tasks/configure-pod-container/limit-range/) for more details. -### MutatingAdmissionWebhook (beta in 1.9) {#mutatingadmissionwebhook} +### MutatingAdmissionWebhook {#mutatingadmissionwebhook} {{< feature-state for_k8s_version="v1.13" state="beta" >}} This admission controller calls any mutating webhooks which match the request. Matching webhooks are called in serial; each one may modify the object if it desires. @@ -444,7 +449,7 @@ This admission controller also protects the access to `metadata.ownerReferences[ of an object, so that only users with "update" permission to the `finalizers` subresource of the referenced *owner* can change it. -### PersistentVolumeLabel (DEPRECATED) {#persistentvolumelabel} +### PersistentVolumeLabel {#persistentvolumelabel} {{< feature-state for_k8s_version="v1.13" state="deprecated" >}} This admission controller automatically attaches region or zone labels to PersistentVolumes as defined by the cloud provider (for example, GCE or AWS). @@ -468,9 +473,9 @@ This file may be json or yaml and has the following format: ```yaml podNodeSelectorPluginConfig: - clusterDefaultNodeSelector: - namespace1: - namespace2: + clusterDefaultNodeSelector: name-of-node-selector + namespace1: name-of-node-selector + namespace2: name-of-node-selector ``` Reference the `PodNodeSelector` configuration file from the file provided to the API server's command line flag `--admission-control-config-file`: @@ -492,7 +497,7 @@ apiVersion: v1 kind: Namespace metadata: annotations: - scheduler.alpha.kubernetes.io/node-selector: + scheduler.alpha.kubernetes.io/node-selector: name-of-node-selector name: namespace3 ``` @@ -605,7 +610,7 @@ We strongly recommend using this admission controller if you intend to make use The `StorageObjectInUseProtection` plugin adds the `kubernetes.io/pvc-protection` or `kubernetes.io/pv-protection` finalizers to newly created Persistent Volume Claims (PVCs) or Persistent Volumes (PV). In case a user deletes a PVC or PV the PVC or PV is not removed until the finalizer is removed from the PVC or PV by PVC or PV Protection Controller. Refer to the [Storage Object in Use Protection](/docs/concepts/storage/persistent-volumes/#storage-object-in-use-protection) for more detailed information. -### ValidatingAdmissionWebhook (alpha in 1.8; beta in 1.9) {#validatingadmissionwebhook} +### ValidatingAdmissionWebhook {#validatingadmissionwebhook} {{< feature-state for_k8s_version="v1.13" state="beta" >}} This admission controller calls any validating webhooks which match the request. Matching webhooks are called in parallel; if any of them rejects the request, the request @@ -633,7 +638,7 @@ For Kubernetes version 1.10 and later, we recommend running the following set of {{< /note >}} ```shell ---enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota +--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota ``` For Kubernetes 1.9 and earlier, we recommend running the following set of admission controllers using the `--admission-control` flag (**order matters**). @@ -653,27 +658,4 @@ in the mutating phase. For earlier versions, there was no concept of validating vs mutating and the admission controllers ran in the exact order specified. -* v1.6 - v1.8 - - ```shell - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds - ``` - -* v1.4 - v1.5 - - ```shell - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota - ``` - -* v1.2 - v1.3 - - ```shell - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota - ``` - -* v1.0 - v1.1 - - ```shell - --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,PersistentVolumeLabel,ResourceQuota - ``` {{% /capture %}} diff --git a/content/en/docs/reference/access-authn-authz/authentication.md b/content/en/docs/reference/access-authn-authz/authentication.md index 1828be30b2..54330b0a79 100644 --- a/content/en/docs/reference/access-authn-authz/authentication.md +++ b/content/en/docs/reference/access-authn-authz/authentication.md @@ -120,7 +120,7 @@ Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269 ### Bootstrap Tokens -This feature is currently in **alpha**. +This feature is currently in **beta**. To allow for streamlined bootstrapping for new clusters, Kubernetes includes a dynamically-managed Bearer token type called a *Bootstrap Token*. These tokens @@ -217,10 +217,21 @@ Kubernetes API. To manually create a service account, simply use the `kubectl create serviceaccount (NAME)` command. This creates a service account in the current namespace and an associated secret. +```bash +kubectl create serviceaccount jenkins ``` -$ kubectl create serviceaccount jenkins + +```none serviceaccount "jenkins" created -$ kubectl get serviceaccounts jenkins -o yaml +``` + +Check an associated secret: + +```bash +kubectl get serviceaccounts jenkins -o yaml +``` + +```yaml apiVersion: v1 kind: ServiceAccount metadata: @@ -232,8 +243,11 @@ secrets: The created secret holds the public CA of the API server and a signed JSON Web Token (JWT). +```bash +kubectl get secret jenkins-token-1yvwg -o yaml ``` -$ kubectl get secret jenkins-token-1yvwg -o yaml + +```yaml apiVersion: v1 data: ca.crt: (APISERVER'S CA BASE64 ENCODED) @@ -308,6 +322,7 @@ To enable the plugin, configure the following flags on the API server: | `--oidc-username-prefix` | Prefix prepended to username claims to prevent clashes with existing names (such as `system:` users). For example, the value `oidc:` will create usernames like `oidc:jane.doe`. If this flag isn't provided and `--oidc-user-claim` is a value other than `email` the prefix defaults to `( Issuer URL )#` where `( Issuer URL )` is the value of `--oidc-issuer-url`. The value `-` can be used to disable all prefixing. | `oidc:` | No | | `--oidc-groups-claim` | JWT claim to use as the user's group. If the claim is present it must be an array of strings. | groups | No | | `--oidc-groups-prefix` | Prefix prepended to group claims to prevent clashes with existing names (such as `system:` groups). For example, the value `oidc:` will create group names like `oidc:engineering` and `oidc:infra`. | `oidc:` | No | +| `--oidc-required-claim` | A key=value pair that describes a required claim in the ID Token. If set, the claim is verified to be present in the ID Token with a matching value. Repeat this flag to specify multiple claims. | `claim=value` | No | | `--oidc-ca-file` | The path to the certificate for the CA that signed your identity provider's web certificate. Defaults to the host's root CAs. | `/etc/kubernetes/ssl/kc-ca.pem` | No | Importantly, the API server is not an OAuth2 client, rather it can only be @@ -334,7 +349,7 @@ Setup instructions for specific systems: - [UAA](http://apigee.com/about/blog/engineering/kubernetes-authentication-enterprise) - [Dex](https://speakerdeck.com/ericchiang/kubernetes-access-control-with-dex) -- [OpenUnison](https://github.com/TremoloSecurity/openunison-qs-kubernetes) +- [OpenUnison](https://www.tremolosecurity.com/orchestra-k8s/) #### Using kubectl @@ -391,7 +406,7 @@ Once your `id_token` expires, `kubectl` will attempt to refresh your `id_token` The `kubectl` command lets you pass in a token using the `--token` option. Simply copy and paste the `id_token` into this option: -``` +```bash kubectl --token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL21sYi50cmVtb2xvLmxhbjo4MDQzL2F1dGgvaWRwL29pZGMiLCJhdWQiOiJrdWJlcm5ldGVzIiwiZXhwIjoxNDc0NTk2NjY5LCJqdGkiOiI2RDUzNXoxUEpFNjJOR3QxaWVyYm9RIiwiaWF0IjoxNDc0NTk2MzY5LCJuYmYiOjE0NzQ1OTYyNDksInN1YiI6Im13aW5kdSIsInVzZXJfcm9sZSI6WyJ1c2VycyIsIm5ldy1uYW1lc3BhY2Utdmlld2VyIl0sImVtYWlsIjoibXdpbmR1QG5vbW9yZWplZGkuY29tIn0.f2As579n9VNoaKzoF-dOQGmXkFKf1FMyNV0-va_B63jn-_n9LGSCca_6IVMP8pO-Zb4KvRqGyTP0r3HkHxYy5c81AnIh8ijarruczl-TK_yF5akjSTHFZD-0gRzlevBDiH8Q79NAr-ky0P4iIXS8lY9Vnjch5MF74Zx0c3alKJHJUnnpjIACByfF2SCaYzbWFMUNat-K1PaUk5-ujMBG7yYnr95xD-63n8CO8teGUAAEMx6zRjzfhnhbzX-ajwZLGwGUBT4WqjMs70-6a7_8gZmLZb2az1cZynkFRj2BaCkVT3A2RrjeEwZEtGXlMqKJ1_I2ulrOVsYx01_yD35-rw get nodes ``` @@ -620,11 +635,21 @@ Impersonate-Extra-scopes: development When using `kubectl` set the `--as` flag to configure the `Impersonate-User` header, set the `--as-group` flag to configure the `Impersonate-Group` header. -```shell -$ kubectl drain mynode -Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode) +```bash +kubectl drain mynode +``` -$ kubectl drain mynode --as=superman --as-group=system:masters +```none +Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode) +``` + +Set the `--as` and `--as-group` flag: + +```bash +kubectl drain mynode --as=superman --as-group=system:masters +``` + +```none node/mynode cordoned node/mynode drained ``` diff --git a/content/en/docs/reference/access-authn-authz/authorization.md b/content/en/docs/reference/access-authn-authz/authorization.md index 366fbefe21..6e9baec83b 100644 --- a/content/en/docs/reference/access-authn-authz/authorization.md +++ b/content/en/docs/reference/access-authn-authz/authorization.md @@ -47,7 +47,7 @@ Kubernetes reviews only the following API request attributes: * **extra** - A map of arbitrary string keys to string values, provided by the authentication layer. * **API** - Indicates whether the request is for an API resource. * **Request path** - Path to miscellaneous non-resource endpoints like `/api` or `/healthz`. - * **API request verb** - API verbs `get`, `list`, `create`, `update`, `patch`, `watch`, `proxy`, `redirect`, `delete`, and `deletecollection` are used for resource requests. To determine the request verb for a resource API endpoint, see [Determine the request verb](/docs/reference/access-authn-authz/authorization/#determine-whether-a-request-is-allowed-or-denied) below. + * **API request verb** - API verbs `get`, `list`, `create`, `update`, `patch`, `watch`, `proxy`, `redirect`, `delete`, and `deletecollection` are used for resource requests. To determine the request verb for a resource API endpoint, see [Determine the request verb](/docs/reference/access-authn-authz/authorization/#determine-the-request-verb). * **HTTP request verb** - HTTP verbs `get`, `post`, `put`, and `delete` are used for non-resource requests. * **Resource** - The ID or name of the resource that is being accessed (for resource requests only) -- For resource requests using `get`, `update`, `patch`, and `delete` verbs, you must provide the resource name. * **Subresource** - The subresource that is being accessed (for resource requests only). @@ -90,9 +90,16 @@ a given action, and works regardless of the authorization mode used. ```bash -$ kubectl auth can-i create deployments --namespace dev +kubectl auth can-i create deployments --namespace dev +``` +``` yes -$ kubectl auth can-i create deployments --namespace prod +``` + +```shell +kubectl auth can-i create deployments --namespace prod +``` +``` no ``` @@ -100,7 +107,9 @@ Administrators can combine this with [user impersonation](/docs/reference/access to determine what action other users can perform. ```bash -$ kubectl auth can-i list secrets --namespace dev --as dave +kubectl auth can-i list secrets --namespace dev --as dave +``` +``` no ``` @@ -116,7 +125,9 @@ These APIs can be queried by creating normal Kubernetes resources, where the res field of the returned object is the result of the query. ```bash -$ kubectl create -f - -o yaml << EOF +kubectl create -f - -o yaml << EOF +``` +``` apiVersion: authorization.k8s.io/v1 kind: SelfSubjectAccessReview spec: diff --git a/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md b/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md index 4d6fde6a00..c405d27366 100644 --- a/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md +++ b/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md @@ -62,13 +62,13 @@ In the following, we describe how to quickly experiment with admission webhooks. ### Write an admission webhook server Please refer to the implementation of the [admission webhook -server](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/webhook/main.go) +server](https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/images/webhook/main.go) that is validated in a Kubernetes e2e test. The webhook handles the `admissionReview` requests sent by the apiservers, and sends back its decision wrapped in `admissionResponse`. The example admission webhook server leaves the `ClientAuth` field -[empty](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/webhook/config.go#L48-L49), +[empty](https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/images/webhook/config.go#L47-L48), which defaults to `NoClientCert`. This means that the webhook server does not authenticate the identity of the clients, supposedly apiservers. If you need mutual TLS or other ways to authenticate the clients, see @@ -80,18 +80,18 @@ The webhook server in the e2e test is deployed in the Kubernetes cluster, via the [deployment API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1beta1-apps). The test also creates a [service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core) as the front-end of the webhook server. See -[code](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/e2e/apimachinery/webhook.go#L196). +[code](https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/e2e/apimachinery/webhook.go#L227). You may also deploy your webhooks outside of the cluster. You will need to update -your [webhook client configurations](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L218) accordingly. +your [webhook client configurations](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L247) accordingly. ### Configure admission webhooks on the fly You can dynamically configure what resources are subject to what admission webhooks via -[ValidatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L68) +[ValidatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L84) or -[MutatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L98). +[MutatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L114). The following is an example `validatingWebhookConfiguration`, a mutating webhook configuration is similar. @@ -170,7 +170,7 @@ plugins: ``` The schema of `admissionConfiguration` is defined -[here](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.0/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go#L27). +[here](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go#L27). * In the kubeConfig file, provide the credentials: @@ -242,7 +242,7 @@ all `spec.initializers[].name`s are appended to the new object's An initializer controller should list and watch for uninitialized objects, by using the query parameter `?includeUninitialized=true`. If using client-go, just set -[listOptions.includeUninitialized](https://github.com/kubernetes/kubernetes/blob/v1.7.0-rc.1/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L315) +[listOptions.includeUninitialized](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L332) to true. For the observed uninitialized objects, an initializer controller should first diff --git a/content/en/docs/reference/access-authn-authz/node.md b/content/en/docs/reference/access-authn-authz/node.md index 5c6d0242e5..f716a99b54 100644 --- a/content/en/docs/reference/access-authn-authz/node.md +++ b/content/en/docs/reference/access-authn-authz/node.md @@ -45,6 +45,9 @@ being in the `system:nodes` group, with a username of `system:node:`. This group and user name format match the identity created for each kubelet as part of [kubelet TLS bootstrapping](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/). +The value of `` **must** match precisely the name of the node as registered by the kubelet. By default, this is the host name as provided by `hostname`, or overridden via the [kubelet option](/docs/reference/command-line-tools-reference/kubelet/) `--hostname-override`. However, when using the `--cloud-provider` kubelet option, the specific hostname may be determined by the cloud provider, ignoring the local `hostname` and the `--hostname-override` option. +For specifics about how the kubelet determines the hostname, as well as cloud provider overrides, see the [kubelet options reference](/docs/reference/command-line-tools-reference/kubelet/) and the [cloud provider details](/docs/concepts/cluster-administration/cloud-providers/). + To enable the Node authorizer, start the apiserver with `--authorization-mode=Node`. To limit the API objects kubelets are able to write, enable the [NodeRestriction](/docs/reference/access-authn-authz/admission-controllers#NodeRestriction) admission plugin by starting the apiserver with `--enable-admission-plugins=...,NodeRestriction,...` diff --git a/content/en/docs/reference/access-authn-authz/rbac.md b/content/en/docs/reference/access-authn-authz/rbac.md index b90509b924..f2cb82bec9 100644 --- a/content/en/docs/reference/access-authn-authz/rbac.md +++ b/content/en/docs/reference/access-authn-authz/rbac.md @@ -148,6 +148,24 @@ roleRef: apiGroup: rbac.authorization.k8s.io ``` +You cannot modify which `Role` or `ClusterRole` a binding object refers to. +Attempts to change the `roleRef` field of a binding object will result in a validation error. +To change the `roleRef` field on an existing binding object, the binding object must be deleted and recreated. +There are two primary reasons for this restriction: + +1. A binding to a different role is a fundamentally different binding. +Requiring a binding to be deleted/recreated in order to change the `roleRef` +ensures the full list of subjects in the binding is intended to be granted +the new role (as opposed to enabling accidentally modifying just the roleRef +without verifying all of the existing subjects should be given the new role's permissions). +2. Making `roleRef` immutable allows giving `update` permission on an existing binding object +to a user, which lets them manage the list of subjects, without being able to change the +role that is granted to those subjects. + +The `kubectl auth reconcile` command-line utility creates or updates a manifest file containing RBAC objects, +and handles deleting and recreating binding objects if required to change the role they refer to. +See [command usage and examples](#kubectl-auth-reconcile) for more information. + ### Referring to Resources Most resources are represented by a string representation of their name, such as "pods", just as it @@ -677,9 +695,9 @@ Because this is enforced at the API level, it applies even when the RBAC authori A user can only create/update a role if at least one of the following things is true: -1. they already have all the permissions contained in the role, at the same scope as the object being modified +1. They already have all the permissions contained in the role, at the same scope as the object being modified (cluster-wide for a `ClusterRole`, within the same namespace or cluster-wide for a `Role`) -2. they are given explicit permission to perform the `escalate` verb on the `roles` or `clusterroles` resource in the `rbac.authorization.k8s.io` API group (Kubernetes 1.12 and newer) +2. They are given explicit permission to perform the `escalate` verb on the `roles` or `clusterroles` resource in the `rbac.authorization.k8s.io` API group (Kubernetes 1.12 and newer) For example, if "user-1" does not have the ability to list secrets cluster-wide, they cannot create a `ClusterRole` containing that permission. To allow a user to create/update roles: @@ -738,46 +756,156 @@ To bootstrap initial roles and role bindings: ## Command-line Utilities -Two `kubectl` commands exist to grant roles within a namespace or across the entire cluster. +### `kubectl create role` + +Creates a `Role` object defining permissions within a single namespace. Examples: + +* Create a `Role` named "pod-reader" that allows user to perform "get", "watch" and "list" on pods: + + ``` + kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods + ``` + +* Create a `Role` named "pod-reader" with resourceNames specified: + + ``` + kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod + ``` + +* Create a `Role` named "foo" with apiGroups specified: + + ``` + kubectl create role foo --verb=get,list,watch --resource=replicasets.apps + ``` + +* Create a `Role` named "foo" with subresource permissions: + + ``` + kubectl create role foo --verb=get,list,watch --resource=pods,pods/status + ``` + +* Create a `Role` named "my-component-lease-holder" with permissions to get/update a resource with a specific name: + + ``` + kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-component + ``` + +### `kubectl create clusterrole` + +Creates a `ClusterRole` object. Examples: + +* Create a `ClusterRole` named "pod-reader" that allows user to perform "get", "watch" and "list" on pods: + + ``` + kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods + ``` + +* Create a `ClusterRole` named "pod-reader" with resourceNames specified: + + ``` + kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod + ``` + +* Create a `ClusterRole` named "foo" with apiGroups specified: + + ``` + kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps + ``` + +* Create a `ClusterRole` named "foo" with subresource permissions: + + ``` + kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status + ``` + +* Create a `ClusterRole` name "foo" with nonResourceURL specified: + + ``` + kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/* + ``` + +* Create a `ClusterRole` name "monitoring" with aggregationRule specified: + + ``` + kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true" + ``` ### `kubectl create rolebinding` Grants a `Role` or `ClusterRole` within a specific namespace. Examples: -* Grant the `admin` `ClusterRole` to a user named "bob" in the namespace "acme": +* Within the namespace "acme", grant the permissions in the `admin` `ClusterRole` to a user named "bob": ``` kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme ``` -* Grant the `view` `ClusterRole` to a service account named "myapp" in the namespace "acme": +* Within the namespace "acme", grant the permissions in the `view` `ClusterRole` to the service account in the namespace "acme" named "myapp" : ``` kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme ``` +* Within the namespace "acme", grant the permissions in the `view` `ClusterRole` to a service account in the namespace "myappnamespace" named "myapp": + + ``` + kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme + ``` + ### `kubectl create clusterrolebinding` Grants a `ClusterRole` across the entire cluster, including all namespaces. Examples: -* Grant the `cluster-admin` `ClusterRole` to a user named "root" across the entire cluster: +* Across the entire cluster, grant the permissions in the `cluster-admin` `ClusterRole` to a user named "root": ``` kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root ``` -* Grant the `system:node` `ClusterRole` to a user named "kubelet" across the entire cluster: +* Across the entire cluster, grant the permissions in the `system:node-proxier ` `ClusterRole` to a user named "system:kube-proxy": ``` - kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet + kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy ``` -* Grant the `view` `ClusterRole` to a service account named "myapp" in the namespace "acme" across the entire cluster: +* Across the entire cluster, grant the permissions in the `view` `ClusterRole` to a service account named "myapp" in the namespace "acme": ``` kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp ``` +### `kubectl auth reconcile` {#kubectl-auth-reconcile} + +Creates or updates `rbac.authorization.k8s.io/v1` API objects from a manifest file. + +Missing objects are created, and the containing namespace is created for namespaced objects, if required. + +Existing roles are updated to include the permissions in the input objects, +and remove extra permissions if `--remove-extra-permissions` is specified. + +Existing bindings are updated to include the subjects in the input objects, +and remove extra subjects if `--remove-extra-subjects` is specified. + +Examples: + +* Test applying a manifest file of RBAC objects, displaying changes that would be made: + + ``` + kubectl auth reconcile -f my-rbac-rules.yaml --dry-run + ``` + +* Apply a manifest file of RBAC objects, preserving any extra permissions (in roles) and any extra subjects (in bindings): + + ``` + kubectl auth reconcile -f my-rbac-rules.yaml + ``` + +* Apply a manifest file of RBAC objects, removing any extra permissions (in roles) and any extra subjects (in bindings): + + ``` + kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions + ``` + See the CLI help for detailed usage. ## Service Account Permissions diff --git a/content/en/docs/reference/access-authn-authz/service-accounts-admin.md b/content/en/docs/reference/access-authn-authz/service-accounts-admin.md index 7e030903bc..c8f41806c9 100644 --- a/content/en/docs/reference/access-authn-authz/service-accounts-admin.md +++ b/content/en/docs/reference/access-authn-authz/service-accounts-admin.md @@ -59,6 +59,10 @@ It acts synchronously to modify pods as they are created or updated. When this p 1. It adds a `volume` to the pod which contains a token for API access. 1. It adds a `volumeSource` to each container of the pod mounted at `/var/run/secrets/kubernetes.io/serviceaccount`. +Starting from v1.13, you can migrate a service account volume to a projected volume when +the `BoundServiceAccountTokenVolume` feature gate is enabled. +The service account token will expire after 1 hour or the pod is deleted. See more details about [projected volume](docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection). + ### Token Controller TokenController runs as part of controller-manager. It acts asynchronously. It: diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates.md b/content/en/docs/reference/command-line-tools-reference/feature-gates.md index 7d665737c3..9a8c7c504a 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates.md @@ -16,7 +16,14 @@ can specify on different Kubernetes components. Feature gates are a set of key=value pairs that describe alpha or experimental features. An administrator can use the `--feature-gates` command line flag on each component -to turn a feature on or off. +to turn a feature on or off. Each component supports a set of feature gates unique to that component. +Use `-h` flag to see a full set of feature gates for all components. +To set feature gates for a component, such as kubelet, use the `--feature-gates` flag assigned to a list of feature pairs: + +```shell +--feature-gates="...,DynamicKubeletConfig=true" +``` + The following table is a summary of the feature gates that you can set on different Kubernetes components. @@ -56,9 +63,11 @@ different Kubernetes components. | `CSIPersistentVolume` | `true` | GA | 1.13 | - | | `CustomPodDNS` | `false` | Alpha | 1.9 | 1.9 | | `CustomPodDNS` | `true` | Beta| 1.10 | | -| `CustomResourceSubresources` | `false` | Alpha | 1.10 | | +| `CustomResourceSubresources` | `false` | Alpha | 1.10 | 1.11 | +| `CustomResourceSubresources` | `true` | Beta | 1.11 | - | | `CustomResourceValidation` | `false` | Alpha | 1.8 | 1.8 | | `CustomResourceValidation` | `true` | Beta | 1.9 | | +| `CustomResourceWebhookConversion` | `false` | Alpha | 1.13 | | | `DebugContainers` | `false` | Alpha | 1.10 | | | `DevicePlugins` | `false` | Alpha | 1.8 | 1.9 | | `DevicePlugins` | `true` | Beta | 1.10 | | @@ -95,7 +104,8 @@ different Kubernetes components. | `NodeLease` | `false` | Alpha | 1.12 | | | `PersistentLocalVolumes` | `false` | Alpha | 1.7 | 1.9 | | `PersistentLocalVolumes` | `true` | Beta | 1.10 | | -| `PodPriority` | `false` | Alpha | 1.8 | | +| `PodPriority` | `false` | Alpha | 1.8 | 1.10 | +| `PodPriority` | `true` | Beta | 1.11 | | | `PodReadinessGates` | `false` | Alpha | 1.11 | | | `PodReadinessGates` | `true` | Beta | 1.12 | | | `PodShareProcessNamespace` | `false` | Alpha | 1.10 | | @@ -215,6 +225,8 @@ Each feature gate is designed for enabling/disabling a specific feature: on resources created from [CustomResourceDefinition](/docs/concepts/api-extension/custom-resources/). - `CustomResourceValidation`: Enable schema based validation on resources created from [CustomResourceDefinition](/docs/concepts/api-extension/custom-resources/). +- `CustomResourceWebhookConversion`: Enable webhook-based conversion + on resources created from [CustomResourceDefinition](/docs/concepts/api-extension/custom-resources/). - `DebugContainers`: Enable running a "debugging" container in a Pod's namespace to troubleshoot a running Pod. - `DevicePlugins`: Enable the [device-plugins](/docs/concepts/cluster-administration/device-plugins/) diff --git a/content/en/docs/reference/command-line-tools-reference/kube-apiserver.md b/content/en/docs/reference/command-line-tools-reference/kube-apiserver.md index 73359207da..433fba1bd3 100644 --- a/content/en/docs/reference/command-line-tools-reference/kube-apiserver.md +++ b/content/en/docs/reference/command-line-tools-reference/kube-apiserver.md @@ -567,16 +567,6 @@ kube-apiserver [flags]
-<<<<<<< HEAD - - - - - - - -======= ->>>>>>> Generate copmonents and tools reference @@ -937,11 +927,7 @@ kube-apiserver [flags] -<<<<<<< HEAD -======= - ->>>>>>> Generate copmonents and tools reference diff --git a/content/en/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping.md b/content/en/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping.md index d5f479ff44..88d1359e69 100644 --- a/content/en/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping.md +++ b/content/en/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping.md @@ -217,7 +217,7 @@ default set of key usages. In order for the controller-manager to sign certificates, it needs the following: -* access to the "kuberetes CA key and certificate" that you created and distributed +* access to the "Kubernetes CA key and certificate" that you created and distributed * enabling CSR signing ### Access to key and certificate @@ -379,10 +379,10 @@ As stated earlier, _any_ valid authentication method can be used, not just token Because the bootstrap `kubeconfig` _is_ a standard `kubeconfig`, you can use `kubectl` to generate it. To create the above example file: ``` -kubectl config -kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-cluster bootstrap --server='https://my.server.example.com:6443' --certificate-authority=/var/lib/kubernetes/ca.pem -kubectl config -kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=07401b.f395accd246ae52d -kubectl config -kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap -kubectl config -kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig use-context bootstrap +kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-cluster bootstrap --server='https://my.server.example.com:6443' --certificate-authority=/var/lib/kubernetes/ca.pem +kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=07401b.f395accd246ae52d +kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap +kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig use-context bootstrap ``` To indicate to the kubelet to use the bootstrap `kubeconfig`, use the following kubelet flag: diff --git a/content/en/docs/reference/command-line-tools-reference/kubelet.md b/content/en/docs/reference/command-line-tools-reference/kubelet.md index 90085458bf..2c2795eb9d 100644 --- a/content/en/docs/reference/command-line-tools-reference/kubelet.md +++ b/content/en/docs/reference/command-line-tools-reference/kubelet.md @@ -721,7 +721,7 @@ kubelet [flags] - + diff --git a/content/en/docs/reference/glossary/app-container.md b/content/en/docs/reference/glossary/app-container.md new file mode 100644 index 0000000000..c5c4697808 --- /dev/null +++ b/content/en/docs/reference/glossary/app-container.md @@ -0,0 +1,20 @@ +--- +title: App Container +id: app-container +date: 2019-02-12 +full_link: +short_description: > + A container used to run part of a workload. Compare with init container. + +aka: +tags: +- workload +--- + Application containers (or app containers) are the {{< glossary_tooltip text="containers" term_id="container" >}} in a {{< glossary_tooltip text="pod" term_id="pod" >}} that are started after any {{< glossary_tooltip text="init containers" term_id="init-container" >}} have completed. + + + +An init container lets you separate initialization details that are important for the overall +{{< glossary_tooltip text="workload" term_id="workload" >}}, and that don't need to keep running +once the application container has started. +If a pod doesn't have any init containers configured, all the containers in that pod are app containers. diff --git a/content/en/docs/reference/glossary/cni.md b/content/en/docs/reference/glossary/cni.md index f654f2586c..c989cc8f69 100644 --- a/content/en/docs/reference/glossary/cni.md +++ b/content/en/docs/reference/glossary/cni.md @@ -1,5 +1,5 @@ --- -title: CNI (Container network interface) +title: Container network interface (CNI) id: cni date: 2018-05-25 full_link: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#cni diff --git a/content/en/docs/reference/glossary/container-lifecycle-hooks.md b/content/en/docs/reference/glossary/container-lifecycle-hooks.md index 527e2f3e6e..5f19d0606f 100644 --- a/content/en/docs/reference/glossary/container-lifecycle-hooks.md +++ b/content/en/docs/reference/glossary/container-lifecycle-hooks.md @@ -6,13 +6,12 @@ full_link: /docs/concepts/containers/container-lifecycle-hooks/ short_description: > The lifecycle hooks expose events in the container management lifecycle and let the user run code when the events occur. -aka: +aka: tags: - extension --- - The lifecycle hooks expose events in the {{< glossary_tooltip text="Container" term_id="container" >}}container management lifecycle and let the user run code when the events occur. + The lifecycle hooks expose events in the {{< glossary_tooltip text="Container" term_id="container" >}} management lifecycle and let the user run code when the events occur. - + Two hooks are exposed to Containers: PostStart which executes immediately after a container is created and PreStop which is blocking and is called immediately before a container is terminated. - diff --git a/content/en/docs/reference/glossary/cronjob.md b/content/en/docs/reference/glossary/cronjob.md index 3173740b5b..d09dc8e0d4 100755 --- a/content/en/docs/reference/glossary/cronjob.md +++ b/content/en/docs/reference/glossary/cronjob.md @@ -13,7 +13,7 @@ tags: --- Manages a [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/) that runs on a periodic schedule. - + -Similar to a line in a *crontab* file, a Cronjob object specifies a schedule using the [Cron](https://en.wikipedia.org/wiki/Cron) format. +Similar to a line in a *crontab* file, a CronJob object specifies a schedule using the [cron](https://en.wikipedia.org/wiki/Cron) format. diff --git a/content/en/docs/reference/glossary/csi.md b/content/en/docs/reference/glossary/csi.md index 29e5550ccf..8b04559082 100644 --- a/content/en/docs/reference/glossary/csi.md +++ b/content/en/docs/reference/glossary/csi.md @@ -15,7 +15,7 @@ tags: -CSI allows vendors to create custom storage plugins for Kubernetes without adding them to the Kubernetes repository (out-of-tree plugins). To use a CSI driver from a storage provider, you must first [deploy it to your cluster](https://kubernetes-csi.github.io/docs/Setup.html). You will then be able to create a {{< glossary_tooltip text="Storage Class" term_id="storage-class" >}} that uses that CSI driver. +CSI allows vendors to create custom storage plugins for Kubernetes without adding them to the Kubernetes repository (out-of-tree plugins). To use a CSI driver from a storage provider, you must first [deploy it to your cluster](https://kubernetes-csi.github.io/docs/deploying.html). You will then be able to create a {{< glossary_tooltip text="Storage Class" term_id="storage-class" >}} that uses that CSI driver. * [CSI in the Kubernetes documentation](https://kubernetes.io/docs/concepts/storage/volumes/#csi) -* [List of available CSI drivers](https://kubernetes-csi.github.io/docs/Drivers.html) +* [List of available CSI drivers](https://kubernetes-csi.github.io/docs/drivers.html) diff --git a/content/en/docs/reference/glossary/device-plugin.md b/content/en/docs/reference/glossary/device-plugin.md new file mode 100644 index 0000000000..02e5500677 --- /dev/null +++ b/content/en/docs/reference/glossary/device-plugin.md @@ -0,0 +1,17 @@ +--- +title: Device Plugin +id: device-plugin +date: 2019-02-02 +full_link: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/ +short_description: > + Device Plugins are containers running in Kubernetes that provide access to a vendor specific resource. +aka: +tags: +- fundamental +- extension +--- + Device Plugins are containers running in Kubernetes that provide access to a vendor specific resource. + + + +[Device Plugin](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/) are containers running in Kubernetes that provide access to a vendor specific resource. Device Plugins advertise these resources to kubelet and can be deployed manually or as a DeamonSet, rather than writing custom Kubernetes code. diff --git a/content/en/docs/reference/glossary/extensions.md b/content/en/docs/reference/glossary/extensions.md new file mode 100644 index 0000000000..1451bd3865 --- /dev/null +++ b/content/en/docs/reference/glossary/extensions.md @@ -0,0 +1,18 @@ +--- +title: Extensions +id: Extensions +date: 2019-02-01 +full_link: https://kubernetes.io/docs/concepts/extend-kubernetes/extend-cluster/#extensions +short_description: > + Extensions are software components that extend and deeply integrate with Kubernetes to support new types of hardware. + +aka: +tags: +- fundamental +- extension +--- + Extensions are software components that extend and deeply integrate with Kubernetes to support new types of hardware. + + + +Most cluster administrators will use a hosted or distribution instance of Kubernetes. As a result, most Kubernetes users will need to install [extensions](https://kubernetes.io/docs/concepts/extend-kubernetes/extend-cluster/#extensions) and fewer will need to author new ones. diff --git a/content/en/docs/reference/glossary/host-aliases.md b/content/en/docs/reference/glossary/host-aliases.md new file mode 100644 index 0000000000..e67b1c25ce --- /dev/null +++ b/content/en/docs/reference/glossary/host-aliases.md @@ -0,0 +1,17 @@ +--- +title: HostAliases +id: HostAliases +date: 2019-01-31 +full_link: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#hostalias-v1-core +short_description: > + A HostAliases is a mapping between the IP address and hostname to be injected into a Pod's hosts file. + +aka: +tags: +- operation +--- + A HostAliases is a mapping between the IP address and hostname to be injected into a Pod's hosts file. + + + +[HostAliases](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#hostalias-v1-corev) is an optional list of hostnames and IP addresses that will be injected into the Pod's hosts file if specified. This is only valid for non-hostNetwork Pods. diff --git a/content/en/docs/reference/glossary/index.md b/content/en/docs/reference/glossary/index.md index a8c229569a..1fb8799a16 100755 --- a/content/en/docs/reference/glossary/index.md +++ b/content/en/docs/reference/glossary/index.md @@ -7,5 +7,9 @@ layout: glossary noedit: true default_active_tag: fundamental weight: 5 +card: + name: reference + weight: 10 + title: Glossary --- diff --git a/content/en/docs/reference/glossary/pod-disruption-budget.md b/content/en/docs/reference/glossary/pod-disruption-budget.md new file mode 100644 index 0000000000..ea5e30e08f --- /dev/null +++ b/content/en/docs/reference/glossary/pod-disruption-budget.md @@ -0,0 +1,19 @@ +--- +id: pod-disruption-budget +title: Pod Disruption Budget +full-link: /docs/concepts/workloads/pods/disruptions/ +date: 2019-02-12 +short_description: > + An object that limits the number of {{< glossary_tooltip text="Pods" term_id="pod" >}} of a replicated application, that are down simultaneously from voluntary disruptions. + +aka: + - PDB +related: + - pod + - container +tags: + - operation +--- + + A [Pod Disruption Budget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/) allows an application owner to create an object for a replicated application, that ensures a certain number or percentage of Pods with an assigned label will not be voluntarily evicted at any point in time. PDBs cannot prevent an involuntary disruption, but will count against the budget. + diff --git a/content/en/docs/reference/glossary/pod-lifecycle.md b/content/en/docs/reference/glossary/pod-lifecycle.md new file mode 100644 index 0000000000..caa588bb8c --- /dev/null +++ b/content/en/docs/reference/glossary/pod-lifecycle.md @@ -0,0 +1,16 @@ +--- +title: Pod Lifecycle +id: pod-lifecycle +date: 2019-02-17 +full-link: /docs/concepts/workloads/pods/pod-lifecycle/ +related: + - pod + - container +tags: + - fundamental +short_description: > + A high-level summary of what phase the Pod is in within its lifecyle. + +--- + +The [Pod Lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/) is a high level summary of where a Pod is in its lifecyle. A Pod’s `status` field is a [PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#podstatus-v1-core) object, which has a `phase` field that displays one of the following phases: Running, Pending, Succeeded, Failed, Unknown, Completed, or CrashLoopBackOff. diff --git a/content/en/docs/reference/glossary/pod-priority.md b/content/en/docs/reference/glossary/pod-priority.md new file mode 100644 index 0000000000..09d1caab15 --- /dev/null +++ b/content/en/docs/reference/glossary/pod-priority.md @@ -0,0 +1,17 @@ +--- +title: Pod Priority +id: pod-priority +date: 2019-01-31 +full_link: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#pod-priority +short_description: > + Pod Priority indicates the importance of a Pod relative to other Pods. + +aka: +tags: +- operation +--- + Pod Priority indicates the importance of a Pod relative to other Pods. + + + +[Pod Priority](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#pod-priority) gives the ability to set scheduling priority of a Pod to be higher and lower than other Pods — an important feature for production clusters workload. diff --git a/content/en/docs/reference/glossary/preemption.md b/content/en/docs/reference/glossary/preemption.md new file mode 100644 index 0000000000..ac1334c979 --- /dev/null +++ b/content/en/docs/reference/glossary/preemption.md @@ -0,0 +1,17 @@ +--- +title: Preemption +id: preemption +date: 2019-01-31 +full_link: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#preemption +short_description: > + Preemption logic in Kubernetes helps a pending Pod to find a suitable Node by evicting low priority Pods existing on that Node. + +aka: +tags: +- operation +--- + Preemption logic in Kubernetes helps a pending Pod to find a suitable Node by evicting low priority Pods existing on that Node. + + + +If a Pod cannot be scheduled, the scheduler tries to [preempt](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#preemption) lower priority Pods to make scheduling of the pending Pod possible. diff --git a/content/en/docs/reference/glossary/rkt.md b/content/en/docs/reference/glossary/rkt.md new file mode 100644 index 0000000000..455484c8ca --- /dev/null +++ b/content/en/docs/reference/glossary/rkt.md @@ -0,0 +1,18 @@ +--- +title: rkt +id: rkt +date: 2019-01-24 +full_link: https://coreos.com/rkt/ +short_description: > + A security-minded, standards-based container engine. + +aka: +tags: +- security +- tool +--- + A security-minded, standards-based container engine. + + + +rkt is an application {% glossary_tooltip text="container" term_id="container" %} engine featuring a {% glossary_tooltip text="pod" term_id="pod" %}-native approach, a pluggable execution environment, and a well-defined surface area. rkt allows users to apply different configurations at both the pod and application level and each pod executes directly in the classic Unix process model, in a self-contained, isolated environment. diff --git a/content/en/docs/reference/glossary/sysctl.md b/content/en/docs/reference/glossary/sysctl.md new file mode 100755 index 0000000000..7b73af4c56 --- /dev/null +++ b/content/en/docs/reference/glossary/sysctl.md @@ -0,0 +1,23 @@ +--- +title: sysctl +id: sysctl +date: 2019-02-12 +full_link: /docs/tasks/administer-cluster/sysctl-cluster/ +short_description: > + An interface for getting and setting Unix kernel parameters + +aka: +tags: +- tool +--- + `sysctl` is a semi-standardized interface for reading or changing the + attributes of the running Unix kernel. + + + +On Unix-like systems, `sysctl` is both the name of the tool that administrators +use to view and modify these settings, and also the system call that the tool +uses. + +{{< glossary_tooltip text="Container" term_id="container" >}} runtimes and +network plugins may rely on `sysctl` values being set a certain way. diff --git a/content/en/docs/reference/glossary/taint.md b/content/en/docs/reference/glossary/taint.md new file mode 100644 index 0000000000..88a6890c61 --- /dev/null +++ b/content/en/docs/reference/glossary/taint.md @@ -0,0 +1,18 @@ +--- +title: Taint +id: taint +date: 2019-01-11 +full_link: /docs/concepts/configuration/taint-and-toleration/ +short_description: > + A key-value pair and an effect to prevent the scheduling of pods on nodes or node groups. + +aka: +tags: +- core-object +- fundamental +--- + A key-value pair and an effect to prevent the scheduling of pods on nodes or node groups. + + + +Taints and {{< glossary_tooltip text="Tolerations" term_id="toleration" >}} work together to ensure that pods are not scheduled onto inappropriate nodes. One or more taints are applied to a {{< glossary_tooltip text="node" term_id="node" >}}; this marks that the {{< glossary_tooltip text="node" term_id="node" >}} should not accept any pods that do not tolerate the taints. diff --git a/content/en/docs/reference/glossary/toleration.md b/content/en/docs/reference/glossary/toleration.md new file mode 100644 index 0000000000..6a2f763d18 --- /dev/null +++ b/content/en/docs/reference/glossary/toleration.md @@ -0,0 +1,18 @@ +--- +title: Toleration +id: toleration +date: 2019-01-11 +full_link: /docs/concepts/configuration/taint-and-toleration/ +short_description: > + A key-value pair and an effect to enable the scheduling of pods on nodes or node groups that have a matching {% glossary_tooltip term_id="taint" %}. + +aka: +tags: +- core-object +- fundamental +--- + A key-value pair and an effect to enable the scheduling of pods on nodes or node groups that have a matching {{< glossary_tooltip text="taints" term_id="taint" >}}. + + + +Tolerations and {{< glossary_tooltip text="Taints" term_id="taint" >}} work together to ensure that pods are not scheduled onto inappropriate nodes. One or more tolerations are applied to a {{< glossary_tooltip text="pod" term_id="pod" >}}; this marks that the {{< glossary_tooltip text="pod" term_id="pod" >}} is allowed (but not required) to be scheduled on nodes or node groups with matching {{< glossary_tooltip text="taints" term_id="taint" >}}. diff --git a/content/en/docs/reference/glossary/workload.md b/content/en/docs/reference/glossary/workload.md new file mode 100644 index 0000000000..1730e7b93f --- /dev/null +++ b/content/en/docs/reference/glossary/workload.md @@ -0,0 +1,28 @@ +--- +title: Workload +id: workload +date: 2019-02-12 +full_link: /docs/concepts/workloads/ +short_description: > + A set of applications for processing information to serve a purpose that is valuable to a single user or group of users. + +aka: +tags: +- workload +--- +A workload consists of a system of services or applications that can run to fulfill a +task or carry out a business process. + + + +Alongside the computer code that runs to carry out the task, a workload also entails +the infrastructure resources that actually run that code. + +For example, a workload that has a web element and a database element might run the +database in one {{< glossary_tooltip term_id="StatefulSet" >}} of +{{< glossary_tooltip text="pods" term_id="pod" >}} and the webserver via +a {{< glossary_tooltip term_id="Deployment" >}} that consists of many web app +{{< glossary_tooltip text="pods" term_id="pod" >}}, all alike. + +The organisation running this workload may well have other workloads that together +provide a valuable outcome to its users. diff --git a/content/en/docs/reference/kubectl/cheatsheet.md b/content/en/docs/reference/kubectl/cheatsheet.md index 0f42751f7c..47c9a505e5 100644 --- a/content/en/docs/reference/kubectl/cheatsheet.md +++ b/content/en/docs/reference/kubectl/cheatsheet.md @@ -6,6 +6,9 @@ reviewers: - krousey - clove content_template: templates/concept +card: + name: reference + weight: 30 --- {{% capture overview %}} @@ -29,6 +32,13 @@ source <(kubectl completion bash) # setup autocomplete in bash into the current echo "source <(kubectl completion bash)" >> ~/.bashrc # add autocomplete permanently to your bash shell. ``` +You can also use a shorthand alias for `kubectl` that also works with completion: + +```bash +alias k=kubectl +complete -F __start_kubectl k +``` + ### ZSH ```bash @@ -72,7 +82,7 @@ kubectl create -f ./my-manifest.yaml # create resource(s) kubectl create -f ./my1.yaml -f ./my2.yaml # create from multiple files kubectl create -f ./dir # create resource(s) in all manifest files in dir kubectl create -f https://git.io/vPieo # create resource(s) from url -kubectl run nginx --image=nginx # start a single instance of nginx +kubectl create deployment nginx --image=nginx # start a single instance of nginx kubectl explain pods,svc # get the documentation for pod and svc manifests # Create multiple YAML objects from stdin @@ -139,6 +149,10 @@ kubectl get pods --sort-by='.status.containerStatuses[0].restartCount' kubectl get pods --selector=app=cassandra rc -o \ jsonpath='{.items[*].metadata.labels.version}' +# Get all worker nodes (use a selector to exclude results that have a label +# named 'node-role.kubernetes.io/master') +kubectl get node --selector='!node-role.kubernetes.io/master' + # Get all running pods in the namespace kubectl get pods --field-selector=status.phase=Running @@ -150,6 +164,10 @@ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?} echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name}) +# Show labels for all pods (or any other Kubernetes object that supports labelling) +# Also uses "jq" +for item in $( kubectl get pod --output=name); do printf "Labels for %s\n" "$item" | grep --color -E '[^/]+$' && kubectl get "$item" --output=json | jq -r -S '.metadata.labels | to_entries | .[] | " \(.key)=\(.value)"' 2>/dev/null; printf "\n"; done + # Check which nodes are ready JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \ && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True" diff --git a/content/en/docs/reference/kubectl/docker-cli-to-kubectl.md b/content/en/docs/reference/kubectl/docker-cli-to-kubectl.md index 0925992ef8..99d951a90f 100644 --- a/content/en/docs/reference/kubectl/docker-cli-to-kubectl.md +++ b/content/en/docs/reference/kubectl/docker-cli-to-kubectl.md @@ -19,10 +19,16 @@ To run an nginx Deployment and expose the Deployment, see [kubectl run](/docs/re docker: ```shell -$ docker run -d --restart=always -e DOMAIN=cluster --name nginx-app -p 80:80 nginx +docker run -d --restart=always -e DOMAIN=cluster --name nginx-app -p 80:80 nginx +``` +``` 55c103fa129692154a7652490236fee9be47d70a8dd562281ae7d2f9a339a6db +``` -$ docker ps +```shell +docker ps +``` +``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 55c103fa1296 nginx "nginx -g 'daemon of…" 9 seconds ago Up 9 seconds 0.0.0.0:80->80/tcp nginx-app ``` @@ -31,7 +37,9 @@ kubectl: ```shell # start the pod running nginx -$ kubectl run --image=nginx nginx-app --port=80 --env="DOMAIN=cluster" +kubectl run --image=nginx nginx-app --port=80 --env="DOMAIN=cluster" +``` +``` deployment "nginx-app" created ``` @@ -41,7 +49,9 @@ deployment "nginx-app" created ```shell # expose a port through with a service -$ kubectl expose deployment nginx-app --port=80 --name=nginx-http +kubectl expose deployment nginx-app --port=80 --name=nginx-http +``` +``` service "nginx-http" exposed ``` @@ -66,7 +76,9 @@ To list what is currently running, see [kubectl get](/docs/reference/generated/k docker: ```shell -$ docker ps -a +docker ps -a +``` +``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 14636241935f ubuntu:16.04 "echo test" 5 seconds ago Exited (0) 5 seconds ago cocky_fermi 55c103fa1296 nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp nginx-app @@ -75,7 +87,9 @@ CONTAINER ID IMAGE COMMAND CREATED kubectl: ```shell -$ kubectl get po +kubectl get po +``` +``` NAME READY STATUS RESTARTS AGE nginx-app-8df569cb7-4gd89 1/1 Running 0 3m ubuntu 0/1 Completed 0 20s @@ -88,22 +102,30 @@ To attach a process that is already running in a container, see [kubectl attach] docker: ```shell -$ docker ps +docker ps +``` +``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 55c103fa1296 nginx "nginx -g 'daemon of…" 5 minutes ago Up 5 minutes 0.0.0.0:80->80/tcp nginx-app +``` -$ docker attach 55c103fa1296 +```shell +docker attach 55c103fa1296 ... ``` kubectl: ```shell -$ kubectl get pods +kubectl get pods +``` +``` NAME READY STATUS RESTARTS AGE nginx-app-5jyvm 1/1 Running 0 10m +``` -$ kubectl attach -it nginx-app-5jyvm +```shell +kubectl attach -it nginx-app-5jyvm ... ``` @@ -116,22 +138,33 @@ To execute a command in a container, see [kubectl exec](/docs/reference/generate docker: ```shell -$ docker ps +docker ps +``` +``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 55c103fa1296 nginx "nginx -g 'daemon of…" 6 minutes ago Up 6 minutes 0.0.0.0:80->80/tcp nginx-app - -$ docker exec 55c103fa1296 cat /etc/hostname +``` +```shell +docker exec 55c103fa1296 cat /etc/hostname +``` +``` 55c103fa1296 ``` kubectl: ```shell -$ kubectl get po +kubectl get po +``` +``` NAME READY STATUS RESTARTS AGE nginx-app-5jyvm 1/1 Running 0 10m +``` -$ kubectl exec nginx-app-5jyvm -- cat /etc/hostname +```shell +kubectl exec nginx-app-5jyvm -- cat /etc/hostname +``` +``` nginx-app-5jyvm ``` @@ -141,14 +174,14 @@ To use interactive commands. docker: ```shell -$ docker exec -ti 55c103fa1296 /bin/sh +docker exec -ti 55c103fa1296 /bin/sh # exit ``` kubectl: ```shell -$ kubectl exec -ti nginx-app-5jyvm -- /bin/sh +kubectl exec -ti nginx-app-5jyvm -- /bin/sh # exit ``` @@ -162,7 +195,9 @@ To follow stdout/stderr of a process that is running, see [kubectl logs](/docs/r docker: ```shell -$ docker logs -f a9e +docker logs -f a9e +``` +``` 192.168.9.1 - - [14/Jul/2015:01:04:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-" 192.168.9.1 - - [14/Jul/2015:01:04:03 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-" ``` @@ -170,7 +205,9 @@ $ docker logs -f a9e kubectl: ```shell -$ kubectl logs -f nginx-app-zibvs +kubectl logs -f nginx-app-zibvs +``` +``` 10.240.63.110 - - [14/Jul/2015:01:09:01 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" 10.240.63.110 - - [14/Jul/2015:01:09:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" ``` @@ -178,7 +215,9 @@ $ kubectl logs -f nginx-app-zibvs There is a slight difference between pods and containers; by default pods do not terminate if their processes exit. Instead the pods restart the process. This is similar to the docker run option `--restart=always` with one major difference. In docker, the output for each invocation of the process is concatenated, but for Kubernetes, each invocation is separate. To see the output from a previous run in Kubernetes, do this: ```shell -$ kubectl logs --previous nginx-app-zibvs +kubectl logs --previous nginx-app-zibvs +``` +``` 10.240.63.110 - - [14/Jul/2015:01:09:01 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" 10.240.63.110 - - [14/Jul/2015:01:09:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.26.0" "-" ``` @@ -192,32 +231,53 @@ To stop and delete a running process, see [kubectl delete](/docs/reference/gener docker: ```shell -$ docker ps +docker ps +``` +``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a9ec34d98787 nginx "nginx -g 'daemon of" 22 hours ago Up 22 hours 0.0.0.0:80->80/tcp, 443/tcp nginx-app +``` -$ docker stop a9ec34d98787 +```shell +docker stop a9ec34d98787 +``` +``` a9ec34d98787 +``` -$ docker rm a9ec34d98787 +```shell +docker rm a9ec34d98787 +``` +``` a9ec34d98787 ``` kubectl: ```shell -$ kubectl get deployment nginx-app +kubectl get deployment nginx-app +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-app 1 1 1 1 2m +``` -$ kubectl get po -l run=nginx-app +```shell +kubectl get po -l run=nginx-app +``` +``` NAME READY STATUS RESTARTS AGE nginx-app-2883164633-aklf7 1/1 Running 0 2m - -$ kubectl delete deployment nginx-app +``` +```shell +kubectl delete deployment nginx-app +``` +``` deployment "nginx-app" deleted +``` -$ kubectl get po -l run=nginx-app +```shell +kubectl get po -l run=nginx-app # Return nothing ``` @@ -236,7 +296,9 @@ To get the version of client and server, see [kubectl version](/docs/reference/g docker: ```shell -$ docker version +docker version +``` +``` Client version: 1.7.0 Client API version: 1.19 Go version (client): go1.4.2 @@ -252,7 +314,9 @@ OS/Arch (server): linux/amd64 kubectl: ```shell -$ kubectl version +kubectl version +``` +``` Client Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.9+a3d1dfa6f4335", GitCommit:"9b77fed11a9843ce3780f70dd251e92901c43072", GitTreeState:"dirty", BuildDate:"2017-08-29T20:32:58Z", OpenPaasKubernetesVersion:"v1.03.02", GoVersion:"go1.7.5", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.9+a3d1dfa6f4335", GitCommit:"9b77fed11a9843ce3780f70dd251e92901c43072", GitTreeState:"dirty", BuildDate:"2017-08-29T20:32:58Z", OpenPaasKubernetesVersion:"v1.03.02", GoVersion:"go1.7.5", Compiler:"gc", Platform:"linux/amd64"} ``` @@ -264,7 +328,9 @@ To get miscellaneous information about the environment and configuration, see [k docker: ```shell -$ docker info +docker info +``` +``` Containers: 40 Images: 168 Storage Driver: aufs @@ -286,7 +352,9 @@ WARNING: No swap limit support kubectl: ```shell -$ kubectl cluster-info +kubectl cluster-info +``` +``` Kubernetes master is running at https://108.59.85.141 KubeDNS is running at https://108.59.85.141/api/v1/namespaces/kube-system/services/kube-dns/proxy kubernetes-dashboard is running at https://108.59.85.141/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy diff --git a/content/en/docs/reference/kubectl/jsonpath.md b/content/en/docs/reference/kubectl/jsonpath.md index 74fcea92fb..1eed8c22be 100644 --- a/content/en/docs/reference/kubectl/jsonpath.md +++ b/content/en/docs/reference/kubectl/jsonpath.md @@ -81,11 +81,11 @@ range, end | iterate list | {range .items[*]}[{.metadata.nam Examples using `kubectl` and JSONPath expressions: ```shell -$ kubectl get pods -o json -$ kubectl get pods -o=jsonpath='{@}' -$ kubectl get pods -o=jsonpath='{.items[0]}' -$ kubectl get pods -o=jsonpath='{.items[0].metadata.name}' -$ kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.startTime}{"\n"}{end}' +kubectl get pods -o json +kubectl get pods -o=jsonpath='{@}' +kubectl get pods -o=jsonpath='{.items[0]}' +kubectl get pods -o=jsonpath='{.items[0].metadata.name}' +kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.startTime}{"\n"}{end}' ``` On Windows, you must _double_ quote any JSONPath template that contains spaces (not single quote as shown above for bash). This in turn means that you must use a single quote or escaped double quote around any literals in the template. For example: diff --git a/content/en/docs/reference/kubectl/overview.md b/content/en/docs/reference/kubectl/overview.md index bdca0e4840..b37233e860 100644 --- a/content/en/docs/reference/kubectl/overview.md +++ b/content/en/docs/reference/kubectl/overview.md @@ -5,6 +5,9 @@ reviewers: title: Overview of kubectl content_template: templates/concept weight: 20 +card: + name: reference + weight: 20 --- {{% capture overview %}} @@ -30,27 +33,27 @@ where `command`, `TYPE`, `NAME`, and `flags` are: * `TYPE`: Specifies the [resource type](#resource-types). Resource types are case-insensitive and you can specify the singular, plural, or abbreviated forms. For example, the following commands produce the same output: ```shell - $ kubectl get pod pod1 - $ kubectl get pods pod1 - $ kubectl get po pod1 + kubectl get pod pod1 + kubectl get pods pod1 + kubectl get po pod1 ``` -* `NAME`: Specifies the name of the resource. Names are case-sensitive. If the name is omitted, details for all resources are displayed, for example `$ kubectl get pods`. +* `NAME`: Specifies the name of the resource. Names are case-sensitive. If the name is omitted, details for all resources are displayed, for example `kubectl get pods`. When performing an operation on multiple resources, you can specify each resource by type and name or specify one or more files: * To specify resources by type and name: * To group resources if they are all the same type: `TYPE1 name1 name2 name<#>`.
- Example: `$ kubectl get pod example-pod1 example-pod2` + Example: `kubectl get pod example-pod1 example-pod2` * To specify multiple resource types individually: `TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>`.
- Example: `$ kubectl get pod/example-pod1 replicationcontroller/example-rc1` + Example: `kubectl get pod/example-pod1 replicationcontroller/example-rc1` * To specify resources with one or more files: `-f file1 -f file2 -f file<#>` - * [Use YAML rather than JSON](/docs/concepts/configuration/overview/#general-config-tips) since YAML tends to be more user-friendly, especially for configuration files.
- Example: `$ kubectl get pod -f ./pod.yaml` + * [Use YAML rather than JSON](/docs/concepts/configuration/overview/#general-configuration-tips) since YAML tends to be more user-friendly, especially for configuration files.
+ Example: `kubectl get pod -f ./pod.yaml` * `flags`: Specifies optional flags. For example, you can use the `-s` or `--server` flags to specify the address and port of the Kubernetes API server.
@@ -173,7 +176,7 @@ Output format | Description In this example, the following command outputs the details for a single pod as a YAML formatted object: ```shell -$ kubectl get pod web-pod-13je7 -o=yaml +kubectl get pod web-pod-13je7 -o=yaml ``` Remember: See the [kubectl](/docs/user-guide/kubectl/) reference documentation for details about which output format is supported by each command. @@ -187,13 +190,13 @@ To define custom columns and output only the details that you want into a table, Inline: ```shell -$ kubectl get pods -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion +kubectl get pods -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion ``` Template file: ```shell -$ kubectl get pods -o=custom-columns-file=template.txt +kubectl get pods -o=custom-columns-file=template.txt ``` where the `template.txt` file contains: @@ -248,7 +251,7 @@ kubectl [command] [TYPE] [NAME] --sort-by= To print a list of pods sorted by name, you run: ```shell -$ kubectl get pods --sort-by=.metadata.name +kubectl get pods --sort-by=.metadata.name ``` ## Examples: Common operations @@ -258,56 +261,53 @@ Use the following set of examples to help you familiarize yourself with running `kubectl create` - Create a resource from a file or stdin. ```shell -// Create a service using the definition in example-service.yaml. -$ kubectl create -f example-service.yaml +# Create a service using the definition in example-service.yaml. +kubectl create -f example-service.yaml -// Create a replication controller using the definition in example-controller.yaml. -$ kubectl create -f example-controller.yaml +# Create a replication controller using the definition in example-controller.yaml. +kubectl create -f example-controller.yaml -// Create the objects that are defined in any .yaml, .yml, or .json file within the directory. -$ kubectl create -f +# Create the objects that are defined in any .yaml, .yml, or .json file within the directory. +kubectl create -f ``` `kubectl get` - List one or more resources. ```shell -// List all pods in plain-text output format. -$ kubectl get pods +# List all pods in plain-text output format. +kubectl get pods -// List all pods in plain-text output format and include additional information (such as node name). -$ kubectl get pods -o wide +# List all pods in plain-text output format and include additional information (such as node name). +kubectl get pods -o wide -// List the replication controller with the specified name in plain-text output format. Tip: You can shorten and replace the 'replicationcontroller' resource type with the alias 'rc'. -$ kubectl get replicationcontroller +# List the replication controller with the specified name in plain-text output format. Tip: You can shorten and replace the 'replicationcontroller' resource type with the alias 'rc'. +kubectl get replicationcontroller -// List all replication controllers and services together in plain-text output format. -$ kubectl get rc,services +# List all replication controllers and services together in plain-text output format. +kubectl get rc,services -// List all daemon sets, including uninitialized ones, in plain-text output format. -$ kubectl get ds --include-uninitialized +# List all daemon sets, including uninitialized ones, in plain-text output format. +kubectl get ds --include-uninitialized -// List all pods running on node server01 -$ kubectl get pods --field-selector=spec.nodeName=server01 - -// List all pods in plain-text output format, delegating the details of printing to the server -$ kubectl get pods --experimental-server-print +# List all pods running on node server01 +kubectl get pods --field-selector=spec.nodeName=server01 ``` `kubectl describe` - Display detailed state of one or more resources, including the uninitialized ones by default. ```shell -// Display the details of the node with name . -$ kubectl describe nodes +# Display the details of the node with name . +kubectl describe nodes -// Display the details of the pod with name . -$ kubectl describe pods/ +# Display the details of the pod with name . +kubectl describe pods/ -// Display the details of all the pods that are managed by the replication controller named . -// Remember: Any pods that are created by the replication controller get prefixed with the name of the replication controller. -$ kubectl describe pods +# Display the details of all the pods that are managed by the replication controller named . +# Remember: Any pods that are created by the replication controller get prefixed with the name of the replication controller. +kubectl describe pods -// Describe all pods, not including uninitialized ones -$ kubectl describe pods --include-uninitialized=false +# Describe all pods, not including uninitialized ones +kubectl describe pods --include-uninitialized=false ``` {{< note >}} @@ -325,40 +325,40 @@ the pods running on it, the events generated for the node etc. `kubectl delete` - Delete resources either from a file, stdin, or specifying label selectors, names, resource selectors, or resources. ```shell -// Delete a pod using the type and name specified in the pod.yaml file. -$ kubectl delete -f pod.yaml +# Delete a pod using the type and name specified in the pod.yaml file. +kubectl delete -f pod.yaml -// Delete all the pods and services that have the label name=. -$ kubectl delete pods,services -l name= +# Delete all the pods and services that have the label name=. +kubectl delete pods,services -l name= -// Delete all the pods and services that have the label name=, including uninitialized ones. -$ kubectl delete pods,services -l name= --include-uninitialized +# Delete all the pods and services that have the label name=, including uninitialized ones. +kubectl delete pods,services -l name= --include-uninitialized -// Delete all pods, including uninitialized ones. -$ kubectl delete pods --all +# Delete all pods, including uninitialized ones. +kubectl delete pods --all ``` `kubectl exec` - Execute a command against a container in a pod. ```shell -// Get output from running 'date' from pod . By default, output is from the first container. -$ kubectl exec date +# Get output from running 'date' from pod . By default, output is from the first container. +kubectl exec date -// Get output from running 'date' in container of pod . -$ kubectl exec -c date +# Get output from running 'date' in container of pod . +kubectl exec -c date -// Get an interactive TTY and run /bin/bash from pod . By default, output is from the first container. -$ kubectl exec -ti /bin/bash +# Get an interactive TTY and run /bin/bash from pod . By default, output is from the first container. +kubectl exec -ti /bin/bash ``` `kubectl logs` - Print the logs for a container in a pod. ```shell -// Return a snapshot of the logs from pod . -$ kubectl logs +# Return a snapshot of the logs from pod . +kubectl logs -// Start streaming the logs from pod . This is similar to the 'tail -f' Linux command. -$ kubectl logs -f +# Start streaming the logs from pod . This is similar to the 'tail -f' Linux command. +kubectl logs -f ``` ## Examples: Creating and using plugins @@ -366,45 +366,54 @@ $ kubectl logs -f Use the following set of examples to help you familiarize yourself with writing and using `kubectl` plugins: ```shell -// create a simple plugin in any language and name the resulting executable file -// so that it begins with the prefix "kubectl-" -$ cat ./kubectl-hello +# create a simple plugin in any language and name the resulting executable file +# so that it begins with the prefix "kubectl-" +cat ./kubectl-hello #!/bin/bash # this plugin prints the words "hello world" echo "hello world" -// with our plugin written, let's make it executable -$ sudo chmod +x ./kubectl-hello +# with our plugin written, let's make it executable +sudo chmod +x ./kubectl-hello -// and move it to a location in our PATH -$ sudo mv ./kubectl-hello /usr/local/bin +# and move it to a location in our PATH +sudo mv ./kubectl-hello /usr/local/bin -// we have now created and "installed" a kubectl plugin. -// we can begin using our plugin by invoking it from kubectl as if it were a regular command -$ kubectl hello +# we have now created and "installed" a kubectl plugin. +# we can begin using our plugin by invoking it from kubectl as if it were a regular command +kubectl hello +``` +``` hello world +``` -// we can "uninstall" a plugin, by simply removing it from our PATH -$ sudo rm /usr/local/bin/kubectl-hello +``` +# we can "uninstall" a plugin, by simply removing it from our PATH +sudo rm /usr/local/bin/kubectl-hello ``` In order to view all of the plugins that are available to `kubectl`, we can use the `kubectl plugin list` subcommand: ```shell -$ kubectl plugin list +kubectl plugin list +``` +``` The following kubectl-compatible plugins are available: /usr/local/bin/kubectl-hello /usr/local/bin/kubectl-foo /usr/local/bin/kubectl-bar - -// this command can also warn us about plugins that are -// not executable, or that are overshadowed by other -// plugins, for example -$ sudo chmod -x /usr/local/bin/kubectl-foo -$ kubectl plugin list +``` +``` +# this command can also warn us about plugins that are +# not executable, or that are overshadowed by other +# plugins, for example +sudo chmod -x /usr/local/bin/kubectl-foo +kubectl plugin list +``` +``` The following kubectl-compatible plugins are available: /usr/local/bin/kubectl-hello @@ -419,7 +428,7 @@ We can think of plugins as a means to build more complex functionality on top of the existing kubectl commands: ```shell -$ cat ./kubectl-whoami +cat ./kubectl-whoami #!/bin/bash # this plugin makes use of the `kubectl config` command in order to output @@ -431,13 +440,13 @@ Running the above plugin gives us an output containing the user for the currentl context in our KUBECONFIG file: ```shell -// make the file executable -$ sudo chmod +x ./kubectl-whoami +# make the file executable +sudo chmod +x ./kubectl-whoami -// and move it into our PATH -$ sudo mv ./kubectl-whoami /usr/local/bin +# and move it into our PATH +sudo mv ./kubectl-whoami /usr/local/bin -$ kubectl whoami +kubectl whoami Current user: plugins-user ``` diff --git a/content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md b/content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md index e626212ffd..ebd50c07e2 100644 --- a/content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md +++ b/content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md @@ -1,12 +1,9 @@ -Run this command in order to set up the Kubernetes master. +Run this command in order to set up the Kubernetes control plane. ### Synopsis - -Run this command in order to set up the Kubernetes master. - -The "init" command executes the following phases: +The `init` command executes the following phases: ``` preflight Run master pre-flight checks kubelet-start Writes kubelet settings and (re)starts the kubelet diff --git a/content/en/docs/reference/setup-tools/kubeadm/kubeadm-init.md b/content/en/docs/reference/setup-tools/kubeadm/kubeadm-init.md index 72cd8f5a63..1130a20b1d 100644 --- a/content/en/docs/reference/setup-tools/kubeadm/kubeadm-init.md +++ b/content/en/docs/reference/setup-tools/kubeadm/kubeadm-init.md @@ -108,8 +108,7 @@ What this example would do is write the manifest files for the control plane and ### Using kubeadm init with a configuration file {#config-file} {{< caution >}} -**Caution:** The config file is -still considered beta and may change in future versions. +The config file is still considered beta and may change in future versions. {{< /caution >}} It's possible to configure `kubeadm init` with a configuration file instead of command @@ -123,7 +122,7 @@ the [kubeadm config migrate](/docs/reference/setup-tools/kubeadm/kubeadm-config/ because `v1alpha3` will be removed in Kubernetes 1.14. For more details on each field in the `v1beta1` configuration you can navigate to our -[API reference pages.] (https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1) +[API reference pages](https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1). ### Adding kube-proxy parameters {#kube-proxy} @@ -149,8 +148,8 @@ Allowed customization are: * To provide an alternative `imageRepository` to be used instead of `k8s.gcr.io`. -* To provide a `unifiedControlPlaneImage` to be used instead of different images for control plane components. -* To provide a specific `etcd.image` to be used instead of the image available at`k8s.gcr.io`. +* To set `useHyperKubeImage` to `true` to use the HyperKube image. +* To provide a specific `imageRepository` and `imageTag` for etcd or DNS add-on. Please note that the configuration field `kubernetesVersion` or the command line flag `--kubernetes-version` affect the version of the images. @@ -410,7 +409,7 @@ provisioned). For details, see the [kubeadm join](/docs/reference/setup-tools/ku {{% capture whatsnext %}} * [kubeadm init phase](/docs/reference/setup-tools/kubeadm/kubeadm-init-phase/) to understand more about -`kubadm init` phases +`kubeadm init` phases * [kubeadm join](/docs/reference/setup-tools/kubeadm/kubeadm-join/) to bootstrap a Kubernetes worker node and join it to the cluster * [kubeadm upgrade](/docs/reference/setup-tools/kubeadm/kubeadm-upgrade/) to upgrade a Kubernetes cluster to a newer version * [kubeadm reset](/docs/reference/setup-tools/kubeadm/kubeadm-reset/) to revert any changes made to this host by `kubeadm init` or `kubeadm join` diff --git a/content/en/docs/reference/setup-tools/kubeadm/kubeadm-join.md b/content/en/docs/reference/setup-tools/kubeadm/kubeadm-join.md index 7cf67a109c..6c6de5a281 100644 --- a/content/en/docs/reference/setup-tools/kubeadm/kubeadm-join.md +++ b/content/en/docs/reference/setup-tools/kubeadm/kubeadm-join.md @@ -146,7 +146,7 @@ for a kubelet when a Bootstrap Token was used when authenticating. If you don't automatically approve kubelet client certs, you can turn it off by executing this command: ```console -$ kubectl delete clusterrole kubeadm:node-autoapprove-bootstrap +$ kubectl delete clusterrolebinding kubeadm:node-autoapprove-bootstrap ``` After that, `kubeadm join` will block until the admin has manually approved the CSR in flight: diff --git a/content/en/docs/reference/setup-tools/kubeadm/kubeadm.md b/content/en/docs/reference/setup-tools/kubeadm/kubeadm.md index eccf635588..80d4dff5b3 100644 --- a/content/en/docs/reference/setup-tools/kubeadm/kubeadm.md +++ b/content/en/docs/reference/setup-tools/kubeadm/kubeadm.md @@ -5,6 +5,9 @@ reviewers: - jbeda title: Overview of kubeadm weight: 10 +card: + name: reference + weight: 40 --- Kubeadm is a tool built to provide `kubeadm init` and `kubeadm join` as best-practice “fast paths” for creating Kubernetes clusters. diff --git a/content/en/docs/reference/setup-tools/kubefed/kubefed.md b/content/en/docs/reference/setup-tools/kubefed/kubefed.md index 8e424f4abe..582c5ddc27 100644 --- a/content/en/docs/reference/setup-tools/kubefed/kubefed.md +++ b/content/en/docs/reference/setup-tools/kubefed/kubefed.md @@ -63,10 +63,10 @@ kubefed [flags] ``` ### SEE ALSO -* [kubefed init](kubefed_init.md) - Initialize a federation control plane -* [kubefed join](kubefed_join.md) - Join a cluster to a federation -* [kubefed options](kubefed_options.md) - Print the list of flags inherited by all commands -* [kubefed unjoin](kubefed_unjoin.md) - Unjoin a cluster from a federation -* [kubefed version](kubefed_version.md) - Print the client and server version information +* [kubefed init](/docs/reference/setup-tools/kubefed/kubefed_init) - Initialize a federation control plane +* [kubefed join](/docs/reference/setup-tools/kubefed/kubefed_join) - Join a cluster to a federation +* [kubefed options](/docs/reference/setup-tools/kubefed/kubefed_options) - Print the list of flags inherited by all commands +* [kubefed unjoin](/docs/reference/setup-tools/kubefed/kubefed_unjoin) - Unjoin a cluster from a federation +* [kubefed version](/docs/reference/setup-tools/kubefed/kubefed_version) - Print the client and server version information ###### Auto generated by spf13/cobra on 1-Dec-2018 diff --git a/content/en/docs/reference/setup-tools/kubefed/kubefed_init.md b/content/en/docs/reference/setup-tools/kubefed/kubefed_init.md index 1748b5b3d3..0aa2874321 100644 --- a/content/en/docs/reference/setup-tools/kubefed/kubefed_init.md +++ b/content/en/docs/reference/setup-tools/kubefed/kubefed_init.md @@ -102,6 +102,6 @@ kubefed init FEDERATION_NAME --host-cluster-context=HOST_CONTEXT [flags] ``` ### SEE ALSO -* [kubefed](kubefed.md) - kubefed controls a Kubernetes Cluster Federation +* [kubefed](/docs/reference/setup-tools/kubefed/kubefed/) - kubefed controls a Kubernetes Cluster Federation ###### Auto generated by spf13/cobra on 1-Dec-2018 diff --git a/content/en/docs/reference/setup-tools/kubefed/kubefed_join.md b/content/en/docs/reference/setup-tools/kubefed/kubefed_join.md index c44520a7b8..7acf150340 100644 --- a/content/en/docs/reference/setup-tools/kubefed/kubefed_join.md +++ b/content/en/docs/reference/setup-tools/kubefed/kubefed_join.md @@ -96,6 +96,6 @@ kubefed join CLUSTER_NAME --host-cluster-context=HOST_CONTEXT [flags] ``` ### SEE ALSO -* [kubefed](kubefed.md) - kubefed controls a Kubernetes Cluster Federation +* [kubefed](/docs/reference/setup-tools/kubefed/kubefed/) - kubefed controls a Kubernetes Cluster Federation ###### Auto generated by spf13/cobra on 1-Dec-2018 diff --git a/content/en/docs/reference/setup-tools/kubefed/kubefed_options.md b/content/en/docs/reference/setup-tools/kubefed/kubefed_options.md index 7e9bca651d..5f8f00a29e 100644 --- a/content/en/docs/reference/setup-tools/kubefed/kubefed_options.md +++ b/content/en/docs/reference/setup-tools/kubefed/kubefed_options.md @@ -73,6 +73,6 @@ kubefed options [flags] ``` ### SEE ALSO -* [kubefed](kubefed.md) - kubefed controls a Kubernetes Cluster Federation +* [kubefed](/docs/reference/setup-tools/kubefed/kubefed/) - kubefed controls a Kubernetes Cluster Federation ###### Auto generated by spf13/cobra on 1-Dec-2018 diff --git a/content/en/docs/reference/setup-tools/kubefed/kubefed_unjoin.md b/content/en/docs/reference/setup-tools/kubefed/kubefed_unjoin.md index c2f8bb3e95..8f25483379 100644 --- a/content/en/docs/reference/setup-tools/kubefed/kubefed_unjoin.md +++ b/content/en/docs/reference/setup-tools/kubefed/kubefed_unjoin.md @@ -83,6 +83,6 @@ kubefed unjoin CLUSTER_NAME --host-cluster-context=HOST_CONTEXT [flags] ``` ### SEE ALSO -* [kubefed](kubefed.md) - kubefed controls a Kubernetes Cluster Federation +* [kubefed](/docs/reference/setup-tools/kubefed/kubefed/) - kubefed controls a Kubernetes Cluster Federation ###### Auto generated by spf13/cobra on 1-Dec-2018 diff --git a/content/en/docs/reference/setup-tools/kubefed/kubefed_version.md b/content/en/docs/reference/setup-tools/kubefed/kubefed_version.md index f9343bd7fe..136dba3dfc 100644 --- a/content/en/docs/reference/setup-tools/kubefed/kubefed_version.md +++ b/content/en/docs/reference/setup-tools/kubefed/kubefed_version.md @@ -76,6 +76,6 @@ kubefed version [flags] ``` ### SEE ALSO -* [kubefed](kubefed.md) - kubefed controls a Kubernetes Cluster Federation +* [kubefed](/docs/reference/setup-tools/kubefed/kubefed/) - kubefed controls a Kubernetes Cluster Federation ###### Auto generated by spf13/cobra on 1-Dec-2018 diff --git a/content/en/docs/reference/using-api/api-overview.md b/content/en/docs/reference/using-api/api-overview.md index 38baa5aa92..f74a204f38 100644 --- a/content/en/docs/reference/using-api/api-overview.md +++ b/content/en/docs/reference/using-api/api-overview.md @@ -7,6 +7,10 @@ reviewers: - jbeda content_template: templates/concept weight: 10 +card: + name: reference + weight: 50 + title: Overview of API --- {{% capture overview %}} diff --git a/content/en/docs/reference/using-api/client-libraries.md b/content/en/docs/reference/using-api/client-libraries.md index ce7f2acd66..e239976c70 100644 --- a/content/en/docs/reference/using-api/client-libraries.md +++ b/content/en/docs/reference/using-api/client-libraries.md @@ -54,13 +54,14 @@ their authors, not the Kubernetes team. | Node.js | [github.com/tenxcloud/node-kubernetes-client](https://github.com/tenxcloud/node-kubernetes-client) | | Node.js | [github.com/godaddy/kubernetes-client](https://github.com/godaddy/kubernetes-client) | | Perl | [metacpan.org/pod/Net::Kubernetes](https://metacpan.org/pod/Net::Kubernetes) | -| PHP | [github.com/devstub/kubernetes-api-php-client](https://github.com/devstub/kubernetes-api-php-client) | | PHP | [github.com/maclof/kubernetes-client](https://github.com/maclof/kubernetes-client) | +| PHP | [github.com/allansun/kubernetes-php-client](https://github.com/allansun/kubernetes-php-client) | | Python | [github.com/eldarion-gondor/pykube](https://github.com/eldarion-gondor/pykube) | | Python | [github.com/mnubo/kubernetes-py](https://github.com/mnubo/kubernetes-py) | | Ruby | [github.com/Ch00k/kuber](https://github.com/Ch00k/kuber) | | Ruby | [github.com/abonas/kubeclient](https://github.com/abonas/kubeclient) | | Ruby | [github.com/kontena/k8s-client](https://github.com/kontena/k8s-client) | +| Rust | [github.com/ynqa/kubernetes-rust](https://github.com/ynqa/kubernetes-rust) | | Scala | [github.com/doriordan/skuber](https://github.com/doriordan/skuber) | | dotNet | [github.com/tonnyeremin/kubernetes_gen](https://github.com/tonnyeremin/kubernetes_gen) | | DotNet (RestSharp) | [github.com/masroorhasan/Kubernetes.DotNet](https://github.com/masroorhasan/Kubernetes.DotNet) | diff --git a/content/en/docs/reference/using-api/deprecation-policy.md b/content/en/docs/reference/using-api/deprecation-policy.md index a6a8f190cd..90364440e1 100644 --- a/content/en/docs/reference/using-api/deprecation-policy.md +++ b/content/en/docs/reference/using-api/deprecation-policy.md @@ -87,7 +87,7 @@ no less than:** * **Beta: 9 months or 3 releases (whichever is longer)** * **Alpha: 0 releases** -This covers the maximum supported version skew of 2 releases. +This covers the [maximum supported version skew of 2 releases](/docs/setup/version-skew-policy/). {{< note >}} Until [#52185](https://github.com/kubernetes/kubernetes/issues/52185) is diff --git a/content/en/docs/setup/certificates.md b/content/en/docs/setup/certificates.md index dc93af997f..460bcf7db8 100644 --- a/content/en/docs/setup/certificates.md +++ b/content/en/docs/setup/certificates.md @@ -87,14 +87,15 @@ Certificates should be placed in a recommended path (as used by [kubeadm][kubead | Default CN | recommend key path | recommended cert path | command | key argument | cert argument | |------------------------------|------------------------------|-----------------------------|----------------|------------------------------|-------------------------------------------| | etcd-ca | | etcd/ca.crt | kube-apiserver | | --etcd-cafile | -| etcd-client | apiserver-etcd-client.crt | apiserver-etcd-client.crt | kube-apiserver | --etcd-certfile | --etcd-keyfile | -| kubernetes-ca | | ca.crt | kube-apiserver | --client-ca-file | | -| kube-apiserver | apiserver.crt | apiserver.key | kube-apiserver | --tls-cert-file | --tls-private-key | -| apiserver-kubelet-client | apiserver-kubelet-client.crt | | kube-apiserver | --kubelet-client-certificate | | -| front-proxy-client | front-proxy-client.key | front-proxy-client.crt | kube-apiserver | --proxy-client-cert-file | --proxy-client-key-file | +| etcd-client | apiserver-etcd-client.key | apiserver-etcd-client.crt | kube-apiserver | --etcd-keyfile | --etcd-certfile | +| kubernetes-ca | | ca.crt | kube-apiserver | | --client-ca-file | +| kube-apiserver | apiserver.key | apiserver.crt | kube-apiserver | --tls-private-key-file | --tls-cert-file | +| apiserver-kubelet-client | | apiserver-kubelet-client.crt| kube-apiserver | | --kubelet-client-certificate | +| front-proxy-ca | | front-proxy-ca.crt | kube-apiserver | | --requestheader-client-ca-file | +| front-proxy-client | front-proxy-client.key | front-proxy-client.crt | kube-apiserver | --proxy-client-key-file | --proxy-client-cert-file | | | | | | | | | etcd-ca | | etcd/ca.crt | etcd | | --trusted-ca-file, --peer-trusted-ca-file | -| kube-etcd | | etcd/server.crt | etcd | | --cert-file | +| kube-etcd | etcd/server.key | etcd/server.crt | etcd | --key-file | --cert-file | | kube-etcd-peer | etcd/peer.key | etcd/peer.crt | etcd | --peer-key-file | --peer-cert-file | | etcd-ca | | etcd/ca.crt | etcdctl[2] | | --cacert | | kube-etcd-healthcheck-client | etcd/healthcheck-client.key | etcd/healthcheck-client.crt | etcdctl[2] | --key | --cert | @@ -108,10 +109,14 @@ You must manually configure these administrator account and service accounts: | filename | credential name | Default CN | O (in Subject) | |-------------------------|----------------------------|--------------------------------|----------------| | admin.conf | default-admin | kubernetes-admin | system:masters | -| kubelet.conf | default-auth | system:node:`` | system:nodes | +| kubelet.conf | default-auth | system:node:`` (see note) | system:nodes | | controller-manager.conf | default-controller-manager | system:kube-controller-manager | | | scheduler.conf | default-manager | system:kube-scheduler | | +{{< note >}} +The value of `` for `kubelet.conf` **must** match precisely the value of the node name provided by the kubelet as it registers with the apiserver. For further details, read the [Node Authorization](/docs/reference/access-authn-authz/node/). +{{< /note >}} + 1. For each config, generate an x509 cert/key pair with the given CN and O. 1. Run `kubectl` as follows for each config: diff --git a/content/en/docs/setup/cri.md b/content/en/docs/setup/cri.md index 017e6925cb..dfe484aa2b 100644 --- a/content/en/docs/setup/cri.md +++ b/content/en/docs/setup/cri.md @@ -7,46 +7,81 @@ content_template: templates/concept weight: 100 --- {{% capture overview %}} -Since v1.6.0, Kubernetes has enabled the use of CRI, Container Runtime Interface, by default. -This page contains installation instruction for various runtimes. +{{< feature-state for_k8s_version="v1.6" state="stable" >}} +To run containers in Pods, Kubernetes uses a container runtime. Here are +the installation instruction for various runtimes. {{% /capture %}} {{% capture body %}} -Please proceed with executing the following commands based on your OS as root. -You may become the root user by executing `sudo -i` after SSH-ing to each host. + +{{< caution >}} +A flaw was found in the way runc handled system file descriptors when running containers. +A malicious container could use this flaw to overwrite contents of the runc binary and +consequently run arbitrary commands on the container host system. + +Please refer to this link for more information about this issue +[cve-2019-5736 : runc vulnerability ] (https://access.redhat.com/security/cve/cve-2019-5736) +{{< /caution >}} + +### Applicability + +{{< note >}} +This document is written for users installing CRI onto Linux. For other operating +systems, look for documentation specific to your platform. +{{< /note >}} + +You should execute all the commands in this guide as `root`. For example, prefix commands +with `sudo `, or become `root` and run the commands as that user. + +### Cgroup drivers + +When systemd is chosen as the init system for a Linux distribution, the init process generates +and consumes a root control group (`cgroup`) and acts as a cgroup manager. Systemd has a tight +integration with cgroups and will allocate cgroups per process. It's possible to configure your +container runtime and the kubelet to use `cgroupfs`. Using `cgroupfs` alongside systemd means +that there will then be two different cgroup managers. + +Control groups are used to constrain resources that are allocated to processes. +A single cgroup manager will simplify the view of what resources are being allocated +and will by default have a more consistent view of the available and in-use resources. When we have +two managers we end up with two views of those resources. We have seen cases in the field +where nodes that are configured to use `cgroupfs` for the kubelet and Docker, and `systemd` +for the rest of the processes running on the node becomes unstable under resource pressure. + +Changing the settings such that your container runtime and kubelet use `systemd` as the cgroup driver +stabilized the system. Please note the `native.cgroupdriver=systemd` option in the Docker setup below. ## Docker On each of your machines, install Docker. -Version 18.06 is recommended, but 1.11, 1.12, 1.13 and 17.03 are known to work as well. +Version 18.06.2 is recommended, but 1.11, 1.12, 1.13, 17.03 and 18.09 are known to work as well. Keep track of the latest verified Docker version in the Kubernetes release notes. Use the following commands to install Docker on your system: {{< tabs name="tab-cri-docker-installation" >}} {{< tab name="Ubuntu 16.04" codelang="bash" >}} -# Install Docker from Ubuntu's repositories: -apt-get update -apt-get install -y docker.io +# Install Docker CE +## Set up the repository: +### Update the apt package index + apt-get update -# or install Docker CE 18.06 from Docker's repositories for Ubuntu or Debian: +### Install packages to allow apt to use a repository over HTTPS + apt-get update && apt-get install apt-transport-https ca-certificates curl software-properties-common -## Install prerequisites. -apt-get update && apt-get install apt-transport-https ca-certificates curl software-properties-common +### Add Docker’s official GPG key + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - -## Download GPG key. -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +### Add docker apt repository. + add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" -## Add docker apt repository. -add-apt-repository \ - "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) \ - stable" - -## Install docker. -apt-get update && apt-get install docker-ce=18.06.0~ce~3-0~ubuntu +## Install docker ce. +apt-get update && apt-get install docker-ce=18.06.2~ce~3-0~ubuntu # Setup daemon. cat > /etc/docker/daemon.json <}} {{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}} -# Install Docker from CentOS/RHEL repository: -yum install -y docker +# Install Docker CE +## Set up the repository +### Install required packages. + yum install yum-utils device-mapper-persistent-data lvm2 -# or install Docker CE 18.06 from Docker's CentOS repositories: - -## Install prerequisites. -yum install yum-utils device-mapper-persistent-data lvm2 - -## Add docker repository. +### Add docker repository. yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo -## Install docker. -yum update && yum install docker-ce-18.06.1.ce +## Install docker ce. +yum update && yum install docker-ce-18.06.2.ce ## Create /etc/docker directory. mkdir /etc/docker @@ -222,8 +254,8 @@ tar --no-overwrite-dir -C / -xzf cri-containerd-${CONTAINERD_VERSION}.linux-amd6 systemctl start containerd ``` -## Other CRI runtimes: rktlet and frakti +## Other CRI runtimes: frakti -Refer to the [Frakti QuickStart guide](https://github.com/kubernetes/frakti#quickstart) and [Rktlet Getting Started guide](https://github.com/kubernetes-incubator/rktlet/blob/master/docs/getting-started-guide.md) for more information. +Refer to the [Frakti QuickStart guide](https://github.com/kubernetes/frakti#quickstart) for more information. {{% /capture %}} diff --git a/content/en/docs/setup/independent/control-plane-flags.md b/content/en/docs/setup/independent/control-plane-flags.md index 1929b1ae17..e3b5edfdd5 100644 --- a/content/en/docs/setup/independent/control-plane-flags.md +++ b/content/en/docs/setup/independent/control-plane-flags.md @@ -8,6 +8,8 @@ weight: 40 {{% capture overview %}} +{{< feature-state for_k8s_version="1.12" state="stable" >}} + The kubeadm `ClusterConfiguration` object exposes the field `extraArgs` that can override the default flags passed to control plane components such as the APIServer, ControllerManager and Scheduler. The components are defined using the following fields: diff --git a/content/en/docs/setup/independent/create-cluster-kubeadm.md b/content/en/docs/setup/independent/create-cluster-kubeadm.md index c69ec05132..c34921894e 100644 --- a/content/en/docs/setup/independent/create-cluster-kubeadm.md +++ b/content/en/docs/setup/independent/create-cluster-kubeadm.md @@ -153,52 +153,69 @@ The output should look like: ```none [init] Using Kubernetes version: vX.Y.Z [preflight] Running pre-flight checks -[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --token-ttl 0) -[certificates] Generated ca certificate and key. -[certificates] Generated apiserver certificate and key. -[certificates] apiserver serving cert is signed for DNS names [kubeadm-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.138.0.4] -[certificates] Generated apiserver-kubelet-client certificate and key. -[certificates] Generated sa key and public key. -[certificates] Generated front-proxy-ca certificate and key. -[certificates] Generated front-proxy-client certificate and key. -[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki" -[kubeconfig] Wrote KubeConfig file to disk: "admin.conf" -[kubeconfig] Wrote KubeConfig file to disk: "kubelet.conf" -[kubeconfig] Wrote KubeConfig file to disk: "controller-manager.conf" -[kubeconfig] Wrote KubeConfig file to disk: "scheduler.conf" -[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml" -[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml" -[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml" -[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml" -[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests" -[init] This often takes around a minute; or longer if the control plane images have to be pulled. -[apiclient] All control plane components are healthy after 39.511972 seconds -[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace -[markmaster] Will mark node master as master by adding a label and a taint -[markmaster] Master master tainted and labelled with key/value: node-role.kubernetes.io/master="" -[bootstraptoken] Using token: -[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials -[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token -[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace +[preflight] Pulling images required for setting up a Kubernetes cluster +[preflight] This might take a minute or two, depending on the speed of your internet connection +[preflight] You can also perform this action in beforehand using 'kubeadm config images pull' +[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" +[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" +[kubelet-start] Activating the kubelet service +[certs] Using certificateDir folder "/etc/kubernetes/pki" +[certs] Generating "etcd/ca" certificate and key +[certs] Generating "etcd/server" certificate and key +[certs] etcd/server serving cert is signed for DNS names [kubeadm-master localhost] and IPs [10.138.0.4 127.0.0.1 ::1] +[certs] Generating "etcd/healthcheck-client" certificate and key +[certs] Generating "etcd/peer" certificate and key +[certs] etcd/peer serving cert is signed for DNS names [kubeadm-master localhost] and IPs [10.138.0.4 127.0.0.1 ::1] +[certs] Generating "apiserver-etcd-client" certificate and key +[certs] Generating "ca" certificate and key +[certs] Generating "apiserver" certificate and key +[certs] apiserver serving cert is signed for DNS names [kubeadm-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.138.0.4] +[certs] Generating "apiserver-kubelet-client" certificate and key +[certs] Generating "front-proxy-ca" certificate and key +[certs] Generating "front-proxy-client" certificate and key +[certs] Generating "sa" key and public key +[kubeconfig] Using kubeconfig folder "/etc/kubernetes" +[kubeconfig] Writing "admin.conf" kubeconfig file +[kubeconfig] Writing "kubelet.conf" kubeconfig file +[kubeconfig] Writing "controller-manager.conf" kubeconfig file +[kubeconfig] Writing "scheduler.conf" kubeconfig file +[control-plane] Using manifest folder "/etc/kubernetes/manifests" +[control-plane] Creating static Pod manifest for "kube-apiserver" +[control-plane] Creating static Pod manifest for "kube-controller-manager" +[control-plane] Creating static Pod manifest for "kube-scheduler" +[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests" +[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s +[apiclient] All control plane components are healthy after 31.501735 seconds +[uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace +[kubelet] Creating a ConfigMap "kubelet-config-X.Y" in namespace kube-system with the configuration for the kubelets in the cluster +[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "kubeadm-master" as an annotation +[mark-control-plane] Marking the node kubeadm-master as control-plane by adding the label "node-role.kubernetes.io/master=''" +[mark-control-plane] Marking the node kubeadm-master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule] +[bootstrap-token] Using token: +[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles +[bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials +[bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token +[bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster +[bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace [addons] Applied essential addon: CoreDNS [addons] Applied essential addon: kube-proxy Your Kubernetes master has initialized successfully! -To start using your cluster, you need to run (as a regular user): +To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. -Run "kubectl apply -f [podnetwork].yaml" with one of the addon options listed at: - http://kubernetes.io/docs/admin/addons/ +Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: + https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of machines by running the following on each node as root: - kubeadm join --token : --discovery-token-ca-cert-hash sha256: + kubeadm join : --token --discovery-token-ca-cert-hash sha256: ``` To make kubectl work for your non-root user, run these commands, which are @@ -264,7 +281,7 @@ Please select one of the tabs to see installation instructions for the respectiv {{% tab name="Calico" %}} For more information about using Calico, see [Quickstart for Calico on Kubernetes](https://docs.projectcalico.org/latest/getting-started/kubernetes/), [Installing Calico for policy and networking](https://docs.projectcalico.org/latest/getting-started/kubernetes/installation/calico), and other related resources. -For Calico to work correctly, you need to pass `--pod-network-cidr=192.168.0.0/16` to `kubeadm init` or update the `calico.yml` file to match your Pod network. Note that Calico works on `amd64` only. +For Calico to work correctly, you need to pass `--pod-network-cidr=192.168.0.0/16` to `kubeadm init` or update the `calico.yml` file to match your Pod network. Note that Calico works on `amd64`, `arm64`, and `ppc64le` only. ```shell kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml @@ -285,31 +302,30 @@ kubectl apply -f https://docs.projectcalico.org/v3.3/getting-started/kubernetes/ {{% /tab %}} {{% tab name="Cilium" %}} -For more information about using Cilium with Kubernetes, see [Quickstart for Cilium on Kubernetes](http://docs.cilium.io/en/v1.2/kubernetes/quickinstall/) and [Kubernetes Install guide for Cilium](http://docs.cilium.io/en/v1.2/kubernetes/install/). - -Passing `--pod-network-cidr` option to `kubeadm init` is not required, but highly recommended. +For more information about using Cilium with Kubernetes, see [Kubernetes Install guide for Cilium](https://docs.cilium.io/en/stable/kubernetes/). These commands will deploy Cilium with its own etcd managed by etcd operator. +_Note_: If you are running kubeadm in a single node please untaint it so that +etcd-operator pods can be scheduled in the control-plane node. + ```shell -# Download required manifests from Cilium repository -wget https://github.com/cilium/cilium/archive/v1.2.0.zip -unzip v1.2.0.zip -cd cilium-1.2.0/examples/kubernetes/addons/etcd-operator - -# Generate and deploy etcd certificates -export CLUSTER_DOMAIN=$(kubectl get ConfigMap --namespace kube-system coredns -o yaml | awk '/kubernetes/ {print $2}') -tls/certs/gen-cert.sh $CLUSTER_DOMAIN -tls/deploy-certs.sh - -# Label kube-dns with fixed identity label -kubectl label -n kube-system pod $(kubectl -n kube-system get pods -l k8s-app=kube-dns -o jsonpath='{range .items[]}{.metadata.name}{" "}{end}') io.cilium.fixed-identity=kube-dns - -kubectl create -f ./ - -# Wait several minutes for Cilium, coredns and etcd pods to converge to a working state +kubectl taint nodes node-role.kubernetes.io/master:NoSchedule- ``` +To deploy Cilium you just need to run: + +```shell +kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.4/examples/kubernetes/1.13/cilium.yaml +``` + +Once all Cilium pods are marked as `READY`, you start using your cluster. + +```shell +$ kubectl get pods -n kube-system --selector=k8s-app=cilium +NAME READY STATUS RESTARTS AGE +cilium-drxkl 1/1 Running 0 18m +``` {{% /tab %}} {{% tab name="Flannel" %}} @@ -320,10 +336,11 @@ Set `/proc/sys/net/bridge/bridge-nf-call-iptables` to `1` by running `sysctl net to pass bridged IPv4 traffic to iptables' chains. This is a requirement for some CNI plugins to work, for more information please see [here](https://kubernetes.io/docs/concepts/cluster-administration/network-plugins/#network-plugin-requirements). -Note that `flannel` works on `amd64`, `arm`, `arm64` and `ppc64le`. +Note that `flannel` works on `amd64`, `arm`, `arm64`, `ppc64le` and `s390x` under Linux. +Windows (`amd64`) is claimed as supported in v0.11.0 but the usage is undocumented. ```shell -kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml +kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml ``` For more information about `flannel`, see [the CoreOS flannel repository on GitHub @@ -381,6 +398,16 @@ There are multiple, flexible ways to install JuniperContrail/TungstenFabric CNI. Kindly refer to this quickstart: [TungstenFabric](https://tungstenfabric.github.io/website/) {{% /tab %}} + +{{% tab name="Contiv-VPP" %}} +[Contiv-VPP](https://contivpp.io/) employs a programmable CNF vSwitch based on [FD.io VPP](https://fd.io/), +offering feature-rich & high-performance cloud-native networking and services. + +It implements k8s services and network policies in the user space (on VPP). + +Please refer to this installation guide: [Contiv-VPP Manual Installation](https://github.com/contiv/vpp/blob/master/docs/setup/MANUAL_INSTALL.md) +{{% /tab %}} + {{< /tabs >}} @@ -545,6 +572,18 @@ Then, on the node being removed, reset all kubeadm installed state: kubeadm reset ``` +The reset process does not reset or clean up iptables rules or IPVS tables. If you wish to reset iptables, you must do so manually: + +```bash +iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X +``` + +If you want to reset the IPVS tables, you must run the following command: + +```bash +ipvsadm -C +``` + If you wish to start over simply run `kubeadm init` or `kubeadm join` with the appropriate arguments. @@ -589,8 +628,10 @@ Due to that we can't see into the future, kubeadm CLI vX.Y may or may not be abl Example: kubeadm v1.8 can deploy both v1.7 and v1.8 clusters and upgrade v1.7 kubeadm-created clusters to v1.8. -Please also check our [installation guide](/docs/setup/independent/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl) -for more information on the version skew between kubelets and the control plane. +These resources provide more information on supported version skew between kubelets and the control plane, and other Kubernetes components: + +* Kubernetes [version and version-skew policy](/docs/setup/version-skew-policy/) +* Kubeadm-specific [installation guide](/docs/setup/independent/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl) ## kubeadm works on multiple platforms {#multi-platform} diff --git a/content/en/docs/setup/independent/high-availability.md b/content/en/docs/setup/independent/high-availability.md index b43bb3377b..1ae27f0236 100644 --- a/content/en/docs/setup/independent/high-availability.md +++ b/content/en/docs/setup/independent/high-availability.md @@ -16,7 +16,7 @@ and control plane nodes are co-located. - With an external etcd cluster. This approach requires more infrastructure. The control plane nodes and etcd members are separated. -Before proceeding, you should carefully consideer which approach best meets the needs of your applications +Before proceeding, you should carefully consider which approach best meets the needs of your applications and environment. [This comparison topic](/docs/setup/independent/ha-topology/) outlines the advantages and disadvantages of each. Your clusters must run Kubernetes version 1.12 or later. You should also be aware that @@ -27,7 +27,7 @@ We encourage you to try either approach, and provide us with feedback in the kub Note that the alpha feature gate `HighAvailability` is deprecated in v1.12 and removed in v1.13. -See also [The HA upgrade documentation](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha). +See also [The HA upgrade documentation](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-13). {{< caution >}} This page does not address running your cluster on a cloud provider. In a cloud @@ -69,12 +69,12 @@ networking provider, make sure to replace any default values as needed. ## First steps for both methods {{< note >}} -**Note**: All commands on any control plane or etcd node should be +All commands on any control plane or etcd node should be run as root. {{< /note >}} - Some CNI network plugins like Calico require a CIDR such as `192.168.0.0/16` and - some like Weave do not. See the see [the CNI network + some like Weave do not. See the [CNI network documentation](/docs/setup/independent/create-cluster-kubeadm/#pod-network). To add a pod CIDR set the `podSubnet: 192.168.0.0/16` field under the `networking` object of `ClusterConfiguration`. @@ -223,6 +223,12 @@ SSH is required if you want to control all nodes from a single machine. done ``` +{{< caution >}} +Copy only the certificates in the above list. kubeadm will take care of generating the rest of the certificates +with the required SANs for the joining control-plane instances. If you copy all the certificates by mistake, +the creation of additional nodes could fail due to a lack of required SANs. +{{< /caution >}} + ### Steps for the rest of the control plane nodes 1. Move the files created by the previous step where `scp` was used: diff --git a/content/en/docs/setup/independent/install-kubeadm.md b/content/en/docs/setup/independent/install-kubeadm.md index cbf1c8ebb4..16570b2a36 100644 --- a/content/en/docs/setup/independent/install-kubeadm.md +++ b/content/en/docs/setup/independent/install-kubeadm.md @@ -2,6 +2,10 @@ title: Installing kubeadm content_template: templates/task weight: 20 +card: + name: setup + weight: 20 + title: Install the kubeadm setup tool --- {{% capture overview %}} @@ -90,7 +94,6 @@ Other CRI-based runtimes include: - [containerd](https://github.com/containerd/cri) (CRI plugin built into containerd) - [cri-o](https://github.com/kubernetes-incubator/cri-o) - [frakti](https://github.com/kubernetes/frakti) -- [rkt](https://github.com/kubernetes-incubator/rktlet) Refer to the [CRI installation instructions](/docs/setup/cri) for more information. @@ -106,7 +109,7 @@ You will install these packages on all of your machines: * `kubectl`: the command line util to talk to your cluster. kubeadm **will not** install or manage `kubelet` or `kubectl` for you, so you will -need to ensure they match the version of the Kubernetes control panel you want +need to ensure they match the version of the Kubernetes control plane you want kubeadm to install for you. If you do not, there is a risk of a version skew occurring that can lead to unexpected, buggy behaviour. However, _one_ minor version skew between the kubelet and the control plane is supported, but the kubelet version may never exceed the API @@ -119,8 +122,10 @@ This is because kubeadm and Kubernetes require [special attention to upgrade](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-11/). {{}} -For more information on version skews, please read our -[version skew policy](/docs/setup/independent/create-cluster-kubeadm/#version-skew-policy). +For more information on version skews, see: + +* Kubernetes [version and version-skew policy](/docs/setup/version-skew-policy/) +* Kubeadm-specific [version skew policy](/docs/setup/independent/create-cluster-kubeadm/#version-skew-policy) {{< tabs name="k8s_install" >}} {{% tab name="Ubuntu, Debian or HypriotOS" %}} @@ -154,7 +159,7 @@ sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes -systemctl enable kubelet && systemctl start kubelet +systemctl enable --now kubelet ``` **Note:** @@ -172,6 +177,7 @@ systemctl enable kubelet && systemctl start kubelet EOF sysctl --system ``` + - Make sure that the `br_netfilter` module is loaded before this step. This can be done by running `lsmod | grep br_netfilter`. To load it explicitly call `modprobe br_netfilter`. {{% /tab %}} {{% tab name="Container Linux" %}} Install CNI plugins (required for most pod network): @@ -208,7 +214,7 @@ curl -sSL "https://raw.githubusercontent.com/kubernetes/kubernetes/${RELEASE}/bu Enable and start `kubelet`: ```bash -systemctl enable kubelet && systemctl start kubelet +systemctl enable --now kubelet ``` {{% /tab %}} {{< /tabs >}} diff --git a/content/en/docs/setup/independent/kubelet-integration.md b/content/en/docs/setup/independent/kubelet-integration.md index 6825c135af..d5cc7d3132 100644 --- a/content/en/docs/setup/independent/kubelet-integration.md +++ b/content/en/docs/setup/independent/kubelet-integration.md @@ -184,7 +184,7 @@ This file specifies the default locations for all of the files managed by kubead - The file containing the kubelet's ComponentConfig is `/var/lib/kubelet/config.yaml`. - The dynamic environment file that contains `KUBELET_KUBEADM_ARGS` is sourced from `/var/lib/kubelet/kubeadm-flags.env`. - The file that can contain user-specified flag overrides with `KUBELET_EXTRA_ARGS` is sourced from - `/etc/default/kubelet` (for DEBs), or `/etc/systconfig/kubelet` (for RPMs). `KUBELET_EXTRA_ARGS` + `/etc/default/kubelet` (for DEBs), or `/etc/sysconfig/kubelet` (for RPMs). `KUBELET_EXTRA_ARGS` is last in the flag chain and has the highest priority in the event of conflicting settings. ## Kubernetes binaries and package contents @@ -193,10 +193,10 @@ The DEB and RPM packages shipped with the Kubernetes releases are: | Package name | Description | |--------------|-------------| -| `kubeadm` | Installs the `/usr/bin/kubeadm` CLI tool and [The kubelet drop-in file(#the-kubelet-drop-in-file-for-systemd) for the kubelet. | +| `kubeadm` | Installs the `/usr/bin/kubeadm` CLI tool and the [kubelet drop-in file](#the-kubelet-drop-in-file-for-systemd) for the kubelet. | | `kubelet` | Installs the `/usr/bin/kubelet` binary. | | `kubectl` | Installs the `/usr/bin/kubectl` binary. | | `kubernetes-cni` | Installs the official CNI binaries into the `/opt/cni/bin` directory. | -| `cri-tools` | Installs the `/usr/bin/crictl` binary from [https://github.com/kubernetes-incubator/cri-tools](https://github.com/kubernetes-incubator/cri-tools). | +| `cri-tools` | Installs the `/usr/bin/crictl` binary from the [cri-tools git repository](https://github.com/kubernetes-incubator/cri-tools). | {{% /capture %}} diff --git a/content/en/docs/setup/independent/setup-ha-etcd-with-kubeadm.md b/content/en/docs/setup/independent/setup-ha-etcd-with-kubeadm.md index 1567bf0dda..d0a85cdb3c 100644 --- a/content/en/docs/setup/independent/setup-ha-etcd-with-kubeadm.md +++ b/content/en/docs/setup/independent/setup-ha-etcd-with-kubeadm.md @@ -46,9 +46,8 @@ this example. 1. Configure the kubelet to be a service manager for etcd. - Running etcd is simpler than running kubernetes so you must override the - kubeadm-provided kubelet unit file by creating a new one with a higher - precedence. + Since etcd was created first, you must override the service priority by creating a new unit file + that has higher precedence than the kubeadm-provided kubelet unit file. ```sh cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf @@ -92,7 +91,7 @@ this example. peerCertSANs: - "${HOST}" extraArgs: - initial-cluster: infra0=https://${ETCDHOSTS[0]}:2380,infra1=https://${ETCDHOSTS[1]}:2380,infra2=https://${ETCDHOSTS[2]}:2380 + initial-cluster: ${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380,${NAMES[2]}=https://${ETCDHOSTS[2]}:2380 initial-cluster-state: new name: ${NAME} listen-peer-urls: https://${HOST}:2380 @@ -258,7 +257,7 @@ this example. {{% capture whatsnext %}} -Once your have a working 3 member etcd cluster, you can continue setting up a +Once you have a working 3 member etcd cluster, you can continue setting up a highly available control plane using the [external etcd method with kubeadm](/docs/setup/independent/high-availability/). diff --git a/content/en/docs/setup/independent/troubleshooting-kubeadm.md b/content/en/docs/setup/independent/troubleshooting-kubeadm.md index b3a9e6fba3..359ce55b74 100644 --- a/content/en/docs/setup/independent/troubleshooting-kubeadm.md +++ b/content/en/docs/setup/independent/troubleshooting-kubeadm.md @@ -56,7 +56,7 @@ This may be caused by a number of problems. The most common are: ``` There are two common ways to fix the cgroup driver problem: - + 1. Install Docker again following instructions [here](/docs/setup/independent/install-kubeadm/#installing-docker). 1. Change the kubelet config to match the Docker cgroup driver manually, you can refer to @@ -100,9 +100,8 @@ Right after `kubeadm init` there should not be any pods in these states. until you have deployed the network solution. - If you see Pods in the `RunContainerError`, `CrashLoopBackOff` or `Error` state after deploying the network solution and nothing happens to `coredns` (or `kube-dns`), - it's very likely that the Pod Network solution and nothing happens to the DNS server, it's very - likely that the Pod Network solution that you installed is somehow broken. You - might have to grant it more RBAC privileges or use a newer version. Please file + it's very likely that the Pod Network solution that you installed is somehow broken. + You might have to grant it more RBAC privileges or use a newer version. Please file an issue in the Pod Network providers' issue tracker and get the issue triaged there. - If you install a version of Docker older than 1.12.1, remove the `MountFlags=slave` option when booting `dockerd` with `systemd` and restart `docker`. You can see the MountFlags in `/usr/lib/systemd/system/docker.service`. @@ -155,6 +154,18 @@ Unable to connect to the server: x509: certificate signed by unknown authority ( regenerate a certificate if necessary. The certificates in a kubeconfig file are base64 encoded. The `base64 -d` command can be used to decode the certificate and `openssl x509 -text -noout` can be used for viewing the certificate information. +- Unset the `KUBECONFIG` environment variable using: + + ```sh + unset KUBECONFIG + ``` + + Or set it to the default `KUBECONFIG` location: + + ```sh + export KUBECONFIG=/etc/kubernetes/admin.conf + ``` + - Another workaround is to overwrite the existing `kubeconfig` for the "admin" user: ```sh @@ -226,4 +237,47 @@ Disabling SELinux or setting `allowPrivilegeEscalation` to `true` can compromise the security of your cluster. {{< /warning >}} +## etcd pods restart continually + +If you encounter the following error: + +``` +rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:110: decoding init error from pipe caused \"read parent: connection reset by peer\"" +``` + +this issue appears if you run CentOS 7 with Docker 1.13.1.84. +This version of Docker can prevent the kubelet from executing into the etcd container. + +To work around the issue, choose one of these options: + +- Roll back to an earlier version of Docker, such as 1.13.1-75 +``` +yum downgrade docker-1.13.1-75.git8633870.el7.centos.x86_64 docker-client-1.13.1-75.git8633870.el7.centos.x86_64 docker-common-1.13.1-75.git8633870.el7.centos.x86_64 +``` + +- Install one of the more recent recommended versions, such as 18.06: +```bash +sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo +yum install docker-ce-18.06.1.ce-3.el7.x86_64 +``` + +## Not possible to pass a comma separated list of values to arguments inside a `--component-extra-args` flag + +`kubeadm init` flags such as `--component-extra-args` allow you to pass custom arguments to a control-plane +component like the kube-apiserver. However, this mechanism is limited due to the underlying type used for parsing +the values (`mapStringString`). + +If you decide to pass an argument that supports multiple, comma-separated values such as +`--apiserver-extra-args "enable-admission-plugins=LimitRanger,NamespaceExists"` this flag will fail with +`flag: malformed pair, expect string=string`. This happens because the list of arguments for +`--apiserver-extra-args` expects `key=value` pairs and in this case `NamespacesExists` is considered +as a key that is missing a value. + +Alternativelly, you can try separating the `key=value` pairs like so: +`--apiserver-extra-args "enable-admission-plugins=LimitRanger,enable-admission-plugins=NamespaceExists"` +but this will result in the key `enable-admission-plugins` only having the value of `NamespaceExists`. + +A known workaround is to use the kubeadm +[configuration file](https://kubernetes.io/docs/setup/independent/control-plane-flags/#apiserver-flags). + {{% /capture %}} diff --git a/content/en/docs/setup/minikube.md b/content/en/docs/setup/minikube.md index 7f1cc4e4b8..0a8d06fe3d 100644 --- a/content/en/docs/setup/minikube.md +++ b/content/en/docs/setup/minikube.md @@ -42,34 +42,55 @@ the following drivers: * kvm ([driver installation](https://git.k8s.io/minikube/docs/drivers.md#kvm-driver)) * hyperkit ([driver installation](https://git.k8s.io/minikube/docs/drivers.md#hyperkit-driver)) * xhyve ([driver installation](https://git.k8s.io/minikube/docs/drivers.md#xhyve-driver)) (deprecated) - +* hyperv ([driver installation](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperv-driver)) Note that the IP below is dynamic and can change. It can be retrieved with `minikube ip`. +* none (Runs the Kubernetes components on the host and not in a VM. Using this driver requires Docker ([docker install](https://docs.docker.com/install/linux/docker-ce/ubuntu/)) and a Linux environment) ```shell -$ minikube start +minikube start +``` +``` Starting local Kubernetes cluster... Running pre-create checks... Creating machine... Starting local Kubernetes cluster... - -$ kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.10 --port=8080 +``` +```shell +kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.10 --port=8080 +``` +``` deployment.apps/hello-minikube created -$ kubectl expose deployment hello-minikube --type=NodePort -service/hello-minikube exposed +``` +```shell +kubectl expose deployment hello-minikube --type=NodePort +``` +``` +service/hello-minikube exposed +``` +``` # We have now launched an echoserver pod but we have to wait until the pod is up before curling/accessing it # via the exposed service. # To check whether the pod is up and running we can use the following: -$ kubectl get pod +kubectl get pod +``` +``` NAME READY STATUS RESTARTS AGE hello-minikube-3383150820-vctvh 0/1 ContainerCreating 0 3s +``` +``` # We can see that the pod is still being created from the ContainerCreating status -$ kubectl get pod +kubectl get pod +``` +``` NAME READY STATUS RESTARTS AGE hello-minikube-3383150820-vctvh 1/1 Running 0 13s +``` +``` # We can see that the pod is now Running and we will now be able to curl it: -$ curl $(minikube service hello-minikube --url) - +curl $(minikube service hello-minikube --url) +``` +``` Hostname: hello-minikube-7c77b68cff-8wdzq @@ -95,13 +116,26 @@ Request Headers: Request Body: -no body in request- +``` - -$ kubectl delete services hello-minikube +```shell +kubectl delete services hello-minikube +``` +``` service "hello-minikube" deleted -$ kubectl delete deployment hello-minikube +``` + +```shell +kubectl delete deployment hello-minikube +``` +``` deployment.extensions "hello-minikube" deleted -$ minikube stop +``` + +```shell +minikube stop +``` +``` Stopping local Kubernetes cluster... Stopping "minikube"... ``` @@ -113,8 +147,9 @@ Stopping "minikube"... To use [containerd](https://github.com/containerd/containerd) as the container runtime, run: ```bash -$ minikube start \ +minikube start \ --network-plugin=cni \ + --enable-default-cni \ --container-runtime=containerd \ --bootstrapper=kubeadm ``` @@ -122,8 +157,9 @@ $ minikube start \ Or you can use the extended version: ```bash -$ minikube start \ +minikube start \ --network-plugin=cni \ + --enable-default-cni \ --extra-config=kubelet.container-runtime=remote \ --extra-config=kubelet.container-runtime-endpoint=unix:///run/containerd/containerd.sock \ --extra-config=kubelet.image-service-endpoint=unix:///run/containerd/containerd.sock \ @@ -135,8 +171,9 @@ $ minikube start \ To use [CRI-O](https://github.com/kubernetes-incubator/cri-o) as the container runtime, run: ```bash -$ minikube start \ +minikube start \ --network-plugin=cni \ + --enable-default-cni \ --container-runtime=cri-o \ --bootstrapper=kubeadm ``` @@ -144,8 +181,9 @@ $ minikube start \ Or you can use the extended version: ```bash -$ minikube start \ +minikube start \ --network-plugin=cni \ + --enable-default-cni \ --extra-config=kubelet.container-runtime=remote \ --extra-config=kubelet.container-runtime-endpoint=/var/run/crio.sock \ --extra-config=kubelet.image-service-endpoint=/var/run/crio.sock \ @@ -157,8 +195,9 @@ $ minikube start \ To use [rkt](https://github.com/rkt/rkt) as the container runtime run: ```shell -$ minikube start \ +minikube start \ --network-plugin=cni \ + --enable-default-cni \ --container-runtime=rkt ``` @@ -263,7 +302,7 @@ To set the `AuthorizationMode` on the `apiserver` to `RBAC`, you can use: `--ext ### Stopping a Cluster The `minikube stop` command can be used to stop your cluster. This command shuts down the Minikube Virtual Machine, but preserves all cluster state and data. -Starting the cluster again will restore it to it's previous state. +Starting the cluster again will restore it to its previous state. ### Deleting a Cluster The `minikube delete` command can be used to delete your cluster. @@ -373,7 +412,7 @@ To do this, pass the required environment variables as flags during `minikube st For example: ```shell -$ minikube start --docker-env http_proxy=http://$YOURPROXY:PORT \ +minikube start --docker-env http_proxy=http://$YOURPROXY:PORT \ --docker-env https_proxy=https://$YOURPROXY:PORT ``` @@ -381,7 +420,7 @@ If your Virtual Machine address is 192.168.99.100, then chances are your proxy s To by-pass proxy configuration for this IP address, you should modify your no_proxy settings. You can do so with: ```shell -$ export no_proxy=$no_proxy,$(minikube ip) +export no_proxy=$no_proxy,$(minikube ip) ``` ## Known Issues @@ -401,12 +440,12 @@ For more information about Minikube, see the [proposal](https://git.k8s.io/commu * **Goals and Non-Goals**: For the goals and non-goals of the Minikube project, please see our [roadmap](https://git.k8s.io/minikube/docs/contributors/roadmap.md). * **Development Guide**: See [CONTRIBUTING.md](https://git.k8s.io/minikube/CONTRIBUTING.md) for an overview of how to send pull requests. * **Building Minikube**: For instructions on how to build/test Minikube from source, see the [build guide](https://git.k8s.io/minikube/docs/contributors/build_guide.md). -* **Adding a New Dependency**: For instructions on how to add a new dependency to Minikube see the [adding dependencies guide](https://git.k8s.io/minikube/docs/contributors/adding_a_dependency.md). -* **Adding a New Addon**: For instruction on how to add a new addon for Minikube see the [adding an addon guide](https://git.k8s.io/minikube/docs/contributors/adding_an_addon.md). -* **Updating Kubernetes**: For instructions on how to update Kubernetes see the [updating Kubernetes guide](https://git.k8s.io/minikube/docs/contributors/updating_kubernetes.md). +* **Adding a New Dependency**: For instructions on how to add a new dependency to Minikube, see the [adding dependencies guide](https://git.k8s.io/minikube/docs/contributors/adding_a_dependency.md). +* **Adding a New Addon**: For instructions on how to add a new addon for Minikube, see the [adding an addon guide](https://git.k8s.io/minikube/docs/contributors/adding_an_addon.md). +* **MicroK8s**: Linux users wishing to avoid running a virtual machine may consider [MicroK8s](https://microk8s.io/) as an alternative. ## Community Contributions, questions, and comments are all welcomed and encouraged! Minikube developers hang out on [Slack](https://kubernetes.slack.com) in the #minikube channel (get an invitation [here](http://slack.kubernetes.io/)). We also have the [kubernetes-dev Google Groups mailing list](https://groups.google.com/forum/#!forum/kubernetes-dev). If you are posting to the list please prefix your subject with "minikube: ". -{{% /capture %}} \ No newline at end of file +{{% /capture %}} diff --git a/content/en/docs/setup/multiple-zones.md b/content/en/docs/setup/multiple-zones.md index 81d4a32ded..7b1af187ac 100644 --- a/content/en/docs/setup/multiple-zones.md +++ b/content/en/docs/setup/multiple-zones.md @@ -5,8 +5,17 @@ reviewers: - quinton-hoole title: Running in Multiple Zones weight: 90 +content_template: templates/concept --- +{{% capture overview %}} + +This page describes how to run a cluster in multiple zones. + +{{% /capture %}} + +{{% capture body %}} + ## Introduction Kubernetes 1.2 adds support for running a single cluster in multiple failure zones @@ -27,8 +36,6 @@ add similar support for other clouds or even bare metal, by simply arranging for the appropriate labels to be added to nodes and volumes). -{{< toc >}} - ## Functionality When nodes are started, the kubelet automatically adds labels to them with @@ -122,14 +129,17 @@ labels are `failure-domain.beta.kubernetes.io/region` for the region, and `failure-domain.beta.kubernetes.io/zone` for the zone: ```shell -> kubectl get nodes --show-labels +kubectl get nodes --show-labels +``` +The output is similar to this: +```shell NAME STATUS ROLES AGE VERSION LABELS -kubernetes-master Ready,SchedulingDisabled 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master -kubernetes-minion-87j9 Ready 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9 -kubernetes-minion-9vlv Ready 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv -kubernetes-minion-a12q Ready 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q +kubernetes-master Ready,SchedulingDisabled 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master +kubernetes-minion-87j9 Ready 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9 +kubernetes-minion-9vlv Ready 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv +kubernetes-minion-a12q Ready 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q ``` ### Add more nodes in a second zone @@ -158,16 +168,20 @@ View the nodes again; 3 more nodes should have launched and be tagged in us-central1-b: ```shell -> kubectl get nodes --show-labels +kubectl get nodes --show-labels +``` +The output is similar to this: + +```shell NAME STATUS ROLES AGE VERSION LABELS -kubernetes-master Ready,SchedulingDisabled 16m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master -kubernetes-minion-281d Ready 2m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d -kubernetes-minion-87j9 Ready 16m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9 -kubernetes-minion-9vlv Ready 16m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv -kubernetes-minion-a12q Ready 17m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q -kubernetes-minion-pp2f Ready 2m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f -kubernetes-minion-wf8i Ready 2m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i +kubernetes-master Ready,SchedulingDisabled 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master +kubernetes-minion-281d Ready 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d +kubernetes-minion-87j9 Ready 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9 +kubernetes-minion-9vlv Ready 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv +kubernetes-minion-a12q Ready 17m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q +kubernetes-minion-pp2f Ready 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f +kubernetes-minion-wf8i Ready 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i ``` ### Volume affinity @@ -208,10 +222,15 @@ always created in the zone of the cluster master was addressed in 1.3+. {{< /note >}} -Now lets validate that Kubernetes automatically labeled the zone & region the PV was created in. +Now let's validate that Kubernetes automatically labeled the zone & region the PV was created in. + +```shell +kubectl get pv --show-labels +``` + +The output is similar to this: ```shell -> kubectl get pv --show-labels NAME CAPACITY ACCESSMODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE LABELS pv-gce-mj4gm 5Gi RWO Retain Bound default/claim1 manual 46s failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a ``` @@ -244,9 +263,20 @@ Note that the pod was automatically created in the same zone as the volume, as cross-zone attachments are not generally permitted by cloud providers: ```shell -> kubectl describe pod mypod | grep Node +kubectl describe pod mypod | grep Node +``` + +```shell Node: kubernetes-minion-9vlv/10.240.0.5 -> kubectl get node kubernetes-minion-9vlv --show-labels +``` + +And check node labels: + +```shell +kubectl get node kubernetes-minion-9vlv --show-labels +``` + +```shell NAME STATUS AGE VERSION LABELS kubernetes-minion-9vlv Ready 22m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv ``` @@ -283,16 +313,24 @@ find kubernetes/examples/guestbook-go/ -name '*.json' | xargs -I {} kubectl crea The pods should be spread across all 3 zones: ```shell -> kubectl describe pod -l app=guestbook | grep Node +kubectl describe pod -l app=guestbook | grep Node +``` + +```shell Node: kubernetes-minion-9vlv/10.240.0.5 Node: kubernetes-minion-281d/10.240.0.8 Node: kubernetes-minion-olsh/10.240.0.11 +``` - > kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels +```shell +kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels +``` + +```shell NAME STATUS ROLES AGE VERSION LABELS -kubernetes-minion-9vlv Ready 34m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv -kubernetes-minion-281d Ready 20m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d -kubernetes-minion-olsh Ready 3m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh +kubernetes-minion-9vlv Ready 34m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv +kubernetes-minion-281d Ready 20m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d +kubernetes-minion-olsh Ready 3m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh ``` @@ -300,15 +338,42 @@ Load-balancers span all zones in a cluster; the guestbook-go example includes an example load-balanced service: ```shell -> kubectl describe service guestbook | grep LoadBalancer.Ingress +kubectl describe service guestbook | grep LoadBalancer.Ingress +``` + +The output is similar to this: + +```shell LoadBalancer Ingress: 130.211.126.21 +``` -> ip=130.211.126.21 +Set the above IP: -> curl -s http://${ip}:3000/env | grep HOSTNAME +```shell +export IP=130.211.126.21 +``` + +Explore with curl via IP: + +```shell +curl -s http://${IP}:3000/env | grep HOSTNAME +``` + +The output is similar to this: + +```shell "HOSTNAME": "guestbook-44sep", +``` -> (for i in `seq 20`; do curl -s http://${ip}:3000/env | grep HOSTNAME; done) | sort | uniq +Again, explore multiple times: + +```shell +(for i in `seq 20`; do curl -s http://${IP}:3000/env | grep HOSTNAME; done) | sort | uniq +``` + +The output is similar to this: + +```shell "HOSTNAME": "guestbook-44sep", "HOSTNAME": "guestbook-hum5n", "HOSTNAME": "guestbook-ppm40", @@ -335,3 +400,5 @@ KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2c k KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2b kubernetes/cluster/kube-down.sh KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a kubernetes/cluster/kube-down.sh ``` + +{{% /capture %}} diff --git a/content/en/docs/setup/on-premises-metal/krib.md b/content/en/docs/setup/on-premises-metal/krib.md index 4438b6a7e0..4ee90777e2 100644 --- a/content/en/docs/setup/on-premises-metal/krib.md +++ b/content/en/docs/setup/on-premises-metal/krib.md @@ -8,7 +8,7 @@ author: Rob Hirschfeld (zehicle) This guide helps to install a Kubernetes cluster hosted on bare metal with [Digital Rebar Provision](https://github.com/digitalrebar/provision) using only its Content packages and *kubeadm*. -Digital Rebar Provision (DRP) is an integrated Golang DHCP, bare metal provisioning (PXE/iPXE) and workflow automation platform. While [DRP can be used to invoke](https://provision.readthedocs.io/en/tip/doc/integrations/ansible.html) [kubespray](../kubespray), it also offers a self-contained Kubernetes installation known as [KRIB (Kubernetes Rebar Integrated Bootstrap)](https://github.com/digitalrebar/provision-content/tree/master/krib). +Digital Rebar Provision (DRP) is an integrated Golang DHCP, bare metal provisioning (PXE/iPXE) and workflow automation platform. While [DRP can be used to invoke](https://provision.readthedocs.io/en/tip/doc/integrations/ansible.html) [kubespray](/docs/setup/custom-cloud/kubespray), it also offers a self-contained Kubernetes installation known as [KRIB (Kubernetes Rebar Integrated Bootstrap)](https://github.com/digitalrebar/provision-content/tree/master/krib). {{< note >}} KRIB is not a _stand-alone_ installer: Digital Rebar templates drive a standard *[kubeadm](/docs/admin/kubeadm/)* configuration that manages the Kubernetes installation with the [Digital Rebar cluster pattern](https://provision.readthedocs.io/en/tip/doc/arch/cluster.html#rs-cluster-pattern) to elect leaders _without external supervision_. @@ -92,4 +92,4 @@ When running the reset Workflow, be sure not to accidentally target your product ## Feedback * Slack Channel: [#community](https://rackn.slack.com/messages/community/) -* [GitHub Issues](https://github.com/digital/provision/issues) +* [GitHub Issues](https://github.com/digitalrebar/provision/issues) diff --git a/content/en/docs/setup/pick-right-solution.md b/content/en/docs/setup/pick-right-solution.md index a043c749a9..05df472220 100644 --- a/content/en/docs/setup/pick-right-solution.md +++ b/content/en/docs/setup/pick-right-solution.md @@ -6,6 +6,20 @@ reviewers: title: Picking the Right Solution weight: 10 content_template: templates/concept +card: + name: setup + weight: 20 + anchors: + - anchor: "#hosted-solutions" + title: Hosted Solutions + - anchor: "#turnkey-cloud-solutions" + title: Turnkey Cloud Solutions + - anchor: "#on-premises-turnkey-cloud-solutions" + title: On-Premises Solutions + - anchor: "#custom-solutions" + title: Custom Solutions + - anchor: "#local-machine-solutions" + title: Local Machine --- {{% capture overview %}} @@ -32,15 +46,28 @@ a Kubernetes cluster from scratch. ## Local-machine Solutions +### Community Supported Tools + * [Minikube](/docs/setup/minikube/) is a method for creating a local, single-node Kubernetes cluster for development and testing. Setup is completely automated and doesn't require a cloud provider account. -* [microk8s](https://microk8s.io/) provides a single command installation of the latest Kubernetes release on a local machine for development and testing. Setup is quick, fast (~30 sec) and supports many plugins including Istio with a single command. +* [Kubeadm-dind](https://github.com/kubernetes-sigs/kubeadm-dind-cluster) is a multi-node (while minikube is single-node) Kubernetes cluster which only requires a docker daemon. It uses docker-in-docker technique to spawn the Kubernetes cluster. + +### Ecosystem Tools + +* [Docker Desktop](https://www.docker.com/products/docker-desktop) is an +easy-to-install application for your Mac or Windows environment that enables you to +start coding and deploying in containers in minutes on a single-node Kubernetes +cluster. + +* [Minishift](https://docs.okd.io/latest/minishift/) installs the community version of the Kubernetes enterprise platform OpenShift for local development & testing. It offers an all-in-one VM (`minishift start`) for Windows, macOS, and Linux. The container start is based on `oc cluster up` (Linux only). You can also install [the included add-ons](https://github.com/minishift/minishift-addons/tree/master/add-ons). + +* [MicroK8s](https://microk8s.io/) provides a single command installation of the latest Kubernetes release on a local machine for development and testing. Setup is quick, fast (~30 sec) and supports many plugins including Istio with a single command. * [IBM Cloud Private-CE (Community Edition)](https://github.com/IBM/deploy-ibm-cloud-private) can use VirtualBox on your machine to deploy Kubernetes to one or more VMs for development and test scenarios. Scales to full multi-node cluster. * [IBM Cloud Private-CE (Community Edition) on Linux Containers](https://github.com/HSBawa/icp-ce-on-linux-containers) is a Terraform/Packer/BASH based Infrastructure as Code (IaC) scripts to create a seven node (1 Boot, 1 Master, 1 Management, 1 Proxy and 3 Workers) LXD cluster on Linux Host. -* [Kubeadm-dind](https://github.com/kubernetes-sigs/kubeadm-dind-cluster) is a multi-node (while minikube is single-node) Kubernetes cluster which only requires a docker daemon. It uses docker-in-docker technique to spawn the Kubernetes cluster. +* [Kind](https://kind.sigs.k8s.io/), Kubernetes IN Docker is a tool for running local Kubernetes clusters using Docker containers as "nodes". It is primarily designed for testing Kubernetes, initially targeting the conformance tests. * [Ubuntu on LXD](/docs/getting-started-guides/ubuntu/local/) supports a nine-instance deployment on localhost. @@ -54,23 +81,31 @@ a Kubernetes cluster from scratch. * [Azure Kubernetes Service](https://azure.microsoft.com/services/container-service/) offers managed Kubernetes clusters. +* [Containership Kubernetes Engine (CKE)](https://containership.io/containership-platform) intuitive Kubernetes cluster provisioning and management on GCP, Azure, AWS, Packet, and DigitalOcean. Seamless version upgrades, autoscaling, metrics, workload creation, and more. + +* [DigitalOcean Kubernetes](https://www.digitalocean.com/products/kubernetes/) offers managed Kubernetes service. + * [Giant Swarm](https://giantswarm.io/product/) offers managed Kubernetes clusters in their own datacenter, on-premises, or on public clouds. * [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) offers managed Kubernetes clusters. -* [IBM Cloud Kubernetes Service](https://console.bluemix.net/docs/containers/container_index.html) offers managed Kubernetes clusters with isolation choice, operational tools, integrated security insight into images and containers, and integration with Watson, IoT, and data. +* [IBM Cloud Kubernetes Service](https://cloud.ibm.com/docs/containers?topic=containers-container_index#container_index) offers managed Kubernetes clusters with isolation choice, operational tools, integrated security insight into images and containers, and integration with Watson, IoT, and data. * [Kubermatic](https://www.loodse.com) provides managed Kubernetes clusters for various public clouds, including AWS and Digital Ocean, as well as on-premises with OpenStack integration. * [Kublr](https://kublr.com) offers enterprise-grade secure, scalable, highly reliable Kubernetes clusters on AWS, Azure, GCP, and on-premise. It includes out-of-the-box backup and disaster recovery, multi-cluster centralized logging and monitoring, and built-in alerting. +* [KubeSail](https://kubesail.com) is an easy, free way to try Kubernetes. + * [Madcore.Ai](https://madcore.ai) is devops-focused CLI tool for deploying Kubernetes infrastructure in AWS. Master, auto-scaling group nodes with spot-instances, ingress-ssl-lego, Heapster, and Grafana. +* [Nutanix Karbon](https://www.nutanix.com/products/karbon/) is a multi-cluster, highly available Kubernetes management and operational platform that simplifies the provisioning, operations, and lifecycle management of Kubernetes. + * [OpenShift Dedicated](https://www.openshift.com/dedicated/) offers managed Kubernetes clusters powered by OpenShift. * [OpenShift Online](https://www.openshift.com/features/) provides free hosted access for Kubernetes applications. -* [Oracle Container Engine for Kubernetes](https://docs.us-phoenix-1.oraclecloud.com/Content/ContEng/Concepts/contengoverview.htm) is a fully-managed, scalable, and highly available service that you can use to deploy your containerized applications to the cloud. +* [Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE)](https://docs.us-phoenix-1.oraclecloud.com/Content/ContEng/Concepts/contengoverview.htm) is a fully-managed, scalable, and highly available service that you can use to deploy your containerized applications to the cloud. * [Platform9](https://platform9.com/products/kubernetes/) offers managed Kubernetes on-premises or on any public cloud, and provides 24/7 health monitoring and alerting. (Kube2go, a web-UI driven Kubernetes cluster deployment service Platform9 released, has been integrated to Platform9 Sandbox.) @@ -92,19 +127,25 @@ few commands. These solutions are actively developed and have active community s * [Azure](/docs/setup/turnkey/azure/) * [CenturyLink Cloud](/docs/setup/turnkey/clc/) * [Conjure-up Kubernetes with Ubuntu on AWS, Azure, Google Cloud, Oracle Cloud](/docs/getting-started-guides/ubuntu/) +* [Containership](https://containership.io/containership-platform) +* [Docker Enterprise](https://www.docker.com/products/docker-enterprise) * [Gardener](https://gardener.cloud/) +* [Giant Swarm](https://giantswarm.io) * [Google Compute Engine (GCE)](/docs/setup/turnkey/gce/) * [IBM Cloud](https://github.com/patrocinio/kubernetes-softlayer) * [Kontena Pharos](https://kontena.io/pharos/) * [Kubermatic](https://cloud.kubermatic.io) * [Kublr](https://kublr.com/) * [Madcore.Ai](https://madcore.ai/) -* [Oracle Container Engine for K8s](https://docs.us-phoenix-1.oraclecloud.com/Content/ContEng/Concepts/contengprerequisites.htm) +* [Nirmata](https://nirmata.com/) +* [Nutanix Karbon](https://www.nutanix.com/products/karbon/) +* [Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE)](https://docs.us-phoenix-1.oraclecloud.com/Content/ContEng/Concepts/contengprerequisites.htm) * [Pivotal Container Service](https://pivotal.io/platform/pivotal-container-service) -* [Giant Swarm](https://giantswarm.io) * [Rancher 2.0](https://rancher.com/docs/rancher/v2.x/en/) * [Stackpoint.io](/docs/setup/turnkey/stackpoint/) -* [Tectonic by CoreOS](https://coreos.com/tectonic) +* [Supergiant.io](https://supergiant.io/) +* [VMware Cloud PKS](https://cloud.vmware.com/vmware-cloud-pks) +* [VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) ## On-Premises turnkey cloud solutions These solutions allow you to create Kubernetes clusters on your internal, secure, cloud network with only a @@ -112,64 +153,69 @@ few commands. * [Agile Stacks](https://www.agilestacks.com/products/kubernetes) * [APPUiO](https://appuio.ch) +* [Docker Enterprise](https://www.docker.com/products/docker-enterprise) +* [Giant Swarm](https://giantswarm.io) * [GKE On-Prem | Google Cloud](https://cloud.google.com/gke-on-prem/) * [IBM Cloud Private](https://www.ibm.com/cloud-computing/products/ibm-cloud-private/) * [Kontena Pharos](https://kontena.io/pharos/) * [Kubermatic](https://www.loodse.com) -* [Kublr](https://kublr.com/) +* [Kublr](www.kublr.com/kubernetes.io/setup-hosted-solution) +* [Mirantis Cloud Platform](https://www.mirantis.com/software/kubernetes/) +* [Nirmata](https://nirmata.com/) +* [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) (OCP) by [Red Hat](https://www.redhat.com) * [Pivotal Container Service](https://pivotal.io/platform/pivotal-container-service) -* [Giant Swarm](https://giantswarm.io) * [Rancher 2.0](https://rancher.com/docs/rancher/v2.x/en/) * [SUSE CaaS Platform](https://www.suse.com/products/caas-platform) * [SUSE Cloud Application Platform](https://www.suse.com/products/cloud-application-platform/) +* [VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) + ## Custom Solutions Kubernetes can run on a wide range of Cloud providers and bare-metal environments, and with many base operating systems. -If you can find a guide below that matches your needs, use it. It may be a little out of date, but -it will be easier than starting from scratch. If you do want to start from scratch, either because you -have special requirements, or just because you want to understand what is underneath a Kubernetes -cluster, try the [Getting Started from Scratch](/docs/setup/scratch/) guide. - -If you are interested in supporting Kubernetes on a new platform, see -[Writing a Getting Started Guide](https://git.k8s.io/community/contributors/devel/writing-a-getting-started-guide.md). +If you can find a guide below that matches your needs, use it. ### Universal If you already have a way to configure hosting resources, use -[kubeadm](/docs/setup/independent/create-cluster-kubeadm/) to easily bring up a cluster +[kubeadm](/docs/setup/independent/create-cluster-kubeadm/) to bring up a cluster with a single command per machine. ### Cloud These solutions are combinations of cloud providers and operating systems not covered by the above solutions. -* [CoreOS on AWS or GCE](/docs/setup/custom-cloud/coreos/) +* [Cloud Foundry Container Runtime (CFCR)](https://docs-cfcr.cfapps.io/) * [Gardener](https://gardener.cloud/) -* [Kublr](https://kublr.com/) +* [Kublr](www.kublr.com/kubernetes.io/setup-hosted-solution) * [Kubernetes on Ubuntu](/docs/getting-started-guides/ubuntu/) * [Kubespray](/docs/setup/custom-cloud/kubespray/) * [Rancher Kubernetes Engine (RKE)](https://github.com/rancher/rke) +* [VMware Essential PKS](https://cloud.vmware.com/vmware-essential-PKS) ### On-Premises VMs -* [CloudStack](/docs/setup/on-premises-vm/cloudstack/) (uses Ansible, CoreOS and flannel) +* [Cloud Foundry Container Runtime (CFCR)](https://docs-cfcr.cfapps.io/) +* [CloudStack](/docs/setup/on-premises-vm/cloudstack/) (uses Ansible) * [Fedora (Multi Node)](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) (uses Fedora and flannel) +* [Nutanix AHV](https://www.nutanix.com/products/acropolis/virtualization/) +* [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) (OCP) Kubernetes platform by [Red Hat](https://www.redhat.com) * [oVirt](/docs/setup/on-premises-vm/ovirt/) -* [Vagrant](/docs/setup/custom-cloud/coreos/) (uses CoreOS and flannel) -* [VMware](/docs/setup/custom-cloud/coreos/) (uses CoreOS and flannel) -* [VMware vSphere](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/) +* [VMware Essential PKS](https://cloud.vmware.com/vmware-essential-PKS) +* [VMware vSphere](https://github.com/kubernetes/cloud-provider-vsphere) * [VMware vSphere, OpenStack, or Bare Metal](/docs/getting-started-guides/ubuntu/) (uses Juju, Ubuntu and flannel) ### Bare Metal -* [CoreOS](/docs/setup/custom-cloud/coreos/) * [Digital Rebar](/docs/setup/on-premises-metal/krib/) +* [Docker Enterprise](https://www.docker.com/products/docker-enterprise) * [Fedora (Single Node)](/docs/getting-started-guides/fedora/fedora_manual_config/) * [Fedora (Multi Node)](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) * [Kubernetes on Ubuntu](/docs/getting-started-guides/ubuntu/) +* [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) (OCP) Kubernetes platform by [Red Hat](https://www.redhat.com) +* [VMware Essential PKS](https://cloud.vmware.com/vmware-essential-PKS) ### Integrations @@ -187,13 +233,16 @@ IaaS Provider | Config. Mgmt. | OS | Networking | Docs -------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------------------------- any | any | multi-support | any CNI | [docs](/docs/setup/independent/create-cluster-kubeadm/) | Project ([SIG-cluster-lifecycle](https://git.k8s.io/community/sig-cluster-lifecycle)) Google Kubernetes Engine | | | GCE | [docs](https://cloud.google.com/kubernetes-engine/docs/) | Commercial +Docker Enterprise | custom | [multi-support](https://success.docker.com/article/compatibility-matrix) | [multi-support](https://docs.docker.com/ee/ucp/kubernetes/install-cni-plugin/) | [docs](https://docs.docker.com/ee/) | Commercial +IBM Cloud Private | Ansible | multi-support | multi-support | [docs](https://www.ibm.com/support/knowledgecenter/SSBS6K/product_welcome_cloud_private.html) | [Commercial](https://www.ibm.com/mysupport/s/topic/0TO500000001o0fGAA/ibm-cloud-private?language=en_US&productId=01t50000004X1PWAA0) and [Community](https://www.ibm.com/support/knowledgecenter/SSBS6K_3.1.2/troubleshoot/support_types.html) | +Red Hat OpenShift | Ansible & CoreOS | RHEL & CoreOS | [multi-support](https://docs.openshift.com/container-platform/3.11/architecture/networking/network_plugins.html) | [docs](https://docs.openshift.com/container-platform/3.11/welcome/index.html) | Commercial Stackpoint.io | | multi-support | multi-support | [docs](https://stackpoint.io/) | Commercial AppsCode.com | Saltstack | Debian | multi-support | [docs](https://appscode.com/products/cloud-deployment/) | Commercial Madcore.Ai | Jenkins DSL | Ubuntu | flannel | [docs](https://madcore.ai) | Community ([@madcore-ai](https://github.com/madcore-ai)) Platform9 | | multi-support | multi-support | [docs](https://platform9.com/managed-kubernetes/) | Commercial Kublr | custom | multi-support | multi-support | [docs](http://docs.kublr.com/) | Commercial Kubermatic | | multi-support | multi-support | [docs](http://docs.kubermatic.io/) | Commercial -IBM Cloud Kubernetes Service | | Ubuntu | IBM Cloud Networking + Calico | [docs](https://console.bluemix.net/docs/containers/) | Commercial +IBM Cloud Kubernetes Service | | Ubuntu | IBM Cloud Networking + Calico | [docs](https://cloud.ibm.com/docs/containers?topic=containers-container_index#container_index) | Commercial Giant Swarm | | CoreOS | flannel and/or Calico | [docs](https://docs.giantswarm.io/) | Commercial GCE | Saltstack | Debian | GCE | [docs](/docs/setup/turnkey/gce/) | Project Azure Kubernetes Service | | Ubuntu | Azure | [docs](https://docs.microsoft.com/en-us/azure/aks/) | Commercial @@ -203,11 +252,8 @@ Bare-metal | custom | Fedora | flannel | [docs](/docs/gettin libvirt | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal)) KVM | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | Community ([@aveshagarwal](https://github.com/aveshagarwal)) DCOS | Marathon | CoreOS/Alpine | custom | [docs](/docs/getting-started-guides/dcos/) | Community ([Kubernetes-Mesos Authors](https://github.com/mesosphere/kubernetes-mesos/blob/master/AUTHORS.md)) -AWS | CoreOS | CoreOS | flannel | [docs](/docs/setup/turnkey/aws/) | Community -GCE | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/coreos/) | Community ([@pires](https://github.com/pires)) -Vagrant | CoreOS | CoreOS | flannel | [docs](/docs/getting-started-guides/coreos/) | Community ([@pires](https://github.com/pires), [@AntonioMeireles](https://github.com/AntonioMeireles)) CloudStack | Ansible | CoreOS | flannel | [docs](/docs/getting-started-guides/cloudstack/) | Community ([@sebgoa](https://github.com/sebgoa)) -VMware vSphere | any | multi-support | multi-support | [docs](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/) | [Community](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/contactus.html) +VMware vSphere | any | multi-support | multi-support | [docs](https://github.com/kubernetes/cloud-provider-vsphere/tree/master/docs) | [Community](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/contactus.html) Bare-metal | custom | CentOS | flannel | [docs](/docs/getting-started-guides/centos/centos_manual_config/) | Community ([@coolsvap](https://github.com/coolsvap)) lxd | Juju | Ubuntu | flannel/canal | [docs](/docs/getting-started-guides/ubuntu/local/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes) AWS | Juju | Ubuntu | flannel/calico/canal | [docs](/docs/getting-started-guides/ubuntu/) | [Commercial](https://www.ubuntu.com/kubernetes) and [Community](https://jujucharms.com/kubernetes) @@ -221,15 +267,17 @@ AWS | Saltstack | Debian | AWS | [docs](/docs/setup/ AWS | kops | Debian | AWS | [docs](https://github.com/kubernetes/kops/) | Community ([@justinsb](https://github.com/justinsb)) Bare-metal | custom | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu/) | Community ([@resouer](https://github.com/resouer), [@WIZARD-CXY](https://github.com/WIZARD-CXY)) oVirt | | | | [docs](/docs/setup/on-premises-vm/ovirt/) | Community ([@simon3z](https://github.com/simon3z)) -any | any | any | any | [docs](/docs/setup/scratch/) | Community ([@erictune](https://github.com/erictune)) any | any | any | any | [docs](http://docs.projectcalico.org/v2.2/getting-started/kubernetes/installation/) | Commercial and Community any | RKE | multi-support | flannel or canal | [docs](https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/) | [Commercial](https://rancher.com/what-is-rancher/overview/) and [Community](https://github.com/rancher/rancher) any | [Gardener Cluster-Operator](https://kubernetes.io/blog/2018/05/17/gardener/) | multi-support | multi-support | [docs](https://gardener.cloud) | [Project/Community](https://github.com/gardener) and [Commercial]( https://cloudplatform.sap.com/) Alibaba Cloud Container Service For Kubernetes | ROS | CentOS | flannel/Terway | [docs](https://www.aliyun.com/product/containerservice) | Commercial Agile Stacks | Terraform | CoreOS | multi-support | [docs](https://www.agilestacks.com/products/kubernetes) | Commercial -IBM Cloud Kubernetes Service | | Ubuntu | calico | [docs](https://console.bluemix.net/docs/containers/container_index.html) | Commercial +IBM Cloud Kubernetes Service | | Ubuntu | calico | [docs](https://cloud.ibm.com/docs/containers?topic=containers-container_index#container_index) | Commercial Digital Rebar | kubeadm | any | metal | [docs](/docs/setup/on-premises-metal/krib/) | Community ([@digitalrebar](https://github.com/digitalrebar)) VMware Cloud PKS | | Photon OS | Canal | [docs](https://docs.vmware.com/en/VMware-Kubernetes-Engine/index.html) | Commercial +VMware Enterprise PKS | BOSH | Ubuntu | VMware NSX-T/flannel | [docs](https://docs.vmware.com/en/VMware-Enterprise-PKS/) | Commercial +Mirantis Cloud Platform | Salt | Ubuntu | multi-support | [docs](https://docs.mirantis.com/mcp/) | Commercial +IAAS Provider- Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) | | | multi-support | [docs](https://docs.cloud.oracle.com/iaas/Content/ContEng/Concepts/contengoverview.htm) | Commercial {{< note >}} The above table is ordered by version test/used in nodes, followed by support level. diff --git a/content/en/docs/setup/release/building-from-source.md b/content/en/docs/setup/release/building-from-source.md index 866d3d7b23..ada3b68970 100644 --- a/content/en/docs/setup/release/building-from-source.md +++ b/content/en/docs/setup/release/building-from-source.md @@ -2,13 +2,20 @@ reviewers: - david-mcmahon - jbeda -title: Building from Source +title: Building a release +content_template: templates/concept +card: + name: download + weight: 20 + title: Building a release --- - +{{% capture overview %}} You can either build a release from source or download a pre-built release. If you do not plan on developing Kubernetes itself, we suggest using a pre-built version of the current release, which can be found in the [Release Notes](/docs/setup/release/notes/). The Kubernetes source code can be downloaded from the [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) repo. +{{% /capture %}} +{{% capture body %}} ## Building from source If you are simply building a release from source there is no need to set up a full golang environment as all building happens in a Docker container. @@ -22,3 +29,5 @@ make release ``` For more details on the release process see the kubernetes/kubernetes [`build`](http://releases.k8s.io/{{< param "githubbranch" >}}/build/) directory. + +{{% /capture %}} diff --git a/content/en/docs/setup/release/notes.md b/content/en/docs/setup/release/notes.md index 6663698f44..c024e44135 100644 --- a/content/en/docs/setup/release/notes.md +++ b/content/en/docs/setup/release/notes.md @@ -1,115 +1,16 @@ --- title: v1.13 Release Notes +card: + name: download + weight: 10 + anchors: + - anchor: "#" + title: Current Release Notes + - anchor: "#urgent-upgrade-notes" + title: Urgent Upgrade Notes --- - - -- [v1.13.0](#v1130) - - [Downloads for v1.13.0](#downloads-for-v1130) - - [Client Binaries](#client-binaries) - - [Server Binaries](#server-binaries) - - [Node Binaries](#node-binaries) -- [Kubernetes 1.13 Release Notes](#kubernetes-113-release-notes) - - [Security Content](#security-content) - - [Urgent Upgrade Notes](#urgent-upgrade-notes) - - [(No, really, you MUST do this before you upgrade)](#no-really-you-must-do-this-before-you-upgrade) - - [Known Issues](#known-issues) - - [Deprecations](#deprecations) - - [Major Themes](#major-themes) - - [SIG API Machinery](#sig-api-machinery) - - [SIG Auth](#sig-auth) - - [SIG AWS](#sig-aws) - - [SIG Azure](#sig-azure) - - [SIG Big Data](#sig-big-data) - - [SIG CLI](#sig-cli) - - [SIG Cloud Provider](#sig-cloud-provider) - - [SIG Cluster Lifecycle](#sig-cluster-lifecycle) - - [SIG IBM Cloud](#sig-ibm-cloud) - - [SIG Multicluster](#sig-multicluster) - - [SIG Network](#sig-network) - - [SIG Node](#sig-node) - - [SIG Openstack](#sig-openstack) - - [SIG Scalability](#sig-scalability) - - [SIG Scheduling](#sig-scheduling) - - [SIG Service Catalog](#sig-service-catalog) - - [SIG Storage](#sig-storage) - - [SIG UI](#sig-ui) - - [SIG VMWare](#sig-vmware) - - [SIG Windows](#sig-windows) - - [New Features](#new-features) - - [Release Notes From SIGs](#release-notes-from-sigs) - - [SIG API Machinery](#sig-api-machinery-1) - - [SIG Auth](#sig-auth-1) - - [SIG Autoscaling](#sig-autoscaling) - - [SIG AWS](#sig-aws-1) - - [SIG Azure](#sig-azure-1) - - [SIG CLI](#sig-cli-1) - - [SIG Cloud Provider](#sig-cloud-provider-1) - - [SIG Cluster Lifecycle](#sig-cluster-lifecycle-1) - - [SIG GCP](#sig-gcp) - - [SIG Network](#sig-network-1) - - [SIG Node](#sig-node-1) - - [SIG OpenStack](#sig-openstack-1) - - [SIG Release](#sig-release) - - [SIG Scheduling](#sig-scheduling-1) - - [SIG Storage](#sig-storage-1) - - [SIG Windows](#sig-windows-1) - - [External Dependencies](#external-dependencies) -- [v1.13.0-rc.2](#v1130-rc2) - - [Downloads for v1.13.0-rc.2](#downloads-for-v1130-rc2) - - [Client Binaries](#client-binaries-1) - - [Server Binaries](#server-binaries-1) - - [Node Binaries](#node-binaries-1) - - [Changelog since v1.13.0-rc.1](#changelog-since-v1130-rc1) - - [Other notable changes](#other-notable-changes) -- [v1.13.0-rc.1](#v1130-rc1) - - [Downloads for v1.13.0-rc.1](#downloads-for-v1130-rc1) - - [Client Binaries](#client-binaries-2) - - [Server Binaries](#server-binaries-2) - - [Node Binaries](#node-binaries-2) - - [Changelog since v1.13.0-beta.2](#changelog-since-v1130-beta2) - - [Other notable changes](#other-notable-changes-1) -- [v1.13.0-beta.2](#v1130-beta2) - - [Downloads for v1.13.0-beta.2](#downloads-for-v1130-beta2) - - [Client Binaries](#client-binaries-3) - - [Server Binaries](#server-binaries-3) - - [Node Binaries](#node-binaries-3) - - [Changelog since v1.13.0-beta.1](#changelog-since-v1130-beta1) - - [Other notable changes](#other-notable-changes-2) -- [v1.13.0-beta.1](#v1130-beta1) - - [Downloads for v1.13.0-beta.1](#downloads-for-v1130-beta1) - - [Client Binaries](#client-binaries-4) - - [Server Binaries](#server-binaries-4) - - [Node Binaries](#node-binaries-4) - - [Changelog since v1.13.0-alpha.3](#changelog-since-v1130-alpha3) - - [Action Required](#action-required) - - [Other notable changes](#other-notable-changes-3) -- [v1.13.0-alpha.3](#v1130-alpha3) - - [Downloads for v1.13.0-alpha.3](#downloads-for-v1130-alpha3) - - [Client Binaries](#client-binaries-5) - - [Server Binaries](#server-binaries-5) - - [Node Binaries](#node-binaries-5) - - [Changelog since v1.13.0-alpha.2](#changelog-since-v1130-alpha2) - - [Other notable changes](#other-notable-changes-4) -- [v1.13.0-alpha.2](#v1130-alpha2) - - [Downloads for v1.13.0-alpha.2](#downloads-for-v1130-alpha2) - - [Client Binaries](#client-binaries-6) - - [Server Binaries](#server-binaries-6) - - [Node Binaries](#node-binaries-6) - - [Changelog since v1.13.0-alpha.1](#changelog-since-v1130-alpha1) - - [Other notable changes](#other-notable-changes-5) -- [v1.13.0-alpha.1](#v1130-alpha1) - - [Downloads for v1.13.0-alpha.1](#downloads-for-v1130-alpha1) - - [Client Binaries](#client-binaries-7) - - [Server Binaries](#server-binaries-7) - - [Node Binaries](#node-binaries-7) - - [Changelog since v1.12.0](#changelog-since-v1120) - - [Action Required](#action-required-1) - - [Other notable changes](#other-notable-changes-6) - - - # v1.13.0 [Documentation](https://docs.k8s.io) diff --git a/content/en/docs/setup/turnkey/alibaba-cloud.md b/content/en/docs/setup/turnkey/alibaba-cloud.md index a15951551f..8dea9624ea 100644 --- a/content/en/docs/setup/turnkey/alibaba-cloud.md +++ b/content/en/docs/setup/turnkey/alibaba-cloud.md @@ -7,9 +7,9 @@ title: Running Kubernetes on Alibaba Cloud ## Alibaba Cloud Container Service -The [Alibaba Cloud Container Service](https://www.aliyun.com/product/containerservice) lets you run and manage Docker applications on a cluster of Alibaba Cloud ECS instances. It supports the popular open source container orchestrators: Docker Swarm and Kubernetes. +The [Alibaba Cloud Container Service](https://www.alibabacloud.com/product/container-service) lets you run and manage Docker applications on a cluster of Alibaba Cloud ECS instances. It supports the popular open source container orchestrators: Docker Swarm and Kubernetes. -To simplify cluster deployment and management, use [Kubernetes Support for Alibaba Cloud Container Service](https://www.aliyun.com/solution/kubernetes/). You can get started quickly by following the [Kubernetes walk-through](https://help.aliyun.com/document_detail/53751.html), and there are some [tutorials for Kubernetes Support on Alibaba Cloud](https://yq.aliyun.com/teams/11/type_blog-cid_200-page_1) in Chinese. +To simplify cluster deployment and management, use [Kubernetes Support for Alibaba Cloud Container Service](https://www.alibabacloud.com/product/kubernetes). You can get started quickly by following the [Kubernetes walk-through](https://www.alibabacloud.com/help/doc-detail/86737.htm), and there are some [tutorials for Kubernetes Support on Alibaba Cloud](https://yq.aliyun.com/teams/11/type_blog-cid_200-page_1) in Chinese. To use custom binaries or open source Kubernetes, follow the instructions below. diff --git a/content/en/docs/setup/turnkey/azure.md b/content/en/docs/setup/turnkey/azure.md index 028bab47b7..eccbbca75b 100644 --- a/content/en/docs/setup/turnkey/azure.md +++ b/content/en/docs/setup/turnkey/azure.md @@ -14,20 +14,18 @@ For an example of deploying a Kubernetes cluster onto Azure via the Azure Kubern **[Microsoft Azure Kubernetes Service](https://docs.microsoft.com/en-us/azure/aks/intro-kubernetes)** -## Custom Deployments: ACS-Engine +## Custom Deployments: AKS-Engine The core of the Azure Kubernetes Service is **open source** and available on GitHub for the community -to use and contribute to: **[ACS-Engine](https://github.com/Azure/acs-engine)**. +to use and contribute to: **[AKS-Engine](https://github.com/Azure/aks-engine)**. The legacy [ACS-Engine](https://github.com/Azure/acs-engine) codebase has been deprecated in favor of AKS-engine. -ACS-Engine is a good choice if you need to make customizations to the deployment beyond what the Azure Kubernetes +AKS-Engine is a good choice if you need to make customizations to the deployment beyond what the Azure Kubernetes Service officially supports. These customizations include deploying into existing virtual networks, utilizing multiple -agent pools, and more. Some community contributions to ACS-Engine may even become features of the Azure Kubernetes Service. +agent pools, and more. Some community contributions to AKS-Engine may even become features of the Azure Kubernetes Service. -The input to ACS-Engine is similar to the ARM template syntax used to deploy a cluster directly with the Azure Kubernetes Service. -The resulting output is an Azure Resource Manager Template that can then be checked into source control and can then be used -to deploy Kubernetes clusters into Azure. +The input to AKS-Engine is an apimodel JSON file describing the Kubernetes cluster. It is similar to the Azure Resource Manager (ARM) template syntax used to deploy a cluster directly with the Azure Kubernetes Service. The resulting output is an ARM template that can be checked into source control and used to deploy Kubernetes clusters to Azure. -You can get started quickly by following the **[ACS-Engine Kubernetes Walkthrough](https://github.com/Azure/acs-engine/blob/master/docs/kubernetes.md)**. +You can get started by following the **[AKS-Engine Kubernetes Tutorial](https://github.com/Azure/aks-engine/blob/master/docs/tutorials/README.md)**. ## CoreOS Tectonic for Azure diff --git a/content/en/docs/setup/turnkey/clc.md b/content/en/docs/setup/turnkey/clc.md index 463787e4c3..c7ff3d997e 100644 --- a/content/en/docs/setup/turnkey/clc.md +++ b/content/en/docs/setup/turnkey/clc.md @@ -288,7 +288,7 @@ Various configuration files are written into the home directory *CLC_CLUSTER_HOM to access the cluster from machines other than where you created the cluster from. * ```config/```: Ansible variable files containing parameters describing the master and minion hosts -* ```hosts/```: hosts files listing access information for the ansible playbooks +* ```hosts/```: hosts files listing access information for the Ansible playbooks * ```kube/```: ```kubectl``` configuration files, and the basic-authentication password for admin access to the Kubernetes API * ```pki/```: public key infrastructure files enabling TLS communication in the cluster * ```ssh/```: SSH keys for root access to the hosts diff --git a/content/en/docs/setup/turnkey/gce.md b/content/en/docs/setup/turnkey/gce.md index 752a8785c0..1ed6551a60 100644 --- a/content/en/docs/setup/turnkey/gce.md +++ b/content/en/docs/setup/turnkey/gce.md @@ -10,7 +10,7 @@ content_template: templates/task {{% capture overview %}} -The example below creates a Kubernetes cluster with 4 worker node Virtual Machines and a master Virtual Machine (i.e. 5 VMs in your cluster). This cluster is set up and controlled from your workstation (or wherever you find convenient). +The example below creates a Kubernetes cluster with 3 worker node Virtual Machines and a master Virtual Machine (i.e. 4 VMs in your cluster). This cluster is set up and controlled from your workstation (or wherever you find convenient). {{% /capture %}} @@ -166,7 +166,7 @@ Likewise, the `kube-up.sh` in the same directory will bring it back up. You do n ## Customizing The script above relies on Google Storage to stage the Kubernetes release. It -then will start (by default) a single master VM along with 4 worker VMs. You +then will start (by default) a single master VM along with 3 worker VMs. You can tweak some of these parameters by editing `kubernetes/cluster/gce/config-default.sh` You can view a transcript of a successful cluster creation [here](https://gist.github.com/satnam6502/fc689d1b46db9772adea). diff --git a/content/en/docs/setup/turnkey/icp.md b/content/en/docs/setup/turnkey/icp.md new file mode 100644 index 0000000000..df2c835b2a --- /dev/null +++ b/content/en/docs/setup/turnkey/icp.md @@ -0,0 +1,69 @@ +--- +reviewers: +- bradtopol +title: Running Kubernetes on Multiple Clouds with IBM Cloud Private +--- + +IBM® Cloud Private is a turnkey cloud solution and an on-premises turnkey cloud solution. IBM Cloud Private delivers pure upstream Kubernetes with the typical management components that are required to run real enterprise workloads. These workloads include health management, log management, audit trails, and metering for tracking usage of workloads on the platform. + +IBM Cloud Private is available in a community edition and a fully supported enterprise edition. The community edition is available at no charge from [Docker Hub](https://hub.docker.com/r/ibmcom/icp-inception/). The enterprise edition supports high availability topologies and includes commercial support from IBM for Kubernetes and the IBM Cloud Private management platform. If you want to try IBM Cloud Private, you can use either the hosted trial, the tutorial, or the self-guided demo. You can also try the free community edition. For details, see [Get started with IBM Cloud Private](https://www.ibm.com/cloud/private/get-started). + +For more information, explore the following resources: + +* [IBM Cloud Private](https://www.ibm.com/cloud/private) +* [Reference architecture for IBM Cloud Private](https://github.com/ibm-cloud-architecture/refarch-privatecloud) +* [IBM Cloud Private documentation](https://www.ibm.com/support/knowledgecenter/SSBS6K/product_welcome_cloud_private.html) + +## IBM Cloud Private and Terraform + +The following modules are available where you can deploy IBM Cloud Private by using Terraform: + +* AWS: [Deploy IBM Cloud Private to AWS](https://github.com/ibm-cloud-architecture/terraform-icp-aws) +* Azure: [Deploy IBM Cloud Private to Azure](https://github.com/ibm-cloud-architecture/terraform-icp-azure) +* IBM Cloud: [Deploy IBM Cloud Private cluster to IBM Cloud](https://github.com/ibm-cloud-architecture/terraform-icp-ibmcloud) +* OpenStack: [Deploy IBM Cloud Private to OpenStack](https://github.com/ibm-cloud-architecture/terraform-icp-openstack) +* Terraform module: [Deploy IBM Cloud Private on any supported infrastructure vendor](https://github.com/ibm-cloud-architecture/terraform-module-icp-deploy) +* VMware: [Deploy IBM Cloud Private to VMware](https://github.com/ibm-cloud-architecture/terraform-icp-vmware) + +## IBM Cloud Private on AWS + +You can deploy an IBM Cloud Private cluster on Amazon Web Services (AWS) by using either AWS CloudFormation or Terraform. + +IBM Cloud Private has a Quick Start that automatically deploys IBM Cloud Private into a new virtual private cloud (VPC) on the AWS Cloud. A regular deployment takes about 60 minutes, and a high availability (HA) deployment takes about 75 minutes to complete. The Quick Start includes AWS CloudFormation templates and a deployment guide. + +This Quick Start is for users who want to explore application modernization and want to accelerate meeting their digital transformation goals, by using IBM Cloud Private and IBM tooling. The Quick Start helps users rapidly deploy a high availability (HA), production-grade, IBM Cloud Private reference architecture on AWS. For all of the details and the deployment guide, see the [IBM Cloud Private on AWS Quick Start](https://aws.amazon.com/quickstart/architecture/ibm-cloud-private/). + +IBM Cloud Private can also run on the AWS cloud platform by using Terraform. To deploy IBM Cloud Private in an AWS EC2 environment, see [Installing IBM Cloud Private on AWS](https://github.com/ibm-cloud-architecture/refarch-privatecloud/blob/master/Installing_ICp_on_aws.md). + +## IBM Cloud Private on Azure + +You can enable Microsoft Azure as a cloud provider for IBM Cloud Private deployment and take advantage of all the IBM Cloud Private features on the Azure public cloud. For more information, see [IBM Cloud Private on Azure](https://www.ibm.com/support/knowledgecenter/SSBS6K_3.1.2/supported_environments/azure_overview.html). + +## IBM Cloud Private on Red Hat OpenShift + +You can deploy IBM certified software containers that are running on IBM Cloud Private onto Red Hat OpenShift. + +Integration capabilities: + +* Supports Linux® 64-bit platform in offline-only installation mode +* Single-master configuration +* Integrated IBM Cloud Private cluster management console and catalog +* Integrated core platform services, such as monitoring, metering, and logging +* IBM Cloud Private uses the OpenShift image registry + +For more information see, [IBM Cloud Private on OpenShift](https://www.ibm.com/support/knowledgecenter/SSBS6K_3.1.2/supported_environments/openshift/overview.html). + +## IBM Cloud Private on VirtualBox + +To install IBM Cloud Private to a VirtualBox environment, see [Installing IBM Cloud Private on VirtualBox](https://github.com/ibm-cloud-architecture/refarch-privatecloud-virtualbox). + +## IBM Cloud Private on VMware + +You can install IBM Cloud Private on VMware with either Ubuntu or RHEL images. For details, see the following projects: + +* [Installing IBM Cloud Private with Ubuntu](https://github.com/ibm-cloud-architecture/refarch-privatecloud/blob/master/Installing_ICp_on_prem_ubuntu.md) +* [Installing IBM Cloud Private with Red Hat Enterprise](https://github.com/ibm-cloud-architecture/refarch-privatecloud/tree/master/icp-on-rhel) + +The IBM Cloud Private Hosted service automatically deploys IBM Cloud Private Hosted on your VMware vCenter Server instances. This service brings the power of microservices and containers to your VMware environment on IBM Cloud. With this service, you can extend the same familiar VMware and IBM Cloud Private operational model and tools from on-premises into the IBM Cloud. + +For more information, see [IBM Cloud Private Hosted service](https://cloud.ibm.com/docs/services/vmwaresolutions/vmonic?topic=vmware-solutions-prod_overview#ibm-cloud-private-hosted). diff --git a/content/en/docs/setup/version-skew-policy.md b/content/en/docs/setup/version-skew-policy.md new file mode 100644 index 0000000000..6903c6cf5b --- /dev/null +++ b/content/en/docs/setup/version-skew-policy.md @@ -0,0 +1,148 @@ +--- +reviewers: +- sig-api-machinery +- sig-architecture +- sig-cli +- sig-cluster-lifecycle +- sig-node +- sig-release +title: Kubernetes Version and Version Skew Support Policy +content_template: templates/concept +weight: 70 +--- + +{{% capture overview %}} +This document describes the maximum version skew supported between various Kubernetes components. +Specific cluster deployment tools may place additional restrictions on version skew. +{{% /capture %}} + +{{% capture body %}} + +## Supported versions + +Kubernetes versions are expressed as **x.y.z**, +where **x** is the major version, **y** is the minor version, and **z** is the patch version, following [Semantic Versioning](http://semver.org/) terminology. +For more information, see [Kubernetes Release Versioning](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/release/versioning.md#kubernetes-release-versioning). + +The Kubernetes project maintains release branches for the most recent three minor releases. + +Applicable fixes, including security fixes, may be backported to those three release branches, depending on severity and feasibility. +Patch releases are cut from those branches at a regular cadence, or as needed. +This decision is owned by the [patch release manager](https://github.com/kubernetes/sig-release/blob/master/release-team/role-handbooks/patch-release-manager/README.md#release-timing). +The patch release manager is a member of the [release team for each release](https://github.com/kubernetes/sig-release/tree/master/releases/). + +Minor releases occur approximately every 3 months, so each minor release branch is maintained for approximately 9 months. + +## Supported version skew + +### kube-apiserver + +In [highly-availabile (HA) clusters](https://kubernetes.io/docs/setup/independent/high-availability/), the newest and oldest `kube-apiserver` instances must be within one minor version. + +Example: + +* newest `kube-apiserver` is at **1.13** +* other `kube-apiserver` instances are supported at **1.13** and **1.12** + +### kubelet + +`kubelet` must not be newer than `kube-apiserver`, and may be up to two minor versions older. + +Example: + +* `kube-apiserver` is at **1.13** +* `kubelet` is supported at **1.13**, **1.12**, and **1.11** + +{{< note >}} +If version skew exists between `kube-apiserver` instances in an HA cluster, this narrows the allowed `kubelet` versions. +{{}} + +Example: + +* `kube-apiserver` instances are at **1.13** and **1.12** +* `kubelet` is supported at **1.12**, and **1.11** (**1.13** is not supported because that would be newer than the `kube-apiserver` instance at version **1.12**) + +### kube-controller-manager, kube-scheduler, and cloud-controller-manager + +`kube-controller-manager`, `kube-scheduler`, and `cloud-controller-manager` must not be newer than the `kube-apiserver` instances they communicate with. They are expected to match the `kube-apiserver` minor version, but may be up to one minor version older (to allow live upgrades). + +Example: + +* `kube-apiserver` is at **1.13** +* `kube-controller-manager`, `kube-scheduler`, and `cloud-controller-manager` are supported at **1.13** and **1.12** + +{{< note >}} +If version skew exists between `kube-apiserver` instances in an HA cluster, and these components can communicate with any `kube-apiserver` instance in the cluster (for example, via a load balancer), this narrows the allowed versions of these components. +{{< /note >}} + +Example: + +* `kube-apiserver` instances are at **1.13** and **1.12** +* `kube-controller-manager`, `kube-scheduler`, and `cloud-controller-manager` communicate with a load balancer that can route to any `kube-apiserver` instance +* `kube-controller-manager`, `kube-scheduler`, and `cloud-controller-manager` are supported at **1.12** (**1.13** is not supported because that would be newer than the `kube-apiserver` instance at version **1.12**) + +### kubectl + +`kubectl` is supported within one minor version (older or newer) of `kube-apiserver`. + +Example: + +* `kube-apiserver` is at **1.13** +* `kubectl` is supported at **1.14**, **1.13**, and **1.12** + +{{< note >}} +If version skew exists between `kube-apiserver` instances in an HA cluster, this narrows the supported `kubectl` versions. +{{< /note >}} + +Example: + +* `kube-apiserver` instances are at **1.13** and **1.12** +* `kubectl` is supported at **1.13** and **1.12** (other versions would be more than one minor version skewed from one of the `kube-apiserver` components) + +## Supported component upgrade order + +The supported version skew between components has implications on the order in which components must be upgraded. +This section describes the order in which components must be upgraded to transition an existing cluster from version **1.n** to version **1.(n+1)**. + +### kube-apiserver + +Pre-requisites: + +* In a single-instance cluster, the existing `kube-apiserver` instance is **1.n** +* In an HA cluster, all `kube-apiserver` instances are at **1.n** or **1.(n+1)** (this ensures maximum skew of 1 minor version between the oldest and newest `kube-apiserver` instance) +* The `kube-controller-manager`, `kube-scheduler`, and `cloud-controller-manager` instances that communicate with this server are at version **1.n** (this ensures they are not newer than the existing API server version, and are within 1 minor version of the new API server version) +* `kubelet` instances on all nodes are at version **1.n** or **1.(n-1)** (this ensures they are not newer than the existing API server version, and are within 2 minor versions of the new API server version) +* Registered admission webhooks are able to handle the data the new `kube-apiserver` instance will send them: + * `ValidatingWebhookConfiguration` and `MutatingWebhookConfiguration` objects are updated to include any new versions of REST resources added in **1.(n+1)** + * The webhooks are able to handle any new versions of REST resources that will be sent to them, and any new fields added to existing versions in **1.(n+1)** + +Upgrade `kube-apiserver` to **1.(n+1)** + +{{< note >}} +Project policies for [API deprecation](https://kubernetes.io/docs/reference/using-api/deprecation-policy/) and +[API change guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/api_changes.md) +require `kube-apiserver` to not skip minor versions when upgrading, even in single-instance clusters. +{{< /note >}} + +### kube-controller-manager, kube-scheduler, and cloud-controller-manager + +Pre-requisites: + +* The `kube-apiserver` instances these components communicate with are at **1.(n+1)** (in HA clusters in which these control plane components can communicate with any `kube-apiserver` instance in the cluster, all `kube-apiserver` instances must be upgraded before upgrading these components) + +Upgrade `kube-controller-manager`, `kube-scheduler`, and `cloud-controller-manager` to **1.(n+1)** + +### kubelet + +Pre-requisites: + +* The `kube-apiserver` instances the `kubelet` communicates with are at **1.(n+1)** + +Optionally upgrade `kubelet` instances to **1.(n+1)** (or they can be left at **1.n** or **1.(n-1)**) + +{{< warning >}} +Running a cluster with `kubelet` instances that are persistently two minor versions behind `kube-apiserver` is not recommended: + +* they must be upgraded within one minor version of `kube-apiserver` before the control plane can be upgraded +* it increases the likelihood of running `kubelet` versions older than the three maintained minor releases +{{}} diff --git a/content/en/docs/tasks/access-application-cluster/access-cluster.md b/content/en/docs/tasks/access-application-cluster/access-cluster.md index 1fcd18c10c..c7598381b2 100644 --- a/content/en/docs/tasks/access-application-cluster/access-cluster.md +++ b/content/en/docs/tasks/access-application-cluster/access-cluster.md @@ -26,7 +26,7 @@ or someone else setup the cluster and provided you with credentials and a locati Check the location and credentials that kubectl knows about with this command: ```shell -$ kubectl config view +kubectl config view ``` Many of the [examples](/docs/user-guide/kubectl-cheatsheet) provide an introduction to using @@ -56,7 +56,7 @@ locating the apiserver and authenticating. Run it like this: ```shell -$ kubectl proxy --port=8080 & +kubectl proxy --port=8080 ``` See [kubectl proxy](/docs/reference/generated/kubectl/kubectl-commands/#proxy) for more details. @@ -65,7 +65,12 @@ Then you can explore the API with curl, wget, or a browser, replacing localhost with [::1] for IPv6, like so: ```shell -$ curl http://localhost:8080/api/ +curl http://localhost:8080/api/ +``` + +The output is similar to this: + +```json { "versions": [ "v1" @@ -76,12 +81,46 @@ $ curl http://localhost:8080/api/ ### Without kubectl proxy -Use `kubectl describe secret...` to get the token for the default service account: +Use `kubectl describe secret...` to get the token for the default service account with grep/cut: ```shell -$ APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ") -$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep ^default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d " ") -$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure +APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ") +SECRET_NAME=$(kubectl get secrets | grep ^default | cut -f1 -d ' ') +TOKEN=$(kubectl describe secret $SECRET_NAME | grep -E '^token' | cut -f2 -d':' | tr -d " ") + +curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure +``` + +The output is similar to this: + +```json +{ + "kind": "APIVersions", + "versions": [ + "v1" + ], + "serverAddressByClientCIDRs": [ + { + "clientCIDR": "0.0.0.0/0", + "serverAddress": "10.0.1.149:443" + } + ] +} +``` + +Using `jsonpath`: + +```shell +APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') +SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') +TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode) + +curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure +``` + +The output is similar to this: + +```json { "kind": "APIVersions", "versions": [ @@ -160,11 +199,11 @@ at `/var/run/secrets/kubernetes.io/serviceaccount/namespace` in each container. From within a pod the recommended ways to connect to API are: - - run `kubectl proxy` in a sidecar container in the pod, or as a background + - Run `kubectl proxy` in a sidecar container in the pod, or as a background process within the container. This proxies the Kubernetes API to the localhost interface of the pod, so that other processes in any container of the pod can access it. - - use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions. + - Use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions. They handle locating and authenticating to the apiserver. [example](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go) In each case, the credentials of the pod are used to communicate securely with the apiserver. @@ -213,14 +252,18 @@ Typically, there are several services which are started on a cluster by kube-sys with the `kubectl cluster-info` command: ```shell -$ kubectl cluster-info +kubectl cluster-info +``` - Kubernetes master is running at https://104.197.5.247 - elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy - kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy - kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy - grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy - heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy +The output is similar to this: + +``` +Kubernetes master is running at https://104.197.5.247 +elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy +kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy +kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy +grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy +heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy ``` This shows the proxy-verb URL for accessing each service. @@ -252,18 +295,18 @@ The supported formats for the name segment of the URL are: * To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true` ```json - { - "cluster_name" : "kubernetes_logging", - "status" : "yellow", - "timed_out" : false, - "number_of_nodes" : 1, - "number_of_data_nodes" : 1, - "active_primary_shards" : 5, - "active_shards" : 5, - "relocating_shards" : 0, - "initializing_shards" : 0, - "unassigned_shards" : 5 - } +{ + "cluster_name" : "kubernetes_logging", + "status" : "yellow", + "timed_out" : false, + "number_of_nodes" : 1, + "number_of_data_nodes" : 1, + "active_primary_shards" : 5, + "active_shards" : 5, + "relocating_shards" : 0, + "initializing_shards" : 0, + "unassigned_shards" : 5 +} ``` ### Using web browsers to access services running on the cluster diff --git a/content/en/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md b/content/en/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md index ee4bd7a8c3..55d5c6873d 100644 --- a/content/en/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md +++ b/content/en/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md @@ -2,6 +2,9 @@ title: Configure Access to Multiple Clusters content_template: templates/task weight: 30 +card: + name: tasks + weight: 40 --- @@ -140,6 +143,14 @@ users: username: exp ``` +The `fake-ca-file`, `fake-cert-file` and `fake-key-file` above is the placeholders +for the real path of the certification files. You need change these to the real path +of certification files in your environment. + +Some times you may want to use base64 encoded data here instead of the path of the +certification files, then you need add the suffix `-data` to the keys. For example, +`certificate-authority-data`, `client-certificate-data`, `client-key-data`. + Each context is a triple (cluster, user, namespace). For example, the `dev-frontend` context says, Use the credentials of the `developer` user to access the `frontend` namespace of the `development` cluster. @@ -243,22 +254,31 @@ The preceding configuration file defines a new context named `dev-ramp-up`. See whether you have an environment variable named `KUBECONFIG`. If so, save the current value of your `KUBECONFIG` environment variable, so you can restore it later. -For example, on Linux: +For example: +### Linux ```shell export KUBECONFIG_SAVED=$KUBECONFIG ``` - +### Windows PowerShell +```shell + $Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG + ``` The `KUBECONFIG` environment variable is a list of paths to configuration files. The list is colon-delimited for Linux and Mac, and semicolon-delimited for Windows. If you have a `KUBECONFIG` environment variable, familiarize yourself with the configuration files in the list. -Temporarily append two paths to your `KUBECONFIG` environment variable. For example, on Linux: +Temporarily append two paths to your `KUBECONFIG` environment variable. For example:
+### Linux ```shell export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2 ``` +### Windows PowerShell +```shell +$Env:KUBECONFIG=("config-demo;config-demo-2") +``` In your `config-exercise` directory, enter this command: @@ -312,11 +332,16 @@ familiarize yourself with the contents of these files. If you have a `$HOME/.kube/config` file, and it's not already listed in your `KUBECONFIG` environment variable, append it to your `KUBECONFIG` environment variable now. -For example, on Linux: +For example: +### Linux ```shell export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config ``` +### Windows Powershell +```shell + $Env:KUBECONFIG=($Env:KUBECONFIG;$HOME/.kube/config) +``` View configuration information merged from all the files that are now listed in your `KUBECONFIG` environment variable. In your config-exercise directory, enter: @@ -327,11 +352,15 @@ kubectl config view ## Clean up -Return your `KUBECONFIG` environment variable to its original value. For example, on Linux: - +Return your `KUBECONFIG` environment variable to its original value. For example:
+Linux: ```shell export KUBECONFIG=$KUBECONFIG_SAVED ``` +Windows PowerShell +```shell + $Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED +``` {{% /capture %}} diff --git a/content/en/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md b/content/en/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md index 1c9e130aee..0ab9428a36 100644 --- a/content/en/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md +++ b/content/en/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md @@ -29,7 +29,7 @@ well as any provider specific details that may be necessary. When using a Service with `spec.type: LoadBalancer`, you can specify the IP ranges that are allowed to access the load balancer by using `spec.loadBalancerSourceRanges`. This field takes a list of IP CIDR ranges, which Kubernetes will use to configure firewall exceptions. - This feature is currently supported on Google Compute Engine, Google Kubernetes Engine, AWS Elastic Kubernetes Service, and Azure Kubernetes Service. This field will be ignored if the cloud provider does not support the feature. + This feature is currently supported on Google Compute Engine, Google Kubernetes Engine, AWS Elastic Kubernetes Service, Azure Kubernetes Service, and IBM Cloud Kubernetes Service. This field will be ignored if the cloud provider does not support the feature. Assuming 10.0.0.0/8 is the internal subnet. In the following example, a load balancer will be created that is only accessible to cluster internal IPs. This will not allow clients from outside of your Kubernetes cluster to access the load balancer. diff --git a/content/en/docs/tasks/access-application-cluster/connecting-frontend-backend.md b/content/en/docs/tasks/access-application-cluster/connecting-frontend-backend.md index a447e85d16..c35dd3571b 100644 --- a/content/en/docs/tasks/access-application-cluster/connecting-frontend-backend.md +++ b/content/en/docs/tasks/access-application-cluster/connecting-frontend-backend.md @@ -8,14 +8,15 @@ weight: 70 This task shows how to create a frontend and a backend microservice. The backend microservice is a hello greeter. The -frontend and backend are connected using a Kubernetes Service object. +frontend and backend are connected using a Kubernetes +{{< glossary_tooltip term_id="service" >}} object. {{% /capture %}} {{% capture objectives %}} -* Create and run a microservice using a Deployment object. +* Create and run a microservice using a {{< glossary_tooltip term_id="deployment" >}} object. * Route traffic to the backend using a frontend. * Use a Service object to connect the frontend application to the backend application. @@ -47,13 +48,13 @@ file for the backend Deployment: Create the backend Deployment: -``` +```shell kubectl create -f https://k8s.io/examples/service/access/hello.yaml ``` View information about the backend Deployment: -``` +```shell kubectl describe deployment hello ``` @@ -99,7 +100,8 @@ Events: The key to connecting a frontend to a backend is the backend Service. A Service creates a persistent IP address and DNS name entry so that the backend microservice can always be reached. A Service uses -selector labels to find the Pods that it routes traffic to. +{{< glossary_tooltip text="selectors" term_id="selector" >}} to find +the Pods that it routes traffic to. First, explore the Service configuration file: @@ -110,7 +112,7 @@ that have the labels `app: hello` and `tier: backend`. Create the `hello` Service: -``` +```shell kubectl create -f https://k8s.io/examples/service/access/hello-service.yaml ``` @@ -137,7 +139,7 @@ the Service uses the default load balancer of your cloud provider. Create the frontend Deployment and Service: -``` +```shell kubectl create -f https://k8s.io/examples/service/access/frontend.yaml ``` @@ -161,7 +163,7 @@ so that you can change the configuration more easily. Once you’ve created a Service of type LoadBalancer, you can use this command to find the external IP: -``` +```shell kubectl get service frontend --watch ``` @@ -169,16 +171,16 @@ This displays the configuration for the `frontend` Service and watches for changes. Initially, the external IP is listed as ``: ``` -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -frontend ClusterIP 10.51.252.116 80/TCP 10s +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +frontend LoadBalancer 10.51.252.116 80/TCP 10s ``` As soon as an external IP is provisioned, however, the configuration updates to include the new IP under the `EXTERNAL-IP` heading: ``` -NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -frontend ClusterIP 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +frontend LoadBalancer 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m ``` That IP can now be used to interact with the `frontend` service from outside the @@ -189,8 +191,8 @@ cluster. The frontend and backends are now connected. You can hit the endpoint by using the curl command on the external IP of your frontend Service. -``` -curl http:// +```shell +curl http://${EXTERNAL_IP} # replace this with the EXTERNAL-IP you saw earlier ``` The output shows the message generated by the backend: diff --git a/content/en/docs/tasks/access-application-cluster/create-external-load-balancer.md b/content/en/docs/tasks/access-application-cluster/create-external-load-balancer.md index 22c601d3d1..b8a5b1c352 100644 --- a/content/en/docs/tasks/access-application-cluster/create-external-load-balancer.md +++ b/content/en/docs/tasks/access-application-cluster/create-external-load-balancer.md @@ -162,7 +162,7 @@ Service Configuration file. ### Feature availability -| k8s version | Feature support | +| K8s version | Feature support | | :---------: |:-----------:| | 1.7+ | Supports the full API fields | | 1.5 - 1.6 | Supports Beta Annotations | diff --git a/content/en/docs/tasks/access-application-cluster/ingress-minikube.md b/content/en/docs/tasks/access-application-cluster/ingress-minikube.md new file mode 100644 index 0000000000..a810603f19 --- /dev/null +++ b/content/en/docs/tasks/access-application-cluster/ingress-minikube.md @@ -0,0 +1,292 @@ +--- +title: Set up Ingress on Minikube with the NGINX Ingress Controller +content_template: templates/task +weight: 100 +--- + +{{% capture overview %}} + +An [Ingress](/docs/concepts/services-networking/ingress/) is an API object that defines rules which allow external access +to services in a cluster. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers/) fulfills the rules set in the Ingress. + +{{< caution >}} +For the Ingress resource to work, the cluster **must** also have an Ingress controller running. +{{< /caution >}} + +This page shows you how to set up a simple Ingress which routes requests to Service web or web2 depending on the HTTP URI. + +{{% /capture %}} + +{{% capture prerequisites %}} + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + +{{% /capture %}} + +{{% capture steps %}} + +## Create a Minikube cluster + +1. Click **Launch Terminal** + + {{< kat-button >}} + +1. (Optional) If you installed Minikube locally, run the following command: + + ```shell + minikube start + ``` + +## Enable the Ingress controller + +1. To enable the NGINX Ingress controller, run the following command: + + ```shell + minikube addons enable ingress + ``` + +1. Verify that the NGINX Ingress controller is running + + ```shell + kubectl get pods -n kube-system + ``` + + {{< note >}}This can take up to a minute.{{< /note >}} + + Output: + + ```shell + NAME READY STATUS RESTARTS AGE + default-http-backend-59868b7dd6-xb8tq 1/1 Running 0 1m + kube-addon-manager-minikube 1/1 Running 0 3m + kube-dns-6dcb57bcc8-n4xd4 3/3 Running 0 2m + kubernetes-dashboard-5498ccf677-b8p5h 1/1 Running 0 2m + nginx-ingress-controller-5984b97644-rnkrg 1/1 Running 0 1m + storage-provisioner 1/1 Running 0 2m + ``` + +## Deploy a hello, world app + +1. Create a Deployment using the following command: + + ```shell + kubectl run web --image=gcr.io/google-samples/hello-app:1.0 --port=8080 + ``` + + Output: + + ```shell + deployment.apps/web created + ``` + +1. Expose the Deployment: + + ```shell + kubectl expose deployment web --target-port=8080 --type=NodePort + ``` + + Output: + + ```shell + service/web exposed + ``` + +1. Verify the Service is created and is available on a node port: + + ```shell + kubectl get service web + ``` + + Output: + + ```shell + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + web NodePort 10.104.133.249 8080:31637/TCP 12m + ``` + +1. Visit the service via NodePort: + + ```shell + minikube service web --url + ``` + + Output: + + ```shell + http://172.17.0.15:31637 + ``` + + {{< note >}}Katacoda environment only: at the top of the terminal panel, click the plus sign, and then click **Select port to view on Host 1**. Enter the NodePort, in this case `31637`, and then click **Display Port**.{{< /note >}} + + Output: + + ```shell + Hello, world! + Version: 1.0.0 + Hostname: web-55b8c6998d-8k564 + ``` + + You can now access the sample app via the Minikube IP address and NodePort. The next step lets you access + the app using the Ingress resource. + +## Create an Ingress resource + +The following file is an Ingress resource that sends traffic to your Service via hello-world.info. + +1. Create `example-ingress.yaml` from the following file: + + ```yaml + --- + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: example-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + spec: + rules: + - host: hello-world.info + http: + paths: + - path: /* + backend: + serviceName: web + servicePort: 8080 + ``` + +1. Create the Ingress resource by running the following command: + + ```shell + kubectl apply -f example-ingress.yaml + ``` + + Output: + + ```shell + ingress.extensions/example-ingress created + ``` + +1. Verify the IP address is set: + + ```shell + kubectl get ingress + ``` + + {{< note >}}This can take a couple of minutes.{{< /note >}} + + ```shell + NAME HOSTS ADDRESS PORTS AGE + example-ingress hello-world.info 172.17.0.15 80 38s + ``` + +1. Add the following line to the bottom of the `/etc/hosts` file. + + ``` + 172.17.0.15 hello-world.info + ``` + + This sends requests from hello-world.info to Minikube. + +1. Verify that the Ingress controller is directing traffic: + + ```shell + curl hello-world.info + ``` + + Output: + + ```shell + Hello, world! + Version: 1.0.0 + Hostname: web-55b8c6998d-8k564 + ``` + + {{< note >}}If you are running Minikube locally, you can visit hello-world.info from your browser.{{< /note >}} + +## Create Second Deployment + +1. Create a v2 Deployment using the following command: + + ```shell + kubectl run web2 --image=gcr.io/google-samples/hello-app:2.0 --port=8080 + ``` + Output: + + ```shell + deployment.apps/web2 created + ``` + +1. Expose the Deployment: + + ```shell + kubectl expose deployment web2 --target-port=8080 --type=NodePort + ``` + + Output: + + ```shell + service/web2 exposed + ``` + +## Edit Ingress + +1. Edit the existing `example-ingress.yaml` and add the following lines: + + ```yaml + - path: /v2/* + backend: + serviceName: web2 + servicePort: 8080 + ``` + +1. Apply the changes: + + ```shell + kubectl apply -f example-ingress.yaml + ``` + + Output: + ```shell + ingress.extensions/example-ingress configured + ``` + +## Test Your Ingress + +1. Access the 1st version of the Hello World app. + + ```shell + curl hello-world.info + ``` + + Output: + ```shell + Hello, world! + Version: 1.0.0 + Hostname: web-55b8c6998d-8k564 + ``` + +1. Access the 2nd version of the Hello World app. + + ```shell + curl hello-world.info/v2 + ``` + + Output: + ```shell + Hello, world! + Version: 2.0.0 + Hostname: web2-75cd47646f-t8cjk + ``` + + {{< note >}}If you are running Minikube locally, you can visit hello-world.info and hello-world.info/v2 from your browser.{{< /note >}} + +{{% /capture %}} + + +{{% capture whatsnext %}} +* Read more about [Ingress](/docs/concepts/services-networking/ingress/) +* Read more about [Ingress Controllers](/docs/concepts/services-networking/ingress-controllers/) +* Read more about [Services](/docs/concepts/services-networking/service/) + +{{% /capture %}} + diff --git a/content/en/docs/tasks/access-application-cluster/load-balance-access-application-cluster.md b/content/en/docs/tasks/access-application-cluster/load-balance-access-application-cluster.md deleted file mode 100644 index 29058660b8..0000000000 --- a/content/en/docs/tasks/access-application-cluster/load-balance-access-application-cluster.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Provide Load-Balanced Access to an Application in a Cluster -content_template: templates/tutorial -weight: 50 ---- - -{{% capture overview %}} - -This page shows how to create a Kubernetes Service object that provides -load-balanced access to an application running in a cluster. - -{{% /capture %}} - - -{{% capture prerequisites %}} - -{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - -{{% /capture %}} - - -{{% capture objectives %}} - -* Run two instances of a Hello World application -* Create a Service object -* Use the Service object to access the running application - -{{% /capture %}} - - -{{% capture lessoncontent %}} - -## Creating a Service for an application running in two pods - -1. Run a Hello World application in your cluster: - - ``` - kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080 - ``` - -1. List the pods that are running the Hello World application: - - ``` - kubectl get pods --selector="run=load-balancer-example" - ``` - - The output is similar to this: - - ``` - NAME READY STATUS RESTARTS AGE - hello-world-2189936611-8fyp0 1/1 Running 0 6m - hello-world-2189936611-9isq8 1/1 Running 0 6m - ``` - -1. Create a Service object that exposes the deployment: - - ``` - kubectl expose deployment --type=NodePort --name=example-service - ``` - - where `` is the name of your deployment. - -1. Display the IP addresses for your service: - - ``` - kubectl get services example-service - ``` - - The output shows the internal IP address and the external IP address of - your service. If the external IP address shows as ``, repeat the - command. - - {{< note >}} - If you are using Minikube, you don't get an external IP address. The - external IP address remains in the pending state. - {{< /note >}} - - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - example-service ClusterIP 10.0.0.160 8080/TCP 40s - -1. Use your Service object to access the Hello World application: - - curl :8080 - - where `` is the external IP address of your - service. - - The output is a hello message from the application: - - Hello Kubernetes! - - {{< note >}} - If you are using Minikube, enter these commands: - {{< /note >}} - - kubectl cluster-info - kubectl describe services example-service - - The output displays the IP address of your Minikube node and the NodePort - value for your service. Then enter this command to access the Hello World - application: - - curl : - - where `` us the IP address of your Minikube node, - and `` is the NodePort value for your service. - -## Using a service configuration file - -As an alternative to using `kubectl expose`, you can use a -[service configuration file](/docs/concepts/services-networking/service/) -to create a Service. - - -{{% /capture %}} - - -{{% capture whatsnext %}} - -Learn more about -[connecting applications with services](/docs/concepts/services-networking/connect-applications-service/). -{{% /capture %}} - - - diff --git a/content/en/docs/tasks/access-application-cluster/web-ui-dashboard.md b/content/en/docs/tasks/access-application-cluster/web-ui-dashboard.md index 6a4fb2fc18..e62aeca24e 100644 --- a/content/en/docs/tasks/access-application-cluster/web-ui-dashboard.md +++ b/content/en/docs/tasks/access-application-cluster/web-ui-dashboard.md @@ -6,13 +6,17 @@ reviewers: title: Web UI (Dashboard) content_template: templates/concept weight: 10 +card: + name: tasks + weight: 30 + title: Use the Web UI Dashboard --- {{% capture overview %}} -Dashboard is a web-based Kubernetes user interface. You can use Dashboard to deploy containerized applications to a Kubernetes cluster, troubleshoot your containerized application, and manage the cluster itself along with its attendant resources. You can use Dashboard to get an overview of applications running on your cluster, as well as for creating or modifying individual Kubernetes resources (such as Deployments, Jobs, DaemonSets, etc). For example, you can scale a Deployment, initiate a rolling update, restart a pod or deploy new applications using a deploy wizard. +Dashboard is a web-based Kubernetes user interface. You can use Dashboard to deploy containerized applications to a Kubernetes cluster, troubleshoot your containerized application, and manage the cluster resources. You can use Dashboard to get an overview of applications running on your cluster, as well as for creating or modifying individual Kubernetes resources (such as Deployments, Jobs, DaemonSets, etc). For example, you can scale a Deployment, initiate a rolling update, restart a pod or deploy new applications using a deploy wizard. -Dashboard also provides information on the state of Kubernetes resources in your cluster, and on any errors that may have occurred. +Dashboard also provides information on the state of Kubernetes resources in your cluster and on any errors that may have occurred. ![Kubernetes Dashboard UI](/images/docs/ui-dashboard.png) @@ -26,12 +30,16 @@ Dashboard also provides information on the state of Kubernetes resources in your The Dashboard UI is not deployed by default. To deploy it, run the following command: ``` -kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml +kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml ``` ## Accessing the Dashboard UI -There are multiple ways you can access the Dashboard UI; either by using the kubectl command-line interface, or by accessing the Kubernetes master apiserver using your web browser. +To protect your cluster data, Dashboard deploys with a minimal RBAC configuration by default. Currently, Dashboard only supports logging in with a Bearer Token. To create a token for this demo, you can follow our guide on [creating a sample user](https://github.com/kubernetes/dashboard/wiki/Creating-sample-user). + +{{< warning >}} +The sample user created in the tutorial will have administrative privileges and is for educational purposes only. +{{< /warning >}} ### Command line proxy You can access Dashboard using the kubectl command-line tool by running the following command: @@ -40,17 +48,13 @@ You can access Dashboard using the kubectl command-line tool by running the foll kubectl proxy ``` -Kubectl will handle authentication with apiserver and make Dashboard available at http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/. +Kubectl will make Dashboard available at http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/. The UI can _only_ be accessed from the machine where the command is executed. See `kubectl proxy --help` for more options. -### Master server -You may access the UI directly via the Kubernetes master apiserver. Open a browser and navigate to ``https://:/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/``, where `` is IP address or domain name of the Kubernetes -master. - -Please note, this works only if the apiserver is set up to allow authentication with username and password. This is not currently the case with some setup tools (e.g., `kubeadm`). Refer to the [authentication admin documentation](/docs/reference/access-authn-authz/authentication/) for information on how to configure authentication manually. - -If the username and password are configured but unknown to you, then use `kubectl config view` to find it. +{{< note >}} +Kubeconfig Authentication method does NOT support external identity providers or x509 certificate-based authentication. +{{< /note >}} ## Welcome view @@ -62,9 +66,7 @@ When you access Dashboard on an empty cluster, you'll see the welcome page. This Dashboard lets you create and deploy a containerized application as a Deployment and optional Service with a simple wizard. You can either manually specify application details, or upload a YAML or JSON file containing application configuration. -To access the deploy wizard from the Welcome page, click the respective button. To access the wizard at a later point in time, click the **CREATE** button in the upper right corner of any page. - -![Deploy wizard](/images/docs/ui-dashboard-deploy-simple.png) +Click the **CREATE** button in the upper right corner of any page to begin. ### Specifying application details @@ -126,9 +128,7 @@ track=stable Kubernetes supports declarative configuration. In this style, all configuration is stored in YAML or JSON configuration files using the Kubernetes [API](/docs/concepts/overview/kubernetes-api/) resource schemas. -As an alternative to specifying application details in the deploy wizard, you can define your application in YAML or JSON files, and upload the files using Dashboard: - -![Deploy wizard file upload](/images/docs/ui-dashboard-deploy-file.png) +As an alternative to specifying application details in the deploy wizard, you can define your application in YAML or JSON files, and upload the files using Dashboard. ## Using Dashboard Following sections describe views of the Kubernetes Dashboard UI; what they provide and how can they be used. @@ -139,35 +139,25 @@ When there are Kubernetes objects defined in the cluster, Dashboard shows them i Dashboard shows most Kubernetes object kinds and groups them in a few menu categories. -#### Admin -View for cluster and namespace administrators. It lists Nodes, Namespaces and Persistent Volumes and has detail views for them. Node list view contains CPU and memory usage metrics aggregated across all Nodes. The details view shows the metrics for a Node, its specification, status, allocated resources, events and pods running on the node. - -![Node detail view](/images/docs/ui-dashboard-node.png) +#### Admin Overview +For cluster and namespace administrators, Dashboard lists Nodes, Namespaces and Persistent Volumes and has detail views for them. Node list view contains CPU and memory usage metrics aggregated across all Nodes. The details view shows the metrics for a Node, its specification, status, allocated resources, events and pods running on the node. #### Workloads -Entry point view that shows all applications running in the selected namespace. The view lists applications by workload kind (e.g., Deployments, Replica Sets, Stateful Sets, etc.) and each workload kind can be viewed separately. The lists summarize actionable information about the workloads, such as the number of ready pods for a Replica Set or current memory usage for a Pod. - -![Workloads view](/images/docs/ui-dashboard-workloadview.png) +Shows all applications running in the selected namespace. The view lists applications by workload kind (e.g., Deployments, Replica Sets, Stateful Sets, etc.) and each workload kind can be viewed separately. The lists summarize actionable information about the workloads, such as the number of ready pods for a Replica Set or current memory usage for a Pod. Detail views for workloads show status and specification information and surface relationships between objects. For example, Pods that Replica Set is controlling or New Replica Sets and Horizontal Pod Autoscalers for Deployments. -![Deployment detail view](/images/docs/ui-dashboard-deployment-detail.png) - -#### Services and discovery -Services and discovery view shows Kubernetes resources that allow for exposing services to external world and discovering them within a cluster. For that reason, Service and Ingress views show Pods targeted by them, internal endpoints for cluster connections and external endpoints for external users. - -![Service list partial view](/images/docs/ui-dashboard-service-list.png) +#### Services +Shows Kubernetes resources that allow for exposing services to external world and discovering them within a cluster. For that reason, Service and Ingress views show Pods targeted by them, internal endpoints for cluster connections and external endpoints for external users. #### Storage Storage view shows Persistent Volume Claim resources which are used by applications for storing data. -#### Config -Config view shows all Kubernetes resources that are used for live configuration of applications running in clusters. This is now Config Maps and Secrets. The view allows for editing and managing config objects and displays secrets hidden by default. - -![Secret detail view](/images/docs/ui-dashboard-secret-detail.png) +#### Config Maps and Secrets +Shows all Kubernetes resources that are used for live configuration of applications running in clusters. The view allows for editing and managing config objects and displays secrets hidden by default. #### Logs viewer -Pod lists and detail pages link to logs viewer that is built into Dashboard. The viewer allows for drilling down logs from containers belonging to a single Pod. +Pod lists and detail pages link to a logs viewer that is built into Dashboard. The viewer allows for drilling down logs from containers belonging to a single Pod. ![Logs viewer](/images/docs/ui-dashboard-logs-view.png) diff --git a/content/en/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md b/content/en/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md index 223dfb67e4..a66be5a1ad 100644 --- a/content/en/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md +++ b/content/en/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md @@ -22,13 +22,173 @@ Configuring the [aggregation layer](/docs/concepts/extend-kubernetes/api-extensi There are a few setup requirements for getting the aggregation layer working in your environment to support mutual TLS auth between the proxy and extension apiservers. Kubernetes and the kube-apiserver have multiple CAs, so make sure that the proxy is signed by the aggregation layer CA and not by something else, like the master CA. {{< /note >}} +{{% /capture %}} + +{{% capture authflow %}} + +## Authentication Flow + +Unlike Custom Resource Definitions (CRDs), the Aggregation API involves another server - your Extension apiserver - in addition to the standard Kubernetes apiserver. The Kubernetes apiserver will need to communicate with your extension apiserver, and your extension apiserver will need to communicate with the Kubernetes apiserver. In order for this communication to be secured, the Kubernetes apiserver uses x509 certificates to authenticate itself to the extension apiserver. + +This section describes how the authentication and authorization flows work, and how to configure them. + +The high-level flow is as follows: + +1. Kubenetes apiserver: authenticate the requesting user and authorize their rights to the requested API path. +2. Kubenetes apiserver: proxy the request to the extension apiserver +3. Extension apiserver: authenticate the request from the Kubernetes apiserver +4. Extension apiserver: authorize the request from the original user +5. Extension apiserver: execute + +The rest of this section describes these steps in detail. + +The flow can be seen in the following diagram. + +![aggregation auth flows](/images/docs/aggregation-api-auth-flow.png). + +The source for the above swimlanes can be found in the source of this document. + + + +### Kubernetes Apiserver Authentication and Authorization + +A request to an API path that is served by an extension apiserver begins the same way as all API requests: communication to the Kubernetes apiserver. This path already has been registered with the Kubernetes apiserver by the extension apiserver. + +The user communicates with the Kubernetes apiserver, requesting access to the path. The Kubernetes apiserver uses standard authentication and authorization configured with the Kubernetes apiserver to authenticate the user and authorize access to the specific path. + +For an overview of authenticating to a Kubernetes cluster, see ["Authenticating to a Cluster"](/docs/reference/access-authn-authz/authentication/). For an overview of authorization of access to Kubernetes cluster resources, see ["Authorization Overview"](/docs/reference/access-authn-authz/authorization/). + +Everything to this point has been standard Kubernetes API requests, authentication and authorization. + +The Kubernetes apiserver now is prepared to send the request to the extension apiserver. + +### Kubernetes Apiserver Proxies the Request + +The Kubernetes apiserver now will send, or proxy, the request to the extension apiserver that registered to handle the request. In order to do so, it needs to know several things: + +1. How should the Kubernetes apiserver authenticate to the extension apiserver, informing the extension apiserver that the request, which comes over the network, is coming from a valid Kubernetes apiserver? +2. How should the Kubernetes apiserver inform the extension apiserver of the username and group for which the original request was authenticated? + +In order to provide for these two, you must configure the Kubernetes apiserver using several flags. + +#### Kubernetes Apiserver Client Authentication + +The Kubernetes apiserver connects to the extension apiserver over TLS, authenticating itself using a client certificate. You must provide the following to the Kubernetes apiserver upon startup, using the provided flags: + +* private key file via `--proxy-client-key-file` +* signed client certificate file via `--proxy-client-cert-file` +* certificate of the CA that signed the client certificate file via `--requestheader-client-ca-file` +* valid Common Names (CN) in the signed client certificate via `--requestheader-allowed-names` + +The Kubernetes apiserver will use the files indicated by `--proxy-client-*-file` to authenticate to the extension apiserver. In order for the request to be considered valid by a compliant extension apiserver, the following conditions must be met: + +1. The connection must be made using a client certificate that is signed by the CA whose certificate is in `--requestheader-client-ca-file`. +2. The connection must be made using a client certificate whose CN is one of those listed in `--requestheader-allowed-names`. **Note:** You can set this option to blank as `--requestheader-allowed-names=""`. This will indicate to an extension apiserver that _any_ CN is acceptable. + +When started with these options, the Kubernetes apiserver will: + +1. Use them to authenticate to the extension apiserver. +2. Create a configmap in the `kube-system` namespace called `extension-apiserver-authentication`, in which it will place the CA certificate and the allowed CNs. These in turn can be retrieved by extension apiservers to validate requests. + +Note that the same client certificate is used by the Kubernetes apiserver to authenticate against _all_ extension apiservers. It does not create a client certificate per extension apiserver, but rather a single one to authenticate as the Kubernetes apiserver. This same one is reused for all extension apiserver requests. + +#### Original Request Username and Group + +When the Kubernetes apiserver proxies the request to the extension apiserver, it informs the extension apiserver of the username and group with which the original request successfully authenticated. It provides these in http headers of its proxied request. You must inform the Kubernetes apiserver of the names of the headers to be used. + +* the header in which to store the username via `--requestheader-username-headers` +* the header in which to store the group via `--requestheader-group-headers` +* the prefix to append to all extra headers via `--requestheader-extra-headers-prefix` + +These header names are also placed in the `extension-apiserver-authentication` configmap, so they can be retrieved and used by extension apiservers. + +### Extension Apiserver Authenticates the Request + +The extension apiserver, upon receiving a proxied request from the Kubernetes apiserver, must validate that the request actually did come from a valid authenticating proxy, which role the Kubernetes apiserver is fulfilling. The extension apiserver validates it via: + +1. Retrieve the following from the configmap in `kube-system`, as described above: + * Client CA certificate + * List of allowed names (CNs) + * Header names for username, group and extra info +2. Check that the TLS connection was authenticated using a client certificate which: + * Was signed by the CA whose certificate matches the retrieved CA certificate. + * Has a CN in the list of allowed CNs, unless the list is blank, in which case all CNs are allowed. + * Extract the username and group from the appropriate headers + +If the above passes, then the request is a valid proxied request from a legitimate authenticating proxy, in this case the Kubernetes apiserver. + +Note that it is the responsibility of the extension apiserver implementation to provide the above. Many do it by default, leveraging the `k8s.io/apiserver/` package. Others may provide options to override it using command-line options. + +In order to have permission to retrieve the configmap, an extension apiserver requires the appropriate role. There is a default role named `extension-apiserver-authentication-reader` in the `kube-system` namespace which can be assigned. + +### Extension Apiserver Authorizes the Request + +The extension apiserver now can validate that the user/group retrieved from the headers are authorized to execute the given request. It does so by sending a standard [SubjectAccessReview](/docs/reference/access-authn-authz/authorization/) request to the Kubernetes apiserver. + +In order for the extension apiserver to be authorized itself to submit the `SubjectAccessReview` request to the Kubernetes apiserver, it needs the correct permissions. Kubernetes includes a default `ClusterRole` named `system:auth-delegator` that has the appropriate permissions. It can be granted to the extension apiserver's service account. + +### Extension Apiserver Executes + +If the `SubjectAccessReview` passes, the extension apiserver executes the request. + + {{% /capture %}} {{% capture steps %}} -## Enable apiserver flags +## Enable Kubernetes Apiserver flags -Enable the aggregation layer via the following kube-apiserver flags. They may have already been taken care of by your provider. +Enable the aggregation layer via the following `kube-apiserver` flags. They may have already been taken care of by your provider. --requestheader-client-ca-file= --requestheader-allowed-names=front-proxy-client @@ -38,9 +198,11 @@ Enable the aggregation layer via the following kube-apiserver flags. They may ha --proxy-client-cert-file= --proxy-client-key-file= -WARNING: do **not** reuse a CA that is used in a different context unless you understand the risks and the mechanisms to protect the CA's usage. +{{< warning >}} +Do **not** reuse a CA that is used in a different context unless you understand the risks and the mechanisms to protect the CA's usage. +{{< /warning >}} -If you are not running kube-proxy on a host running the API server, then you must make sure that the system is enabled with the following apiserver flag: +If you are not running kube-proxy on a host running the API server, then you must make sure that the system is enabled with the following `kube-apiserver` flag: --enable-aggregator-routing=true @@ -54,5 +216,3 @@ If you are not running kube-proxy on a host running the API server, then you mus {{% /capture %}} - - diff --git a/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md b/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md index 034200a1e4..275955c8f5 100644 --- a/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md +++ b/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning.md @@ -110,7 +110,7 @@ same way that the Kubernetes project sorts Kubernetes versions. Versions start w `v` followed by a number, an optional `beta` or `alpha` designation, and optional additional numeric versioning information. Broadly, a version string might look like `v2` or `v2beta1`. Versions are sorted using the following algorithm: - + - Entries that follow Kubernetes version patterns are sorted before those that do not. - For entries that follow Kubernetes version patterns, the numeric portions of @@ -185,7 +185,7 @@ how to [authenticate API servers](/docs/reference/access-authn-authz/extensible- ### Deploy the conversion webhook service Documentation for deploying the conversion webhook is the same as for the [admission webhook example service](/docs/reference/access-authn-authz/extensible-admission-controllers/#deploy_the_admission_webhook_service). -The assumption for next sections is that the conversion webhook server is deployed to a service named `example-conversion-webhook-server` in `default` namespace. +The assumption for next sections is that the conversion webhook server is deployed to a service named `example-conversion-webhook-server` in `default` namespace and serving traffic on path `/crdconvert`. {{< note >}} When the webhook server is deployed into the Kubernetes cluster as a @@ -242,6 +242,8 @@ spec: service: namespace: default name: example-conversion-webhook-server + # path is the url the API server will call. It should match what the webhook is serving at. The default is '/'. + path: /crdconvert caBundle: # either Namespaced or Cluster scope: Namespaced diff --git a/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions.md b/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions.md index 36ea1a0dfe..fddff0fcbe 100644 --- a/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions.md +++ b/content/en/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions.md @@ -228,7 +228,7 @@ meaning all finalizers have been executed. {{< feature-state state="beta" for_kubernetes_version="1.9" >}} Validation of custom objects is possible via -[OpenAPI v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject). +[OpenAPI v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject) or [validatingadmissionwebhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook). Additionally, the following restrictions are applied to the schema: - The fields `default`, `nullable`, `discriminator`, `readOnly`, `writeOnly`, `xml`, diff --git a/content/en/docs/tasks/access-kubernetes-api/http-proxy-access-api.md b/content/en/docs/tasks/access-kubernetes-api/http-proxy-access-api.md index 8171e50611..5519ef0052 100644 --- a/content/en/docs/tasks/access-kubernetes-api/http-proxy-access-api.md +++ b/content/en/docs/tasks/access-kubernetes-api/http-proxy-access-api.md @@ -10,12 +10,14 @@ This page shows how to use an HTTP proxy to access the Kubernetes API. {{% capture prerequisites %}} -* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} -* If you do not already have an application running in your cluster, start - a Hello world application by entering this command: +If you do not already have an application running in your cluster, start +a Hello world application by entering this command: - kubectl run node-hello --image=gcr.io/google-samples/node-hello:1.0 --port=8080 +```shell +kubectl run node-hello --image=gcr.io/google-samples/node-hello:1.0 --port=8080 +``` {{% /capture %}} diff --git a/content/en/docs/tasks/administer-cluster/access-cluster-api.md b/content/en/docs/tasks/administer-cluster/access-cluster-api.md index 16ba5585b8..16434ca0a4 100644 --- a/content/en/docs/tasks/administer-cluster/access-cluster-api.md +++ b/content/en/docs/tasks/administer-cluster/access-cluster-api.md @@ -29,7 +29,7 @@ or someone else setup the cluster and provided you with credentials and a locati Check the location and credentials that kubectl knows about with this command: ```shell -$ kubectl config view +kubectl config view ``` Many of the [examples](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/) provide an introduction to using @@ -53,7 +53,7 @@ locating the API server and authenticating. Run it like this: ```shell -$ kubectl proxy --port=8080 & +kubectl proxy --port=8080 & ``` See [kubectl proxy](/docs/reference/generated/kubectl/kubectl-commands/#proxy) for more details. @@ -61,7 +61,12 @@ See [kubectl proxy](/docs/reference/generated/kubectl/kubectl-commands/#proxy) f Then you can explore the API with curl, wget, or a browser, like so: ```shell -$ curl http://localhost:8080/api/ +curl http://localhost:8080/api/ +``` + +The output is similar to this: + +```json { "versions": [ "v1" @@ -80,9 +85,47 @@ $ curl http://localhost:8080/api/ It is possible to avoid using kubectl proxy by passing an authentication token directly to the API server, like this: -``` shell -$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ") -$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t') +Using `grep/cut` approach: + +```shell +# Check all possible clusters, as you .KUBECONFIG may have multiple contexts: +kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}' + +# Select name of cluster you want to interact with from above output: +export CLUSTER_NAME="some_server_name" + +# Point to the API server refering the cluster name +APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}") + +# Gets the token value +TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -d) + +# Explore the API with TOKEN +curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure +``` + +The output is similar to this: + +```json +{ + "kind": "APIVersions", + "versions": [ + "v1" + ], + "serverAddressByClientCIDRs": [ + { + "clientCIDR": "0.0.0.0/0", + "serverAddress": "10.0.1.149:443" + } + ] +} +``` + +Using `jsonpath` approach: + +``` +$ APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') +$ TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode ) $ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure { "kind": "APIVersions", diff --git a/content/en/docs/tasks/administer-cluster/access-cluster-services.md b/content/en/docs/tasks/administer-cluster/access-cluster-services.md index 76fc058cd0..57cdc835de 100644 --- a/content/en/docs/tasks/administer-cluster/access-cluster-services.md +++ b/content/en/docs/tasks/administer-cluster/access-cluster-services.md @@ -56,49 +56,72 @@ Typically, there are several services which are started on a cluster by kube-sys with the `kubectl cluster-info` command: ```shell -$ kubectl cluster-info +kubectl cluster-info +``` - Kubernetes master is running at https://104.197.5.247 - elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy - kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy - kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy - grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy - heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy +The output is similar to this: + +``` +Kubernetes master is running at https://104.197.5.247 +elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy +kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy +kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy +grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy +heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy ``` This shows the proxy-verb URL for accessing each service. For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached at `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/` if suitable credentials are passed, or through a kubectl proxy at, for example: `http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`. -(See [Access Clusters Using the Kubernetes API](/docs/tasks/administer-cluster/access-cluster-api/#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.) + +{{< note >}} +See [Access Clusters Using the Kubernetes API](/docs/tasks/administer-cluster/access-cluster-api/#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy. +{{< /note >}} #### Manually constructing apiserver proxy URLs As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you simply append to the service's proxy URL: `http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`[https:]service_name[:port_name]`*`/proxy` -If you haven't specified a name for your port, you don't have to specify *port_name* in the URL +If you haven't specified a name for your port, you don't have to specify *port_name* in the URL. ##### Examples - * To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: `http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy` - * To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true` +* To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: -```json - { - "cluster_name" : "kubernetes_logging", - "status" : "yellow", - "timed_out" : false, - "number_of_nodes" : 1, - "number_of_data_nodes" : 1, - "active_primary_shards" : 5, - "active_shards" : 5, - "relocating_shards" : 0, - "initializing_shards" : 0, - "unassigned_shards" : 5 - } -``` - * To access the *https* Elasticsearch service health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/namespaces/kube-system/services/https:elasticsearch-logging/proxy/_cluster/health?pretty=true` + ``` + http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy + ``` + +* To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: + + ``` + https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true + ``` + + The health information is similar to this: + + ```json + { + "cluster_name" : "kubernetes_logging", + "status" : "yellow", + "timed_out" : false, + "number_of_nodes" : 1, + "number_of_data_nodes" : 1, + "active_primary_shards" : 5, + "active_shards" : 5, + "relocating_shards" : 0, + "initializing_shards" : 0, + "unassigned_shards" : 5 + } + ``` + +* To access the *https* Elasticsearch service health information `_cluster/health?pretty=true`, you would use: + + ``` + https://104.197.5.247/api/v1/namespaces/kube-system/services/https:elasticsearch-logging/proxy/_cluster/health?pretty=true + ``` #### Using web browsers to access services running on the cluster diff --git a/content/en/docs/tasks/administer-cluster/cluster-management.md b/content/en/docs/tasks/administer-cluster/cluster-management.md index 2908666dcb..3533a0a223 100644 --- a/content/en/docs/tasks/administer-cluster/cluster-management.md +++ b/content/en/docs/tasks/administer-cluster/cluster-management.md @@ -65,6 +65,10 @@ Google Kubernetes Engine automatically updates master components (e.g. `kube-api The node upgrade process is user-initiated and is described in the [Google Kubernetes Engine documentation](https://cloud.google.com/kubernetes-engine/docs/clusters/upgrade). +### Upgrading an Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) cluster + +Oracle creates and manages a set of master nodes in the Oracle control plane on your behalf (and associated Kubernetes infrastructure such as etcd nodes) to ensure you have a highly available managed Kubernetes control plane. You can also seamlessly upgrade these master nodes to new versions of Kubernetes with zero downtime. These actions are described in the [OKE documentation](https://docs.cloud.oracle.com/iaas/Content/ContEng/Tasks/contengupgradingk8smasternode.htm). + ### Upgrading clusters on other platforms Different providers, and tools, will manage upgrades differently. It is recommended that you consult their main documentation regarding upgrades. diff --git a/content/en/docs/tasks/administer-cluster/configure-multiple-schedulers.md b/content/en/docs/tasks/administer-cluster/configure-multiple-schedulers.md index b6edeb4bc2..fe835c684d 100644 --- a/content/en/docs/tasks/administer-cluster/configure-multiple-schedulers.md +++ b/content/en/docs/tasks/administer-cluster/configure-multiple-schedulers.md @@ -96,7 +96,9 @@ kubectl create -f my-scheduler.yaml Verify that the scheduler pod is running: ```shell -$ kubectl get pods --namespace=kube-system +kubectl get pods --namespace=kube-system +``` +``` NAME READY STATUS RESTARTS AGE .... my-scheduler-lnf4s-4744f 1/1 Running 0 2m @@ -114,9 +116,11 @@ First, update the following fields in your YAML file: * `--lock-object-namespace=lock-object-namespace` * `--lock-object-name=lock-object-name` -If RBAC is enabled on your cluster, you must update the `system:kube-scheduler` cluster role. Add you scheduler name to the resourceNames of the rule applied for endpoints resources, as in the following example: +If RBAC is enabled on your cluster, you must update the `system:kube-scheduler` cluster role. Add your scheduler name to the resourceNames of the rule applied for endpoints resources, as in the following example: ``` -$ kubectl edit clusterrole system:kube-scheduler +kubectl edit clusterrole system:kube-scheduler +``` +```yaml - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/content/en/docs/tasks/administer-cluster/coredns.md b/content/en/docs/tasks/administer-cluster/coredns.md index a892cc69c7..00cbe26aa6 100644 --- a/content/en/docs/tasks/administer-cluster/coredns.md +++ b/content/en/docs/tasks/administer-cluster/coredns.md @@ -72,7 +72,7 @@ For versions 1.13 and later, follow the guide outlined [here](/docs/reference/se ## Tuning CoreDNS When resource utilisation is a concern, it may be useful to tune the configuration of CoreDNS. For more details, check out the -[documentation on scaling CoreDNS]((https://github.com/coredns/deployment/blob/master/kubernetes/Scaling_CoreDNS.md)). +[documentation on scaling CoreDNS](https://github.com/coredns/deployment/blob/master/kubernetes/Scaling_CoreDNS.md). {{% /capture %}} diff --git a/content/en/docs/tasks/administer-cluster/declare-network-policy.md b/content/en/docs/tasks/administer-cluster/declare-network-policy.md index 3ea02e0ed4..164bb358c2 100644 --- a/content/en/docs/tasks/administer-cluster/declare-network-policy.md +++ b/content/en/docs/tasks/administer-cluster/declare-network-policy.md @@ -30,19 +30,32 @@ The above list is sorted alphabetically by product name, not by recommendation o ## Create an `nginx` deployment and expose it via a service -To see how Kubernetes network policy works, start off by creating an `nginx` deployment and exposing it via a service. +To see how Kubernetes network policy works, start off by creating an `nginx` deployment. ```console -$ kubectl run nginx --image=nginx --replicas=2 +kubectl run nginx --image=nginx --replicas=2 +``` +```none deployment.apps/nginx created -$ kubectl expose deployment nginx --port=80 +``` + +And expose it via a service. + +```console +kubectl expose deployment nginx --port=80 +``` + +```none service/nginx exposed ``` This runs two `nginx` pods in the default namespace, and exposes them through a service called `nginx`. ```console -$ kubectl get svc,pod +kubectl get svc,pod +``` + +```none NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes 10.100.0.1 443/TCP 46m service/nginx 10.100.0.16 80/TCP 33s @@ -59,7 +72,10 @@ You should be able to access the new `nginx` service from other pods. To test, a Start a busybox container, and use `wget` on the `nginx` service: ```console -$ kubectl run busybox --rm -ti --image=busybox /bin/sh +kubectl run busybox --rm -ti --image=busybox /bin/sh +``` + +```console Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt @@ -94,7 +110,10 @@ spec: Use kubectl to create a NetworkPolicy from the above nginx-policy.yaml file: ```console -$ kubectl create -f nginx-policy.yaml +kubectl create -f nginx-policy.yaml +``` + +```none networkpolicy.networking.k8s.io/access-nginx created ``` @@ -102,7 +121,10 @@ networkpolicy.networking.k8s.io/access-nginx created If we attempt to access the nginx Service from a pod without the correct labels, the request will now time out: ```console -$ kubectl run busybox --rm -ti --image=busybox /bin/sh +kubectl run busybox --rm -ti --image=busybox /bin/sh +``` + +```console Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt @@ -118,7 +140,10 @@ wget: download timed out Create a pod with the correct labels, and you'll see that the request is allowed: ```console -$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh +kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh +``` + +```console Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false Hit enter for command prompt diff --git a/content/en/docs/tasks/administer-cluster/developing-cloud-controller-manager.md b/content/en/docs/tasks/administer-cluster/developing-cloud-controller-manager.md index f533c80869..7afb9e9f15 100644 --- a/content/en/docs/tasks/administer-cluster/developing-cloud-controller-manager.md +++ b/content/en/docs/tasks/administer-cluster/developing-cloud-controller-manager.md @@ -31,7 +31,7 @@ To dive a little deeper into implementation details, all cloud controller manage To build an out-of-tree cloud-controller-manager for your cloud, follow these steps: -1. Create a go package with an implementation that satisfies [cloudprovider.Interface](https://git.k8s.io/kubernetes/pkg/cloudprovider/cloud.go). +1. Create a go package with an implementation that satisfies [cloudprovider.Interface](https://github.com/kubernetes/cloud-provider/blob/master/cloud.go). 2. Use [main.go in cloud-controller-manager](https://github.com/kubernetes/kubernetes/blob/master/cmd/cloud-controller-manager/controller-manager.go) from Kubernetes core as a template for your main.go. As mentioned above, the only difference should be the cloud package that will be imported. 3. Import your cloud package in `main.go`, ensure your package has an `init` block to run [cloudprovider.RegisterCloudProvider](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/plugins.go#L42-L52). diff --git a/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md b/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md index dd569aa774..c521b0291d 100644 --- a/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md +++ b/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md @@ -95,7 +95,7 @@ Use the `kubectl get pods` command to verify that the DNS pod is running. For CoreDNS: ```shell -kubectl get pods --namespace=kube-system -l k8s-app=kube-dns +kubectl get pods --namespace=kube-system -l k8s-app=coredns NAME READY STATUS RESTARTS AGE ... coredns-7b96bf9f76-5hsxb 1/1 Running 0 1h @@ -122,7 +122,7 @@ Use `kubectl logs` command to see logs for the DNS containers. For CoreDNS: ```shell -for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name); do kubectl logs --namespace=kube-system $p; done +for p in $(kubectl get pods --namespace=kube-system -l k8s-app=coredns -o name); do kubectl logs --namespace=kube-system $p; done ``` Here is an example of a healthy CoreDNS log: diff --git a/content/en/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md b/content/en/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md index eaded41813..6a18263b31 100644 --- a/content/en/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md +++ b/content/en/docs/tasks/administer-cluster/dns-horizontal-autoscaling.md @@ -73,14 +73,14 @@ If you have a DNS Deployment, your scale target is: Deployment/ -where is the name of your DNS Deployment. For example, if +where `` is the name of your DNS Deployment. For example, if your DNS Deployment name is coredns, your scale target is Deployment/coredns. If you have a DNS ReplicationController, your scale target is: ReplicationController/ -where is the name of your DNS ReplicationController. For example, +where `` is the name of your DNS ReplicationController. For example, if your DNS ReplicationController name is kube-dns-v20, your scale target is ReplicationController/kube-dns-v20. @@ -145,7 +145,7 @@ There are other supported scaling patterns. For details, see ## Disable DNS horizontal autoscaling -There are a few options for turning DNS horizontal autoscaling. Which option to +There are a few options for tuning DNS horizontal autoscaling. Which option to use depends on different conditions. ### Option 1: Scale down the dns-autoscaler deployment to 0 replicas @@ -183,8 +183,8 @@ The output is: ### Option 3: Delete the dns-autoscaler manifest file from the master node This option works if dns-autoscaler is under control of the -[Addon Manager](https://git.k8s.io/kubernetes/cluster/addons/README.md)'s -control, and you have write access to the master node. +[Addon Manager](https://git.k8s.io/kubernetes/cluster/addons/README.md), +and you have write access to the master node. Sign in to the master node and delete the corresponding manifest file. The common path for this dns-autoscaler is: @@ -238,6 +238,3 @@ is under consideration as a future development. Learn more about the [implementation of cluster-proportional-autoscaler](https://github.com/kubernetes-incubator/cluster-proportional-autoscaler). {{% /capture %}} - - - diff --git a/content/en/docs/tasks/administer-cluster/highly-available-master.md b/content/en/docs/tasks/administer-cluster/highly-available-master.md index 598339a3b1..192eca3c93 100644 --- a/content/en/docs/tasks/administer-cluster/highly-available-master.md +++ b/content/en/docs/tasks/administer-cluster/highly-available-master.md @@ -42,7 +42,7 @@ Set the following flag: The following sample command sets up a HA-compatible cluster in the GCE zone europe-west1-b: ```shell -$ MULTIZONE=true KUBE_GCE_ZONE=europe-west1-b ENABLE_ETCD_QUORUM_READS=true ./cluster/kube-up.sh +MULTIZONE=true KUBE_GCE_ZONE=europe-west1-b ENABLE_ETCD_QUORUM_READS=true ./cluster/kube-up.sh ``` Note that the commands above create a cluster with one master; @@ -65,7 +65,7 @@ as those are inherited from when you started your HA-compatible cluster. The following sample command replicates the master on an existing HA-compatible cluster: ```shell -$ KUBE_GCE_ZONE=europe-west1-c KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh +KUBE_GCE_ZONE=europe-west1-c KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh ``` ## Removing a master replica @@ -82,7 +82,7 @@ If empty: any replica from the given zone will be removed. The following sample command removes a master replica from an existing HA cluster: ```shell -$ KUBE_DELETE_NODES=false KUBE_GCE_ZONE=europe-west1-c ./cluster/kube-down.sh +KUBE_DELETE_NODES=false KUBE_GCE_ZONE=europe-west1-c ./cluster/kube-down.sh ``` ## Handling master replica failures @@ -94,13 +94,13 @@ The following sample commands demonstrate this process: 1. Remove the broken replica: ```shell -$ KUBE_DELETE_NODES=false KUBE_GCE_ZONE=replica_zone KUBE_REPLICA_NAME=replica_name ./cluster/kube-down.sh +KUBE_DELETE_NODES=false KUBE_GCE_ZONE=replica_zone KUBE_REPLICA_NAME=replica_name ./cluster/kube-down.sh ```
  1. Add a new replica in place of the old one:
```shell -$ KUBE_GCE_ZONE=replica-zone KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh +KUBE_GCE_ZONE=replica-zone KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh ``` ## Best practices for replicating masters for HA clusters diff --git a/content/en/docs/tasks/administer-cluster/kms-provider.md b/content/en/docs/tasks/administer-cluster/kms-provider.md index 601b0fb97d..cfd0e23d6e 100644 --- a/content/en/docs/tasks/administer-cluster/kms-provider.md +++ b/content/en/docs/tasks/administer-cluster/kms-provider.md @@ -89,7 +89,7 @@ resources: name: myKmsPlugin endpoint: unix:///tmp/socketfile.sock cachesize: 100 - - identity: {} + - identity: {} ``` 2. Set the `--encryption-provider-config` flag on the kube-apiserver to point to the location of the configuration file. diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md index 6414a9e8de..913e672ac0 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md @@ -23,7 +23,9 @@ You should be familiar with [PKI certificates and requirements in Kubernetes](/d ## Renew certificates with the certificates API -Kubeadm can renew certificates with the `kubeadm alpha certs renew` commands. +The Kubernetes certificates normally reach their expiration date after one year. + +Kubeadm can renew certificates with the `kubeadm alpha certs renew` commands; you should run these commands on control-plane nodes only. Typically this is done by loading on-disk CA certificates and keys and using them to issue new certificates. This approach works well if your certificate tree is self-contained. However, if your certificates are externally @@ -65,14 +67,18 @@ You pass these arguments in any of the following ways: ### Approve requests If you set up an external signer such as [cert-manager][cert-manager], certificate signing requests (CSRs) are automatically approved. -Otherwise, you must manually approve certificates with the [`kubectl certificates`][certs] command. +Otherwise, you must manually approve certificates with the [`kubectl certificate`][certs] command. The following kubeadm command outputs the name of the certificate to approve, then blocks and waits for approval to occur: ```shell -$ sudo kubeadm alpha certs renew apiserver --use-api & +sudo kubeadm alpha certs renew apiserver --use-api & +``` +``` [1] 2890 [certs] certificate request "kubeadm-cert-kube-apiserver-ld526" created -$ kubectl certificate approve kubeadm-cert-kube-apiserver-ld526 +``` +```shell +kubectl certificate approve kubeadm-cert-kube-apiserver-ld526 certificatesigningrequest.certificates.k8s.io/kubeadm-cert-kube-apiserver-ld526 approved [1]+ Done sudo kubeadm alpha certs renew apiserver --use-api ``` @@ -89,16 +95,16 @@ To better integrate with external CAs, kubeadm can also produce certificate sign A CSR represents a request to a CA for a signed certificate for a client. In kubeadm terms, any certificate that would normally be signed by an on-disk CA can be produced as a CSR instead. A CA, however, cannot be produced as a CSR. -You can create an individual CSR with `kubeadm init phase certs apiserver --use-csr`. -The `--use-csr` flag can be applied only to individual phases. After [all certificates are in place][certs], you can run `kubeadm init --external-ca`. +You can create an individual CSR with `kubeadm init phase certs apiserver --csr-only`. +The `--csr-only` flag can be applied only to individual phases. After [all certificates are in place][certs], you can run `kubeadm init --external-ca`. You can pass in a directory with `--csr-dir` to output the CSRs to the specified location. -If `--csr-dire` is not specified, the default certificate directory (`/etc/kubernetes/pki`) is used. +If `--csr-dir` is not specified, the default certificate directory (`/etc/kubernetes/pki`) is used. Both the CSR and the accompanying private key are given in the output. After a certificate is signed, the certificate and the private key must be copied to the PKI directory (by default `/etc/kubernetes/pki`). ### Renew certificates -Certificates can be renewed with `kubeadm alpha certs renew --use-csr`. +Certificates can be renewed with `kubeadm alpha certs renew --csr-only`. As with `kubeadm init`, an output directory can be specified with the `--csr-dir` flag. To use the new certificates, copy the signed certificate and private key into the PKI directory (by default `/etc/kubernetes/pki`) @@ -121,4 +127,3 @@ Kubeadm sets up [three CAs][cert-cas] by default. Make sure to sign the CSRs wit [cert-table]: https://kubernetes.io/docs/setup/certificates/#all-certificates {{% /capture %}} -https://prow.k8s.io/?pull=71212 diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-12.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-12.md index 934717cd91..fa8831a92c 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-12.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-12.md @@ -39,11 +39,14 @@ This page explains how to upgrade a Kubernetes cluster created with `kubeadm` fr {{< tabs name="k8s_install" >}} {{% tab name="Ubuntu, Debian or HypriotOS" %}} - apt-get update - apt-get upgrade -y kubeadm + # replace "x" with the latest patch version + apt-mark unhold kubeadm && \ + apt-get update && apt-get upgrade -y kubeadm=1.12.x-00 && \ + apt-mark hold kubeadm {{% /tab %}} {{% tab name="CentOS, RHEL or Fedora" %}} - yum upgrade -y kubeadm --disableexcludes=kubernetes + # replace "x" with the latest patch version + yum upgrade -y kubeadm-1.12.x --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} @@ -229,11 +232,13 @@ This page explains how to upgrade a Kubernetes cluster created with `kubeadm` fr {{< tabs name="k8s_upgrade" >}} {{% tab name="Ubuntu, Debian or HypriotOS" %}} + # replace "x" with the latest patch version apt-get update - apt-get upgrade -y kubelet kubeadm + apt-get upgrade -y kubelet=1.12.x-00 kubeadm=1.12.x-00 {{% /tab %}} {{% tab name="CentOS, RHEL or Fedora" %}} - yum upgrade -y kubelet kubeadm --disableexcludes=kubernetes + # replace "x" with the latest patch version + yum upgrade -y kubelet-1.12.x kubeadm-1.12.x --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-13.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-13.md index 728f88936c..a7d42ef2e3 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-13.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-13.md @@ -29,21 +29,48 @@ This page explains how to upgrade a Kubernetes cluster created with `kubeadm` fr That is, you cannot skip versions when you upgrade. For example, you can upgrade only from 1.10 to 1.11, not from 1.9 to 1.11. +{{< warning >}} +The command `join --experimental-control-plane` is known to fail on single node clusters created with kubeadm v1.12 and then upgraded to v1.13.x. +This will be fixed when graduating the `join --control-plane` workflow from alpha to beta. +A possible workaround is described [here](https://github.com/kubernetes/kubeadm/issues/1269#issuecomment-441116249). +{{}} + {{% /capture %}} {{% capture steps %}} -## Upgrade the control plane +## Determine which version to upgrade to -1. On your master node, upgrade kubeadm: +1. Find the latest stable 1.13 version: - {{< tabs name="k8s_install" >}} + {{< tabs name="k8s_install_versions" >}} {{% tab name="Ubuntu, Debian or HypriotOS" %}} - apt-get update - apt-get upgrade -y kubelet kubeadm + apt update + apt-cache policy kubeadm + # find the latest 1.13 version in the list + # it should look like 1.13.x-00, where x is the latest patch {{% /tab %}} {{% tab name="CentOS, RHEL or Fedora" %}} - yum upgrade -y kubeadm --disableexcludes=kubernetes + yum list --showduplicates kubeadm --disableexcludes=kubernetes + # find the latest 1.13 version in the list + # it should look like 1.13.x-0, where x is the latest patch + {{% /tab %}} + {{< /tabs >}} + +## Upgrade the control plane node + +1. On your control plane node, upgrade kubeadm: + + {{< tabs name="k8s_install_kubeadm" >}} + {{% tab name="Ubuntu, Debian or HypriotOS" %}} + # replace x in 1.13.x-00 with the latest patch version + apt-mark unhold kubeadm && \ + apt-get update && apt-get install -y kubeadm=1.13.x-00 && \ + apt-mark hold kubeadm + {{% /tab %}} + {{% tab name="CentOS, RHEL or Fedora" %}} + # replace x in 1.13.x-0 with the latest patch version + yum install -y kubeadm-1.13.x-0 --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} @@ -181,7 +208,39 @@ This page explains how to upgrade a Kubernetes cluster created with `kubeadm` fr Check the [addons](/docs/concepts/cluster-administration/addons/) page to find your CNI provider and see whether additional upgrade steps are required. -## Upgrade master and node packages +1. Upgrade the kubelet on the control plane node: + + {{< tabs name="k8s_install_kubelet" >}} + {{% tab name="Ubuntu, Debian or HypriotOS" %}} + # replace x in 1.13.x-00 with the latest patch version + apt-mark unhold kubelet && \ + apt-get update && apt-get install -y kubelet=1.13.x-00 && \ + apt-mark hold kubelet + {{% /tab %}} + {{% tab name="CentOS, RHEL or Fedora" %}} + # replace x in 1.13.x-0 with the latest patch version + yum install -y kubelet-1.13.x-0 --disableexcludes=kubernetes + {{% /tab %}} + {{< /tabs >}} + +## Ugrade kubectl on all nodes + +1. Upgrade kubectl on all nodes: + + {{< tabs name="k8s_install_kubectl" >}} + {{% tab name="Ubuntu, Debian or HypriotOS" %}} + # replace x in 1.13.x-00 with the latest patch version + apt-mark unhold kubectl && \ + apt-get update && apt-get install -y kubectl=1.13.x-00 && \ + apt-mark hold kubectl + {{% /tab %}} + {{% tab name="CentOS, RHEL or Fedora" %}} + # replace x in 1.13.x-0 with the latest patch version + yum install -y kubectl-1.13.x-0 --disableexcludes=kubernetes + {{% /tab %}} + {{< /tabs >}} + +## Drain control plane and worker nodes 1. Prepare each node for maintenance by marking it unschedulable and evicting the workloads. Run: @@ -189,7 +248,7 @@ This page explains how to upgrade a Kubernetes cluster created with `kubeadm` fr kubectl drain $NODE --ignore-daemonsets ``` - On the master node, you must add `--ignore-daemonsets`: + On the control plane node, you must add `--ignore-daemonsets`: ```shell kubectl drain ip-172-31-85-18 @@ -208,27 +267,36 @@ This page explains how to upgrade a Kubernetes cluster created with `kubeadm` fr node "ip-172-31-85-18" drained ``` +## Upgrade the kubelet config on worker nodes + +1. On each node except the control plane node, upgrade the kubelet config: + + ```shell + kubeadm upgrade node config --kubelet-version v1.13.x + ``` + + Replace `x` with the patch version you picked for this ugprade. + + +## Upgrade kubeadm and the kubelet on worker nodes + 1. Upgrade the Kubernetes package version on each `$NODE` node by running the Linux package manager for your distribution: - {{< tabs name="k8s_install" >}} + {{< tabs name="k8s_kubelet_and_kubeadm" >}} {{% tab name="Ubuntu, Debian or HypriotOS" %}} + # replace x in 1.13.x-00 with the latest patch version apt-get update - apt-get upgrade -y kubelet kubeadm + apt-get install -y kubelet=1.13.x-00 kubeadm=1.13.x-00 {{% /tab %}} {{% tab name="CentOS, RHEL or Fedora" %}} - yum upgrade -y kubelet kubeadm --disableexcludes=kubernetes + # replace x in 1.13.x-0 with the latest patch version + yum install -y kubelet-1.13.x-0 kubeadm-1.13.x-0 --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} -## Upgrade kubelet on each node +## Restart the kubelet for all nodes -1. On each node except the master node, upgrade the kubelet config: - - ```shell - kubeadm upgrade node config --kubelet-version $(kubelet --version | cut -d ' ' -f 2) - ``` - -1. Restart the kubelet process: +1. Restart the kubelet process for all nodes: ```shell systemctl restart kubelet diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-12.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-12.md index f43cd16567..a8a9bbb439 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-12.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-12.md @@ -37,7 +37,7 @@ Upgrade `kubeadm` to the version that matches the version of Kubernetes that you ```shell apt-mark unhold kubeadm && \ -apt-get update && apt-get install -y kubeadm && \ +apt-get update && apt-get upgrade -y kubeadm && \ apt-mark hold kubeadm ``` @@ -113,7 +113,7 @@ You should see something like the following: [upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.12.0". Enjoy! -The `kubeadm-config` ConfigMap is now updated from `v1alpha3` version to `v1beta1`. +The `kubeadm-config` ConfigMap is now updated from `v1alpha2` version to `v1alpha3`. ### Upgrading additional control plane nodes @@ -143,7 +143,7 @@ Open the file in an editor and replace the following values for `ClusterConfigur You must also modify the `ClusterStatus` to add a mapping for the current host under apiEndpoints. -Add an annotation for the cri-socket to the current node, for example to use docker: +Add an annotation for the cri-socket to the current node, for example to use Docker: ```shell kubectl annotate node kubeadm.alpha.kubernetes.io/cri-socket=/var/run/dockershim.sock diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-13.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-13.md index 8b019ea043..19aafebdc6 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-13.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha-1-13.md @@ -36,7 +36,7 @@ Upgrade `kubeadm` to the version that matches the version of Kubernetes that you ```shell apt-mark unhold kubeadm && \ -apt-get update && apt-get install -y kubeadm && \ +apt-get update && apt-get upgrade -y kubeadm && \ apt-mark hold kubeadm ``` diff --git a/content/en/docs/tasks/administer-cluster/namespaces-walkthrough.md b/content/en/docs/tasks/administer-cluster/namespaces-walkthrough.md index 4cd6eba746..7779b25d73 100644 --- a/content/en/docs/tasks/administer-cluster/namespaces-walkthrough.md +++ b/content/en/docs/tasks/administer-cluster/namespaces-walkthrough.md @@ -7,7 +7,8 @@ content_template: templates/task --- {{% capture overview %}} -Kubernetes _namespaces_ help different projects, teams, or customers to share a Kubernetes cluster. +Kubernetes {{< glossary_tooltip text="namespaces" term_id="namespace" >}} +help different projects, teams, or customers to share a Kubernetes cluster. It does this by providing the following: @@ -44,7 +45,9 @@ Services, and Deployments used by the cluster. Assuming you have a fresh cluster, you can inspect the available namespaces by doing the following: ```shell -$ kubectl get namespaces +kubectl get namespaces +``` +``` NAME STATUS AGE default Active 13m ``` @@ -62,34 +65,36 @@ are relaxed to enable agile development. The operations team would like to maintain a space in the cluster where they can enforce strict procedures on who can or cannot manipulate the set of Pods, Services, and Deployments that run the production site. -One pattern this organization could follow is to partition the Kubernetes cluster into two namespaces: development and production. +One pattern this organization could follow is to partition the Kubernetes cluster into two namespaces: `development` and `production`. Let's create two new namespaces to hold our work. -Use the file [`namespace-dev.json`](/examples/admin/namespace-dev.json) which describes a development namespace: +Use the file [`namespace-dev.json`](/examples/admin/namespace-dev.json) which describes a `development` namespace: {{< codenew language="json" file="admin/namespace-dev.json" >}} -Create the development namespace using kubectl. +Create the `development` namespace using kubectl. ```shell -$ kubectl create -f https://k8s.io/examples/admin/namespace-dev.json +kubectl create -f https://k8s.io/examples/admin/namespace-dev.json ``` -Save the following contents into file [`namespace-prod.json`](/examples/admin/namespace-prod.json) which describes a production namespace: +Save the following contents into file [`namespace-prod.json`](/examples/admin/namespace-prod.json) which describes a `production` namespace: {{< codenew language="json" file="admin/namespace-prod.json" >}} -And then let's create the production namespace using kubectl. +And then let's create the `production` namespace using kubectl. ```shell -$ kubectl create -f https://k8s.io/examples/admin/namespace-prod.json +kubectl create -f https://k8s.io/examples/admin/namespace-prod.json ``` To be sure things are right, let's list all of the namespaces in our cluster. ```shell -$ kubectl get namespaces --show-labels +kubectl get namespaces --show-labels +``` +``` NAME STATUS AGE LABELS default Active 32m development Active 29s name=development @@ -102,12 +107,14 @@ A Kubernetes namespace provides the scope for Pods, Services, and Deployments in Users interacting with one namespace do not see the content in another namespace. -To demonstrate this, let's spin up a simple Deployment and Pods in the development namespace. +To demonstrate this, let's spin up a simple Deployment and Pods in the `development` namespace. We first check what is the current context: ```shell -$ kubectl config view +kubectl config view +``` +```yaml apiVersion: v1 clusters: - cluster: @@ -132,18 +139,22 @@ users: user: password: h5M0FtUUIflBSdI7 username: admin - -$ kubectl config current-context +``` +```shell +kubectl config current-context +``` +``` lithe-cocoa-92103_kubernetes ``` The next step is to define a context for the kubectl client to work in each namespace. The value of "cluster" and "user" fields are copied from the current context. ```shell -$ kubectl config set-context dev --namespace=development \ +kubectl config set-context dev --namespace=development \ --cluster=lithe-cocoa-92103_kubernetes \ --user=lithe-cocoa-92103_kubernetes -$ kubectl config set-context prod --namespace=production \ + +kubectl config set-context prod --namespace=production \ --cluster=lithe-cocoa-92103_kubernetes \ --user=lithe-cocoa-92103_kubernetes ``` @@ -155,7 +166,9 @@ new request contexts depending on which namespace you wish to work against. To view the new contexts: ```shell -$ kubectl config view +kubectl config view +``` +```yaml apiVersion: v1 clusters: - cluster: @@ -192,62 +205,72 @@ users: username: admin ``` -Let's switch to operate in the development namespace. +Let's switch to operate in the `development` namespace. ```shell -$ kubectl config use-context dev +kubectl config use-context dev ``` You can verify your current context by doing the following: ```shell -$ kubectl config current-context +kubectl config current-context +``` +``` dev ``` -At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the development namespace. +At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the `development` namespace. Let's create some contents. ```shell -$ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2 +kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2 ``` -We have just created a deployment whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname. +We have just created a deployment whose replica size is 2 that is running the pod called `snowflake` with a basic container that just serves the hostname. Note that `kubectl run` creates deployments only on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead. If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/reference/generated/kubectl/kubectl-commands/#run) for more details. ```shell -$ kubectl get deployment +kubectl get deployment +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE snowflake 2 2 2 2 2m +``` -$ kubectl get pods -l run=snowflake +```shell +kubectl get pods -l run=snowflake +``` +``` NAME READY STATUS RESTARTS AGE snowflake-3968820950-9dgr8 1/1 Running 0 2m snowflake-3968820950-vgc4n 1/1 Running 0 2m ``` -And this is great, developers are able to do what they want, and they do not have to worry about affecting content in the production namespace. +And this is great, developers are able to do what they want, and they do not have to worry about affecting content in the `production` namespace. -Let's switch to the production namespace and show how resources in one namespace are hidden from the other. +Let's switch to the `production` namespace and show how resources in one namespace are hidden from the other. ```shell -$ kubectl config use-context prod +kubectl config use-context prod ``` -The production namespace should be empty, and the following commands should return nothing. +The `production` namespace should be empty, and the following commands should return nothing. ```shell -$ kubectl get deployment -$ kubectl get pods +kubectl get deployment +kubectl get pods ``` Production likes to run cattle, so let's create some cattle pods. ```shell -$ kubectl run cattle --image=kubernetes/serve_hostname --replicas=5 +kubectl run cattle --image=kubernetes/serve_hostname --replicas=5 -$ kubectl get deployment +kubectl get deployment +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE cattle 5 5 5 5 10s diff --git a/content/en/docs/tasks/administer-cluster/namespaces.md b/content/en/docs/tasks/administer-cluster/namespaces.md index ce1ebbce3d..6900d6d558 100644 --- a/content/en/docs/tasks/administer-cluster/namespaces.md +++ b/content/en/docs/tasks/administer-cluster/namespaces.md @@ -7,7 +7,7 @@ content_template: templates/task --- {{% capture overview %}} -This page shows how to view, work in, and delete namespaces. The page also shows how to use Kubernetes namespaces to subdivide your cluster. +This page shows how to view, work in, and delete {{< glossary_tooltip text="namespaces" term_id="namespace" >}}. The page also shows how to use Kubernetes namespaces to subdivide your cluster. {{% /capture %}} {{% capture prerequisites %}} @@ -22,7 +22,9 @@ This page shows how to view, work in, and delete namespaces. The page also shows 1. List the current namespaces in a cluster using: ```shell -$ kubectl get namespaces +kubectl get namespaces +``` +``` NAME STATUS AGE default Active 11d kube-system Active 11d @@ -38,13 +40,15 @@ Kubernetes starts with three initial namespaces: You can also get the summary of a specific namespace using: ```shell -$ kubectl get namespaces +kubectl get namespaces ``` Or you can get detailed information with: ```shell -$ kubectl describe namespaces +kubectl describe namespaces +``` +``` Name: default Labels: Annotations: @@ -89,7 +93,7 @@ metadata: Then run: ```shell -$ kubectl create -f ./my-namespace.yaml +kubectl create -f ./my-namespace.yaml ``` Note that the name of your namespace must be a DNS compatible label. @@ -103,7 +107,7 @@ More information on `finalizers` can be found in the namespace [design doc](http 1. Delete a namespace with ```shell -$ kubectl delete namespaces +kubectl delete namespaces ``` {{< warning >}} @@ -122,7 +126,9 @@ Services, and Deployments used by the cluster. Assuming you have a fresh cluster, you can introspect the available namespace's by doing the following: ```shell -$ kubectl get namespaces +kubectl get namespaces +``` +``` NAME STATUS AGE default Active 13m ``` @@ -140,30 +146,32 @@ are relaxed to enable agile development. The operations team would like to maintain a space in the cluster where they can enforce strict procedures on who can or cannot manipulate the set of Pods, Services, and Deployments that run the production site. -One pattern this organization could follow is to partition the Kubernetes cluster into two namespaces: development and production. +One pattern this organization could follow is to partition the Kubernetes cluster into two namespaces: `development` and `production`. Let's create two new namespaces to hold our work. -Use the file [`namespace-dev.json`](/examples/admin/namespace-dev.json) which describes a development namespace: +Use the file [`namespace-dev.json`](/examples/admin/namespace-dev.json) which describes a `development` namespace: {{< codenew language="json" file="admin/namespace-dev.json" >}} -Create the development namespace using kubectl. +Create the `development` namespace using kubectl. ```shell -$ kubectl create -f https://k8s.io/examples/admin/namespace-dev.json +kubectl create -f https://k8s.io/examples/admin/namespace-dev.json ``` -And then let's create the production namespace using kubectl. +And then let's create the `production` namespace using kubectl. ```shell -$ kubectl create -f https://k8s.io/examples/admin/namespace-prod.json +kubectl create -f https://k8s.io/examples/admin/namespace-prod.json ``` To be sure things are right, list all of the namespaces in our cluster. ```shell -$ kubectl get namespaces --show-labels +kubectl get namespaces --show-labels +``` +``` NAME STATUS AGE LABELS default Active 32m development Active 29s name=development @@ -176,12 +184,14 @@ A Kubernetes namespace provides the scope for Pods, Services, and Deployments in Users interacting with one namespace do not see the content in another namespace. -To demonstrate this, let's spin up a simple Deployment and Pods in the development namespace. +To demonstrate this, let's spin up a simple Deployment and Pods in the `development` namespace. We first check what is the current context: ```shell -$ kubectl config view +kubectl config view +``` +```yaml apiVersion: v1 clusters: - cluster: @@ -206,81 +216,96 @@ users: user: password: h5M0FtUUIflBSdI7 username: admin +``` -$ kubectl config current-context +```shell +kubectl config current-context +``` +``` lithe-cocoa-92103_kubernetes ``` The next step is to define a context for the kubectl client to work in each namespace. The values of "cluster" and "user" fields are copied from the current context. ```shell -$ kubectl config set-context dev --namespace=development --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes -$ kubectl config set-context prod --namespace=production --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes +kubectl config set-context dev --namespace=development --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes +kubectl config set-context prod --namespace=production --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes ``` The above commands provided two request contexts you can alternate against depending on what namespace you wish to work against. -Let's switch to operate in the development namespace. +Let's switch to operate in the `development` namespace. ```shell -$ kubectl config use-context dev +kubectl config use-context dev ``` You can verify your current context by doing the following: ```shell -$ kubectl config current-context +kubectl config current-context dev ``` -At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the development namespace. +At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the `development` namespace. Let's create some contents. ```shell -$ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2 +kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2 ``` -We have just created a deployment whose replica size is 2 that is running the pod called snowflake with a basic container that just serves the hostname. +We have just created a deployment whose replica size is 2 that is running the pod called `snowflake` with a basic container that just serves the hostname. Note that `kubectl run` creates deployments only on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead. If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/reference/generated/kubectl/kubectl-commands/#run) for more details. ```shell -$ kubectl get deployment +kubectl get deployment +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE snowflake 2 2 2 2 2m - -$ kubectl get pods -l run=snowflake +``` +```shell +kubectl get pods -l run=snowflake +``` +``` NAME READY STATUS RESTARTS AGE snowflake-3968820950-9dgr8 1/1 Running 0 2m snowflake-3968820950-vgc4n 1/1 Running 0 2m ``` -And this is great, developers are able to do what they want, and they do not have to worry about affecting content in the production namespace. +And this is great, developers are able to do what they want, and they do not have to worry about affecting content in the `production` namespace. -Let's switch to the production namespace and show how resources in one namespace are hidden from the other. +Let's switch to the `production` namespace and show how resources in one namespace are hidden from the other. ```shell -$ kubectl config use-context prod +kubectl config use-context prod ``` -The production namespace should be empty, and the following commands should return nothing. +The `production` namespace should be empty, and the following commands should return nothing. ```shell -$ kubectl get deployment -$ kubectl get pods +kubectl get deployment +kubectl get pods ``` Production likes to run cattle, so let's create some cattle pods. ```shell -$ kubectl run cattle --image=kubernetes/serve_hostname --replicas=5 +kubectl run cattle --image=kubernetes/serve_hostname --replicas=5 -$ kubectl get deployment +kubectl get deployment +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE cattle 5 5 5 5 10s +``` +```shell kubectl get pods -l run=cattle +``` +``` NAME READY STATUS RESTARTS AGE cattle-2263376956-41xy6 1/1 Running 0 34s cattle-2263376956-kw466 1/1 Running 0 34s diff --git a/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md b/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md index ed3fd0f715..0e26feba6e 100644 --- a/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md +++ b/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md @@ -26,20 +26,28 @@ To get familiar with Cilium easily you can follow the [Cilium Kubernetes Getting Started Guide](https://cilium.readthedocs.io/en/stable/gettingstarted/minikube/) to perform a basic DaemonSet installation of Cilium in minikube. -As Cilium requires a standalone etcd instance, for minikube you can deploy it -by running: +To start minikube, minimal version required is >= v0.33.1, run the with the +following arguments: ```shell -kubectl create -n kube-system -f https://raw.githubusercontent.com/cilium/cilium/v1.3/examples/kubernetes/addons/etcd/standalone-etcd.yaml +minikube version +``` +``` +minikube version: v0.33.1 ``` -After etcd is up and running you can deploy Cilium Kubernetes descriptor which -is a simple ''all-in-one'' YAML file that includes DaemonSet configurations for -Cilium, to connect to the etcd instance previously deployed as well as -appropriate RBAC settings: +```shell +minikube start --network-plugin=cni --memory=4096 +``` + +For minikube you can deploy this simple ''all-in-one'' YAML file that includes +DaemonSet configurations for Cilium, and the necessary configurations to connect +to the etcd instance deployed in minikube as well as appropriate RBAC settings: ```shell -$ kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.3/examples/kubernetes/1.12/cilium.yaml +kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.4/examples/kubernetes/1.13/cilium-minikube.yaml +``` +``` configmap/cilium-config created daemonset.apps/cilium created clusterrolebinding.rbac.authorization.k8s.io/cilium created @@ -54,7 +62,7 @@ policies using an example application. ## Deploying Cilium for Production Use For detailed instructions around deploying Cilium for production, see: -[Cilium Kubernetes Installation Guide](https://cilium.readthedocs.io/en/latest/kubernetes/install/) +[Cilium Kubernetes Installation Guide](https://cilium.readthedocs.io/en/stable/kubernetes/intro/) This documentation includes detailed requirements, instructions and example production DaemonSet files. @@ -83,7 +91,7 @@ There are two main components to be aware of: - One `cilium` Pod runs on each node in your cluster and enforces network policy on the traffic to/from Pods on that node using Linux BPF. - For production deployments, Cilium should leverage a key-value store -(e.g., etcd). The [Cilium Kubernetes Installation Guide](https://cilium.readthedocs.io/en/latest/kubernetes/install/) +(e.g., etcd). The [Cilium Kubernetes Installation Guide](https://cilium.readthedocs.io/en/stable/kubernetes/intro/) will provide the necessary steps on how to install this required key-value store as well how to configure it in Cilium. diff --git a/content/en/docs/tasks/administer-cluster/out-of-resource.md b/content/en/docs/tasks/administer-cluster/out-of-resource.md index 9d74dc289b..9051f57d15 100644 --- a/content/en/docs/tasks/administer-cluster/out-of-resource.md +++ b/content/en/docs/tasks/administer-cluster/out-of-resource.md @@ -225,7 +225,7 @@ If necessary, `kubelet` evicts Pods one at a time to reclaim disk when `DiskPres is encountered. If the `kubelet` is responding to `inode` starvation, it reclaims `inodes` by evicting Pods with the lowest quality of service first. If the `kubelet` is responding to lack of available disk, it ranks Pods within a quality of service -that consumes the largest amount of disk and kill those first. +that consumes the largest amount of disk and kills those first. #### With `imagefs` @@ -277,7 +277,7 @@ pods on the node. ## Node OOM Behavior -If the node experiences a system OOM (out of memory) event prior to the `kubelet` is able to reclaim memory, +If the node experiences a system OOM (out of memory) event prior to the `kubelet` being able to reclaim memory, the node depends on the [oom_killer](https://lwn.net/Articles/391222/) to respond. The `kubelet` sets a `oom_score_adj` value for each container based on the quality of service for the Pod. diff --git a/content/en/docs/tasks/administer-cluster/reconfigure-kubelet.md b/content/en/docs/tasks/administer-cluster/reconfigure-kubelet.md index f984c4c5fd..99fb27f946 100644 --- a/content/en/docs/tasks/administer-cluster/reconfigure-kubelet.md +++ b/content/en/docs/tasks/administer-cluster/reconfigure-kubelet.md @@ -9,7 +9,7 @@ content_template: templates/task {{% capture overview %}} {{< feature-state for_k8s_version="v1.11" state="beta" >}} -[Dynamic Kubelet Configuration](https://github.com/kubernetes/features/issues/281) +[Dynamic Kubelet Configuration](https://github.com/kubernetes/enhancements/issues/281) allows you to change the configuration of each Kubelet in a live Kubernetes cluster by deploying a ConfigMap and configuring each Node to use it. diff --git a/content/en/docs/tasks/administer-cluster/reserve-compute-resources.md b/content/en/docs/tasks/administer-cluster/reserve-compute-resources.md index 923db9a03c..2cd6afa304 100644 --- a/content/en/docs/tasks/administer-cluster/reserve-compute-resources.md +++ b/content/en/docs/tasks/administer-cluster/reserve-compute-resources.md @@ -211,7 +211,7 @@ Here is an example to illustrate Node Allocatable computation: * `--eviction-hard` is set to `memory.available<500Mi,nodefs.available<10%` Under this scenario, `Allocatable` will be `14.5 CPUs`, `28.5Gi` of memory and -`98Gi` of local storage. +`88Gi` of local storage. Scheduler ensures that the total memory `requests` across all pods on this node does not exceed `28.5Gi` and storage doesn't exceed `88Gi`. Kubelet evicts pods whenever the overall memory usage across pods exceeds `28.5Gi`, diff --git a/content/en/docs/tasks/administer-cluster/running-cloud-controller.md b/content/en/docs/tasks/administer-cluster/running-cloud-controller.md index e84a5a2813..83c24f639e 100644 --- a/content/en/docs/tasks/administer-cluster/running-cloud-controller.md +++ b/content/en/docs/tasks/administer-cluster/running-cloud-controller.md @@ -36,11 +36,6 @@ Successfully running cloud-controller-manager requires some changes to your clus * `kube-apiserver` and `kube-controller-manager` MUST NOT specify the `--cloud-provider` flag. This ensures that it does not run any cloud specific loops that would be run by cloud controller manager. In the future, this flag will be deprecated and removed. * `kubelet` must run with `--cloud-provider=external`. This is to ensure that the kubelet is aware that it must be initialized by the cloud controller manager before it is scheduled any work. -* `kube-apiserver` SHOULD NOT run the `PersistentVolumeLabel` admission controller - since the cloud controller manager takes over labeling persistent volumes. -* For the `cloud-controller-manager` to label persistent volumes, initializers will need to be enabled and an InitializerConifguration needs to be added to the system. Follow [these instructions](/docs/reference/access-authn-authz/extensible-admission-controllers/#enable-initializers-alpha-feature) to enable initializers. Use the following YAML to create the InitializerConfiguration: - -{{< codenew file="admin/cloud/pvl-initializer-config.yaml" >}} Keep in mind that setting up your cluster to use cloud controller manager will change your cluster behaviour in a few ways: @@ -53,7 +48,6 @@ As of v1.8, cloud controller manager can implement: * node controller - responsible for updating kubernetes nodes using cloud APIs and deleting kubernetes nodes that were deleted on your cloud. * service controller - responsible for loadbalancers on your cloud against services of type LoadBalancer. * route controller - responsible for setting up network routes on your cloud -* persistent volume labels controller - responsible for setting the zone and region labels on PersistentVolumes created in GCP and AWS clouds. * any other features you would like to implement if you are running an out-of-tree provider. diff --git a/content/en/docs/tasks/administer-cluster/safely-drain-node.md b/content/en/docs/tasks/administer-cluster/safely-drain-node.md index 2cb77e3149..4762d9902b 100644 --- a/content/en/docs/tasks/administer-cluster/safely-drain-node.md +++ b/content/en/docs/tasks/administer-cluster/safely-drain-node.md @@ -117,7 +117,7 @@ itself. To attempt an eviction (perhaps more REST-precisely, to attempt to You can attempt an eviction using `curl`: ```bash -$ curl -v -H 'Content-type: application/json' http://127.0.0.1:8080/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json +curl -v -H 'Content-type: application/json' http://127.0.0.1:8080/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json ``` The API can respond in one of three ways: diff --git a/content/en/docs/tasks/administer-cluster/static-pod.md b/content/en/docs/tasks/administer-cluster/static-pod.md index 1499c6b14a..d75cd2f4a9 100644 --- a/content/en/docs/tasks/administer-cluster/static-pod.md +++ b/content/en/docs/tasks/administer-cluster/static-pod.md @@ -25,7 +25,7 @@ Static pod can be created in two ways: either by using configuration file(s) or ### Configuration files -The configuration files are just standard pod definitions in json or yaml format in a specific directory. Use `kubelet --pod-manifest-path=` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there. +The configuration files are just standard pod definitions in json or yaml format in a specific directory. Use `kubelet --pod-manifest-path=` to start kubelet daemon or add the `staticPodPath: ` field in the [KubeletConfiguration file](/docs/tasks/administer-cluster/kubelet-config-file), which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there. Note that kubelet will ignore files starting with dots when scanning the specified directory. For example, this is how to start a simple web server as a static pod: @@ -58,7 +58,7 @@ spec: EOF ``` -3. Configure your kubelet daemon on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument. +3. Configure your kubelet daemon on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument or add the `staticPodPath: ` field in the [KubeletConfiguration file](/docs/tasks/administer-cluster/kubelet-config-file). On Fedora edit `/etc/kubernetes/kubelet` to include this line: ``` @@ -79,7 +79,7 @@ Kubelet periodically downloads a file specified by `--manifest-url=` argume ## Behavior of static pods -When kubelet starts, it automatically starts all pods defined in directory specified in `--pod-manifest-path=` or `--manifest-url=` arguments, i.e. our static-web. (It may take some time to pull nginx image, be patient…): +When kubelet starts, it automatically starts all pods defined in directory specified in `--pod-manifest-path=` or `--manifest-url=` arguments or add the `staticPodPath: ` field in the [KubeletConfiguration file](/docs/tasks/administer-cluster/kubelet-config-file), i.e. our static-web. (It may take some time to pull nginx image, be patient…): ```shell [joe@my-node1 ~] $ docker ps diff --git a/content/en/docs/tasks/administer-cluster/sysctl-cluster.md b/content/en/docs/tasks/administer-cluster/sysctl-cluster.md index 3fadc04540..4262d943de 100644 --- a/content/en/docs/tasks/administer-cluster/sysctl-cluster.md +++ b/content/en/docs/tasks/administer-cluster/sysctl-cluster.md @@ -36,7 +36,7 @@ process file system. The parameters cover various subsystems such as: To get a list of all parameters, you can run ```shell -$ sudo sysctl -a +sudo sysctl -a ``` ## Enabling Unsafe Sysctls @@ -76,14 +76,14 @@ application tuning. _Unsafe_ sysctls are enabled on a node-by-node basis with a flag of the kubelet, e.g.: ```shell -$ kubelet --allowed-unsafe-sysctls \ +kubelet --allowed-unsafe-sysctls \ 'kernel.msg*,net.ipv4.route.min_pmtu' ... ``` For minikube, this can be done via the `extra-config` flag: ```shell -$ minikube start --extra-config="kubelet.AllowedUnsafeSysctls=kernel.msg*,net.ipv4.route.min_pmtu"... +minikube start --extra-config="kubelet.allowed-unsafe-sysctls=kernel.msg*,net.ipv4.route.min_pmtu"... ``` Only _namespaced_ sysctls can be enabled this way. diff --git a/content/en/docs/tasks/administer-federation/_index.md b/content/en/docs/tasks/administer-federation/_index.md deleted file mode 100755 index e3cb1fe59d..0000000000 --- a/content/en/docs/tasks/administer-federation/_index.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "Federation - Run an App on Multiple Clusters" -weight: 160 ---- - diff --git a/content/en/docs/tasks/configure-pod-container/assign-cpu-resource.md b/content/en/docs/tasks/configure-pod-container/assign-cpu-resource.md index 516e33d1ed..55abb118dd 100644 --- a/content/en/docs/tasks/configure-pod-container/assign-cpu-resource.md +++ b/content/en/docs/tasks/configure-pod-container/assign-cpu-resource.md @@ -22,7 +22,7 @@ Each node in your cluster must have at least 1 CPU. A few of the steps on this page require you to run the [metrics-server](https://github.com/kubernetes-incubator/metrics-server) -service in your cluster. If you do not have the metrics-server +service in your cluster. If you have the metrics-server running, you can skip those steps. If you are running minikube, run the following command to enable diff --git a/content/en/docs/tasks/configure-pod-container/assign-memory-resource.md b/content/en/docs/tasks/configure-pod-container/assign-memory-resource.md index fd8e610a21..df19079cbe 100644 --- a/content/en/docs/tasks/configure-pod-container/assign-memory-resource.md +++ b/content/en/docs/tasks/configure-pod-container/assign-memory-resource.md @@ -21,7 +21,7 @@ Each node in your cluster must have at least 300 MiB of memory. A few of the steps on this page require you to run the [metrics-server](https://github.com/kubernetes-incubator/metrics-server) -service in your cluster. If you do not have the metrics-server +service in your cluster. If you have the metrics-server running, you can skip those steps. If you are running Minikube, run the following command to enable the @@ -223,7 +223,7 @@ kubectl describe nodes The output includes a record of the Container being killed because of an out-of-memory condition: ``` -Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child +Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child ``` Delete your Pod: diff --git a/content/en/docs/tasks/configure-pod-container/assign-pods-nodes.md b/content/en/docs/tasks/configure-pod-container/assign-pods-nodes.md index d1b0a42128..25247a1a00 100644 --- a/content/en/docs/tasks/configure-pod-container/assign-pods-nodes.md +++ b/content/en/docs/tasks/configure-pod-container/assign-pods-nodes.md @@ -29,9 +29,9 @@ Kubernetes cluster. ```shell NAME STATUS ROLES AGE VERSION - worker0 Ready 1d v1.12.0 - worker1 Ready 1d v1.12.0 - worker2 Ready 1d v1.12.0 + worker0 Ready 1d v1.13.0 + worker1 Ready 1d v1.13.0 + worker2 Ready 1d v1.13.0 ``` 1. Chose one of your nodes, and add a label to it: @@ -51,9 +51,9 @@ Kubernetes cluster. ```shell NAME STATUS ROLES AGE VERSION LABELS - worker0 Ready 1d v1.12.0 ...,disktype=ssd,kubernetes.io/hostname=worker0 - worker1 Ready 1d v1.12.0 ...,kubernetes.io/hostname=worker1 - worker2 Ready 1d v1.12.0 ...,kubernetes.io/hostname=worker2 + worker0 Ready 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0 + worker1 Ready 1d v1.13.0 ...,kubernetes.io/hostname=worker1 + worker2 Ready 1d v1.13.0 ...,kubernetes.io/hostname=worker2 ``` In the preceding output, you can see that the `worker0` node has a @@ -86,6 +86,13 @@ a `disktype=ssd` label. NAME READY STATUS RESTARTS AGE IP NODE nginx 1/1 Running 0 13s 10.200.0.4 worker0 ``` +## Create a pod that gets scheduled to specific node + +You can also schedule a pod to one specific node via setting `nodeName`. + +{{< codenew file="pods/pod-nginx-specific-node.yaml" >}} + +Use the configuration file to create a pod that will get scheduled on `foo-node` only. {{% /capture %}} diff --git a/content/en/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md b/content/en/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md index d3e09d1208..36c4f758ac 100644 --- a/content/en/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md +++ b/content/en/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md @@ -173,6 +173,12 @@ the Container has been restarted: kubectl describe pod liveness-http ``` +In releases prior to v1.13 (including v1.13), if the environment variable +`http_proxy` (or `HTTP_PROXY`) is set on the node where a pod is running, +the HTTP liveness probe uses that proxy. +In releases after v1.13, local HTTP proxy environment variable settings do not +affect the HTTP liveness probe. + ## Define a TCP liveness probe A third type of liveness probe uses a TCP Socket. With this configuration, the @@ -229,12 +235,17 @@ livenessProbe: Sometimes, applications are temporarily unable to serve traffic. For example, an application might need to load large data or configuration -files during startup. In such cases, you don't want to kill the application, +files during startup, or depend on external services after startup. +In such cases, you don't want to kill the application, but you don’t want to send it requests either. Kubernetes provides readiness probes to detect and mitigate these situations. A pod with containers reporting that they are not ready does not receive traffic through Kubernetes Services. +{{< note >}} +Readiness probes runs on the container during its whole lifecycle. +{{< /note >}} + Readiness probes are configured similarly to liveness probes. The only difference is that you use the `readinessProbe` field instead of the `livenessProbe` field. diff --git a/content/en/docs/tasks/configure-pod-container/configure-pod-configmap.md b/content/en/docs/tasks/configure-pod-container/configure-pod-configmap.md index a34de6eb45..c8c6106438 100644 --- a/content/en/docs/tasks/configure-pod-container/configure-pod-configmap.md +++ b/content/en/docs/tasks/configure-pod-container/configure-pod-configmap.md @@ -2,6 +2,9 @@ title: Configure a Pod to Use a ConfigMap content_template: templates/task weight: 150 +card: + name: tasks + weight: 50 --- {{% capture overview %}} @@ -44,16 +47,20 @@ You can use `kubectl create configmap` to create a ConfigMap from multiple files For example: ```shell -mkdir -p configure-pod-container/configmap/kubectl/ -wget https://k8s.io/docs/tasks/configure-pod-container/configmap/kubectl/game.properties -O configure-pod-container/configmap/kubectl/game.properties -wget https://k8s.io/docs/tasks/configure-pod-container/configmap/kubectl/ui.properties -O configure-pod-container/configmap/kubectl/ui.properties -kubectl create configmap game-config --from-file=configure-pod-container/configmap/kubectl/ +# Create the local directory +mkdir -p configure-pod-container/configmap/ + +# Download the sample files into `configure-pod-container/configmap/` directory +wget https://k8s.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties +wget https://k8s.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties + +# Create the configmap +kubectl create configmap game-config --from-file=configure-pod-container/configmap/ ``` -combines the contents of the `configure-pod-container/configmap/kubectl/` directory +combines the contents of the `configure-pod-container/configmap/` directory ```shell -ls configure-pod-container/configmap/kubectl/ game.properties ui.properties ``` @@ -62,6 +69,10 @@ into the following ConfigMap: ```shell kubectl describe configmaps game-config +``` + +where the output is similar to this: +``` Name: game-config Namespace: default Labels: @@ -73,11 +84,12 @@ game.properties: 158 bytes ui.properties: 83 bytes ``` -The `game.properties` and `ui.properties` files in the `configure-pod-container/configmap/kubectl/` directory are represented in the `data` section of the ConfigMap. +The `game.properties` and `ui.properties` files in the `configure-pod-container/configmap/` directory are represented in the `data` section of the ConfigMap. ```shell kubectl get configmaps game-config -o yaml ``` +The output is similar to this: ```yaml apiVersion: v1 @@ -112,13 +124,18 @@ You can use `kubectl create configmap` to create a ConfigMap from an individual For example, ```shell -kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/kubectl/game.properties +kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties ``` would produce the following ConfigMap: ```shell kubectl describe configmaps game-config-2 +``` + +where the output is similar to this: + +``` Name: game-config-2 Namespace: default Labels: @@ -129,14 +146,21 @@ Data game.properties: 158 bytes ``` -You can pass in the `--from-file` argument multiple times to create a ConfigMap from multiple data sources. +You can pass in the `--from-file` argument multiple times to create a ConfigMap from multiple data sources. ```shell -kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/kubectl/game.properties --from-file=configure-pod-container/configmap/kubectl/ui.properties +kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties ``` +Describe the above `game-config-2` configmap created + ```shell kubectl describe configmaps game-config-2 +``` + +The output is similar to this: + +``` Name: game-config-2 Namespace: default Labels: @@ -149,6 +173,7 @@ ui.properties: 83 bytes ``` Use the option `--from-env-file` to create a ConfigMap from an env-file, for example: + ```shell # Env-files contain a list of environment variables. # These syntax rules apply: @@ -157,8 +182,11 @@ Use the option `--from-env-file` to create a ConfigMap from an env-file, for exa # Blank lines are ignored. # There is no special handling of quotation marks (i.e. they will be part of the ConfigMap value)). -wget https://k8s.io/docs/tasks/configure-pod-container/configmap/kubectl/game-env-file.properties -O configure-pod-container/configmap/kubectl/game-env-file.properties -cat configure-pod-container/configmap/kubectl/game-env-file.properties +# Download the sample files into `configure-pod-container/configmap/` directory +wget https://k8s.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties + +# The env-file `game-env-file.properties` looks like below +cat configure-pod-container/configmap/game-env-file.properties enemies=aliens lives=3 allowed="true" @@ -168,7 +196,7 @@ allowed="true" ```shell kubectl create configmap game-config-env-file \ - --from-env-file=configure-pod-container/configmap/kubectl/game-env-file.properties + --from-env-file=configure-pod-container/configmap/game-env-file.properties ``` would produce the following ConfigMap: @@ -177,6 +205,7 @@ would produce the following ConfigMap: kubectl get configmap game-config-env-file -o yaml ``` +where the output is similar to this: ```yaml apiVersion: v1 data: @@ -196,10 +225,13 @@ metadata: When passing `--from-env-file` multiple times to create a ConfigMap from multiple data sources, only the last env-file is used: ```shell -wget https://k8s.io/docs/tasks/configure-pod-container/configmap/kubectl/ui-env-file.properties -O configure-pod-container/configmap/kubectl/ui-env-file.properties +# Download the sample files into `configure-pod-container/configmap/` directory +wget https://k8s.io/examples/configmap/ui-env-file.properties -O configure-pod-container/configmap/ui-env-file.properties + +# Create the configmap kubectl create configmap config-multi-env-files \ - --from-env-file=configure-pod-container/configmap/kubectl/game-env-file.properties \ - --from-env-file=configure-pod-container/configmap/kubectl/ui-env-file.properties + --from-env-file=configure-pod-container/configmap/game-env-file.properties \ + --from-env-file=configure-pod-container/configmap/ui-env-file.properties ``` would produce the following ConfigMap: @@ -208,6 +240,7 @@ would produce the following ConfigMap: kubectl get configmap config-multi-env-files -o yaml ``` +where the output is similar to this: ```yaml apiVersion: v1 data: @@ -237,11 +270,15 @@ where `` is the key you want to use in the ConfigMap and `}} - ```yaml - apiVersion: v1 - kind: Pod - metadata: - name: dapi-test-pod - spec: - containers: - - name: test-container - image: k8s.gcr.io/busybox - command: [ "/bin/sh", "-c", "env" ] - env: - # Define the environment variable - - name: SPECIAL_LEVEL_KEY - valueFrom: - configMapKeyRef: - # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY - name: special-config - # Specify the key associated with the value - key: special.how - restartPolicy: Never - ``` - -1. Save the changes to the Pod specification. Now, the Pod's output includes `SPECIAL_LEVEL_KEY=very`. + Create the Pod: + + ```shell + kubectl create -f https://k8s.io/examples/pods/pod-single-configmap-env-variable.yaml + ``` + + Now, the Pod's output includes `SPECIAL_LEVEL_KEY=very`. ### Define container environment variables with data from multiple ConfigMaps -1. As with the previous example, create the ConfigMaps first. + * As with the previous example, create the ConfigMaps first. - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: special-config - namespace: default - data: - special.how: very - ``` + {{< codenew file="configmap/configmaps.yaml" >}} - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: env-config - namespace: default - data: - log_level: INFO - ``` - -1. Define the environment variables in the Pod specification. - - ```yaml - apiVersion: v1 - kind: Pod - metadata: - name: dapi-test-pod - spec: - containers: - - name: test-container - image: k8s.gcr.io/busybox - command: [ "/bin/sh", "-c", "env" ] - env: - - name: SPECIAL_LEVEL_KEY - valueFrom: - configMapKeyRef: - name: special-config - key: special.how - - name: LOG_LEVEL - valueFrom: - configMapKeyRef: - name: env-config - key: log_level - restartPolicy: Never - ``` + Create the ConfigMap: -1. Save the changes to the Pod specification. Now, the Pod's output includes `SPECIAL_LEVEL_KEY=very` and `LOG_LEVEL=INFO`. + ```shell + kubectl create -f https://k8s.io/examples/configmap/configmaps.yaml + ``` + +* Define the environment variables in the Pod specification. + + {{< codenew file="pods/pod-multiple-configmap-env-variable.yaml" >}} + + Create the Pod: + + ```shell + kubectl create -f https://k8s.io/examples/pods/pod-multiple-configmap-env-variable.yaml + ``` + + Now, the Pod's output includes `SPECIAL_LEVEL_KEY=very` and `LOG_LEVEL=INFO`. ## Configure all key-value pairs in a ConfigMap as container environment variables - {{< note >}} - This functionality is available in Kubernetes v1.6 and later. - {{< /note >}} +{{< note >}} +This functionality is available in Kubernetes v1.6 and later. +{{< /note >}} -1. Create a ConfigMap containing multiple key-value pairs. +* Create a ConfigMap containing multiple key-value pairs. - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: special-config - namespace: default - data: - SPECIAL_LEVEL: very - SPECIAL_TYPE: charm - ``` + {{< codenew file="configmap/configmap-multikeys.yaml" >}} -1. Use `envFrom` to define all of the ConfigMap's data as container environment variables. The key from the ConfigMap becomes the environment variable name in the Pod. + Create the ConfigMap: + + ```shell + kubectl create -f https://k8s.io/examples/configmap/configmap-multikeys.yaml + ``` + +* Use `envFrom` to define all of the ConfigMap's data as container environment variables. The key from the ConfigMap becomes the environment variable name in the Pod. - ```yaml - apiVersion: v1 - kind: Pod - metadata: - name: dapi-test-pod - spec: - containers: - - name: test-container - image: k8s.gcr.io/busybox - command: [ "/bin/sh", "-c", "env" ] - envFrom: - - configMapRef: - name: special-config - restartPolicy: Never - ``` + {{< codenew file="pods/pod-configmap-envFrom.yaml" >}} -1. Save the changes to the Pod specification. Now, the Pod's output includes `SPECIAL_LEVEL=very` and `SPECIAL_TYPE=charm`. + Create the Pod: + + ```shell + kubectl create -f https://k8s.io/examples/pods/pod-configmap-envFrom.yaml + ``` + + Now, the Pod's output includes `SPECIAL_LEVEL=very` and `SPECIAL_TYPE=charm`. ## Use ConfigMap-defined environment variables in Pod commands You can use ConfigMap-defined environment variables in the `command` section of the Pod specification using the `$(VAR_NAME)` Kubernetes substitution syntax. -For example: +For example, the following Pod specification -The following Pod specification +{{< codenew file="pods/pod-configmap-env-var-valueFrom.yaml" >}} -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: dapi-test-pod -spec: - containers: - - name: test-container - image: k8s.gcr.io/busybox - command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] - env: - - name: SPECIAL_LEVEL_KEY - valueFrom: - configMapKeyRef: - name: special-config - key: SPECIAL_LEVEL - - name: SPECIAL_TYPE_KEY - valueFrom: - configMapKeyRef: - name: special-config - key: SPECIAL_TYPE - restartPolicy: Never +created by running + +```shell +kubectl create -f https://k8s.io/examples/pods/pod-configmap-env-var-valueFrom.yaml ``` produces the following output in the `test-container` container: @@ -469,15 +432,12 @@ As explained in [Create ConfigMaps from files](#create-configmaps-from-files), w The examples in this section refer to a ConfigMap named special-config, shown below. -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: special-config - namespace: default -data: - special.level: very - special.type: charm +{{< codenew file="configmap/configmap-multikeys.yaml" >}} + +Create the ConfigMap: + +```shell +kubectl create -f https://k8s.io/examples/configmap/configmap-multikeys.yaml ``` ### Populate a Volume with data stored in a ConfigMap @@ -486,29 +446,15 @@ Add the ConfigMap name under the `volumes` section of the Pod specification. This adds the ConfigMap data to the directory specified as `volumeMounts.mountPath` (in this case, `/etc/config`). The `command` section references the `special.level` item stored in the ConfigMap. -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: dapi-test-pod -spec: - containers: - - name: test-container - image: k8s.gcr.io/busybox - command: [ "/bin/sh", "-c", "ls /etc/config/" ] - volumeMounts: - - name: config-volume - mountPath: /etc/config - volumes: - - name: config-volume - configMap: - # Provide the name of the ConfigMap containing the files you want - # to add to the container - name: special-config - restartPolicy: Never +{{< codenew file="pods/pod-configmap-volume.yaml" >}} + +Create the Pod: + +```shell +kubectl create -f https://k8s.io/examples/pods/pod-configmap-volume.yaml ``` -When the pod runs, the command (`"ls /etc/config/"`) produces the output below: +When the pod runs, the command `ls /etc/config/` produces the output below: ```shell special.level @@ -524,30 +470,15 @@ If there are some files in the `/etc/config/` directory, they will be deleted. Use the `path` field to specify the desired file path for specific ConfigMap items. In this case, the `special.level` item will be mounted in the `config-volume` volume at `/etc/config/keys`. -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: dapi-test-pod -spec: - containers: - - name: test-container - image: k8s.gcr.io/busybox - command: [ "/bin/sh","-c","cat /etc/config/keys" ] - volumeMounts: - - name: config-volume - mountPath: /etc/config - volumes: - - name: config-volume - configMap: - name: special-config - items: - - key: special.level - path: keys - restartPolicy: Never +{{< codenew file="pods/pod-configmap-volume-specific-key.yaml" >}} + +Create the Pod: + +```shell +kubectl create -f https://k8s.io/examples/pods/pod-configmap-volume-specific-key.yaml ``` -When the pod runs, the command (`"cat /etc/config/keys"`) produces the output below: +When the pod runs, the command `cat /etc/config/keys` produces the output below: ```shell very @@ -563,9 +494,7 @@ basis. The [Secrets](/docs/concepts/configuration/secret/#using-secrets-as-files When a ConfigMap already being consumed in a volume is updated, projected keys are eventually updated as well. Kubelet is checking whether the mounted ConfigMap is fresh on every periodic sync. However, it is using its local ttl-based cache for getting the current value of the ConfigMap. As a result, the total delay from the moment when the ConfigMap is updated to the moment when new keys are projected to the pod can be as long as kubelet sync period + ttl of ConfigMaps cache in kubelet. {{< note >}} -A container using a ConfigMap as a -[subPath](/docs/concepts/storage/volumes/#using-subpath) volume will not receive -ConfigMap updates. +A container using a ConfigMap as a [subPath](/docs/concepts/storage/volumes/#using-subpath) volume will not receive ConfigMap updates. {{< /note >}} {{% /capture %}} @@ -608,14 +537,17 @@ data: ```shell kubectl get events + ``` + + The output is similar to this: + ``` LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names. ``` - ConfigMaps reside in a specific [namespace](/docs/concepts/overview/working-with-objects/namespaces/). A ConfigMap can only be referenced by pods residing in the same namespace. -- Kubelet doesn't support the use of ConfigMaps for pods not found on the API server. - This includes pods created via the Kubelet's --manifest-url flag, --config flag, or the Kubelet REST API. +- Kubelet doesn't support the use of ConfigMaps for pods not found on the API server. This includes pods created via the Kubelet's `--manifest-url` flag, `--config` flag, or the Kubelet REST API. {{< note >}} These are not commonly-used ways to create pods. @@ -629,3 +561,4 @@ data: {{% /capture %}} +` diff --git a/content/en/docs/tasks/configure-pod-container/configure-projected-volume-storage.md b/content/en/docs/tasks/configure-pod-container/configure-projected-volume-storage.md index 19c5ecc744..122f3e0beb 100644 --- a/content/en/docs/tasks/configure-pod-container/configure-projected-volume-storage.md +++ b/content/en/docs/tasks/configure-pod-container/configure-projected-volume-storage.md @@ -50,10 +50,10 @@ the Pod: kubectl get --watch pod test-projected-volume ``` The output looks like this: - +```shell NAME READY STATUS RESTARTS AGE test-projected-volume 1/1 Running 0 14s - +``` 1. In another terminal, get a shell to the running Container: ```shell kubectl exec -it test-projected-volume -- /bin/sh diff --git a/content/en/docs/tasks/configure-pod-container/configure-service-account.md b/content/en/docs/tasks/configure-pod-container/configure-service-account.md index 1777b5e41a..2cc040aa28 100644 --- a/content/en/docs/tasks/configure-pod-container/configure-service-account.md +++ b/content/en/docs/tasks/configure-pod-container/configure-service-account.md @@ -11,22 +11,20 @@ weight: 90 {{% capture overview %}} A service account provides an identity for processes that run in a Pod. -*This is a user introduction to Service Accounts. See also the +*This is a user introduction to Service Accounts. See also the [Cluster Admin Guide to Service Accounts](/docs/reference/access-authn-authz/service-accounts-admin/).* {{< note >}} This document describes how service accounts behave in a cluster set up -as recommended by the Kubernetes project. Your cluster administrator may have +as recommended by the Kubernetes project. Your cluster administrator may have customized the behavior in your cluster, in which case this documentation may not apply. {{< /note >}} When you (a human) access the cluster (for example, using `kubectl`), you are authenticated by the apiserver as a particular User Account (currently this is -usually `admin`, unless your cluster administrator has customized your -cluster). Processes in containers inside pods can also contact the apiserver. -When they do, they are authenticated as a particular Service Account (for example, -`default`). +usually `admin`, unless your cluster administrator has customized your cluster). Processes in containers inside pods can also contact the apiserver. +When they do, they are authenticated as a particular Service Account (for example, `default`). {{% /capture %}} @@ -43,16 +41,12 @@ When they do, they are authenticated as a particular Service Account (for exampl When you create a pod, if you do not specify a service account, it is automatically assigned the `default` service account in the same namespace. -If you get the raw json or yaml for a pod you have created (for example, `kubectl get pods/podname -o yaml`), -you can see the `spec.serviceAccountName` field has been -[automatically set](/docs/user-guide/working-with-resources/#resources-are-automatically-modified). +If you get the raw json or yaml for a pod you have created (for example, `kubectl get pods/ -o yaml`), you can see the `spec.serviceAccountName` field has been [automatically set](/docs/user-guide/working-with-resources/#resources-are-automatically-modified). -You can access the API from inside a pod using automatically mounted service account credentials, -as described in [Accessing the Cluster](/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod). +You can access the API from inside a pod using automatically mounted service account credentials, as described in [Accessing the Cluster](/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod). The API permissions of the service account depend on the [authorization plugin and policy](/docs/reference/access-authn-authz/authorization/#authorization-modules) in use. -In version 1.6+, you can opt out of automounting API credentials for a service account by setting -`automountServiceAccountToken: false` on the service account: +In version 1.6+, you can opt out of automounting API credentials for a service account by setting `automountServiceAccountToken: false` on the service account: ```yaml apiVersion: v1 @@ -85,6 +79,10 @@ You can list this and any other serviceAccount resources in the namespace with t ```shell kubectl get serviceAccounts +``` +The output is similar to this: + +``` NAME SECRETS AGE default 1 1d ``` @@ -98,13 +96,16 @@ kind: ServiceAccount metadata: name: build-robot EOF -serviceaccount/build-robot created ``` If you get a complete dump of the service account object, like this: ```shell kubectl get serviceaccounts/build-robot -o yaml +``` +The output is similar to this: + +``` apiVersion: v1 kind: ServiceAccount metadata: @@ -150,7 +151,6 @@ metadata: kubernetes.io/service-account.name: build-robot type: kubernetes.io/service-account-token EOF -secret/build-robot-secret created ``` Now you can confirm that the newly built secret is populated with an API token for the "build-robot" service account. @@ -159,6 +159,10 @@ Any tokens for non-existent service accounts will be cleaned up by the token con ```shell kubectl describe secrets/build-robot-secret +``` +The output is similar to this: + +``` Name: build-robot-secret Namespace: default Labels: @@ -181,10 +185,15 @@ The content of `token` is elided here. ## Add ImagePullSecrets to a service account First, create an imagePullSecret, as described [here](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod). -Next, verify it has been created. For example: +Next, verify it has been created. For example: ```shell kubectl get secrets myregistrykey +``` + +The output is similar to this: + +``` NAME TYPE DATA AGE myregistrykey   kubernetes.io/.dockerconfigjson   1       1d ``` @@ -195,12 +204,15 @@ Next, modify the default service account for the namespace to use this secret as kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}' ``` -Interactive version requiring manual edit: +Interactive version requires manual edit: ```shell kubectl get serviceaccounts default -o yaml > ./sa.yaml +``` -cat sa.yaml +The output of the `sa.yaml` file is similar to this: + +```shell apiVersion: v1 kind: ServiceAccount metadata: @@ -212,13 +224,13 @@ metadata: uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 secrets: - name: default-token-uudge +``` -vi sa.yaml -[editor session not shown] -[delete line with key "resourceVersion"] -[add lines with "imagePullSecrets:"] +Using your editor of choice (for example `vi`), open the `sa.yaml` file, delete line with key `resourceVersion`, add lines with `imagePullSecrets:` and save. -cat sa.yaml +The output of the `sa.yaml` file is similar to this: + +```shell apiVersion: v1 kind: ServiceAccount metadata: @@ -231,9 +243,12 @@ secrets: - name: default-token-uudge imagePullSecrets: - name: myregistrykey +``` +Finally replace the serviceaccount with the new updated `sa.yaml` file + +```shell kubectl replace serviceaccount default -f ./sa.yaml -serviceaccounts/default ``` Now, any new pods created in the current namespace will have this added to their spec: @@ -274,32 +289,17 @@ This behavior is configured on a PodSpec using a ProjectedVolume type called pod with a token with an audience of "vault" and a validity duration of two hours, you would configure the following in your PodSpec: -```yaml -kind: Pod -apiVersion: v1 -spec: - containers: - - image: nginx - name: nginx - volumeMounts: - - mountPath: /var/run/secrets/tokens - name: vault-token - volumes: - - name: vault-token - projected: - sources: - - serviceAccountToken: - path: vault-token - expirationSeconds: 7200 - audience: vault +{{< codenew file="pods/pod-projected-svc-token.yaml" >}} + +Create the Pod: + +```shell +kubectl create -f https://k8s.io/examples/pods/pod-projected-svc-token.yaml ``` The kubelet will request and store the token on behalf of the pod, make the -token available to the pod at a configurable file path, and refresh the token as -it approaches expiration. Kubelet proactively rotates the token if it is older -than 80% of its total TTL, or if the token is older than 24 hours. +token available to the pod at a configurable file path, and refresh the token as it approaches expiration. Kubelet proactively rotates the token if it is older than 80% of its total TTL, or if the token is older than 24 hours. -The application is responsible for reloading the token when it rotates. Periodic -reloading (e.g. once every 5 minutes) is sufficient for most usecases. +The application is responsible for reloading the token when it rotates. Periodic reloading (e.g. once every 5 minutes) is sufficient for most usecases. {{% /capture %}} diff --git a/content/en/docs/tasks/configure-pod-container/pull-image-private-registry.md b/content/en/docs/tasks/configure-pod-container/pull-image-private-registry.md index 836d89c0c4..f8e162fb00 100644 --- a/content/en/docs/tasks/configure-pod-container/pull-image-private-registry.md +++ b/content/en/docs/tasks/configure-pod-container/pull-image-private-registry.md @@ -56,9 +56,46 @@ The output contains a section similar to this: If you use a Docker credentials store, you won't see that `auth` entry but a `credsStore` entry with the name of the store as value. {{< /note >}} -## Create a Secret in the cluster that holds your authorization token +## Create a Secret based on existing Docker credentials {#registry-secret-existing-credentials} -A Kubernetes cluster uses the Secret of `docker-registry` type to authenticate with a container registry to pull a private image. +A Kubernetes cluster uses the Secret of `docker-registry` type to authenticate with +a container registry to pull a private image. + +If you already ran `docker login`, you can copy that credential into Kubernetes: + +```shell +kubectl create secret generic regcred \ + --from-file=.dockerconfigjson= \ + --type=kubernetes.io/dockerconfigjson +``` + +If you need more control (for example, to set a namespace or a label on the new +secret) then you can customise the Secret before storing it. +Be sure to: + +- set the name of the data item to `.dockerconfigjson` +- base64 encode the docker file and paste that string, unbroken + as the value for field `data[".dockerconfigjson"]` +- set `type` to `kubernetes.io/dockerconfigjson` + +Example: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey + namespace: awesomeapps +data: + .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== +type: kubernetes.io/dockerconfigjson +``` + +If you get the error message `error: no objects passed to create`, it may mean the base64 encoded string is invalid. +If you get an error message like `Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...`, it means +the base64 encoded string in the data was successfully decoded, but could not be parsed as a `.docker/config.json` file. + +## Create a Secret by providing credentials on the command line Create this Secret, naming it `regcred`: @@ -75,6 +112,13 @@ where: You have successfully set your Docker credentials in the cluster as a Secret called `regcred`. +{{< note >}} +Typing secrets on the command line may store them in your shell history unprotected, and +those secrets might also be visible to other users on your PC during the time that +`kubectl` is running. +{{< /note >}} + + ## Inspecting the Secret `regcred` To understand the contents of the `regcred` Secret you just created, start by viewing the Secret in YAML format: diff --git a/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md b/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md index 87cf2ef2f0..867b4bcd0d 100644 --- a/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md +++ b/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md @@ -297,7 +297,7 @@ INFO OpenShift file "foo-buildconfig.yaml" created ``` {{< note >}} -If you are manually pushing the Openshift artifacts using ``oc create -f``, you need to ensure that you push the imagestream artifact before the buildconfig artifact, to workaround this Openshift issue: https://github.com/openshift/origin/issues/4518 . +If you are manually pushing the OpenShift artifacts using ``oc create -f``, you need to ensure that you push the imagestream artifact before the buildconfig artifact, to workaround this OpenShift issue: https://github.com/openshift/origin/issues/4518 . {{< /note >}} ## `kompose up` diff --git a/content/en/docs/tasks/debug-application-cluster/audit.md b/content/en/docs/tasks/debug-application-cluster/audit.md index fdceb5c5e7..6d7735cb49 100644 --- a/content/en/docs/tasks/debug-application-cluster/audit.md +++ b/content/en/docs/tasks/debug-application-cluster/audit.md @@ -92,13 +92,13 @@ admins constructing their own audit profiles. ## Audit backends Audit backends persist audit events to an external storage. -[Kube-apiserver][kube-apiserver] out of the box provides two backends: +[Kube-apiserver][kube-apiserver] out of the box provides three backends: - Log backend, which writes events to a disk - Webhook backend, which sends events to an external API - Dynamic backend, which configures webhook backends through an AuditSink API object. -In both cases, audit events structure is defined by the API in the +In all cases, audit events structure is defined by the API in the `audit.k8s.io` API group. The current version of the API is [`v1`][auditing-api]. @@ -207,13 +207,13 @@ By default truncate is disabled in both `webhook` and `log`, a cluster administr {{< feature-state for_k8s_version="v1.13" state="alpha" >}} -In Kubernetes version 1.13, you can configure dynamic audit webhook backends AuditSink API objects. +In Kubernetes version 1.13, you can configure dynamic audit webhook backends AuditSink API objects. To enable dynamic auditing you must set the following apiserver flags: -- `--audit-dynamic-configuration`: the primary switch. When the feature is at GA, the only required flag. -- `--feature-gates=DynamicAuditing=true`: feature gate at alpha and beta. -- `--runtime-config=auditregistration.k8s.io/v1alpha1=true`: enable API. +- `--audit-dynamic-configuration`: the primary switch. When the feature is at GA, the only required flag. +- `--feature-gates=DynamicAuditing=true`: feature gate at alpha and beta. +- `--runtime-config=auditregistration.k8s.io/v1alpha1=true`: enable API. When enabled, an AuditSink object can be provisioned: @@ -276,7 +276,7 @@ Fluent-plugin-forest and fluent-plugin-rewrite-tag-filter are plugins for fluent 1. create a config file for fluentd ```none - $ cat < /etc/fluentd/config + $ cat <<'EOF' > /etc/fluentd/config # fluentd conf runs in the same host with kube-apiserver @type tail @@ -301,7 +301,11 @@ Fluent-plugin-forest and fluent-plugin-rewrite-tag-filter are plugins for fluent # route audit according to namespace element in context @type rewrite_tag_filter - rewriterule1 namespace ^(.+) ${tag}.$1 + + key namespace + pattern /^(.+)/ + tag ${tag}.$1 + @@ -321,6 +325,7 @@ Fluent-plugin-forest and fluent-plugin-rewrite-tag-filter are plugins for fluent include_time_key true + EOF ``` 1. start fluentd @@ -373,6 +378,7 @@ different users into different files. path=>"/var/log/kube-audit-%{[event][user][username]}/audit" } } + EOF ``` 1. start logstash @@ -418,8 +424,8 @@ plugin which supports full-text search and analytics. [gce-audit-profile]: https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/cluster/gce/gci/configure-helper.sh#L735 [kubeconfig]: /docs/tasks/access-application-cluster/configure-access-multiple-clusters/ [fluentd]: http://www.fluentd.org/ -[fluentd_install_doc]: http://docs.fluentd.org/v0.12/articles/quickstart#step1-installing-fluentd -[fluentd_plugin_management_doc]: https://docs.fluentd.org/v0.12/articles/plugin-management +[fluentd_install_doc]: https://docs.fluentd.org/v1.0/articles/quickstart#step-1:-installing-fluentd +[fluentd_plugin_management_doc]: https://docs.fluentd.org/v1.0/articles/plugin-management [logstash]: https://www.elastic.co/products/logstash [logstash_install_doc]: https://www.elastic.co/guide/en/logstash/current/installing-logstash.html [kube-aggregator]: /docs/concepts/api-extension/apiserver-aggregation diff --git a/content/en/docs/tasks/debug-application-cluster/debug-application-introspection.md b/content/en/docs/tasks/debug-application-cluster/debug-application-introspection.md index e64ba4db1d..a04200e9a0 100644 --- a/content/en/docs/tasks/debug-application-cluster/debug-application-introspection.md +++ b/content/en/docs/tasks/debug-application-cluster/debug-application-introspection.md @@ -26,12 +26,20 @@ For this example we'll use a Deployment to create two pods, similar to the earli Create deployment by running following command: ```shell -$ kubectl create -f https://k8s.io/examples/application/nginx-with-request.yaml +kubectl create -f https://k8s.io/examples/application/nginx-with-request.yaml +``` + +```none deployment.apps/nginx-deployment created ``` +Check pod status by following command: + ```shell -$ kubectl get pods +kubectl get pods +``` + +```none NAME READY STATUS RESTARTS AGE nginx-deployment-1006230814-6winp 1/1 Running 0 11s nginx-deployment-1006230814-fmgu3 1/1 Running 0 11s @@ -40,13 +48,16 @@ nginx-deployment-1006230814-fmgu3 1/1 Running 0 11s We can retrieve a lot more information about each of these pods using `kubectl describe pod`. For example: ```shell -$ kubectl describe pod nginx-deployment-1006230814-6winp +kubectl describe pod nginx-deployment-1006230814-6winp +``` + +```none Name: nginx-deployment-1006230814-6winp Namespace: default Node: kubernetes-node-wul5/10.240.0.9 Start Time: Thu, 24 Mar 2016 01:39:49 +0000 Labels: app=nginx,pod-template-hash=1006230814 -Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind" :"ReplicaSet","namespace":"default","name":"nginx-deployment-1956810328","uid":"14e607e7-8ba1-11e7-b5cb-fa16" ... +Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"nginx-deployment-1956810328","uid":"14e607e7-8ba1-11e7-b5cb-fa16" ... Status: Running IP: 10.244.0.6 Controllers: ReplicaSet/nginx-deployment-1006230814 @@ -112,7 +123,10 @@ Lastly, you see a log of recent events related to your Pod. The system compresse A common scenario that you can detect using events is when you've created a Pod that won't fit on any node. For example, the Pod might request more resources than are free on any node, or it might specify a label selector that doesn't match any nodes. Let's say we created the previous Deployment with 5 replicas (instead of 2) and requesting 600 millicores instead of 500, on a four-node cluster where each (virtual) machine has 1 CPU. In that case one of the Pods will not be able to schedule. (Note that because of the cluster addon pods such as fluentd, skydns, etc., that run on each node, if we requested 1000 millicores then none of the Pods would be able to schedule.) ```shell -$ kubectl get pods +kubectl get pods +``` + +```none NAME READY STATUS RESTARTS AGE nginx-deployment-1006230814-6winp 1/1 Running 0 7m nginx-deployment-1006230814-fmgu3 1/1 Running 0 7m @@ -124,7 +138,10 @@ nginx-deployment-1370807587-fz9sd 0/1 Pending 0 1m To find out why the nginx-deployment-1370807587-fz9sd pod is not running, we can use `kubectl describe pod` on the pending Pod and look at its events: ```shell -$ kubectl describe pod nginx-deployment-1370807587-fz9sd +kubectl describe pod nginx-deployment-1370807587-fz9sd +``` + +```none Name: nginx-deployment-1370807587-fz9sd Namespace: default Node: / @@ -178,8 +195,11 @@ To see events from all namespaces, you can use the `--all-namespaces` argument. In addition to `kubectl describe pod`, another way to get extra information about a pod (beyond what is provided by `kubectl get pod`) is to pass the `-o yaml` output format flag to `kubectl get pod`. This will give you, in YAML format, even more information than `kubectl describe pod`--essentially all of the information the system has about the Pod. Here you will see things like annotations (which are key-value metadata without the label restrictions, that is used internally by Kubernetes system components), restart policy, ports, and volumes. +```shell +kubectl get pod nginx-deployment-1006230814-6winp -o yaml +``` + ```yaml -$ kubectl get pod nginx-deployment-1006230814-6winp -o yaml apiVersion: v1 kind: Pod metadata: @@ -255,16 +275,22 @@ status: Sometimes when debugging it can be useful to look at the status of a node -- for example, because you've noticed strange behavior of a Pod that's running on the node, or to find out why a Pod won't schedule onto the node. As with Pods, you can use `kubectl describe node` and `kubectl get node -o yaml` to retrieve detailed information about nodes. For example, here's what you'll see if a node is down (disconnected from the network, or kubelet dies and won't restart, etc.). Notice the events that show the node is NotReady, and also notice that the pods are no longer running (they are evicted after five minutes of NotReady status). ```shell -$ kubectl get nodes +kubectl get nodes +``` + +```none NAME STATUS ROLES AGE VERSION -kubernetes-node-861h NotReady 1h v1.12.0 -kubernetes-node-bols Ready 1h v1.12.0 -kubernetes-node-st6x Ready 1h v1.12.0 -kubernetes-node-unaj Ready 1h v1.12.0 +kubernetes-node-861h NotReady 1h v1.13.0 +kubernetes-node-bols Ready 1h v1.13.0 +kubernetes-node-st6x Ready 1h v1.13.0 +kubernetes-node-unaj Ready 1h v1.13.0 ``` ```shell -$ kubectl describe node kubernetes-node-861h +kubectl describe node kubernetes-node-861h +``` + +```none Name: kubernetes-node-861h Role Labels: beta.kubernetes.io/arch=amd64 @@ -318,8 +344,9 @@ Events: ``` ```shell -$ kubectl get node kubernetes-node-861h -o yaml +kubectl get node kubernetes-node-861h -o yaml ``` + ```yaml apiVersion: v1 kind: Node diff --git a/content/en/docs/tasks/debug-application-cluster/debug-application.md b/content/en/docs/tasks/debug-application-cluster/debug-application.md index 94adc0578c..eb69129790 100644 --- a/content/en/docs/tasks/debug-application-cluster/debug-application.md +++ b/content/en/docs/tasks/debug-application-cluster/debug-application.md @@ -31,7 +31,7 @@ your Service? The first step in debugging a Pod is taking a look at it. Check the current state of the Pod and recent events with the following command: ```shell -$ kubectl describe pods ${POD_NAME} +kubectl describe pods ${POD_NAME} ``` Look at the state of the containers in the pod. Are they all `Running`? Have there been recent restarts? @@ -68,19 +68,19 @@ First, take a look at the logs of the current container: ```shell -$ kubectl logs ${POD_NAME} ${CONTAINER_NAME} +kubectl logs ${POD_NAME} ${CONTAINER_NAME} ``` If your container has previously crashed, you can access the previous container's crash log with: ```shell -$ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME} +kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME} ``` Alternately, you can run commands inside that container with `exec`: ```shell -$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN} +kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN} ``` {{< note >}} @@ -90,7 +90,7 @@ $ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ As an example, to look at the logs from a running Cassandra pod, you might run ```shell -$ kubectl exec cassandra -- cat /var/log/cassandra/system.log +kubectl exec cassandra -- cat /var/log/cassandra/system.log ``` If none of these approaches work, you can find the host machine that the pod is running on and SSH into that host, @@ -145,7 +145,7 @@ First, verify that there are endpoints for the service. For every Service object You can view this resource with: ```shell -$ kubectl get endpoints ${SERVICE_NAME} +kubectl get endpoints ${SERVICE_NAME} ``` Make sure that the endpoints match up with the number of containers that you expect to be a member of your service. @@ -168,7 +168,7 @@ spec: You can use: ```shell -$ kubectl get pods --selector=name=nginx,type=frontend +kubectl get pods --selector=name=nginx,type=frontend ``` to list pods that match this selector. Verify that the list matches the Pods that you expect to provide your Service. diff --git a/content/en/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md b/content/en/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md index 806347eff0..1f996b1042 100644 --- a/content/en/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md +++ b/content/en/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md @@ -63,7 +63,7 @@ case you can try several things: information: ```shell - kubectl get nodes -o yaml | grep '\sname\|cpu\|memory' + kubectl get nodes -o yaml | egrep '\sname:\|cpu:\|memory:' kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cap: .status.capacity}' ``` diff --git a/content/en/docs/tasks/debug-application-cluster/debug-service.md b/content/en/docs/tasks/debug-application-cluster/debug-service.md index 29a3cb047b..01b794ce00 100644 --- a/content/en/docs/tasks/debug-application-cluster/debug-service.md +++ b/content/en/docs/tasks/debug-application-cluster/debug-service.md @@ -41,7 +41,7 @@ OUTPUT If the command is "kubectl ARGS": ```shell -$ kubectl ARGS +kubectl ARGS OUTPUT ``` @@ -51,16 +51,18 @@ For many steps here you will want to see what a `Pod` running in the cluster sees. The simplest way to do this is to run an interactive busybox `Pod`: ```none -$ kubectl run -it --rm --restart=Never busybox --image=busybox sh -If you don't see a command prompt, try pressing enter. +kubectl run -it --rm --restart=Never busybox --image=busybox sh / # ``` +{{< note >}} +If you don't see a command prompt, try pressing enter. +{{< /note >}} If you already have a running `Pod` that you prefer to use, you can run a command in it using: ```shell -$ kubectl exec -c -- +kubectl exec -c -- ``` ## Setup @@ -70,7 +72,7 @@ probably debugging your own `Service` you can substitute your own details, or yo can follow along and get a second data point. ```shell -$ kubectl run hostnames --image=k8s.gcr.io/serve_hostname \ +kubectl run hostnames --image=k8s.gcr.io/serve_hostname \ --labels=app=hostnames \ --port=9376 \ --replicas=3 @@ -108,7 +110,7 @@ spec: Confirm your `Pods` are running: ```shell -$ kubectl get pods -l app=hostnames +kubectl get pods -l app=hostnames NAME READY STATUS RESTARTS AGE hostnames-632524106-bbpiw 1/1 Running 0 2m hostnames-632524106-ly40y 1/1 Running 0 2m @@ -134,7 +136,7 @@ wget: unable to resolve host address 'hostnames' So the first thing to check is whether that `Service` actually exists: ```shell -$ kubectl get svc hostnames +kubectl get svc hostnames No resources found. Error from server (NotFound): services "hostnames" not found ``` @@ -143,14 +145,14 @@ So we have a culprit, let's create the `Service`. As before, this is for the walk-through - you can use your own `Service`'s details here. ```shell -$ kubectl expose deployment hostnames --port=80 --target-port=9376 +kubectl expose deployment hostnames --port=80 --target-port=9376 service/hostnames exposed ``` And read it back, just to be sure: ```shell -$ kubectl get svc hostnames +kubectl get svc hostnames NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hostnames ClusterIP 10.0.1.175 80/TCP 5s ``` @@ -301,7 +303,7 @@ It might sound silly, but you should really double and triple check that your and verify it: ```shell -$ kubectl get service hostnames -o json +kubectl get service hostnames -o json ``` ```json { @@ -341,11 +343,13 @@ $ kubectl get service hostnames -o json } ``` -Is the port you are trying to access in `spec.ports[]`? Is the `targetPort` -correct for your `Pods` (many `Pods` choose to use a different port than the -`Service`)? If you meant it to be a numeric port, is it a number (9376) or a -string "9376"? If you meant it to be a named port, do your `Pods` expose a port -with the same name? Is the port's `protocol` the same as the `Pod`'s? +* Is the port you are trying to access in `spec.ports[]`? +* Is the `targetPort` correct for your `Pods` (many `Pods` choose to use a different port than the `Service`)? +* If you meant it to be a numeric port, is it a number (9376) or a +string "9376"? +* If you meant it to be a named port, do your `Pods` expose a port +with the same name? +* Is the port's `protocol` the same as the `Pod`'s? ## Does the Service have any Endpoints? @@ -356,7 +360,7 @@ actually being selected by the `Service`. Earlier we saw that the `Pods` were running. We can re-check that: ```shell -$ kubectl get pods -l app=hostnames +kubectl get pods -l app=hostnames NAME READY STATUS RESTARTS AGE hostnames-0uton 1/1 Running 0 1h hostnames-bvc05 1/1 Running 0 1h @@ -371,7 +375,7 @@ has. Inside the Kubernetes system is a control loop which evaluates the selector of every `Service` and saves the results into an `Endpoints` object. ```shell -$ kubectl get endpoints hostnames +kubectl get endpoints hostnames NAME ENDPOINTS hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376 ``` @@ -414,7 +418,7 @@ Another thing to check is that your `Pods` are not crashing or being restarted. Frequent restarts could lead to intermittent connectivity issues. ```shell -$ kubectl get pods -l app=hostnames +kubectl get pods -l app=hostnames NAME READY STATUS RESTARTS AGE hostnames-632524106-bbpiw 1/1 Running 0 2m hostnames-632524106-ly40y 1/1 Running 0 2m @@ -489,7 +493,7 @@ u@node$ iptables-save | grep hostnames There should be 2 rules for each port on your `Service` (just one in this example) - a "KUBE-PORTALS-CONTAINER" and a "KUBE-PORTALS-HOST". If you do -not see these, try restarting `kube-proxy` with the `-V` flag set to 4, and +not see these, try restarting `kube-proxy` with the `-v` flag set to 4, and then look at the logs again. Almost nobody should be using the "userspace" mode any more, so we won't spend @@ -559,7 +563,7 @@ If this still fails, look at the `kube-proxy` logs for specific lines like: Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376] ``` -If you don't see those, try restarting `kube-proxy` with the `-V` flag set to 4, and +If you don't see those, try restarting `kube-proxy` with the `-v` flag set to 4, and then look at the logs again. ### A Pod cannot reach itself via Service IP diff --git a/content/en/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md b/content/en/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md index 93ae3c38dd..327bfdf925 100644 --- a/content/en/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md +++ b/content/en/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md @@ -39,7 +39,9 @@ Now, when you create a cluster, a message will indicate that the Fluentd log collection daemons that run on each node will target Elasticsearch: ```shell -$ cluster/kube-up.sh +cluster/kube-up.sh +``` +``` ... Project: kubernetes-satnam Zone: us-central1-b @@ -63,7 +65,9 @@ all be running in the kube-system namespace soon after the cluster comes to life. ```shell -$ kubectl get pods --namespace=kube-system +kubectl get pods --namespace=kube-system +``` +``` NAME READY STATUS RESTARTS AGE elasticsearch-logging-v1-78nog 1/1 Running 0 2h elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h diff --git a/content/en/docs/tasks/debug-application-cluster/logging-stackdriver.md b/content/en/docs/tasks/debug-application-cluster/logging-stackdriver.md index 1a5bc4e8e6..2b1233efeb 100644 --- a/content/en/docs/tasks/debug-application-cluster/logging-stackdriver.md +++ b/content/en/docs/tasks/debug-application-cluster/logging-stackdriver.md @@ -135,7 +135,7 @@ synthetic log generator pod specification [counter-pod.yaml](/examples/debug/cou {{< codenew file="debug/counter-pod.yaml" >}} This pod specification has one container that runs a bash script -that writes out the value of a counter and the date once per +that writes out the value of a counter and the datetime once per second, and runs indefinitely. Let's create this pod in the default namespace. ```shell @@ -145,7 +145,9 @@ kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml You can observe the running pod: ```shell -$ kubectl get pods +kubectl get pods +``` +``` NAME READY STATUS RESTARTS AGE counter 1/1 Running 0 5m ``` @@ -155,7 +157,9 @@ has to download the container image first. When the pod status changes to `Runni you can use the `kubectl logs` command to view the output of this counter pod. ```shell -$ kubectl logs counter +kubectl logs counter +``` +``` 0: Mon Jan 1 00:00:00 UTC 2001 1: Mon Jan 1 00:00:01 UTC 2001 2: Mon Jan 1 00:00:02 UTC 2001 @@ -169,21 +173,27 @@ if the pod is evicted from the node, log files are lost. Let's demonstrate this by deleting the currently running counter container: ```shell -$ kubectl delete pod counter +kubectl delete pod counter +``` +``` pod "counter" deleted ``` and then recreating it: ```shell -$ kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml +kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml +``` +``` pod/counter created ``` After some time, you can access logs from the counter pod again: ```shell -$ kubectl logs counter +kubectl logs counter +``` +``` 0: Mon Jan 1 00:01:00 UTC 2001 1: Mon Jan 1 00:01:01 UTC 2001 2: Mon Jan 1 00:01:02 UTC 2001 @@ -226,7 +236,9 @@ It uses Stackdriver Logging [filtering syntax](https://cloud.google.com/logging/ to query specific logs. For example, you can run the following command: ```none -$ gcloud beta logging read 'logName="projects/$YOUR_PROJECT_ID/logs/count"' --format json | jq '.[].textPayload' +gcloud beta logging read 'logName="projects/$YOUR_PROJECT_ID/logs/count"' --format json | jq '.[].textPayload' +``` +``` ... "2: Mon Jan 1 00:01:02 UTC 2001\n" "1: Mon Jan 1 00:01:01 UTC 2001\n" @@ -329,7 +341,7 @@ by running the following command: kubectl get cm fluentd-gcp-config --namespace kube-system -o yaml > fluentd-gcp-configmap.yaml ``` -Then in the value for the key `containers.input.conf` insert a new filter right after +Then in the value of the key `containers.input.conf` insert a new filter right after the `source` section. {{< note >}} diff --git a/content/en/docs/tasks/debug-application-cluster/monitor-node-health.md b/content/en/docs/tasks/debug-application-cluster/monitor-node-health.md index 223cf63a7d..43b3c8fc86 100644 --- a/content/en/docs/tasks/debug-application-cluster/monitor-node-health.md +++ b/content/en/docs/tasks/debug-application-cluster/monitor-node-health.md @@ -88,7 +88,7 @@ Just create `node-problem-detector.yaml`, and put it under the addon pods direct ## Overwrite the Configuration The [default configuration](https://github.com/kubernetes/node-problem-detector/tree/v0.1/config) -is embedded when building the docker image of node problem detector. +is embedded when building the Docker image of node problem detector. However, you can use [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/) to overwrite it following the steps: diff --git a/content/en/docs/tasks/debug-application-cluster/resource-usage-monitoring.md b/content/en/docs/tasks/debug-application-cluster/resource-usage-monitoring.md index 609adc498c..805e77a847 100644 --- a/content/en/docs/tasks/debug-application-cluster/resource-usage-monitoring.md +++ b/content/en/docs/tasks/debug-application-cluster/resource-usage-monitoring.md @@ -52,10 +52,14 @@ The Kubelet acts as a bridge between the Kubernetes master and the nodes. It man cAdvisor is an open source container resource usage and performance analysis agent. It is purpose-built for containers and supports Docker containers natively. In Kubernetes, cAdvisor is integrated into the Kubelet binary. cAdvisor auto-discovers all containers in the machine and collects CPU, memory, filesystem, and network usage statistics. cAdvisor also provides the overall machine usage by analyzing the 'root' container on the machine. -On most Kubernetes clusters, cAdvisor exposes a simple UI for on-machine containers on port 4194. Here is a snapshot of part of cAdvisor's UI that shows the overall machine usage: +Kubelet exposes a simple cAdvisor UI for containers on a machine, via the default port 4194. +The picture below is an example showing the overall machine usage. However, this feature has been marked +deprecated in v1.10 and completely removed in v1.12. ![cAdvisor](/images/docs/cadvisor.png) +Starting from v1.13, you can [deploy cAdvisor as a DaemonSet](https://github.com/google/cadvisor/tree/master/deploy/kubernetes) for an access to the cAdvisor UI. + ## Full metrics pipelines Many full metrics solutions exist for Kubernetes. diff --git a/content/en/docs/tasks/extend-kubectl/kubectl-plugins.md b/content/en/docs/tasks/extend-kubectl/kubectl-plugins.md index 387b14c802..3d142e51af 100644 --- a/content/en/docs/tasks/extend-kubectl/kubectl-plugins.md +++ b/content/en/docs/tasks/extend-kubectl/kubectl-plugins.md @@ -96,25 +96,35 @@ sudo mv ./kubectl-foo /usr/local/bin You may now invoke your plugin as a `kubectl` command: ``` -$ kubectl foo +kubectl foo +``` +``` I am a plugin named kubectl-foo ``` All args and flags are passed as-is to the executable: ``` -$ kubectl foo version +kubectl foo version +``` +``` 1.0.0 ``` All environment variables are also passed as-is to the executable: ```bash -$ export KUBECONFIG=~/.kube/config -$ kubectl foo config +export KUBECONFIG=~/.kube/config +kubectl foo config +``` +``` /home//.kube/config +``` -$ KUBECONFIG=/etc/kube/config kubectl foo config +```shell +KUBECONFIG=/etc/kube/config kubectl foo config +``` +``` /etc/kube/config ``` @@ -142,22 +152,27 @@ Example: ```bash # create a plugin -$ echo '#!/bin/bash\n\necho "My first command-line argument was $1"' > kubectl-foo-bar-baz -$ sudo chmod +x ./kubectl-foo-bar-baz +echo '#!/bin/bash\n\necho "My first command-line argument was $1"' > kubectl-foo-bar-baz +sudo chmod +x ./kubectl-foo-bar-baz # "install" our plugin by placing it on our PATH -$ sudo mv ./kubectl-foo-bar-baz /usr/local/bin +sudo mv ./kubectl-foo-bar-baz /usr/local/bin # ensure our plugin is recognized by kubectl -$ kubectl plugin list +kubectl plugin list +``` +``` The following kubectl-compatible plugins are available: /usr/local/bin/kubectl-foo-bar-baz - +``` +``` # test that calling our plugin via a "kubectl" command works # even when additional arguments and flags are passed to our # plugin executable by the user. -$ kubectl foo bar baz arg1 --meaningless-flag=true +kubectl foo bar baz arg1 --meaningless-flag=true +``` +``` My first command-line argument was arg1 ``` @@ -172,14 +187,16 @@ Example: ```bash # create a plugin containing an underscore in its filename -$ echo '#!/bin/bash\n\necho "I am a plugin with a dash in my name"' > ./kubectl-foo_bar -$ sudo chmod +x ./kubectl-foo_bar +echo '#!/bin/bash\n\necho "I am a plugin with a dash in my name"' > ./kubectl-foo_bar +sudo chmod +x ./kubectl-foo_bar # move the plugin into your PATH -$ sudo mv ./kubectl-foo_bar /usr/local/bin +sudo mv ./kubectl-foo_bar /usr/local/bin # our plugin can now be invoked from `kubectl` like so: -$ kubectl foo-bar +kubectl foo-bar +``` +``` I am a plugin with a dash in my name ``` @@ -188,11 +205,17 @@ The command from the above example, can be invoked using either a dash (`-`) or ```bash # our plugin can be invoked with a dash -$ kubectl foo-bar +kubectl foo-bar +``` +``` I am a plugin with a dash in my name +``` +```bash # it can also be invoked using an underscore -$ kubectl foo_bar +kubectl foo_bar +``` +``` I am a plugin with a dash in my name ``` @@ -203,7 +226,9 @@ For example, given a PATH with the following value: `PATH=/usr/local/bin/plugins such that the output of the `kubectl plugin list` command is: ```bash -$ PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins kubectl plugin list +PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins kubectl plugin list +``` +```bash The following kubectl-compatible plugins are available: /usr/local/bin/plugins/kubectl-foo @@ -223,23 +248,39 @@ There is another kind of overshadowing that can occur with plugin filenames. Giv ```bash # for a given kubectl command, the plugin with the longest possible filename will always be preferred -$ kubectl foo bar baz +kubectl foo bar baz +``` +``` Plugin kubectl-foo-bar-baz is executed +``` -$ kubectl foo bar +```bash +kubectl foo bar +``` +``` Plugin kubectl-foo-bar is executed +``` -$ kubectl foo bar baz buz +```bash +kubectl foo bar baz buz +``` +``` Plugin kubectl-foo-bar-baz is executed, with "buz" as its first argument +``` -$ kubectl foo bar buz +```bash +kubectl foo bar buz +``` +``` Plugin kubectl-foo-bar is executed, with "buz" as its first argument ``` This design choice ensures that plugin sub-commands can be implemented across multiple files, if needed, and that these sub-commands can be nested under a "parent" plugin command: ```bash -$ ls ./plugin_command_tree +ls ./plugin_command_tree +``` +``` kubectl-parent kubectl-parent-subcommand kubectl-parent-subcommand-subsubcommand @@ -250,7 +291,9 @@ kubectl-parent-subcommand-subsubcommand You can use the aforementioned `kubectl plugin list` command to ensure that your plugin is visible by `kubectl`, and verify that there are no warnings preventing it from being called as a `kubectl` command. ```bash -$ kubectl plugin list +kubectl plugin list +``` +``` The following kubectl-compatible plugins are available: test/fixtures/pkg/kubectl/plugins/kubectl-foo diff --git a/content/en/docs/tasks/federation/_index.md b/content/en/docs/tasks/federation/_index.md index fc7458f1d9..869c63fc6a 100755 --- a/content/en/docs/tasks/federation/_index.md +++ b/content/en/docs/tasks/federation/_index.md @@ -1,5 +1,5 @@ --- -title: "Federation - Run an App on Multiple Clusters" +title: "Federation" weight: 120 --- diff --git a/content/en/docs/tasks/federation/administer-federation/_index.md b/content/en/docs/tasks/federation/administer-federation/_index.md new file mode 100755 index 0000000000..555416fb9b --- /dev/null +++ b/content/en/docs/tasks/federation/administer-federation/_index.md @@ -0,0 +1,5 @@ +--- +title: "Administer Federation Control Plane" +weight: 160 +--- + diff --git a/content/en/docs/tasks/administer-federation/cluster.md b/content/en/docs/tasks/federation/administer-federation/cluster.md similarity index 97% rename from content/en/docs/tasks/administer-federation/cluster.md rename to content/en/docs/tasks/federation/administer-federation/cluster.md index 6e350f4b25..11afbbe159 100644 --- a/content/en/docs/tasks/administer-federation/cluster.md +++ b/content/en/docs/tasks/federation/administer-federation/cluster.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use Clusters API resource in a Federation control plane. diff --git a/content/en/docs/tasks/administer-federation/configmap.md b/content/en/docs/tasks/federation/administer-federation/configmap.md similarity index 95% rename from content/en/docs/tasks/administer-federation/configmap.md rename to content/en/docs/tasks/federation/administer-federation/configmap.md index 4123b4ab22..cf36e2e6ea 100644 --- a/content/en/docs/tasks/administer-federation/configmap.md +++ b/content/en/docs/tasks/federation/administer-federation/configmap.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use ConfigMaps in a Federation control plane. diff --git a/content/en/docs/tasks/administer-federation/daemonset.md b/content/en/docs/tasks/federation/administer-federation/daemonset.md similarity index 95% rename from content/en/docs/tasks/administer-federation/daemonset.md rename to content/en/docs/tasks/federation/administer-federation/daemonset.md index 54a04493f6..dd9ed4f93a 100644 --- a/content/en/docs/tasks/administer-federation/daemonset.md +++ b/content/en/docs/tasks/federation/administer-federation/daemonset.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use DaemonSets in a federation control plane. diff --git a/content/en/docs/tasks/administer-federation/deployment.md b/content/en/docs/tasks/federation/administer-federation/deployment.md similarity index 97% rename from content/en/docs/tasks/administer-federation/deployment.md rename to content/en/docs/tasks/federation/administer-federation/deployment.md index 624a527cfc..cf80b9610a 100644 --- a/content/en/docs/tasks/administer-federation/deployment.md +++ b/content/en/docs/tasks/federation/administer-federation/deployment.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use Deployments in the Federation control plane. diff --git a/content/en/docs/tasks/administer-federation/events.md b/content/en/docs/tasks/federation/administer-federation/events.md similarity index 92% rename from content/en/docs/tasks/administer-federation/events.md rename to content/en/docs/tasks/federation/administer-federation/events.md index e855afb3d1..2c8cfee4ff 100644 --- a/content/en/docs/tasks/administer-federation/events.md +++ b/content/en/docs/tasks/federation/administer-federation/events.md @@ -5,9 +5,9 @@ content_template: templates/concept {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use events in federation control plane to help in debugging. diff --git a/content/en/docs/tasks/administer-federation/hpa.md b/content/en/docs/tasks/federation/administer-federation/hpa.md similarity index 98% rename from content/en/docs/tasks/administer-federation/hpa.md rename to content/en/docs/tasks/federation/administer-federation/hpa.md index 496a7032a6..ee7c85482b 100644 --- a/content/en/docs/tasks/administer-federation/hpa.md +++ b/content/en/docs/tasks/federation/administer-federation/hpa.md @@ -7,9 +7,9 @@ content_template: templates/task {{< feature-state state="alpha" >}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use federated horizontal pod autoscalers (HPAs) in the federation control plane. diff --git a/content/en/docs/tasks/administer-federation/ingress.md b/content/en/docs/tasks/federation/administer-federation/ingress.md similarity index 99% rename from content/en/docs/tasks/administer-federation/ingress.md rename to content/en/docs/tasks/federation/administer-federation/ingress.md index 51bfce65d5..60b0d61845 100644 --- a/content/en/docs/tasks/administer-federation/ingress.md +++ b/content/en/docs/tasks/federation/administer-federation/ingress.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This page explains how to use Kubernetes Federated Ingress to deploy a common HTTP(S) virtual IP load balancer across a federated service running in diff --git a/content/en/docs/tasks/administer-federation/job.md b/content/en/docs/tasks/federation/administer-federation/job.md similarity index 97% rename from content/en/docs/tasks/administer-federation/job.md rename to content/en/docs/tasks/federation/administer-federation/job.md index d495d1e42e..77f98836dd 100644 --- a/content/en/docs/tasks/administer-federation/job.md +++ b/content/en/docs/tasks/federation/administer-federation/job.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use jobs in the federation control plane. diff --git a/content/en/docs/tasks/administer-federation/namespaces.md b/content/en/docs/tasks/federation/administer-federation/namespaces.md similarity index 93% rename from content/en/docs/tasks/administer-federation/namespaces.md rename to content/en/docs/tasks/federation/administer-federation/namespaces.md index bf8cd84c35..71019d81f0 100644 --- a/content/en/docs/tasks/administer-federation/namespaces.md +++ b/content/en/docs/tasks/federation/administer-federation/namespaces.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use Namespaces in Federation control plane. @@ -64,7 +64,7 @@ the Federated Namespace that you created above. You can update a federated Namespace as you would update a Kubernetes Namespace, just send the request to federation apiserver instead of sending it to a specific Kubernetes cluster. -Federation control plan will ensure that whenever the federated Namespace is +Federation control plane will ensure that whenever the federated Namespace is updated, it updates the corresponding Namespaces in all underlying clusters to match it. diff --git a/content/en/docs/tasks/administer-federation/replicaset.md b/content/en/docs/tasks/federation/administer-federation/replicaset.md similarity index 97% rename from content/en/docs/tasks/administer-federation/replicaset.md rename to content/en/docs/tasks/federation/administer-federation/replicaset.md index 932abd7095..0ffef6a692 100644 --- a/content/en/docs/tasks/administer-federation/replicaset.md +++ b/content/en/docs/tasks/federation/administer-federation/replicaset.md @@ -5,9 +5,9 @@ content_template: templates/task {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use ReplicaSets in the Federation control plane. diff --git a/content/en/docs/tasks/administer-federation/secret.md b/content/en/docs/tasks/federation/administer-federation/secret.md similarity index 94% rename from content/en/docs/tasks/administer-federation/secret.md rename to content/en/docs/tasks/federation/administer-federation/secret.md index a553e0562e..e50fd13005 100644 --- a/content/en/docs/tasks/administer-federation/secret.md +++ b/content/en/docs/tasks/federation/administer-federation/secret.md @@ -5,9 +5,9 @@ content_template: templates/concept {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use secrets in Federation control plane. @@ -70,7 +70,7 @@ These secrets in underlying clusters will match the federated secret. You can update a federated secret as you would update a Kubernetes secret; however, for a federated secret, you must send the request to the federation apiserver instead of sending it to a specific Kubernetes cluster. -The Federation control plan ensures that whenever the federated secret is +The Federation control plane ensures that whenever the federated secret is updated, it updates the corresponding secrets in all underlying clusters to match it. diff --git a/content/en/docs/tasks/federation/federation-service-discovery.md b/content/en/docs/tasks/federation/federation-service-discovery.md index b80a6d8d22..ea06eaa17f 100644 --- a/content/en/docs/tasks/federation/federation-service-discovery.md +++ b/content/en/docs/tasks/federation/federation-service-discovery.md @@ -1,16 +1,17 @@ --- +title: Cross-cluster Service Discovery using Federated Services reviewers: - bprashanth - quinton-hoole content_template: templates/task -title: Cross-cluster Service Discovery using Federated Services +weight: 140 --- {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This guide explains how to use Kubernetes Federated Services to deploy a common Service across multiple Kubernetes clusters. This makes it @@ -118,8 +119,9 @@ The status of your Federated Service will automatically reflect the real-time status of the underlying Kubernetes services, for example: ``` shell -$kubectl --context=federation-cluster describe services nginx - +kubectl --context=federation-cluster describe services nginx +``` +``` Name: nginx Namespace: default Labels: run=nginx @@ -187,7 +189,9 @@ this. For example, if your Federation is configured to use Google Cloud DNS, and a managed DNS domain 'example.com': ``` shell -$ gcloud dns managed-zones describe example-dot-com +gcloud dns managed-zones describe example-dot-com +``` +``` creationTime: '2016-06-26T18:18:39.229Z' description: Example domain for Kubernetes Cluster Federation dnsName: example.com. @@ -202,7 +206,9 @@ nameServers: ``` ```shell -$ gcloud dns record-sets list --zone example-dot-com +gcloud dns record-sets list --zone example-dot-com +``` +``` NAME TYPE TTL DATA example.com. NS 21600 ns-cloud-e1.googledomains.com., ns-cloud-e2.googledomains.com. example.com. OA 21600 ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 1209600 300 @@ -225,12 +231,12 @@ nginx.mynamespace.myfederation.svc.europe-west1-d.example.com. CNAME 180 If your Federation is configured to use AWS Route53, you can use one of the equivalent AWS tools, for example: ``` shell -$ aws route53 list-hosted-zones +aws route53 list-hosted-zones ``` and ``` shell -$ aws route53 list-resource-record-sets --hosted-zone-id Z3ECL0L9QLOVBX +aws route53 list-resource-record-sets --hosted-zone-id Z3ECL0L9QLOVBX ``` {{< /note >}} diff --git a/content/en/docs/tasks/federation/set-up-cluster-federation-kubefed.md b/content/en/docs/tasks/federation/set-up-cluster-federation-kubefed.md index 739d143931..9a751661e8 100644 --- a/content/en/docs/tasks/federation/set-up-cluster-federation-kubefed.md +++ b/content/en/docs/tasks/federation/set-up-cluster-federation-kubefed.md @@ -1,14 +1,16 @@ --- +title: Set up Cluster Federation with Kubefed reviewers: - madhusudancs content_template: templates/task -title: Set up Cluster Federation with Kubefed +weight: 125 --- {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} + +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} Kubernetes version 1.5 and above includes a new command line tool called [`kubefed`](/docs/admin/kubefed/) to help you administrate your federated @@ -52,7 +54,7 @@ now maintained. Consequently, the federation release information is available on [release page](https://github.com/kubernetes/federation/releases). {{< /note >}} -### For k8s versions 1.8.x and earlier: +### For Kubernetes versions 1.8.x and earlier: ```shell curl -LO https://storage.googleapis.com/kubernetes-release/release/${RELEASE-VERSION}/kubernetes-client-linux-amd64.tar.gz @@ -70,7 +72,7 @@ sudo cp kubernetes/client/bin/kubefed /usr/local/bin sudo chmod +x /usr/local/bin/kubefed ``` -### For k8s versions 1.9.x and above: +### For Kubernetes versions 1.9.x and above: ```shell curl -LO https://storage.cloud.google.com/kubernetes-federation-release/release/${RELEASE-VERSION}/federation-client-linux-amd64.tar.gz diff --git a/content/en/docs/tasks/federation/set-up-coredns-provider-federation.md b/content/en/docs/tasks/federation/set-up-coredns-provider-federation.md index b2379f79b9..572a348a82 100644 --- a/content/en/docs/tasks/federation/set-up-coredns-provider-federation.md +++ b/content/en/docs/tasks/federation/set-up-coredns-provider-federation.md @@ -1,13 +1,14 @@ --- title: Set up CoreDNS as DNS provider for Cluster Federation content_template: templates/tutorial +weight: 130 --- {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This page shows how to configure and deploy CoreDNS to be used as the DNS provider for Cluster Federation. diff --git a/content/en/docs/tasks/federation/set-up-placement-policies-federation.md b/content/en/docs/tasks/federation/set-up-placement-policies-federation.md index cb1e02d8cf..957702d02e 100644 --- a/content/en/docs/tasks/federation/set-up-placement-policies-federation.md +++ b/content/en/docs/tasks/federation/set-up-placement-policies-federation.md @@ -1,13 +1,14 @@ --- title: Set up placement policies in Federation content_template: templates/task +weight: 135 --- {{% capture overview %}} -{{< note >}} -{{< include "federation-current-state.md" >}} -{{< /note >}} +{{< deprecationfilewarning >}} +{{< include "federation-deprecation-warning-note.md" >}} +{{< /deprecationfilewarning >}} This page shows how to enforce policy-based placement decisions over Federated resources using an external policy engine. diff --git a/content/en/docs/tasks/inject-data-application/define-command-argument-container.md b/content/en/docs/tasks/inject-data-application/define-command-argument-container.md index 64fc918206..f7f2e2035f 100644 --- a/content/en/docs/tasks/inject-data-application/define-command-argument-container.md +++ b/content/en/docs/tasks/inject-data-application/define-command-argument-container.md @@ -46,11 +46,15 @@ file for the Pod defines a command and two arguments: 1. Create a Pod based on the YAML configuration file: - kubectl create -f https://k8s.io/examples/pods/commands.yaml + ```shell + kubectl create -f https://k8s.io/examples/pods/commands.yaml + ``` 1. List the running Pods: - kubectl get pods + ```shell + kubectl get pods + ``` The output shows that the container that ran in the command-demo Pod has completed. @@ -58,13 +62,17 @@ file for the Pod defines a command and two arguments: 1. To see the output of the command that ran in the container, view the logs from the Pod: - kubectl logs command-demo + ```shell + kubectl logs command-demo + ``` The output shows the values of the HOSTNAME and KUBERNETES_PORT environment variables: - command-demo - tcp://10.3.240.1:443 + ``` + command-demo + tcp://10.3.240.1:443 + ``` ## Use environment variables to define arguments @@ -72,11 +80,13 @@ In the preceding example, you defined the arguments directly by providing strings. As an alternative to providing strings directly, you can define arguments by using environment variables: - env: - - name: MESSAGE - value: "hello world" - command: ["/bin/echo"] - args: ["$(MESSAGE)"] +```yaml +env: +- name: MESSAGE + value: "hello world" +command: ["/bin/echo"] +args: ["$(MESSAGE)"] +``` This means you can define an argument for a Pod using any of the techniques available for defining environment variables, including @@ -95,8 +105,10 @@ In some cases, you need your command to run in a shell. For example, your command might consist of several commands piped together, or it might be a shell script. To run your command in a shell, wrap it like this: - command: ["/bin/sh"] - args: ["-c", "while true; do echo hello; sleep 10;done"] +```shell +command: ["/bin/sh"] +args: ["-c", "while true; do echo hello; sleep 10;done"] +``` ## Notes diff --git a/content/en/docs/tasks/inject-data-application/define-environment-variable-container.md b/content/en/docs/tasks/inject-data-application/define-environment-variable-container.md index f43c4cdc22..ec70cae998 100644 --- a/content/en/docs/tasks/inject-data-application/define-environment-variable-container.md +++ b/content/en/docs/tasks/inject-data-application/define-environment-variable-container.md @@ -48,7 +48,7 @@ Pod: The output is similar to this: - ```log + ``` NAME READY STATUS RESTARTS AGE envar-demo 1/1 Running 0 9s ``` @@ -67,7 +67,7 @@ Pod: The output is similar to this: - ```log + ``` NODE_VERSION=4.4.2 EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237 HOSTNAME=envar-demo diff --git a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md index 7b17ba4368..a2533ac9c0 100644 --- a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md +++ b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md @@ -24,8 +24,10 @@ Suppose you want to have two pieces of secret data: a username `my-app` and a pa convert your username and password to a base-64 representation. Here's a Linux example: - echo -n 'my-app' | base64 - echo -n '39528$vdg7Jb' | base64 +```shell +echo -n 'my-app' | base64 +echo -n '39528$vdg7Jb' | base64 +``` The output shows that the base-64 representation of your username is `bXktYXBw`, and the base-64 representation of your password is `Mzk1MjgkdmRnN0pi`. @@ -40,44 +42,43 @@ username and password: 1. Create the Secret ```shell - kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret.yaml + kubectl create -f https://k8s.io/examples/pods/inject/secret.yaml ``` - {{< note >}} - If you want to skip the Base64 encoding step, you can create a Secret by using the `kubectl create secret` command: - ```shell - kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb' - ``` - {{< /note >}} - 1. View information about the Secret: - kubectl get secret test-secret + ```shell + kubectl get secret test-secret + ``` Output: - NAME TYPE DATA AGE - test-secret Opaque 2 1m - + ``` + NAME TYPE DATA AGE + test-secret Opaque 2 1m + ``` 1. View more detailed information about the Secret: - kubectl describe secret test-secret + ```shell + kubectl describe secret test-secret + ``` Output: - Name: test-secret - Namespace: default - Labels: - Annotations: + ``` + Name: test-secret + Namespace: default + Labels: + Annotations: - Type: Opaque - - Data - ==== - password: 13 bytes - username: 7 bytes + Type: Opaque + Data + ==== + password: 13 bytes + username: 7 bytes + ``` {{< note >}} If you want to skip the Base64 encoding step, you can create a Secret @@ -97,7 +98,7 @@ Here is a configuration file you can use to create a Pod: 1. Create the Pod: ```shell - kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-pod.yaml + kubectl create -f https://k8s.io/examples/pods/inject/secret-pod.yaml ``` 1. Verify that your Pod is running: @@ -152,7 +153,7 @@ Here is a configuration file you can use to create a Pod: 1. Create the Pod: ```shell - kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-envars-pod.yaml + kubectl create -f https://k8s.io/examples/pods/inject/secret-envars-pod.yaml ``` 1. Verify that your Pod is running: diff --git a/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md b/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md index 643237887f..d9bcccdd9e 100644 --- a/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md +++ b/content/en/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md @@ -84,7 +84,7 @@ builder="john-doe" Get a shell into the Container that is running in your Pod: -``` +```shell kubectl exec -it kubernetes-downwardapi-volume-example -- sh ``` @@ -177,7 +177,7 @@ kubectl create -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml Get a shell into the Container that is running in your Pod: -``` +```shell kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh ``` diff --git a/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md b/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md index 2c543b1d6f..ddb32c380a 100644 --- a/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md +++ b/content/en/docs/tasks/inject-data-application/environment-variable-expose-pod-information.md @@ -60,13 +60,13 @@ kubectl create -f https://k8s.io/examples/pods/inject/dapi-envars-pod.yaml Verify that the Container in the Pod is running: -``` +```shell kubectl get pods ``` View the Container's logs: -``` +```shell kubectl logs dapi-envars-fieldref ``` @@ -86,13 +86,13 @@ five environment variables to stdout. It repeats this every ten seconds. Next, get a shell into the Container that is running in your Pod: -``` +```shell kubectl exec -it dapi-envars-fieldref -- sh ``` In your shell, view the environment variables: -``` +```shell /# printenv ``` @@ -135,13 +135,13 @@ kubectl create -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml Verify that the Container in the Pod is running: -``` +```shell kubectl get pods ``` View the Container's logs: -``` +```shell kubectl logs dapi-envars-resourcefieldref ``` diff --git a/content/en/docs/tasks/inject-data-application/podpreset.md b/content/en/docs/tasks/inject-data-application/podpreset.md index 10fff8cec4..0655907797 100644 --- a/content/en/docs/tasks/inject-data-application/podpreset.md +++ b/content/en/docs/tasks/inject-data-application/podpreset.md @@ -42,7 +42,9 @@ kubectl create -f https://k8s.io/examples/podpreset/preset.yaml Examine the created PodPreset: ```shell -$ kubectl get podpreset +kubectl get podpreset +``` +``` NAME AGE allow-database 1m ``` @@ -54,13 +56,15 @@ The new PodPreset will act upon any pod that has label `role: frontend`. Create a pod: ```shell -$ kubectl create -f https://k8s.io/examples/podpreset/pod.yaml +kubectl create -f https://k8s.io/examples/podpreset/pod.yaml ``` List the running Pods: ```shell -$ kubectl get pods +kubectl get pods +``` +``` NAME READY STATUS RESTARTS AGE website 1/1 Running 0 4m ``` @@ -72,7 +76,7 @@ website 1/1 Running 0 4m To see above output, run the following command: ```shell -$ kubectl get pod website -o yaml +kubectl get pod website -o yaml ``` ## Pod Spec with ConfigMap Example @@ -157,7 +161,9 @@ when there is a conflict. **If we run `kubectl describe...` we can see the event:** ```shell -$ kubectl describe ... +kubectl describe ... +``` +``` .... Events: FirstSeen LastSeen Count From SubobjectPath Reason Message @@ -169,7 +175,9 @@ Events: Once you don't need a pod preset anymore, you can delete it with `kubectl`: ```shell -$ kubectl delete podpreset allow-database +kubectl delete podpreset allow-database +``` +``` podpreset "allow-database" deleted ``` diff --git a/content/en/docs/tasks/job/automated-tasks-with-cron-jobs.md b/content/en/docs/tasks/job/automated-tasks-with-cron-jobs.md index 364908f01a..168e9a4959 100644 --- a/content/en/docs/tasks/job/automated-tasks-with-cron-jobs.md +++ b/content/en/docs/tasks/job/automated-tasks-with-cron-jobs.md @@ -47,71 +47,93 @@ This example cron job config `.spec` file prints the current time and a hello me {{< codenew file="application/job/cronjob.yaml" >}} -Run the example cron job by downloading the example file and then running this command: +Run the example CronJob by using this command: ```shell -$ kubectl create -f ./cronjob.yaml -cronjob "hello" created +kubectl create -f https://k8s.io/examples/application/job/cronjob.yaml +``` +The output is similar to this: + +``` +cronjob.batch/hello created ``` Alternatively, you can use `kubectl run` to create a cron job without writing a full config: ```shell -$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster" -cronjob "hello" created +kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster" ``` After creating the cron job, get its status using this command: ```shell -$ kubectl get cronjob hello -NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE -hello */1 * * * * False 0 +kubectl get cronjob hello +``` +The output is similar to this: + +``` +NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE +hello */1 * * * * False 0 10s ``` As you can see from the results of the command, the cron job has not scheduled or run any jobs yet. Watch for the job to be created in around one minute: ```shell -$ kubectl get jobs --watch -NAME DESIRED SUCCESSFUL AGE -hello-4111706356 1 1 2s +kubectl get jobs --watch +``` +The output is similar to this: + +``` +NAME COMPLETIONS DURATION AGE +hello-4111706356 0/1 0s +hello-4111706356 0/1 0s 0s +hello-4111706356 1/1 5s 5s ``` Now you've seen one running job scheduled by the "hello" cron job. You can stop watching the job and view the cron job again to see that it scheduled the job: ```shell -$ kubectl get cronjob hello -NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE -hello */1 * * * * False 0 Mon, 29 Aug 2016 14:34:00 -0700 +kubectl get cronjob hello +``` +The output is similar to this: + +``` +NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE +hello */1 * * * * False 0 50s 75s ``` -You should see that the cron job "hello" successfully scheduled a job at the time specified in `LAST-SCHEDULE`. -There are currently 0 active jobs, meaning that the job has completed or failed. +You should see that the cron job `hello` successfully scheduled a job at the time specified in `LAST SCHEDULE`. There are currently 0 active jobs, meaning that the job has completed or failed. Now, find the pods that the last scheduled job created and view the standard output of one of the pods. -Note that the job name and pod name are different. + +{{< note >}} +The job name and pod name are different. +{{< /note >}} ```shell # Replace "hello-4111706356" with the job name in your system -$ pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items..metadata.name}) +pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items.metadata.name}) +``` +Show pod log: -$ echo $pods -hello-4111706356-o9qcm +```shell +kubectl logs $pods +``` +The output is similar to this: -$ kubectl logs $pods -Mon Aug 29 21:34:09 UTC 2016 +``` +Fri Feb 22 11:02:09 UTC 2019 Hello from the Kubernetes cluster ``` ## Deleting a Cron Job -When you don't need a cron job any more, delete it with `kubectl delete cronjob`: +When you don't need a cron job any more, delete it with `kubectl delete cronjob `: ```shell -$ kubectl delete cronjob hello -cronjob "hello" deleted +kubectl delete cronjob hello ``` Deleting the cron job removes all the jobs and pods it created and stops it from creating additional jobs. @@ -137,11 +159,11 @@ It takes a [Cron](https://en.wikipedia.org/wiki/Cron) format string, such as `0 The format also includes extended `vixie cron` step values. As explained in the [FreeBSD manual](https://www.freebsd.org/cgi/man.cgi?crontab%285%29): > Step values can be used in conjunction with ranges. Following a range -> with ``/'' specifies skips of the number's value through the -> range. For example, ``0-23/2'' can be used in the hours field to specify +> with `/` specifies skips of the number's value through the +> range. For example, `0-23/2` can be used in the hours field to specify > command execution every other hour (the alternative in the V7 standard is -> ``0,2,4,6,8,10,12,14,16,18,20,22''). Steps are also permitted after an -> asterisk, so if you want to say ``every two hours'', just use ``*/2''. +> `0,2,4,6,8,10,12,14,16,18,20,22`). Steps are also permitted after an +> asterisk, so if you want to say "every two hours", just use `*/2`. {{< note >}} A question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is, it stands for any of available value for a given field. @@ -161,21 +183,19 @@ After the deadline, the cron job does not start the job. Jobs that do not meet their deadline in this way count as failed jobs. If this field is not specified, the jobs have no deadline. -The CronJob controller counts how many missed schedules happen for a cron job. If there are more than 100 missed -schedules, the cron job is no longer scheduled. When `.spec.startingDeadlineSeconds` is not set, the CronJob -controller counts missed schedules from `status.lastScheduleTime` until now. For example, one cron job is -supposed to run every minute, the `status.lastScheduleTime` of the cronjob is 5:00am, but now it's 7:00am. -That means 120 schedules were missed, so the cron job is no longer scheduled. If the `.spec.startingDeadlineSeconds` -field is set (not null), the CronJob controller counts how many missed jobs occurred from the value of -`.spec.startingDeadlineSeconds` until now. For example, if it is set to `200`, it counts how many missed -schedules occurred in the last 200 seconds. In that case, if there were more than 100 missed schedules in the -last 200 seconds, the cron job is no longer scheduled. +The CronJob controller counts how many missed schedules happen for a cron job. If there are more than 100 missed schedules, the cron job is no longer scheduled. When `.spec.startingDeadlineSeconds` is not set, the CronJob controller counts missed schedules from `status.lastScheduleTime` until now. + +For example, one cron job is supposed to run every minute, the `status.lastScheduleTime` of the cronjob is 5:00am, but now it's 7:00am. That means 120 schedules were missed, so the cron job is no longer scheduled. + +If the `.spec.startingDeadlineSeconds` field is set (not null), the CronJob controller counts how many missed jobs occurred from the value of `.spec.startingDeadlineSeconds` until now. + +For example, if it is set to `200`, it counts how many missed schedules occurred in the last 200 seconds. In that case, if there were more than 100 missed schedules in the last 200 seconds, the cron job is no longer scheduled. ### Concurrency Policy The `.spec.concurrencyPolicy` field is also optional. It specifies how to treat concurrent executions of a job that is created by this cron job. -the spec may specify only one of the following concurrency policies: +The spec may specify only one of the following concurrency policies: * `Allow` (default): The cron job allows concurrently running jobs * `Forbid`: The cron job does not allow concurrent runs; if it is time for a new job run and the previous job run hasn't finished yet, the cron job skips the new job run diff --git a/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md b/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md index c24790b2f4..7f81ed1c0c 100644 --- a/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md +++ b/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md @@ -46,9 +46,16 @@ cluster and reuse it for many jobs, as well as for long-running services. Start RabbitMQ as follows: ```shell -$ kubectl create -f examples/celery-rabbitmq/rabbitmq-service.yaml +kubectl create -f examples/celery-rabbitmq/rabbitmq-service.yaml +``` +``` service "rabbitmq-service" created -$ kubectl create -f examples/celery-rabbitmq/rabbitmq-controller.yaml +``` + +```shell +kubectl create -f examples/celery-rabbitmq/rabbitmq-controller.yaml +``` +``` replicationcontroller "rabbitmq-controller" created ``` @@ -64,7 +71,9 @@ First create a temporary interactive Pod. ```shell # Create a temporary interactive container -$ kubectl run -i --tty temp --image ubuntu:14.04 +kubectl run -i --tty temp --image ubuntu:18.04 +``` +``` Waiting for pod default/temp-loe07 to be running, status is Pending, pod ready: false ... [ previous line repeats several times .. hit return when it stops ] ... ``` @@ -141,7 +150,7 @@ return so the example is readable. ## Filling the Queue with tasks -Now lets fill the queue with some "tasks". In our example, our tasks are just strings to be +Now let's fill the queue with some "tasks". In our example, our tasks are just strings to be printed. In a practice, the content of the messages might be: @@ -161,9 +170,11 @@ For our example, we will create the queue and fill it using the amqp command lin In practice, you might write a program to fill the queue using an amqp client library. ```shell -$ /usr/bin/amqp-declare-queue --url=$BROKER_URL -q job1 -d +/usr/bin/amqp-declare-queue --url=$BROKER_URL -q job1 -d job1 -$ for f in apple banana cherry date fig grape lemon melon +``` +```shell +for f in apple banana cherry date fig grape lemon melon do /usr/bin/amqp-publish --url=$BROKER_URL -r job1 -p -b $f done @@ -181,6 +192,12 @@ example program: {{< codenew language="python" file="application/job/rabbitmq/worker.py" >}} +Give the script execution permission: + +```shell +chmod +x worker.py +``` + Now, build an image. If you are working in the source tree, then change directory to `examples/job/work-queue-1`. Otherwise, make a temporary directory, change to it, @@ -189,7 +206,7 @@ and [worker.py](/examples/application/job/rabbitmq/worker.py). In either case, build the image with this command: ```shell -$ docker build -t job-wq-1 . +docker build -t job-wq-1 . ``` For the [Docker Hub](https://hub.docker.com/), tag your app image with @@ -234,7 +251,9 @@ kubectl create -f ./job.yaml Now wait a bit, then check on the job. ```shell -$ kubectl describe jobs/job-wq-1 +kubectl describe jobs/job-wq-1 +``` +``` Name: job-wq-1 Namespace: default Selector: controller-uid=41d75705-92df-11e7-b85e-fa163ee3c11f @@ -289,7 +308,7 @@ This approach creates a pod for every work item. If your work items only take a though, creating a Pod for every work item may add a lot of overhead. Consider another [example](/docs/tasks/job/fine-parallel-processing-work-queue/), that executes multiple work items per Pod. -In this example, we used use the `amqp-consume` utility to read the message +In this example, we use the `amqp-consume` utility to read the message from the queue and run our actual program. This has the advantage that you do not need to modify your program to be aware of the queue. A [different example](/docs/tasks/job/fine-parallel-processing-work-queue/), shows how to diff --git a/content/en/docs/tasks/job/fine-parallel-processing-work-queue.md b/content/en/docs/tasks/job/fine-parallel-processing-work-queue.md index d96f5ed986..80cff2bd9e 100644 --- a/content/en/docs/tasks/job/fine-parallel-processing-work-queue.md +++ b/content/en/docs/tasks/job/fine-parallel-processing-work-queue.md @@ -48,19 +48,7 @@ For this example, for simplicity, we will start a single instance of Redis. See the [Redis Example](https://github.com/kubernetes/examples/tree/master/guestbook) for an example of deploying Redis scalably and redundantly. -If you are working from the website source tree, you can go to the following -directory and start a temporary Pod running Redis and a service so we can find it. - -```shell -$ cd content/en/examples/application/job/redis -$ kubectl create -f ./redis-pod.yaml -pod/redis-master created -$ kubectl create -f ./redis-service.yaml -service/redis created -``` - -If you're not working from the source tree, you could also download the following -files directly: +You could also download the following files directly: - [`redis-pod.yaml`](/examples/application/job/redis/redis-pod.yaml) - [`redis-service.yaml`](/examples/application/job/redis/redis-service.yaml) @@ -78,7 +66,7 @@ printed. Start a temporary interactive pod for running the Redis CLI. ```shell -$ kubectl run -i --tty temp --image redis --command "/bin/sh" +kubectl run -i --tty temp --image redis --command "/bin/sh" Waiting for pod default/redis2-c7h78 to be running, status is Pending, pod ready: false Hit enter for command prompt ``` @@ -138,9 +126,7 @@ client library to get work. Here it is: {{< codenew language="python" file="application/job/redis/worker.py" >}} -If you are working from the source tree, change directory to the -`content/en/examples/application/job/redis/` directory. -Otherwise, download [`worker.py`](/examples/application/job/redis/worker.py), +You could also download [`worker.py`](/examples/application/job/redis/worker.py), [`rediswq.py`](/examples/application/job/redis/rediswq.py), and [`Dockerfile`](/examples/application/job/redis/Dockerfile) files, then build the image: @@ -202,7 +188,7 @@ kubectl create -f ./job.yaml Now wait a bit, then check on the job. ```shell -$ kubectl describe jobs/job-wq-2 +kubectl describe jobs/job-wq-2 Name: job-wq-2 Namespace: default Selector: controller-uid=b1c7e4e3-92e1-11e7-b85e-fa163ee3c11f @@ -229,7 +215,7 @@ Events: 33s 33s 1 {job-controller } Normal SuccessfulCreate Created pod: job-wq-2-lglf8 -$ kubectl logs pods/job-wq-2-7r7b2 +kubectl logs pods/job-wq-2-7r7b2 Worker with sessionID: bbd72d0a-9e5c-4dd6-abf6-416cc267991f Initial queue state: empty=False Working on banana @@ -249,7 +235,7 @@ If running a queue service or modifying your containers to use a work queue is i want to consider one of the other [job patterns](/docs/concepts/jobs/run-to-completion-finite-workloads/#job-patterns). If you have a continuous stream of background processing work to run, then -consider running your background workers with a `replicationController` instead, +consider running your background workers with a `ReplicaSet` instead, and consider running a background processing library such as [https://github.com/resque/resque](https://github.com/resque/resque). diff --git a/content/en/docs/tasks/job/parallel-processing-expansion.md b/content/en/docs/tasks/job/parallel-processing-expansion.md index b71f1c7c2e..9a20fccc30 100644 --- a/content/en/docs/tasks/job/parallel-processing-expansion.md +++ b/content/en/docs/tasks/job/parallel-processing-expansion.md @@ -43,8 +43,8 @@ Next, expand the template into multiple files, one for each item to be processed ```shell # Expand files into a temporary directory -$ mkdir ./jobs -$ for i in apple banana cherry +mkdir ./jobs +for i in apple banana cherry do cat job-tmpl.yaml | sed "s/\$ITEM/$i/" > ./jobs/job-$i.yaml done @@ -53,7 +53,7 @@ done Check if it worked: ```shell -$ ls jobs/ +ls jobs/ job-apple.yaml job-banana.yaml job-cherry.yaml @@ -66,7 +66,7 @@ to generate the Job objects. Next, create all the jobs with one kubectl command: ```shell -$ kubectl create -f ./jobs +kubectl create -f ./jobs job "process-item-apple" created job "process-item-banana" created job "process-item-cherry" created @@ -75,7 +75,7 @@ job "process-item-cherry" created Now, check on the jobs: ```shell -$ kubectl get jobs -l jobgroup=jobexample +kubectl get jobs -l jobgroup=jobexample NAME DESIRED SUCCESSFUL AGE process-item-apple 1 1 31s process-item-banana 1 1 31s @@ -89,7 +89,7 @@ do not care to see.) We can check on the pods as well using the same label selector: ```shell -$ kubectl get pods -l jobgroup=jobexample +kubectl get pods -l jobgroup=jobexample NAME READY STATUS RESTARTS AGE process-item-apple-kixwv 0/1 Completed 0 4m process-item-banana-wrsf7 0/1 Completed 0 4m @@ -100,7 +100,7 @@ There is not a single command to check on the output of all jobs at once, but looping over all the pods is pretty easy: ```shell -$ for p in $(kubectl get pods -l jobgroup=jobexample -o name) +for p in $(kubectl get pods -l jobgroup=jobexample -o name) do kubectl logs $p done diff --git a/content/en/docs/tasks/manage-gpus/scheduling-gpus.md b/content/en/docs/tasks/manage-gpus/scheduling-gpus.md index 91ae88bb8e..c751d00261 100644 --- a/content/en/docs/tasks/manage-gpus/scheduling-gpus.md +++ b/content/en/docs/tasks/manage-gpus/scheduling-gpus.md @@ -142,9 +142,9 @@ Report issues with this device plugin and installation method to [GoogleCloudPla Instructions for using NVIDIA GPUs on GKE are [here](https://cloud.google.com/kubernetes-engine/docs/how-to/gpus) -## Clusters containing different types of NVIDIA GPUs +## Clusters containing different types of GPUs -If different nodes in your cluster have different types of NVIDIA GPUs, then you +If different nodes in your cluster have different types of GPUs, then you can use [Node Labels and Node Selectors](/docs/tasks/configure-pod-container/assign-pods-nodes/) to schedule pods to appropriate nodes. @@ -156,6 +156,39 @@ kubectl label nodes accelerator=nvidia-tesla-k80 kubectl label nodes accelerator=nvidia-tesla-p100 ``` +For AMD GPUs, you can deploy [Node Labeller](https://github.com/RadeonOpenCompute/k8s-device-plugin/tree/master/cmd/k8s-node-labeller), which automatically labels your nodes with GPU properties. Currently supported properties: + +* Device ID (-device-id) +* VRAM Size (-vram) +* Number of SIMD (-simd-count) +* Number of Compute Unit (-cu-count) +* Firmware and Feature Versions (-firmware) +* GPU Family, in two letters acronym (-family) + * SI - Southern Islands + * CI - Sea Islands + * KV - Kaveri + * VI - Volcanic Islands + * CZ - Carrizo + * AI - Arctic Islands + * RV - Raven + +Example result: + + $ kubectl describe node cluster-node-23 + Name: cluster-node-23 + Roles: + Labels: beta.amd.com/gpu.cu-count.64=1 + beta.amd.com/gpu.device-id.6860=1 + beta.amd.com/gpu.family.AI=1 + beta.amd.com/gpu.simd-count.256=1 + beta.amd.com/gpu.vram.16G=1 + beta.kubernetes.io/arch=amd64 + beta.kubernetes.io/os=linux + kubernetes.io/hostname=cluster-node-23 + Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock + node.alpha.kubernetes.io/ttl: 0 + ...... + Specify the GPU type in the pod spec: ```yaml diff --git a/content/en/docs/tasks/run-application/configure-pdb.md b/content/en/docs/tasks/run-application/configure-pdb.md index 36a06dedda..7f994032dd 100644 --- a/content/en/docs/tasks/run-application/configure-pdb.md +++ b/content/en/docs/tasks/run-application/configure-pdb.md @@ -179,7 +179,9 @@ Assuming you don't actually have pods matching `app: zookeeper` in your namespac then you'll see something like this: ```shell -$ kubectl get poddisruptionbudgets +kubectl get poddisruptionbudgets +``` +``` NAME MIN-AVAILABLE ALLOWED-DISRUPTIONS AGE zk-pdb 2 0 7s ``` @@ -187,7 +189,9 @@ zk-pdb 2 0 7s If there are matching pods (say, 3), then you would see something like this: ```shell -$ kubectl get poddisruptionbudgets +kubectl get poddisruptionbudgets +``` +``` NAME MIN-AVAILABLE ALLOWED-DISRUPTIONS AGE zk-pdb 2 1 7s ``` @@ -198,7 +202,9 @@ counted the matching pods, and updated the status of the PDB. You can get more information about the status of a PDB with this command: ```shell -$ kubectl get poddisruptionbudgets zk-pdb -o yaml +kubectl get poddisruptionbudgets zk-pdb -o yaml +``` +```yaml apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: diff --git a/content/en/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md b/content/en/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md index 8cdf150782..d6f95f0651 100644 --- a/content/en/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md +++ b/content/en/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md @@ -65,7 +65,9 @@ It defines an index.php page which performs some CPU intensive computations: First, we will start a deployment running the image and expose it as a service: ```shell -$ kubectl run php-apache --image=k8s.gcr.io/hpa-example --requests=cpu=200m --expose --port=80 +kubectl run php-apache --image=k8s.gcr.io/hpa-example --requests=cpu=200m --expose --port=80 +``` +``` service/php-apache created deployment.apps/php-apache created ``` @@ -82,14 +84,18 @@ Roughly speaking, HPA will increase and decrease the number of replicas See [here](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#autoscaling-algorithm) for more details on the algorithm. ```shell -$ kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10 +kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10 +``` +``` horizontalpodautoscaler.autoscaling/php-apache autoscaled ``` We may check the current status of autoscaler by running: ```shell -$ kubectl get hpa +kubectl get hpa +``` +``` NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 18s @@ -104,17 +110,19 @@ Now, we will see how the autoscaler reacts to increased load. We will start a container, and send an infinite loop of queries to the php-apache service (please run it in a different terminal): ```shell -$ kubectl run -i --tty load-generator --image=busybox /bin/sh +kubectl run -i --tty load-generator --image=busybox /bin/sh Hit enter for command prompt -$ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done +while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done ``` Within a minute or so, we should see the higher CPU load by executing: ```shell -$ kubectl get hpa +kubectl get hpa +``` +``` NAME REFERENCE TARGET CURRENT MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache/scale 305% / 50% 305% 1 10 1 3m @@ -124,7 +132,9 @@ Here, CPU consumption has increased to 305% of the request. As a result, the deployment was resized to 7 replicas: ```shell -$ kubectl get deployment php-apache +kubectl get deployment php-apache +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php-apache 7 7 7 7 19m ``` @@ -145,11 +155,17 @@ the load generation by typing ` + C`. Then we will verify the result state (after a minute or so): ```shell -$ kubectl get hpa +kubectl get hpa +``` +``` NAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 11m +``` -$ kubectl get deployment php-apache +```shell +kubectl get deployment php-apache +``` +``` NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE php-apache 1 1 1 1 27m ``` @@ -172,7 +188,7 @@ by making use of the `autoscaling/v2beta2` API version. First, get the YAML of your HorizontalPodAutoscaler in the `autoscaling/v2beta2` form: ```shell -$ kubectl get hpa.v2beta2.autoscaling -o yaml > /tmp/hpa-v2.yaml +kubectl get hpa.v2beta2.autoscaling -o yaml > /tmp/hpa-v2.yaml ``` Open the `/tmp/hpa-v2.yaml` file in an editor, and you should see YAML which looks like this: @@ -288,7 +304,7 @@ spec: resource: name: cpu target: - kind: AverageUtilization + type: AverageUtilization averageUtilization: 50 - type: Pods pods: @@ -401,7 +417,9 @@ The conditions appear in the `status.conditions` field. To see the conditions a we can use `kubectl describe hpa`: ```shell -$ kubectl describe hpa cm-test +kubectl describe hpa cm-test +``` +```shell Name: cm-test Namespace: prom Labels: @@ -454,7 +472,9 @@ can use the following file to create it declaratively: We will create the autoscaler by executing the following command: ```shell -$ kubectl create -f https://k8s.io/examples/application/hpa/php-apache.yaml +kubectl create -f https://k8s.io/examples/application/hpa/php-apache.yaml +``` +``` horizontalpodautoscaler.autoscaling/php-apache created ``` diff --git a/content/en/docs/tasks/run-application/horizontal-pod-autoscale.md b/content/en/docs/tasks/run-application/horizontal-pod-autoscale.md index 1859a19e99..38d615293d 100644 --- a/content/en/docs/tasks/run-application/horizontal-pod-autoscale.md +++ b/content/en/docs/tasks/run-application/horizontal-pod-autoscale.md @@ -37,7 +37,7 @@ to match the observed average CPU utilization to the target specified by user. The Horizontal Pod Autoscaler is implemented as a control loop, with a period controlled by the controller manager's `--horizontal-pod-autoscaler-sync-period` flag (with a default -value of 30 seconds). +value of 15 seconds). During each period, the controller manager queries the resource utilization against the metrics specified in each HorizontalPodAutoscaler definition. The controller manager @@ -249,7 +249,7 @@ Kubernetes 1.6 adds support for making use of custom metrics in the Horizontal P You can add custom metrics for the Horizontal Pod Autoscaler to use in the `autoscaling/v2beta2` API. Kubernetes then queries the new custom metrics API to fetch the values of the appropriate custom metrics. -See [Support for metrics APIs](#support-for-metrics-APIs) for the requirements. +See [Support for metrics APIs](#support-for-metrics-apis) for the requirements. ## Support for metrics APIs diff --git a/content/en/docs/tasks/run-application/rolling-update-replication-controller.md b/content/en/docs/tasks/run-application/rolling-update-replication-controller.md index e0ace5c4c9..1802465d11 100644 --- a/content/en/docs/tasks/run-application/rolling-update-replication-controller.md +++ b/content/en/docs/tasks/run-application/rolling-update-replication-controller.md @@ -37,7 +37,7 @@ A rolling update works by: Rolling updates are initiated with the `kubectl rolling-update` command: - $ kubectl rolling-update NAME \ + kubectl rolling-update NAME \ ([NEW_NAME] --image=IMAGE | -f FILE) {{% /capture %}} @@ -50,7 +50,7 @@ Rolling updates are initiated with the `kubectl rolling-update` command: To initiate a rolling update using a configuration file, pass the new file to `kubectl rolling-update`: - $ kubectl rolling-update NAME -f FILE + kubectl rolling-update NAME -f FILE The configuration file must: @@ -66,17 +66,17 @@ Replication controller configuration files are described in ### Examples // Update pods of frontend-v1 using new replication controller data in frontend-v2.json. - $ kubectl rolling-update frontend-v1 -f frontend-v2.json + kubectl rolling-update frontend-v1 -f frontend-v2.json // Update pods of frontend-v1 using JSON data passed into stdin. - $ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - + cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - ## Updating the container image To update only the container image, pass a new image name and tag with the `--image` flag and (optionally) a new controller name: - $ kubectl rolling-update NAME [NEW_NAME] --image=IMAGE:TAG + kubectl rolling-update NAME [NEW_NAME] --image=IMAGE:TAG The `--image` flag is only supported for single-container pods. Specifying `--image` with multi-container pods returns an error. @@ -95,10 +95,10 @@ Moreover, the use of `:latest` is not recommended, see ### Examples // Update the pods of frontend-v1 to frontend-v2 - $ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 + kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 // Update the pods of frontend, keeping the replication controller name - $ kubectl rolling-update frontend --image=image:v2 + kubectl rolling-update frontend --image=image:v2 ## Required and optional fields @@ -165,14 +165,18 @@ spec: To update to version 1.9.1, you can use [`kubectl rolling-update --image`](https://git.k8s.io/community/contributors/design-proposals/cli/simple-rolling-update.md) to specify the new image: ```shell -$ kubectl rolling-update my-nginx --image=nginx:1.9.1 +kubectl rolling-update my-nginx --image=nginx:1.9.1 +``` +``` Created my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 ``` In another window, you can see that `kubectl` added a `deployment` label to the pods, whose value is a hash of the configuration, to distinguish the new pods from the old: ```shell -$ kubectl get pods -l app=nginx -L deployment +kubectl get pods -l app=nginx -L deployment +``` +``` NAME READY STATUS RESTARTS AGE DEPLOYMENT my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-k156z 1/1 Running 0 1m ccba8fbd8cc8160970f63f9a2696fc46 my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-v95yh 1/1 Running 0 35s ccba8fbd8cc8160970f63f9a2696fc46 @@ -199,7 +203,9 @@ replicationcontroller "my-nginx" rolling updated If you encounter a problem, you can stop the rolling update midway and revert to the previous version using `--rollback`: ```shell -$ kubectl rolling-update my-nginx --rollback +kubectl rolling-update my-nginx --rollback +``` +``` Setting "my-nginx" replicas to 1 Continuing update with existing controller my-nginx. Scaling up nginx from 1 to 1, scaling down my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 1 to 0 (keep 1 pods available, don't exceed 2 pods) @@ -239,7 +245,9 @@ spec: and roll it out: ```shell -$ kubectl rolling-update my-nginx -f ./nginx-rc.yaml +kubectl rolling-update my-nginx -f ./nginx-rc.yaml +``` +``` Created my-nginx-v4 Scaling up my-nginx-v4 from 0 to 5, scaling down my-nginx from 4 to 0 (keep 4 pods available, don't exceed 5 pods) Scaling my-nginx-v4 up to 1 diff --git a/content/en/docs/tasks/service-catalog/install-service-catalog-using-helm.md b/content/en/docs/tasks/service-catalog/install-service-catalog-using-helm.md index 728d7a8950..a265c91974 100644 --- a/content/en/docs/tasks/service-catalog/install-service-catalog-using-helm.md +++ b/content/en/docs/tasks/service-catalog/install-service-catalog-using-helm.md @@ -53,12 +53,20 @@ svc-cat/catalog 0.0.1 service-catalog API server and controller-manag... Your Kubernetes cluster must have RBAC enabled, which requires your Tiller Pod(s) to have `cluster-admin` access. -If you are using Minikube, run the `minikube start` command with the following flag: +When using Minikube v0.25 or older, you must run Minikube with RBAC explicitly enabled: ```shell minikube start --extra-config=apiserver.Authorization.Mode=RBAC ``` +When using Minikube v0.26+, run: + +```shell +minikube start +``` + +With Minikube v0.26+, do not specify `--extra-config`. The flag has since been changed to --extra-config=apiserver.authorization-mode and Minikube now uses RBAC by default. Specifying the older flag may cause the start command to hang. + If you are using `hack/local-up-cluster.sh`, set the `AUTHORIZATION_MODE` environment variable with the following values: ``` diff --git a/content/en/docs/tasks/tools/install-kubectl.md b/content/en/docs/tasks/tools/install-kubectl.md index b5151a4d2e..c9f1d892f6 100644 --- a/content/en/docs/tasks/tools/install-kubectl.md +++ b/content/en/docs/tasks/tools/install-kubectl.md @@ -5,6 +5,10 @@ reviewers: title: Install and Set Up kubectl content_template: templates/task weight: 10 +card: + name: tasks + weight: 20 + title: Install kubectl --- {{% capture overview %}} @@ -85,7 +89,8 @@ If you are on macOS and using [Macports](https://macports.org/) package manager, 1. Run the installation command: ``` - port install kubectl + sudo port selfupdate + sudo port install kubectl ``` 2. Test to ensure the version you installed is sufficiently up-to-date: @@ -105,9 +110,7 @@ If you are on Windows and using [Powershell Gallery](https://www.powershellgalle install-kubectl.ps1 [-DownloadLocation ] ``` - {{< note >}} - If you do not specify a `DownloadLocation`, `kubectl` will be installed in the user's temp Directory. - {{< /note >}} + {{< note >}}If you do not specify a `DownloadLocation`, `kubectl` will be installed in the user's temp Directory.{{< /note >}} The installer creates `$HOME/.kube` and instructs it to create a config file @@ -117,36 +120,41 @@ If you are on Windows and using [Powershell Gallery](https://www.powershellgalle kubectl version ``` - {{< note >}} - Updating the installation is performed by rerunning the two commands listed in step 1. - {{< /note >}} + {{< note >}}Updating the installation is performed by rerunning the two commands listed in step 1.{{< /note >}} -## Install with Chocolatey on Windows +## Install on Windows using Chocolatey or scoop -If you are on Windows and using [Chocolatey](https://chocolatey.org) package manager, you can install kubectl with Chocolatey. +To install kubectl on Windows you can use either [Chocolatey](https://chocolatey.org) package manager or [scoop](https://scoop.sh) command-line installer. +{{< tabs name="kubectl_win_install" >}} +{{% tab name="choco" %}} -1. Run the installation command: - - ``` choco install kubernetes-cli - ``` - + +{{% /tab %}} +{{% tab name="scoop" %}} + + scoop install kubectl + +{{% /tab %}} +{{< /tabs >}} 2. Test to ensure the version you installed is sufficiently up-to-date: ``` kubectl version ``` -3. Change to your %HOME% directory: - For example: `cd C:\users\yourusername` +3. Navigate to your home directory: -4. Create the .kube directory: + ``` + cd %USERPROFILE% + ``` +4. Create the `.kube` directory: ``` mkdir .kube ``` -5. Change to the .kube directory you just created: +5. Change to the `.kube` directory you just created: ``` cd .kube @@ -158,9 +166,7 @@ If you are on Windows and using [Chocolatey](https://chocolatey.org) package man New-Item config -type file ``` - {{< note >}} - Edit the config file with a text editor of your choice, such as Notepad. - {{< /note >}} + {{< note >}}Edit the config file with a text editor of your choice, such as Notepad.{{< /note >}} ## Download as part of the Google Cloud SDK @@ -283,63 +289,139 @@ kubectl cluster-info dump ## Enabling shell autocompletion -kubectl includes autocompletion support, which can save a lot of typing! +kubectl provides autocompletion support for Bash and Zsh, which can save you a lot of typing! -The completion script itself is generated by kubectl, so you typically just need to invoke it from your profile. +Below are the procedures to set up autocompletion for Bash (including the difference between Linux and macOS) and Zsh. -Common examples are provided here. For more details, consult `kubectl completion -h`. +{{< tabs name="kubectl_autocompletion" >}} -### On Linux, using bash -On CentOS Linux, you may need to install the bash-completion package which is not installed by default. +{{% tab name="Bash on Linux" %}} + +### Introduction + +The kubectl completion script for Bash can be generated with the command `kubectl completion bash`. Sourcing the completion script in your shell enables kubectl autocompletion. + +However, the completion script depends on [**bash-completion**](https://github.com/scop/bash-completion), which means that you have to install this software first (you can test if you have bash-completion already installed by running `type _init_completion`). + +### Install bash-completion + +bash-completion is provided by many package managers (see [here](https://github.com/scop/bash-completion#installation)). You can install it with `apt-get install bash-completion` or `yum install bash-completion`, etc. + +The above commands create `/usr/share/bash-completion/bash_completion`, which is the main script of bash-completion. Depending on your package manager, you have to manually source this file in your `~/.bashrc` file. + +To find out, reload your shell and run `type _init_completion`. If the command succeeds, you're already set, otherwise add the following to your `~/.bashrc` file: ```shell -yum install bash-completion -y +source /usr/share/bash-completion/bash_completion ``` -To add kubectl autocompletion to your current shell, run `source <(kubectl completion bash)`. +Reload your shell and verify that bash-completion is correctly installed by typing `type _init_completion`. -To add kubectl autocompletion to your profile, so it is automatically loaded in future shells run: +### Enable kubectl autocompletion + +You now need to ensure that the kubectl completion script gets sourced in all your shell sessions. There are two ways in which you can do this: + +- Source the completion script in your `~/.bashrc` file: + + ```shell + echo 'source <(kubectl completion bash)' >>~/.bashrc + ``` + +- Add the completion script to the `/etc/bash_completion.d` directory: + + ```shell + kubectl completion bash >/etc/bash_completion.d/kubectl + ``` + +{{< note >}} +bash-completion sources all completion scripts in `/etc/bash_completion.d`. +{{< /note >}} + +Both approaches are equivalent. After reloading your shell, kubectl autocompletion should be working. + +{{% /tab %}} + + +{{% tab name="Bash on macOS" %}} + +{{< warning>}} +macOS includes Bash 3.2 by default. The kubectl completion script requires Bash 4.1+ and doesn't work with Bash 3.2. A possible way around this is to install a newer version of Bash on macOS (see instructions [here](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)). The below instructions only work if you are using Bash 4.1+. +{{< /warning >}} + +### Introduction + +The kubectl completion script for Bash can be generated with the command `kubectl completion bash`. Sourcing the completion script in your shell enables kubectl autocompletion. + +However, the completion script depends on [**bash-completion**](https://github.com/scop/bash-completion), which means that you have to install this software first (you can test if you have bash-completion already installed by running `type _init_completion`). + +### Install bash-completion + +You can install bash-completion with Homebrew: ```shell -echo "source <(kubectl completion bash)" >> ~/.bashrc -``` - -### On macOS, using bash -On macOS, you will need to install bash-completion support via [Homebrew](https://brew.sh/) first: - -```shell -## If running Bash 3.2 included with macOS -brew install bash-completion -## or, if running Bash 4.1+ brew install bash-completion@2 ``` -Follow the "caveats" section of brew's output to add the appropriate bash completion path to your local .bashrc. +{{< note >}} +The `@2` stands for bash-completion 2, which is required by the kubectl completion script (it doesn't work with bash-completion 1). In turn, bash-completion 2 requires Bash 4.1+, that's why you needed to upgrade Bash. +{{< /note >}} -If you installed kubectl using the [Homebrew instructions](#install-with-homebrew-on-macos) then kubectl completion should start working immediately. - -If you have installed kubectl manually, you need to add kubectl autocompletion to the bash-completion: +As stated in the output of `brew install` ("Caveats" section), add the following lines to your `~/.bashrc` or `~/.bash_profile` file: ```shell -kubectl completion bash > $(brew --prefix)/etc/bash_completion.d/kubectl +export BASH_COMPLETION_COMPAT_DIR=/usr/local/etc/bash_completion.d +[[ -r /usr/local/etc/profile.d/bash_completion.sh ]] && . /usr/local/etc/profile.d/bash_completion.sh ``` -The Homebrew project is independent from Kubernetes, so the bash-completion packages are not guaranteed to work. +Reload your shell and verify that bash-completion is correctly installed by typing `type _init_completion`. -### Using Zsh -If you are using zsh edit the ~/.zshrc file and add the following code to enable kubectl autocompletion: +### Enable kubectl autocompletion + +You now need to ensure that the kubectl completion script gets sourced in all your shell sessions. There are multiple ways in which you can do this: + +- Source the completion script in your `~/.bashrc` file: + + ```shell + echo 'source <(kubectl completion bash)' >>~/.bashrc + + ``` + +- Add the completion script to `/usr/local/etc/bash_completion.d`: + + ```shell + kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl + ``` + +- If you installed kubectl with Homebrew (as explained [here](#install-with-homebrew-on-macos)), then the completion script was automatically installed to `/usr/local/etc/bash_completion.d/kubectl`. In that case, you don't need to do anything. + +{{< note >}} +bash-completion (if installed with Homebrew) sources all the completion scripts in the directory that is set in the `BASH_COMPLETION_COMPAT_DIR` environment variable. +{{< /note >}} + +All approaches are equivalent. After reloading your shell, kubectl autocompletion should be working. +{{% /tab %}} + +{{% tab name="Zsh" %}} + +The kubectl completion script for Zsh can be generated with the command `kubectl completion zsh`. Sourcing the completion script in your shell enables kubectl autocompletion. + +To do so in all your shell sessions, add the following to your `~/.zshrc` file: ```shell -if [ $commands[kubectl] ]; then - source <(kubectl completion zsh) -fi +source <(kubectl completion zsh) ``` -Or when using [Oh-My-Zsh](http://ohmyz.sh/), edit the ~/.zshrc file and update the `plugins=` line to include the kubectl plugin. +After reloading your shell, kubectl autocompletion should be working. + +If you get an error like `complete:13: command not found: compdef`, then add the following to the beginning of your `~/.zshrc` file: ```shell -plugins=(kubectl) +autoload -Uz compinit +compinit ``` +{{% /tab %}} +{{< /tabs >}} + {{% /capture %}} {{% capture whatsnext %}} diff --git a/content/en/docs/tasks/tools/install-minikube.md b/content/en/docs/tasks/tools/install-minikube.md index ca56e7ef26..e36e453dd0 100644 --- a/content/en/docs/tasks/tools/install-minikube.md +++ b/content/en/docs/tasks/tools/install-minikube.md @@ -2,17 +2,23 @@ title: Install Minikube content_template: templates/task weight: 20 +card: + name: tasks + weight: 10 --- {{% capture overview %}} -This page shows how to install Minikube. +This page shows you how to install [Minikube](/docs/tutorials/hello-minikube), a tool that runs a single-node Kubernetes cluster in a virtual machine on your laptop. {{% /capture %}} {{% capture prerequisites %}} -VT-x or AMD-v virtualization must be enabled in your computer's BIOS. +VT-x or AMD-v virtualization must be enabled in your computer's BIOS. To check this on Linux run the following and verify the output is non-empty: +```shell +egrep --color 'vmx|svm' /proc/cpuinfo +``` {{% /capture %}} @@ -20,21 +26,17 @@ VT-x or AMD-v virtualization must be enabled in your computer's BIOS. ## Install a Hypervisor -If you do not already have a hypervisor installed, install the appropriate one for your OS now: +If you do not already have a hypervisor installed, install one for your OS now: -* macOS: [VirtualBox](https://www.virtualbox.org/wiki/Downloads) or -[VMware Fusion](https://www.vmware.com/products/fusion), or -[HyperKit](https://github.com/moby/hyperkit). +Operating system | Supported hypervisors +:----------------|:--------------------- +macOS | [VirtualBox](https://www.virtualbox.org/wiki/Downloads), [VMware Fusion](https://www.vmware.com/products/fusion), [HyperKit](https://github.com/moby/hyperkit) +Linux | [VirtualBox](https://www.virtualbox.org/wiki/Downloads), [KVM](http://www.linux-kvm.org/) +Windows | [VirtualBox](https://www.virtualbox.org/wiki/Downloads), [Hyper-V](https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/quick_start/walkthrough_install) -* Linux: [VirtualBox](https://www.virtualbox.org/wiki/Downloads) or -[KVM](http://www.linux-kvm.org/). - - {{< note >}} - Minikube also supports a `-\-vm-driver=none` option that runs the Kubernetes components on the host and not in a VM. Using this driver requires Docker and a linux environment, but not a hypervisor. - {{< /note >}} - -* Windows: [VirtualBox](https://www.virtualbox.org/wiki/Downloads) or -[Hyper-V](https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/quick_start/walkthrough_install). +{{< note >}} +Minikube also supports a `--vm-driver=none` option that runs the Kubernetes components on the host and not in a VM. Using this driver requires Docker and a Linux environment but not a hypervisor. +{{< /note >}} ## Install kubectl @@ -42,14 +44,89 @@ If you do not already have a hypervisor installed, install the appropriate one f ## Install Minikube -* Install Minikube according to the instructions for the [latest release](https://github.com/kubernetes/minikube/releases). +### macOS + +The easiest way to install Minikube on macOS is using [Homebrew](https://brew.sh): + +```shell +brew cask install minikube +``` + +You can also install it on macOS by downloading a static binary: + +```shell +curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \ + && chmod +x minikube +``` + +Here's an easy way to add the Minikube executable to your path: + +```shell +sudo mv minikube /usr/local/bin +``` + +### Linux + +{{< note >}} +This document shows you how to install Minikube on Linux using a static binary. For alternative Linux installation methods, see [Other Ways to Install](https://github.com/kubernetes/minikube#other-ways-to-install) in the official Minikube GitHub repository. +{{< /note >}} + +You can install Minikube on Linux by downloading a static binary: + +```shell +curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \ + && chmod +x minikube +``` + +Here's an easy way to add the Minikube executable to your path: + +```shell +sudo cp minikube /usr/local/bin && rm minikube +``` + +### Windows + +{{< note >}} +To run Minikube on Windows, you need to install [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) first, which can be run on three versions of Windows 10: Windows 10 Enterprise, Windows 10 Professional, and Windows 10 Education. +{{< /note >}} + +The easiest way to install Minikube on Windows is using [Chocolatey](https://chocolatey.org/) (run as an administrator): + +```shell +choco install minikube kubernetes-cli +``` + +After Minikube has finished installing, close the current CLI session and restart. Minikube should have been added to your path automatically. + +#### Windows manual installation + +To install Minikube manually on Windows, download [`minikube-windows-amd64`](https://github.com/kubernetes/minikube/releases/latest), rename it to `minikube.exe`, and add it to your path. + +#### Windows Installer + +To install Minikube manually on windows using [Windows Installer](https://docs.microsoft.com/en-us/windows/desktop/msi/windows-installer-portal), download [`minikube-installer.exe`](https://github.com/kubernetes/minikube/releases/latest) and execute the installer. {{% /capture %}} {{% capture whatsnext %}} -* [Running Kubernetes Locally via Minikube](/docs/getting-started-guides/minikube/) +* [Running Kubernetes Locally via Minikube](/docs/setup/minikube/) {{% /capture %}} +## Cleanup everything to start fresh +If you have previously installed minikube, and run: +```shell +minikube start +``` + +And this command returns an error: +```shell +machine does not exist +``` + +You need to wipe the configuration files: +```shell +rm -rf ~/.minikube +``` diff --git a/content/en/docs/test.md b/content/en/docs/test.md index e7faf57d12..1e682f538d 100644 --- a/content/en/docs/test.md +++ b/content/en/docs/test.md @@ -344,7 +344,7 @@ Warnings point out something that could cause harm if ignored. To add shortcodes to includes. {{< note >}} -{{< include "federation-current-state.md" >}} +{{< include "task-tutorial-prereqs.md" >}} {{< /note >}} ## Katacoda Embedded Live Environment diff --git a/content/en/docs/tutorials/clusters/apparmor.md b/content/en/docs/tutorials/clusters/apparmor.md index 1f6658fe2b..4e1fff809e 100644 --- a/content/en/docs/tutorials/clusters/apparmor.md +++ b/content/en/docs/tutorials/clusters/apparmor.md @@ -46,7 +46,9 @@ Make sure: receiving the expected protections, it is important to verify the Kubelet version of your nodes: ```shell - $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}' + kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}' + ``` + ``` gke-test-default-pool-239f5d02-gyn2: v1.4.0 gke-test-default-pool-239f5d02-x1kf: v1.4.0 gke-test-default-pool-239f5d02-xwux: v1.4.0 @@ -58,7 +60,7 @@ Make sure: module is enabled, check the `/sys/module/apparmor/parameters/enabled` file: ```shell - $ cat /sys/module/apparmor/parameters/enabled + cat /sys/module/apparmor/parameters/enabled Y ``` @@ -76,7 +78,9 @@ Make sure: expanded. You can verify that your nodes are running docker with: ```shell - $ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.containerRuntimeVersion}\n{end}' + kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.containerRuntimeVersion}\n{end}' + ``` + ``` gke-test-default-pool-239f5d02-gyn2: docker://1.11.2 gke-test-default-pool-239f5d02-x1kf: docker://1.11.2 gke-test-default-pool-239f5d02-xwux: docker://1.11.2 @@ -91,7 +95,9 @@ Make sure: node by checking the `/sys/kernel/security/apparmor/profiles` file. For example: ```shell - $ ssh gke-test-default-pool-239f5d02-gyn2 "sudo cat /sys/kernel/security/apparmor/profiles | sort" + ssh gke-test-default-pool-239f5d02-gyn2 "sudo cat /sys/kernel/security/apparmor/profiles | sort" + ``` + ``` apparmor-test-deny-write (enforce) apparmor-test-audit-write (enforce) docker-default (enforce) @@ -107,7 +113,9 @@ on nodes by checking the node ready condition message (though this is likely to later release): ```shell -$ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {.status.conditions[?(@.reason=="KubeletReady")].message}\n{end}' +kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {.status.conditions[?(@.reason=="KubeletReady")].message}\n{end}' +``` +``` gke-test-default-pool-239f5d02-gyn2: kubelet is posting ready status. AppArmor enabled gke-test-default-pool-239f5d02-x1kf: kubelet is posting ready status. AppArmor enabled gke-test-default-pool-239f5d02-xwux: kubelet is posting ready status. AppArmor enabled @@ -148,14 +156,18 @@ prerequisites have not been met, the Pod will be rejected, and will not run. To verify that the profile was applied, you can look for the AppArmor security option listed in the container created event: ```shell -$ kubectl get events | grep Created +kubectl get events | grep Created +``` +``` 22s 22s 1 hello-apparmor Pod spec.containers{hello} Normal Created {kubelet e2e-test-stclair-minion-group-31nt} Created container with docker id 269a53b202d3; Security:[seccomp=unconfined apparmor=k8s-apparmor-example-deny-write] ``` You can also verify directly that the container's root process is running with the correct profile by checking its proc attr: ```shell -$ kubectl exec cat /proc/1/attr/current +kubectl exec cat /proc/1/attr/current +``` +``` k8s-apparmor-example-deny-write (enforce) ``` @@ -173,12 +185,12 @@ nodes. For this example we'll just use SSH to install the profiles, but other ap discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles). ```shell -$ NODES=( +NODES=( # The SSH-accessible domain names of your nodes gke-test-default-pool-239f5d02-gyn2.us-central1-a.my-k8s gke-test-default-pool-239f5d02-x1kf.us-central1-a.my-k8s gke-test-default-pool-239f5d02-xwux.us-central1-a.my-k8s) -$ for NODE in ${NODES[*]}; do ssh $NODE 'sudo apparmor_parser -q < profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { @@ -198,14 +210,16 @@ Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile: {{< codenew file="pods/security/hello-apparmor.yaml" >}} ```shell -$ kubectl create -f ./hello-apparmor.yaml +kubectl create -f ./hello-apparmor.yaml ``` If we look at the pod events, we can see that the Pod container was created with the AppArmor profile "k8s-apparmor-example-deny-write": ```shell -$ kubectl get events | grep hello-apparmor +kubectl get events | grep hello-apparmor +``` +``` 14s 14s 1 hello-apparmor Pod Normal Scheduled {default-scheduler } Successfully assigned hello-apparmor to gke-test-default-pool-239f5d02-gyn2 14s 14s 1 hello-apparmor Pod spec.containers{hello} Normal Pulling {kubelet gke-test-default-pool-239f5d02-gyn2} pulling image "busybox" 13s 13s 1 hello-apparmor Pod spec.containers{hello} Normal Pulled {kubelet gke-test-default-pool-239f5d02-gyn2} Successfully pulled image "busybox" @@ -216,14 +230,18 @@ $ kubectl get events | grep hello-apparmor We can verify that the container is actually running with that profile by checking its proc attr: ```shell -$ kubectl exec hello-apparmor cat /proc/1/attr/current +kubectl exec hello-apparmor cat /proc/1/attr/current +``` +``` k8s-apparmor-example-deny-write (enforce) ``` Finally, we can see what happens if we try to violate the profile by writing to a file: ```shell -$ kubectl exec hello-apparmor touch /tmp/test +kubectl exec hello-apparmor touch /tmp/test +``` +``` touch: /tmp/test: Permission denied error: error executing remote command: command terminated with non-zero exit code: Error executing in Docker Container: 1 ``` @@ -231,7 +249,9 @@ error: error executing remote command: command terminated with non-zero exit cod To wrap up, let's look at what happens if we try to specify a profile that hasn't been loaded: ```shell -$ kubectl create -f /dev/stdin <`: Refers to a profile loaded on the node (localhost) by name. - The possible profile names are detailed in the - [core policy reference](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Profile_names_and_attachment_specifications). + [core policy reference](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference#profile-names-and-attachment-specifications). - `unconfined`: This effectively disables AppArmor on the container. Any other profile reference format is invalid. @@ -439,9 +463,7 @@ Specifying the list of profiles Pod containers is allowed to specify: Additional resources: -* [Quick guide to the AppArmor profile language](http://wiki.apparmor.net/index.php/QuickProfileLanguage) -* [AppArmor core policy reference](http://wiki.apparmor.net/index.php/ProfileLanguage) +* [Quick guide to the AppArmor profile language](https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage) +* [AppArmor core policy reference](https://gitlab.com/apparmor/apparmor/wikis/Policy_Layout) {{% /capture %}} - - diff --git a/content/en/docs/tutorials/hello-minikube.md b/content/en/docs/tutorials/hello-minikube.md index 11e04c12fc..5099beadf1 100644 --- a/content/en/docs/tutorials/hello-minikube.md +++ b/content/en/docs/tutorials/hello-minikube.md @@ -8,6 +8,9 @@ menu: weight: 10 post: >

Ready to get your hands dirty? Build a simple Kubernetes cluster that runs "Hello World" for Node.js.

+card: + name: tutorials + weight: 10 --- {{% capture overview %}} @@ -60,7 +63,7 @@ For more information on the `docker build` command, read the [Docker documentati 3. Katacoda environment only: At the top of the terminal pane, click the plus sign, and then click **Select port to view on Host 1**. -4. Katacoda environment only: Type 30000, and then click **Display Port**. +4. Katacoda environment only: Type `30000`, and then click **Display Port**. ## Create a Deployment @@ -75,7 +78,7 @@ recommended way to manage the creation and scaling of Pods. Pod runs a Container based on the provided Docker image. ```shell - kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node --port=8080 + kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node ``` 2. View the Deployment: @@ -127,7 +130,7 @@ Kubernetes [*Service*](/docs/concepts/services-networking/service/). 1. Expose the Pod to the public internet using the `kubectl expose` command: ```shell - kubectl expose deployment hello-node --type=LoadBalancer + kubectl expose deployment hello-node --type=LoadBalancer --port=8080 ``` The `--type=LoadBalancer` flag indicates that you want to expose your Service @@ -160,7 +163,7 @@ Kubernetes [*Service*](/docs/concepts/services-networking/service/). 4. Katacoda environment only: Click the plus sign, and then click **Select port to view on Host 1**. -5. Katacoda environment only: Type in the Port number following `8080:`, and then click **Display Port**. +5. Katacoda environment only: Type `30369` (see port opposite to `8080` in services output), and then click This opens up a browser window that serves your app and shows the "Hello World" message. diff --git a/content/en/docs/tutorials/kubernetes-basics/_index.html b/content/en/docs/tutorials/kubernetes-basics/_index.html index 39a7f9a56f..342cf2cdd7 100644 --- a/content/en/docs/tutorials/kubernetes-basics/_index.html +++ b/content/en/docs/tutorials/kubernetes-basics/_index.html @@ -2,6 +2,10 @@ title: Learn Kubernetes Basics linkTitle: Learn Kubernetes Basics weight: 10 +card: + name: tutorials + weight: 20 + title: Walkthrough the basics --- @@ -17,7 +21,7 @@ weight: 10

Kubernetes Basics

-

This tutorial provides a walkthrough of the basics of the Kubernetes cluster orchestration system. Each module contains some background information on major Kubernetes features and concepts, and includes an interactive online tutorial. These interactive tutorials let you manage a simple cluster and its containerized applications for yourself.

+

This tutorial provides a walkthrough of the basics of the Kubernetes cluster orchestration system. Each module contains some background information on major Kubernetes features and concepts, and includes an interactive online tutorial. These interactive tutorials let you manage a simple cluster and its containerized applications for yourself.

Using the interactive tutorials, you can learn to:

  • Deploy a containerized application on a cluster
  • @@ -34,7 +38,7 @@ weight: 10

    What can Kubernetes do for you?

    -

    With modern web services, users expect applications to be available 24/7, and developers expect to deploy new versions of those applications several times a day. Containerization helps package software to serve these goals, enabling applications to be released and updated in an easy and fast way without downtime. Kubernetes helps you make sure those containerized applications run where and when you want, and helps them find the resources and tools they need to work. Kubernetes is a production-ready, open source platform designed with Google's accumulated experience in container orchestration, combined with best-of-breed ideas from the community.

    +

    With modern web services, users expect applications to be available 24/7, and developers expect to deploy new versions of those applications several times a day. Containerization helps package software to serve these goals, enabling applications to be released and updated in an easy and fast way without downtime. Kubernetes helps you make sure those containerized applications run where and when you want, and helps them find the resources and tools they need to work. Kubernetes is a production-ready, open source platform designed with Google's accumulated experience in container orchestration, combined with best-of-breed ideas from the community.

    diff --git a/content/en/docs/tutorials/kubernetes-basics/create-cluster/cluster-intro.html b/content/en/docs/tutorials/kubernetes-basics/create-cluster/cluster-intro.html index 11b790a4ce..a203274a6c 100644 --- a/content/en/docs/tutorials/kubernetes-basics/create-cluster/cluster-intro.html +++ b/content/en/docs/tutorials/kubernetes-basics/create-cluster/cluster-intro.html @@ -29,7 +29,7 @@ weight: 10

    Kubernetes Clusters

    - Kubernetes coordinates a highly available cluster of computers that are connected to work as a single unit. The abstractions in Kubernetes allow you to deploy containerized applications to a cluster without tying them specifically to individual machines. To make use of this new model of deployment, applications need to be packaged in a way that decouples them from individual hosts: they need to be containerized. Containerized applications are more flexible and available than in past deployment models, where applications were installed directly onto specific machines as packages deeply integrated into the host. Kubernetes automates the distribution and scheduling of application containers across a cluster in a more efficient way. Kubernetes is an open-source platform and is production-ready. + Kubernetes coordinates a highly available cluster of computers that are connected to work as a single unit. The abstractions in Kubernetes allow you to deploy containerized applications to a cluster without tying them specifically to individual machines. To make use of this new model of deployment, applications need to be packaged in a way that decouples them from individual hosts: they need to be containerized. Containerized applications are more flexible and available than in past deployment models, where applications were installed directly onto specific machines as packages deeply integrated into the host. Kubernetes automates the distribution and scheduling of application containers across a cluster in a more efficient way. Kubernetes is an open-source platform and is production-ready.

    A Kubernetes cluster consists of two types of resources:

      @@ -72,12 +72,12 @@ weight: 10

      The Master is responsible for managing the cluster. The master coordinates all activities in your cluster, such as scheduling applications, maintaining applications' desired state, scaling applications, and rolling out new updates.

      -

      A node is a VM or a physical computer that serves as a worker machine in a Kubernetes cluster. Each node has a Kubelet, which is an agent for managing the node and communicating with the Kubernetes master. The node should also have tools for handling container operations, such as Docker or rkt. A Kubernetes cluster that handles production traffic should have a minimum of three nodes.

      +

      A node is a VM or a physical computer that serves as a worker machine in a Kubernetes cluster. Each node has a Kubelet, which is an agent for managing the node and communicating with the Kubernetes master. The node should also have tools for handling container operations, such as Docker or rkt. A Kubernetes cluster that handles production traffic should have a minimum of three nodes.

      -

      Masters manage the cluster and the nodes are used to host the running applications.

      +

      Masters manage the cluster and the nodes are used to host the running applications.

      @@ -86,7 +86,7 @@ weight: 10

      When you deploy applications on Kubernetes, you tell the master to start the application containers. The master schedules the containers to run on the cluster's nodes. The nodes communicate with the master using the Kubernetes API, which the master exposes. End users can also use the Kubernetes API directly to interact with the cluster.

      -

      A Kubernetes cluster can be deployed on either physical or virtual machines. To get started with Kubernetes development, you can use Minikube. Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing only one node. Minikube is available for Linux, macOS, and Windows systems. The Minikube CLI provides basic bootstrapping operations for working with your cluster, including start, stop, status, and delete. For this tutorial, however, you'll use a provided online terminal with Minikube pre-installed.

      +

      A Kubernetes cluster can be deployed on either physical or virtual machines. To get started with Kubernetes development, you can use Minikube. Minikube is a lightweight Kubernetes implementation that creates a VM on your local machine and deploys a simple cluster containing only one node. Minikube is available for Linux, macOS, and Windows systems. The Minikube CLI provides basic bootstrapping operations for working with your cluster, including start, stop, status, and delete. For this tutorial, however, you'll use a provided online terminal with Minikube pre-installed.

      Now that you know what Kubernetes is, let's go to the online tutorial and start our first cluster!

      diff --git a/content/en/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro.html b/content/en/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro.html index 5b52ad102b..37b1e52b7d 100644 --- a/content/en/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro.html +++ b/content/en/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro.html @@ -34,7 +34,7 @@ weight: 10 master schedules mentioned application instances onto individual Nodes in the cluster.

      -

      Once the application instances are created, a Kubernetes Deployment Controller continuously monitors those instances. If the Node hosting an instance goes down or is deleted, the Deployment controller replaces it. This provides a self-healing mechanism to address machine failure or maintenance.

      +

      Once the application instances are created, a Kubernetes Deployment Controller continuously monitors those instances. If the Node hosting an instance goes down or is deleted, the Deployment controller replaces the instance with an instance on another Node in the cluster. This provides a self-healing mechanism to address machine failure or maintenance.

      In a pre-orchestration world, installation scripts would often be used to start applications, but they did not allow recovery from machine failure. By both creating your application instances and keeping them running across Nodes, Kubernetes Deployments provide a fundamentally different approach to application management.

      @@ -91,9 +91,9 @@ weight: 10
      -

      For our first Deployment, we'll use a Node.js application packaged in a Docker container. +

      For our first Deployment, we'll use a Node.js application packaged in a Docker container. To create the Node.js application and deploy the Docker container, follow the instructions from the - Hello Minikube tutorial.

      + Hello Minikube tutorial.

      Now that you know what Deployments are, let's go to the online tutorial and deploy our first app!

      diff --git a/content/en/docs/tutorials/kubernetes-basics/expose/expose-intro.html b/content/en/docs/tutorials/kubernetes-basics/expose/expose-intro.html index c0288c5ddb..8adf05965b 100644 --- a/content/en/docs/tutorials/kubernetes-basics/expose/expose-intro.html +++ b/content/en/docs/tutorials/kubernetes-basics/expose/expose-intro.html @@ -28,9 +28,9 @@ weight: 10

      Overview of Kubernetes Services

      -

      Kubernetes Pods are mortal. Pods in fact have a lifecycle. When a worker node dies, the Pods running on the Node are also lost. A ReplicationController might then dynamically drive the cluster back to desired state via creation of new Pods to keep your application running. As another example, consider an image-processing backend with 3 replicas. Those replicas are exchangeable; the front-end system should not care about backend replicas or even if a Pod is lost and recreated. That said, each Pod in a Kubernetes cluster has a unique IP address, even Pods on the same Node, so there needs to be a way of automatically reconciling changes among Pods so that your applications continue to function.

      - -

      A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them. Services enable a loose coupling between dependent Pods. A Service is defined using YAML (preferred) or JSON, like all Kubernetes objects. The set of Pods targeted by a Service is usually determined by a LabelSelector (see below for why you might want a Service without including selector in the spec).

      +

      Kubernetes Pods are mortal. Pods in fact have a lifecycle. When a worker node dies, the Pods running on the Node are also lost. A ReplicaSet might then dynamically drive the cluster back to desired state via creation of new Pods to keep your application running. As another example, consider an image-processing backend with 3 replicas. Those replicas are exchangeable; the front-end system should not care about backend replicas or even if a Pod is lost and recreated. That said, each Pod in a Kubernetes cluster has a unique IP address, even Pods on the same Node, so there needs to be a way of automatically reconciling changes among Pods so that your applications continue to function.

      + +

      A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them. Services enable a loose coupling between dependent Pods. A Service is defined using YAML (preferred) or JSON, like all Kubernetes objects. The set of Pods targeted by a Service is usually determined by a LabelSelector (see below for why you might want a Service without including selector in the spec).

      Although each Pod has a unique IP address, those IPs are not exposed outside the cluster without a Service. Services allow your applications to receive traffic. Services can be exposed in different ways by specifying a type in the ServiceSpec:

        diff --git a/content/en/docs/tutorials/online-training/overview.md b/content/en/docs/tutorials/online-training/overview.md index 99f7d748ae..7b3348d9da 100644 --- a/content/en/docs/tutorials/online-training/overview.md +++ b/content/en/docs/tutorials/online-training/overview.md @@ -11,24 +11,37 @@ Here are some of the sites that offer online training for Kubernetes: {{% capture body %}} -* [Scalable Microservices with Kubernetes (Udacity)](https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615) +* [Certified Kubernetes Administrator Preparation Course (Linux Academy)](https://linuxacademy.com/linux/training/course/name/certified-kubernetes-administrator-preparation-course) -* [Introduction to Kubernetes (edX)](https://www.edx.org/course/introduction-kubernetes-linuxfoundationx-lfs158x) +* [Certified Kubernetes Application Developer Preparation Course with Practice Tests (KodeKloud.com)](https://kodekloud.com/p/kubernetes-certification-course) + +* [Getting Started with Google Kubernetes Engine (Coursera)](https://www.coursera.org/learn/google-kubernetes-engine) * [Getting Started with Kubernetes (Pluralsight)](https://www.pluralsight.com/courses/getting-started-kubernetes) +* [Getting Started with Kubernetes Clusters on OCI Oracle Kubernetes Engine (OKE) (Learning Library)](https://apexapps.oracle.com/pls/apex/f?p=44785:50:0:::50:P50_EVENT_ID,P50_COURSE_ID:5935,256) + +* [Google Kubernetes Engine Deep Dive (Linux Academy)] (https://linuxacademy.com/google-cloud-platform/training/course/name/google-kubernetes-engine-deep-dive) + * [Hands-on Introduction to Kubernetes (Instruqt)](https://play.instruqt.com/public/topics/getting-started-with-kubernetes) +* [IBM Cloud: Deploying Microservices with Kubernetes (Coursera)](https://www.coursera.org/learn/deploy-micro-kube-ibm-cloud) + +* [Introduction to Kubernetes (edX)](https://www.edx.org/course/introduction-kubernetes-linuxfoundationx-lfs158x) + +* [Kubernetes Essentials (Linux Academy)] (https://linuxacademy.com/linux/training/course/name/kubernetes-essentials) + +* [Kubernetes for the Absolute Beginners with Hands-on Labs (KodeKloud.com)](https://kodekloud.com/p/kubernetes-for-the-absolute-beginners-hands-on) + +* [Kubernetes Quick Start (Linux Academy)] (https://linuxacademy.com/linux/training/course/name/kubernetes-quick-start) + +* [Kubernetes the Hard Way (Linux Academy)](https://linuxacademy.com/linux/training/course/name/kubernetes-the-hard-way) + * [Learn Kubernetes using Interactive Hands-on Scenarios (Katacoda)](https://www.katacoda.com/courses/kubernetes/) -* [Certified Kubernetes Administrator Preparation Course (LinuxAcademy.com)](https://linuxacademy.com/linux/training/course/name/certified-kubernetes-administrator-preparation-course) +* [Monitoring Kubernetes With Prometheus (Linux Academy)] (https://linuxacademy.com/linux/training/course/name/kubernetes-and-prometheus) -* [Kubernetes the Hard Way (LinuxAcademy.com)](https://linuxacademy.com/linux/training/course/name/kubernetes-the-hard-way) - -* [Certified Kubernetes Application Developer Preparation Course (KodeKloud.com)](https://kodekloud.com/p/kubernetes-certification-course) +* [Scalable Microservices with Kubernetes (Udacity)](https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615) +* [Self-paced Kubernetes online course (Learnk8s Academy)](https://learnk8s.io/academy) {{% /capture %}} - - - - diff --git a/content/en/docs/tutorials/services/source-ip.md b/content/en/docs/tutorials/services/source-ip.md index 536f17c509..b61b194114 100644 --- a/content/en/docs/tutorials/services/source-ip.md +++ b/content/en/docs/tutorials/services/source-ip.md @@ -61,9 +61,9 @@ a `proxyMode` endpoint: ```console $ kubectl get nodes NAME STATUS ROLES AGE VERSION -kubernetes-minion-group-6jst Ready 2h v1.12.0 -kubernetes-minion-group-cx31 Ready 2h v1.12.0 -kubernetes-minion-group-jj1t Ready 2h v1.12.0 +kubernetes-minion-group-6jst Ready 2h v1.13.0 +kubernetes-minion-group-cx31 Ready 2h v1.13.0 +kubernetes-minion-group-jj1t Ready 2h v1.13.0 kubernetes-minion-group-6jst $ curl localhost:10249/proxyMode iptables @@ -107,7 +107,7 @@ client_address=10.244.3.8 command=GET ... ``` -If the client pod and server pod are in the same node, the client_address is the client pod's IP address. However, if the client pod and server pod are in different nodes, the client_address is the client pod's node flannel IP address. +The client_address is always the client pod's IP address, whether the client pod and server pod are in the same node or in different nodes. ## Source IP for Services with Type=NodePort diff --git a/content/en/docs/tutorials/stateful-application/basic-stateful-set.md b/content/en/docs/tutorials/stateful-application/basic-stateful-set.md index 93fee4e210..e8a44b5a74 100644 --- a/content/en/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/content/en/docs/tutorials/stateful-application/basic-stateful-set.md @@ -160,7 +160,7 @@ Using `nslookup` on the Pods' hostnames, you can examine their in-cluster DNS addresses. ```shell -kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh +kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm nslookup web-0.nginx Server: 10.0.0.10 Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local diff --git a/content/en/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md b/content/en/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md index 63b6b032db..f518c4bb0d 100644 --- a/content/en/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md +++ b/content/en/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md @@ -4,6 +4,10 @@ reviewers: - ahmetb content_template: templates/tutorial weight: 20 +card: + name: tutorials + weight: 40 + title: "Stateful Example: Wordpress with Persistent Volumes" --- {{% capture overview %}} @@ -104,12 +108,15 @@ The following manifest describes a single-instance MySQL Deployment. The MySQL c kubectl create -f https://k8s.io/examples/application/wordpress/mysql-deployment.yaml ``` -2. Verify that a PersistentVolume got dynamically provisioned. Note that it can - It can take up to a few minutes for the PVs to be provisioned and bound. - +2. Verify that a PersistentVolume got dynamically provisioned. + ```shell kubectl get pvc ``` + + {{< note >}} + It can take up to a few minutes for the PVs to be provisioned and bound. + {{< /note >}} The response should be like this: diff --git a/content/en/docs/tutorials/stateful-application/zookeeper.md b/content/en/docs/tutorials/stateful-application/zookeeper.md index d1de3e8b04..2a2d72d3af 100644 --- a/content/en/docs/tutorials/stateful-application/zookeeper.md +++ b/content/en/docs/tutorials/stateful-application/zookeeper.md @@ -66,7 +66,7 @@ consensus protocol to replicate a state machine across all servers in the ensemb The ensemble uses the Zab protocol to elect a leader, and the ensemble cannot write data until that election is complete. Once complete, the ensemble uses Zab to ensure that it replicates all writes to a quorum before it acknowledges and makes them visible to clients. Without respect to weighted quorums, a quorum is a majority component of the ensemble containing the current leader. For instance, if the ensemble has three servers, a component that contains the leader and one other server constitutes a quorum. If the ensemble can not achieve a quorum, the ensemble cannot write data. -ZooKeeper servers keep their entire state machine in memory, and write every mutation to a durable WAL (Write Ahead Log) on storage media. When a server crashes, it can recover its previous state by replaying the WAL. To prevent the WAL from growing without bound, ZooKeeper servers will periodically snapshot their in memory state to storage media. These snapshots can be loaded directly into memory, and all WAL entries that preceded the snapshot may be discarded. +ZooKeeper servers keep their entire state machine in memory, and write every mutation to a durable WAL (Write Ahead Log) on storage media. When a server crashes, it can recover its previous state by replaying the WAL. To prevent the WAL from growing without bound, ZooKeeper servers will periodically snapshot them in memory state to storage media. These snapshots can be loaded directly into memory, and all WAL entries that preceded the snapshot may be discarded. ## Creating a ZooKeeper Ensemble diff --git a/content/en/docs/tutorials/stateless-application/guestbook.md b/content/en/docs/tutorials/stateless-application/guestbook.md index 2d82a7a045..b8d7045e32 100644 --- a/content/en/docs/tutorials/stateless-application/guestbook.md +++ b/content/en/docs/tutorials/stateless-application/guestbook.md @@ -4,6 +4,10 @@ reviewers: - ahmetb content_template: templates/tutorial weight: 20 +card: + name: tutorials + weight: 30 + title: "Stateless Example: PHP Guestbook with Redis" --- {{% capture overview %}} diff --git a/content/en/docs/user-journeys/users/application-developer/foundational.md b/content/en/docs/user-journeys/users/application-developer/foundational.md index 02e84a4dd5..9bcd490626 100644 --- a/content/en/docs/user-journeys/users/application-developer/foundational.md +++ b/content/en/docs/user-journeys/users/application-developer/foundational.md @@ -53,9 +53,9 @@ Minikube can be installed locally, and runs a simple, single-node Kubernetes clu You can get basic information about your cluster with the commands `kubectl cluster-info` and `kubectl get nodes`. However, to get a good idea of what's really going on, you need to deploy an application to your cluster. This is covered in the next section. -#### microk8s +#### MicroK8s -On Linux, *microk8s* is a good alternative to Minikube for a local +On Linux, *MicroK8s* is a good alternative to Minikube for a local install of Kubernetes: * Runs on the native OS, so there is no overhead from running a virtual machine. @@ -64,8 +64,8 @@ install of Kubernetes: * {{< link text="Install microk8s" url="https://microk8s.io/" >}}. -After you install microk8s, you can use its tab-completion -functionality. All microk8s commands start with `microk8s.`. Type +After you install MicroK8s, you can use its tab-completion +functionality. All MicroK8s commands start with `microk8s.`. Type `microk8s.` (with the period) and then use the tab key to see a list of available commands. @@ -204,7 +204,7 @@ Examples of state include but are not limited to the following: Note that the API server is just the gateway, and that object data is actually stored in a highly available datastore called {{< link text="*etcd*" url="https://github.com/coreos/etcd" >}}. For most intents and purposes, though, you can focus on the API server. Most reads and writes to cluster state take place as API requests. -You can read more about the Kubernetes API {{< link text="here" url="/docs/concepts/overview/working-with-objects/kubernetes-objects/" >}}. +For more information, see {{< link text="Understanding Kubernetes Objects" url="/docs/concepts/overview/working-with-objects/kubernetes-objects/" >}}. #### Controllers @@ -258,6 +258,3 @@ If you feel fairly comfortable with the topics on this page and want to learn mo * {{< link text="Foundational Cluster Operator" url="/docs/user-journeys/users/cluster-operator/foundational/" >}} - Build breadth, by exploring other journeys. {{% /capture %}} - - - diff --git a/content/en/docs/user-journeys/users/cluster-operator/foundational.md b/content/en/docs/user-journeys/users/cluster-operator/foundational.md index d943a0e0cc..888d8b47f8 100644 --- a/content/en/docs/user-journeys/users/cluster-operator/foundational.md +++ b/content/en/docs/user-journeys/users/cluster-operator/foundational.md @@ -65,7 +65,8 @@ These resources are covered in a number of articles within the Kubernetes docume As a cluster operator you may not need to use all these resources, although you should be familiar with them to understand how the cluster is being used. There are a number of additional resources that you should be aware of, some listed under [Intermediate Resources](/docs/user-journeys/users/cluster-operator/intermediate#section-1). -You should also be familiar with [how to manage kubernetes resources](/docs/concepts/cluster-administration/manage-deployment/). +You should also be familiar with [how to manage kubernetes resources](/docs/concepts/cluster-administration/manage-deployment/) +and [supported versions and version skew between cluster components](/docs/setup/version-skew-policy/). ## Get information about your cluster diff --git a/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml b/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml index 5e6d55a6b2..b868c05332 100644 --- a/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml +++ b/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml @@ -8,7 +8,7 @@ metadata: spec: selector: matchLabels: - k8s-app: dns-autoscaler + k8s-app: dns-autoscaler template: metadata: labels: @@ -18,16 +18,16 @@ spec: - name: autoscaler image: k8s.gcr.io/cluster-proportional-autoscaler-amd64:1.1.1 resources: - requests: - cpu: "20m" - memory: "10Mi" + requests: + cpu: 20m + memory: 10Mi command: - - /cluster-proportional-autoscaler - - --namespace=kube-system - - --configmap=dns-autoscaler - - --target= - # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate. - # If using small nodes, "nodesPerReplica" should dominate. - - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"min":1}} - - --logtostderr=true - - --v=2 + - /cluster-proportional-autoscaler + - --namespace=kube-system + - --configmap=dns-autoscaler + - --target= + # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate. + # If using small nodes, "nodesPerReplica" should dominate. + - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"min":1}} + - --logtostderr=true + - --v=2 diff --git a/content/en/examples/application/job/rabbitmq/worker.py b/content/en/examples/application/job/rabbitmq/worker.py index a20884515d..88a7fcf96d 100644 --- a/content/en/examples/application/job/rabbitmq/worker.py +++ b/content/en/examples/application/job/rabbitmq/worker.py @@ -3,5 +3,5 @@ # Just prints standard out and sleeps for 10 seconds. import sys import time -print("Processing " + sys.stdin.lines()) +print("Processing " + sys.stdin.readlines()[0]) time.sleep(10) diff --git a/content/en/examples/configmap/configmap-multikeys.yaml b/content/en/examples/configmap/configmap-multikeys.yaml new file mode 100644 index 0000000000..289702d123 --- /dev/null +++ b/content/en/examples/configmap/configmap-multikeys.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: special-config + namespace: default +data: + SPECIAL_LEVEL: very + SPECIAL_TYPE: charm diff --git a/content/en/examples/configmap/configmaps.yaml b/content/en/examples/configmap/configmaps.yaml new file mode 100644 index 0000000000..91b9f29755 --- /dev/null +++ b/content/en/examples/configmap/configmaps.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: special-config + namespace: default +data: + special.how: very +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: env-config + namespace: default +data: + log_level: INFO diff --git a/content/en/docs/tasks/configure-pod-container/configmap/kubectl/game-env-file.properties b/content/en/examples/configmap/game-env-file.properties similarity index 100% rename from content/en/docs/tasks/configure-pod-container/configmap/kubectl/game-env-file.properties rename to content/en/examples/configmap/game-env-file.properties diff --git a/content/en/docs/tasks/configure-pod-container/configmap/kubectl/game.properties b/content/en/examples/configmap/game.properties similarity index 100% rename from content/en/docs/tasks/configure-pod-container/configmap/kubectl/game.properties rename to content/en/examples/configmap/game.properties diff --git a/content/en/docs/tasks/configure-pod-container/configmap/kubectl/ui-env-file.properties b/content/en/examples/configmap/ui-env-file.properties similarity index 100% rename from content/en/docs/tasks/configure-pod-container/configmap/kubectl/ui-env-file.properties rename to content/en/examples/configmap/ui-env-file.properties diff --git a/content/en/docs/tasks/configure-pod-container/configmap/kubectl/ui.properties b/content/en/examples/configmap/ui.properties similarity index 100% rename from content/en/docs/tasks/configure-pod-container/configmap/kubectl/ui.properties rename to content/en/examples/configmap/ui.properties diff --git a/content/en/examples/controllers/frontend.yaml b/content/en/examples/controllers/frontend.yaml index f9dba82b7e..b9f31044ec 100644 --- a/content/en/examples/controllers/frontend.yaml +++ b/content/en/examples/controllers/frontend.yaml @@ -11,28 +11,11 @@ spec: selector: matchLabels: tier: frontend - matchExpressions: - - {key: tier, operator: In, values: [frontend]} template: metadata: labels: - app: guestbook tier: frontend spec: containers: - name: php-redis image: gcr.io/google_samples/gb-frontend:v3 - resources: - requests: - cpu: 100m - memory: 100Mi - env: - - name: GET_HOSTS_FROM - value: dns - # If your cluster config does not include a dns service, then to - # instead access environment variables to find service host - # info, comment out the 'value: dns' line above, and uncomment the - # line below. - # value: env - ports: - - containerPort: 80 diff --git a/content/en/examples/controllers/nginx-deployment.yaml b/content/en/examples/controllers/nginx-deployment.yaml index 5dd80da371..f7f95deebb 100644 --- a/content/en/examples/controllers/nginx-deployment.yaml +++ b/content/en/examples/controllers/nginx-deployment.yaml @@ -16,6 +16,6 @@ spec: spec: containers: - name: nginx - image: nginx:1.15.4 + image: nginx:1.7.9 ports: - containerPort: 80 diff --git a/content/en/examples/examples_test.go b/content/en/examples/examples_test.go index 0dd16589d0..e01cd543fb 100644 --- a/content/en/examples/examples_test.go +++ b/content/en/examples/examples_test.go @@ -184,16 +184,16 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) { t.ObjectMeta.Name = "skip-for-good" } errors = job.Strategy.Validate(nil, t) - case *extensions.DaemonSet: + case *apps.DaemonSet: if t.Namespace == "" { t.Namespace = api.NamespaceDefault } - errors = ext_validation.ValidateDaemonSet(t) - case *extensions.Deployment: + errors = apps_validation.ValidateDaemonSet(t) + case *apps.Deployment: if t.Namespace == "" { t.Namespace = api.NamespaceDefault } - errors = ext_validation.ValidateDeployment(t) + errors = apps_validation.ValidateDeployment(t) case *extensions.Ingress: if t.Namespace == "" { t.Namespace = api.NamespaceDefault @@ -201,11 +201,11 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) { errors = ext_validation.ValidateIngress(t) case *policy.PodSecurityPolicy: errors = policy_validation.ValidatePodSecurityPolicy(t) - case *extensions.ReplicaSet: + case *apps.ReplicaSet: if t.Namespace == "" { t.Namespace = api.NamespaceDefault } - errors = ext_validation.ValidateReplicaSet(t) + errors = apps_validation.ValidateReplicaSet(t) case *batch.CronJob: if t.Namespace == "" { t.Namespace = api.NamespaceDefault @@ -298,12 +298,11 @@ func TestExampleObjectSchemas(t *testing.T) { "namespace-prod": {&api.Namespace{}}, }, "admin/cloud": { - "ccm-example": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.DaemonSet{}}, - "pvl-initializer-config": {&admissionregistration.InitializerConfiguration{}}, + "ccm-example": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &apps.DaemonSet{}}, }, "admin/dns": { "busybox": {&api.Pod{}}, - "dns-horizontal-autoscaler": {&extensions.Deployment{}}, + "dns-horizontal-autoscaler": {&apps.Deployment{}}, }, "admin/logging": { "fluentd-sidecar-config": {&api.ConfigMap{}}, @@ -337,42 +336,42 @@ func TestExampleObjectSchemas(t *testing.T) { "quota-objects-pvc": {&api.PersistentVolumeClaim{}}, "quota-objects-pvc-2": {&api.PersistentVolumeClaim{}}, "quota-pod": {&api.ResourceQuota{}}, - "quota-pod-deployment": {&extensions.Deployment{}}, + "quota-pod-deployment": {&apps.Deployment{}}, }, "admin/sched": { - "my-scheduler": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}}, + "my-scheduler": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &apps.Deployment{}}, "pod1": {&api.Pod{}}, "pod2": {&api.Pod{}}, "pod3": {&api.Pod{}}, }, "application": { - "deployment": {&extensions.Deployment{}}, - "deployment-patch": {&extensions.Deployment{}}, - "deployment-scale": {&extensions.Deployment{}}, - "deployment-update": {&extensions.Deployment{}}, - "nginx-app": {&api.Service{}, &extensions.Deployment{}}, - "nginx-with-request": {&extensions.Deployment{}}, + "deployment": {&apps.Deployment{}}, + "deployment-patch": {&apps.Deployment{}}, + "deployment-scale": {&apps.Deployment{}}, + "deployment-update": {&apps.Deployment{}}, + "nginx-app": {&api.Service{}, &apps.Deployment{}}, + "nginx-with-request": {&apps.Deployment{}}, "shell-demo": {&api.Pod{}}, - "simple_deployment": {&extensions.Deployment{}}, - "update_deployment": {&extensions.Deployment{}}, + "simple_deployment": {&apps.Deployment{}}, + "update_deployment": {&apps.Deployment{}}, }, "application/cassandra": { "cassandra-service": {&api.Service{}}, "cassandra-statefulset": {&apps.StatefulSet{}, &storage.StorageClass{}}, }, "application/guestbook": { - "frontend-deployment": {&extensions.Deployment{}}, + "frontend-deployment": {&apps.Deployment{}}, "frontend-service": {&api.Service{}}, - "redis-master-deployment": {&extensions.Deployment{}}, + "redis-master-deployment": {&apps.Deployment{}}, "redis-master-service": {&api.Service{}}, - "redis-slave-deployment": {&extensions.Deployment{}}, + "redis-slave-deployment": {&apps.Deployment{}}, "redis-slave-service": {&api.Service{}}, }, "application/hpa": { "php-apache": {&autoscaling.HorizontalPodAutoscaler{}}, }, "application/nginx": { - "nginx-deployment": {&extensions.Deployment{}}, + "nginx-deployment": {&apps.Deployment{}}, "nginx-svc": {&api.Service{}}, }, "application/job": { @@ -389,7 +388,7 @@ func TestExampleObjectSchemas(t *testing.T) { }, "application/mysql": { "mysql-configmap": {&api.ConfigMap{}}, - "mysql-deployment": {&api.Service{}, &extensions.Deployment{}}, + "mysql-deployment": {&api.Service{}, &apps.Deployment{}}, "mysql-pv": {&api.PersistentVolume{}, &api.PersistentVolumeClaim{}}, "mysql-services": {&api.Service{}, &api.Service{}}, "mysql-statefulset": {&apps.StatefulSet{}}, @@ -399,34 +398,38 @@ func TestExampleObjectSchemas(t *testing.T) { "web-parallel": {&api.Service{}, &apps.StatefulSet{}}, }, "application/wordpress": { - "mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}}, - "wordpress-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}}, + "mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &apps.Deployment{}}, + "wordpress-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &apps.Deployment{}}, }, "application/zookeeper": { "zookeeper": {&api.Service{}, &api.Service{}, &policy.PodDisruptionBudget{}, &apps.StatefulSet{}}, }, + "configmap": { + "configmaps": {&api.ConfigMap{}, &api.ConfigMap{}}, + "configmap-multikeys": {&api.ConfigMap{}}, + }, "controllers": { - "daemonset": {&extensions.DaemonSet{}}, - "frontend": {&extensions.ReplicaSet{}}, + "daemonset": {&apps.DaemonSet{}}, + "frontend": {&apps.ReplicaSet{}}, "hpa-rs": {&autoscaling.HorizontalPodAutoscaler{}}, "job": {&batch.Job{}}, - "replicaset": {&extensions.ReplicaSet{}}, + "replicaset": {&apps.ReplicaSet{}}, "replication": {&api.ReplicationController{}}, - "nginx-deployment": {&extensions.Deployment{}}, + "nginx-deployment": {&apps.Deployment{}}, }, "debug": { "counter-pod": {&api.Pod{}}, - "event-exporter": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &extensions.Deployment{}}, + "event-exporter": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &apps.Deployment{}}, "fluentd-gcp-configmap": {&api.ConfigMap{}}, - "fluentd-gcp-ds": {&extensions.DaemonSet{}}, - "node-problem-detector": {&extensions.DaemonSet{}}, - "node-problem-detector-configmap": {&extensions.DaemonSet{}}, + "fluentd-gcp-ds": {&apps.DaemonSet{}}, + "node-problem-detector": {&apps.DaemonSet{}}, + "node-problem-detector-configmap": {&apps.DaemonSet{}}, "termination": {&api.Pod{}}, }, "federation": { - "policy-engine-deployment": {&extensions.Deployment{}}, + "policy-engine-deployment": {&apps.Deployment{}}, "policy-engine-service": {&api.Service{}}, - "replicaset-example-policy": {&extensions.ReplicaSet{}}, + "replicaset-example-policy": {&apps.ReplicaSet{}}, "scheduling-policy-admission": {&api.ConfigMap{}}, }, "podpreset": { @@ -441,19 +444,28 @@ func TestExampleObjectSchemas(t *testing.T) { "preset": {&settings.PodPreset{}}, "proxy": {&settings.PodPreset{}}, "replicaset-merged": {&api.Pod{}}, - "replicaset": {&extensions.ReplicaSet{}}, + "replicaset": {&apps.ReplicaSet{}}, }, "pods": { - "commands": {&api.Pod{}}, - "init-containers": {&api.Pod{}}, - "lifecycle-events": {&api.Pod{}}, - "pod-nginx": {&api.Pod{}}, - "pod-with-node-affinity": {&api.Pod{}}, - "pod-with-pod-affinity": {&api.Pod{}}, - "private-reg-pod": {&api.Pod{}}, - "share-process-namespace": {&api.Pod{}}, - "simple-pod": {&api.Pod{}}, - "two-container-pod": {&api.Pod{}}, + "commands": {&api.Pod{}}, + "init-containers": {&api.Pod{}}, + "lifecycle-events": {&api.Pod{}}, + "pod-configmap-env-var-valueFrom": {&api.Pod{}}, + "pod-configmap-envFrom": {&api.Pod{}}, + "pod-configmap-volume": {&api.Pod{}}, + "pod-configmap-volume-specific-key": {&api.Pod{}}, + "pod-multiple-configmap-env-variable": {&api.Pod{}}, + "pod-nginx-specific-node": {&api.Pod{}}, + "pod-nginx": {&api.Pod{}}, + "pod-projected-svc-token": {&api.Pod{}}, + "pod-rs": {&api.Pod{}, &api.Pod{}}, + "pod-single-configmap-env-variable": {&api.Pod{}}, + "pod-with-node-affinity": {&api.Pod{}}, + "pod-with-pod-affinity": {&api.Pod{}}, + "private-reg-pod": {&api.Pod{}}, + "share-process-namespace": {&api.Pod{}}, + "simple-pod": {&api.Pod{}}, + "two-container-pod": {&api.Pod{}}, }, "pods/config": { "redis-pod": {&api.Pod{}}, @@ -513,24 +525,24 @@ func TestExampleObjectSchemas(t *testing.T) { "nginx-service": {&api.Service{}}, }, "service/access": { - "frontend": {&api.Service{}, &extensions.Deployment{}}, + "frontend": {&api.Service{}, &apps.Deployment{}}, "hello-service": {&api.Service{}}, - "hello": {&extensions.Deployment{}}, + "hello": {&apps.Deployment{}}, }, "service/networking": { - "curlpod": {&extensions.Deployment{}}, + "curlpod": {&apps.Deployment{}}, "custom-dns": {&api.Pod{}}, "hostaliases-pod": {&api.Pod{}}, "ingress": {&extensions.Ingress{}}, - "nginx-secure-app": {&api.Service{}, &extensions.Deployment{}}, + "nginx-secure-app": {&api.Service{}, &apps.Deployment{}}, "nginx-svc": {&api.Service{}}, - "run-my-nginx": {&extensions.Deployment{}}, + "run-my-nginx": {&apps.Deployment{}}, }, "windows": { "configmap-pod": {&api.ConfigMap{}, &api.Pod{}}, - "daemonset": {&extensions.DaemonSet{}}, - "deploy-hyperv": {&extensions.Deployment{}}, - "deploy-resource": {&extensions.Deployment{}}, + "daemonset": {&apps.DaemonSet{}}, + "deploy-hyperv": {&apps.Deployment{}}, + "deploy-resource": {&apps.Deployment{}}, "emptydir-pod": {&api.Pod{}}, "hostpath-volume-pod": {&api.Pod{}}, "secret-pod": {&api.Secret{}, &api.Pod{}}, diff --git a/content/en/examples/podpreset/allow-db-merged.yaml b/content/en/examples/podpreset/allow-db-merged.yaml index 4f5af10abd..8a0ad101d7 100644 --- a/content/en/examples/podpreset/allow-db-merged.yaml +++ b/content/en/examples/podpreset/allow-db-merged.yaml @@ -34,4 +34,4 @@ spec: emptyDir: {} - name: secret-volume secret: - secretName: config-details + secretName: config-details diff --git a/content/en/examples/podpreset/allow-db.yaml b/content/en/examples/podpreset/allow-db.yaml index a5504789fe..0cca13bab2 100644 --- a/content/en/examples/podpreset/allow-db.yaml +++ b/content/en/examples/podpreset/allow-db.yaml @@ -27,4 +27,4 @@ spec: emptyDir: {} - name: secret-volume secret: - secretName: config-details + secretName: config-details diff --git a/content/en/examples/pods/lifecycle-events.yaml b/content/en/examples/pods/lifecycle-events.yaml index e5fcffcc9e..4b79d7289c 100644 --- a/content/en/examples/pods/lifecycle-events.yaml +++ b/content/en/examples/pods/lifecycle-events.yaml @@ -12,5 +12,5 @@ spec: command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] preStop: exec: - command: ["/usr/sbin/nginx","-s","quit"] + command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"] diff --git a/content/en/examples/pods/pod-configmap-env-var-valueFrom.yaml b/content/en/examples/pods/pod-configmap-env-var-valueFrom.yaml new file mode 100644 index 0000000000..a72b4335ce --- /dev/null +++ b/content/en/examples/pods/pod-configmap-env-var-valueFrom.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: k8s.gcr.io/busybox + command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: + configMapKeyRef: + name: special-config + key: SPECIAL_LEVEL + - name: SPECIAL_TYPE_KEY + valueFrom: + configMapKeyRef: + name: special-config + key: SPECIAL_TYPE + restartPolicy: Never diff --git a/content/en/examples/pods/pod-configmap-envFrom.yaml b/content/en/examples/pods/pod-configmap-envFrom.yaml new file mode 100644 index 0000000000..70ae7e5bcf --- /dev/null +++ b/content/en/examples/pods/pod-configmap-envFrom.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: k8s.gcr.io/busybox + command: [ "/bin/sh", "-c", "env" ] + envFrom: + - configMapRef: + name: special-config + restartPolicy: Never diff --git a/content/en/examples/pods/pod-configmap-volume-specific-key.yaml b/content/en/examples/pods/pod-configmap-volume-specific-key.yaml new file mode 100644 index 0000000000..7a7c7bf605 --- /dev/null +++ b/content/en/examples/pods/pod-configmap-volume-specific-key.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: k8s.gcr.io/busybox + command: [ "/bin/sh","-c","cat /etc/config/keys" ] + volumeMounts: + - name: config-volume + mountPath: /etc/config + volumes: + - name: config-volume + configMap: + name: special-config + items: + - key: special.level + path: keys + restartPolicy: Never diff --git a/content/en/examples/pods/pod-configmap-volume.yaml b/content/en/examples/pods/pod-configmap-volume.yaml new file mode 100644 index 0000000000..23b0f7718e --- /dev/null +++ b/content/en/examples/pods/pod-configmap-volume.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: k8s.gcr.io/busybox + command: [ "/bin/sh", "-c", "ls /etc/config/" ] + volumeMounts: + - name: config-volume + mountPath: /etc/config + volumes: + - name: config-volume + configMap: + # Provide the name of the ConfigMap containing the files you want + # to add to the container + name: special-config + restartPolicy: Never diff --git a/content/en/examples/pods/pod-multiple-configmap-env-variable.yaml b/content/en/examples/pods/pod-multiple-configmap-env-variable.yaml new file mode 100644 index 0000000000..4790a9c661 --- /dev/null +++ b/content/en/examples/pods/pod-multiple-configmap-env-variable.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: k8s.gcr.io/busybox + command: [ "/bin/sh", "-c", "env" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: + configMapKeyRef: + name: special-config + key: special.how + - name: LOG_LEVEL + valueFrom: + configMapKeyRef: + name: env-config + key: log_level + restartPolicy: Never diff --git a/content/en/examples/pods/pod-nginx-specific-node.yaml b/content/en/examples/pods/pod-nginx-specific-node.yaml new file mode 100644 index 0000000000..5923400d64 --- /dev/null +++ b/content/en/examples/pods/pod-nginx-specific-node.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx +spec: + nodeName: foo-node # schedule pod to specific node + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent diff --git a/content/en/examples/pods/pod-projected-svc-token.yaml b/content/en/examples/pods/pod-projected-svc-token.yaml new file mode 100644 index 0000000000..1c6ba24980 --- /dev/null +++ b/content/en/examples/pods/pod-projected-svc-token.yaml @@ -0,0 +1,20 @@ +kind: Pod +apiVersion: v1 +metadata: + name: nginx +spec: + containers: + - image: nginx + name: nginx + volumeMounts: + - mountPath: /var/run/secrets/tokens + name: vault-token + serviceAccountName: acct + volumes: + - name: vault-token + projected: + sources: + - serviceAccountToken: + path: vault-token + expirationSeconds: 7200 + audience: vault diff --git a/content/en/examples/pods/pod-rs.yaml b/content/en/examples/pods/pod-rs.yaml new file mode 100644 index 0000000000..df7b390597 --- /dev/null +++ b/content/en/examples/pods/pod-rs.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod1 + labels: + tier: frontend +spec: + containers: + - name: hello1 + image: gcr.io/google-samples/hello-app:2.0 + +--- + +apiVersion: v1 +kind: Pod +metadata: + name: pod2 + labels: + tier: frontend +spec: + containers: + - name: hello2 + image: gcr.io/google-samples/hello-app:1.0 diff --git a/content/en/examples/pods/pod-single-configmap-env-variable.yaml b/content/en/examples/pods/pod-single-configmap-env-variable.yaml new file mode 100644 index 0000000000..c86123afd7 --- /dev/null +++ b/content/en/examples/pods/pod-single-configmap-env-variable.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: dapi-test-pod +spec: + containers: + - name: test-container + image: k8s.gcr.io/busybox + command: [ "/bin/sh", "-c", "env" ] + env: + # Define the environment variable + - name: SPECIAL_LEVEL_KEY + valueFrom: + configMapKeyRef: + # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY + name: special-config + # Specify the key associated with the value + key: special.how + restartPolicy: Never diff --git a/content/en/examples/pods/probe/http-liveness.yaml b/content/en/examples/pods/probe/http-liveness.yaml index 23d37b480a..670af18399 100644 --- a/content/en/examples/pods/probe/http-liveness.yaml +++ b/content/en/examples/pods/probe/http-liveness.yaml @@ -15,7 +15,7 @@ spec: path: /healthz port: 8080 httpHeaders: - - name: X-Custom-Header + - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3 diff --git a/content/en/includes/federated-task-tutorial-prereqs.md b/content/en/includes/federated-task-tutorial-prereqs.md index c5ec939c07..b254407a67 100644 --- a/content/en/includes/federated-task-tutorial-prereqs.md +++ b/content/en/includes/federated-task-tutorial-prereqs.md @@ -1,8 +1,5 @@ -This guide assumes that you have a running Kubernetes Cluster -Federation installation. If not, then head over to the -[federation admin guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) to learn how to -bring up a cluster federation (or have your cluster administrator do -this for you). -Other tutorials, such as Kelsey Hightower's -[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), -might also help you create a Federated Kubernetes cluster. \ No newline at end of file +This guide assumes that you have a running Kubernetes Cluster Federation installation. +If not, then head over to the [federation admin guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) to learn how to +bring up a cluster federation (or have your cluster administrator do this for you). +Other tutorials, such as Kelsey Hightower's [Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation), +might also help you create a Federated Kubernetes cluster. diff --git a/content/en/includes/federation-content-moved.md b/content/en/includes/federation-content-moved.md deleted file mode 100644 index 87a10e7199..0000000000 --- a/content/en/includes/federation-content-moved.md +++ /dev/null @@ -1,2 +0,0 @@ -The topics in the [Federation API](/docs/federation/api-reference/) section of the Kubernetes docs -are being moved to the [Reference](/docs/reference/) section. The content in this topic has moved to: diff --git a/content/en/includes/federation-current-state.md b/content/en/includes/federation-current-state.md deleted file mode 100644 index d04fda15e0..0000000000 --- a/content/en/includes/federation-current-state.md +++ /dev/null @@ -1 +0,0 @@ -`Federation V1`, the current Kubernetes federation API which reuses the Kubernetes API resources 'as is', is currently considered alpha for many of its features. There is no clear path to evolve the API to GA; however, there is a `Federation V2` effort in progress to implement a dedicated federation API apart from the Kubernetes API. The details are available at [sig-multicluster community page](https://github.com/kubernetes/community/tree/master/sig-multicluster). diff --git a/content/en/includes/federation-deprecation-warning-note.md b/content/en/includes/federation-deprecation-warning-note.md new file mode 100644 index 0000000000..b7a05b1077 --- /dev/null +++ b/content/en/includes/federation-deprecation-warning-note.md @@ -0,0 +1,3 @@ +Use of `Federation v1` is strongly discouraged. `Federation V1` never achieved GA status and is no longer under active development. Documentation is for historical purposes only. + +For more information, see the intended replacement, [Kubernetes Federation v2](https://github.com/kubernetes-sigs/federation-v2). diff --git a/content/en/partners/_index.html b/content/en/partners/_index.html index e8f87478dc..40dd8e17fd 100644 --- a/content/en/partners/_index.html +++ b/content/en/partners/_index.html @@ -44,9 +44,9 @@ cid: partners - +
      diff --git a/content/fr/OWNERS b/content/fr/OWNERS new file mode 100644 index 0000000000..c91ec02821 --- /dev/null +++ b/content/fr/OWNERS @@ -0,0 +1,13 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# This is the localization project for French. +# Teams and members are visible at https://github.com/orgs/kubernetes/teams. + +reviewers: +- sig-docs-fr-reviews + +approvers: +- sig-docs-fr-owners + +labels: +- language/fr diff --git a/content/fr/_common-resources/index.md b/content/fr/_common-resources/index.md new file mode 100644 index 0000000000..3d65eaa0ff --- /dev/null +++ b/content/fr/_common-resources/index.md @@ -0,0 +1,3 @@ +--- +headless: true +--- \ No newline at end of file diff --git a/content/fr/_index.html b/content/fr/_index.html new file mode 100644 index 0000000000..493bf1ccd2 --- /dev/null +++ b/content/fr/_index.html @@ -0,0 +1,65 @@ +--- +title: "La meilleure solution d'orchestration de conteneurs en production" +abstract: "Déploiement, mise à l'échelle et gestion automatisés des conteneurs" +cid: home +--- + +{{< deprecationwarning >}} + +{{< blocks/section id="oceanNodes" >}} +{{% blocks/feature image="flower" %}} + +### [Kubernetes (k8s)]({{< relref "/docs/concepts/overview/what-is-kubernetes" >}}) est un système open-source permettant d'automatiser le déploiement, la mise à l'échelle et la gestion des applications conteneurisées. + +Les conteneurs qui composent une application sont regroupés dans des unités logiques pour en faciliter la gestion et la découverte. Kubernetes s’appuie sur [15 années d’expérience dans la gestion de charges de travail de production (workloads) chez Google](http://queue.acm.org/detail.cfm?id=2898444), associé aux meilleures idées et pratiques de la communauté. +{{% /blocks/feature %}} + +{{% blocks/feature image="scalable" %}} +#### Quelque soit le nombre + +Conçu selon les mêmes principes qui permettent à Google de gérer des milliards de conteneurs par semaine, Kubernetes peut évoluer sans augmenter votre équipe d'opérations. +{{% /blocks/feature %}} + +{{% blocks/feature image="blocks" %}} +#### Quelque soit la complexité + +Qu'il s'agisse de tester localement ou d'une implémentation globale, Kubernetes est suffisamment flexible pour fournir vos applications de manière cohérente et simple, quelle que soit la complexité de vos besoins. + +{{% /blocks/feature %}} + +{{% blocks/feature image="suitcase" %}} + +#### Quelque soit l'endroit + +Kubernetes est une solution open-source qui vous permet de tirer parti de vos infrastructure qu'elles soient sur site (on-premises), hybride ou en Cloud publique. +Vous pourrez ainsi répartir sans effort vos workloads là où vous le souhaitez. + +{{% /blocks/feature %}} + +{{< /blocks/section >}} + +{{< blocks/section id="video" background-image="kub_video_banner_homepage" >}} + +
      +

      Les défis de la migration de plus de 150 microservices vers Kubernetes

      +

      Par Sarah Wells, directrice technique des opérations et de la fiabilité, Financial Times

      + +
      +
      +
      + Venez au KubeCon Barcelone du 20 au 23 mai 2019 +
      +
      +
      +
      + Venez au KubeCon Shanghai du 24 au 26 juin 2019 +
      +
      + + +
      +{{< /blocks/section >}} + +{{< blocks/kubernetes-features >}} + +{{< blocks/case-studies >}} diff --git a/content/fr/case-studies/_index.html b/content/fr/case-studies/_index.html new file mode 100644 index 0000000000..b783e0330d --- /dev/null +++ b/content/fr/case-studies/_index.html @@ -0,0 +1,10 @@ +--- +title: Études de cas +linkTitle: Études de cas +bigheader: Études de cas d'utilisation de Kubernetes +abstract: Une collection de cas d'utilisation de Kubernetes en production. +layout: basic +class: gridPage +cid: caseStudies +--- + diff --git a/content/fr/docs/_index.md b/content/fr/docs/_index.md new file mode 100644 index 0000000000..05e96e2901 --- /dev/null +++ b/content/fr/docs/_index.md @@ -0,0 +1,3 @@ +--- +title: Documentation +--- diff --git a/content/fr/docs/concepts/_index.md b/content/fr/docs/concepts/_index.md new file mode 100644 index 0000000000..cd1ea84780 --- /dev/null +++ b/content/fr/docs/concepts/_index.md @@ -0,0 +1,91 @@ +--- +title: Concepts +main_menu: true +content_template: templates/concept +weight: 40 +--- + +{{% capture overview %}} + +La section Concepts vous aide à mieux comprendre les composants du système Kubernetes et les abstractions que Kubernetes utilise pour représenter votre cluster. +Elle vous aide également à mieux comprendre le fonctionnement de Kubernetes en général. + +{{% /capture %}} + +{{% capture body %}} + +## Vue d'ensemble + +Pour utiliser Kubernetes, vous utilisez *les objets de l'API Kubernetes* pour décrire *l'état souhaité* de votre cluster: quelles applications ou autres processus que vous souhaitez exécuter, quelles images de conteneur elles utilisent, le nombre de réplicas, les ressources réseau et disque que vous mettez à disposition, et plus encore. +Vous définissez l'état souhaité en créant des objets à l'aide de l'API Kubernetes, généralement via l'interface en ligne de commande, `kubectl`. +Vous pouvez également utiliser l'API Kubernetes directement pour interagir avec le cluster et définir ou modifier l'état souhaité. + +Une fois que vous avez défini l'état souhaité, le *plan de contrôle Kubernetes* (control plane en anglais) permet de faire en sorte que l'état actuel du cluster corresponde à l'état souhaité. +Pour ce faire, Kubernetes effectue automatiquement diverses tâches, telles que le démarrage ou le redémarrage de conteneurs, la mise à jour du nombre de réplicas d'une application donnée, etc. +Le control plane Kubernetes comprend un ensemble de processus en cours d'exécution sur votre cluster: + +* Le **maître Kubernetes** (Kubernetes master en anglais) qui est un ensemble de trois processus qui s'exécutent sur un seul nœud de votre cluster, désigné comme nœud maître (master node en anglais). Ces processus sont: [kube-apiserver](/docs/admin/kube-apiserver/), [kube-controller-manager](/docs/admin/kube-controller-manager/) et [kube-scheduler](/docs/admin/kube-scheduler/). +* Chaque nœud non maître de votre cluster exécute deux processus: + * **[kubelet](/docs/admin/kubelet/)**, qui communique avec le Kubernetes master. + * **[kube-proxy](/docs/admin/kube-proxy/)**, un proxy réseau reflétant les services réseau Kubernetes sur chaque nœud. + +## Objets Kubernetes + +Kubernetes contient un certain nombre d'abstractions représentant l'état de votre système: applications et processus conteneurisés déployés, leurs ressources réseau et disque associées, ainsi que d'autres informations sur les activités de votre cluster. +Ces abstractions sont représentées par des objets de l'API Kubernetes; consultez [Vue d'ensemble des objets Kubernetes](/docs/concepts/abstractions/overview/) pour plus d'informations. + +Les objets de base de Kubernetes incluent: + +* [Pod](/docs/concepts/workloads/pods/pod-overview/) +* [Service](/docs/concepts/services-networking/service/) +* [Volume](/docs/concepts/storage/volumes/) +* [Namespace](/docs/concepts/overview/working-with-objects/namespaces/) + +En outre, Kubernetes contient un certain nombre d'abstractions de niveau supérieur appelées Contrôleurs. +Les contrôleurs s'appuient sur les objets de base et fournissent des fonctionnalités supplémentaires. + +Voici quelques exemples: + +* [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) +* [Deployment](/docs/concepts/workloads/controllers/deployment/) +* [StatefulSet](/docs/concepts/workloads/controllers/statefulset/) +* [DaemonSet](/docs/concepts/workloads/controllers/daemonset/) +* [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/) + +## Kubernetes control plane + +Les différentes parties du control plane Kubernetes, telles que les processus Kubernetes master et kubelet, déterminent la manière dont Kubernetes communique avec votre cluster. +Le control plane conserve un enregistrement de tous les objets Kubernetes du système et exécute des boucles de contrôle continues pour gérer l'état de ces objets. +À tout moment, les boucles de contrôle du control plane répondent aux modifications du cluster et permettent de faire en sorte que l'état réel de tous les objets du système corresponde à l'état souhaité que vous avez fourni. + +Par exemple, lorsque vous utilisez l'API Kubernetes pour créer un objet Deployment, vous fournissez un nouvel état souhaité pour le système. +Le control plane Kubernetes enregistre la création de cet objet et exécute vos instructions en lançant les applications requises et en les planifiant vers des nœuds de cluster, afin que l'état actuel du cluster corresponde à l'état souhaité. + +### Kubernetes master + +Le Kubernetes master est responsable du maintien de l'état souhaité pour votre cluster. +Lorsque vous interagissez avec Kubernetes, par exemple en utilisant l'interface en ligne de commande `kubectl`, vous communiquez avec le master Kubernetes de votre cluster. + +> Le "master" fait référence à un ensemble de processus gérant l'état du cluster. +En règle générale, tous les processus sont exécutés sur un seul nœud du cluster. +Ce nœud est également appelé master. +Le master peut également être répliqué pour la disponibilité et la redondance. + +### Noeuds Kubernetes + +Les nœuds d’un cluster sont les machines (serveurs physiques, machines virtuelles, etc.) qui exécutent vos applications et vos workflows. +Le master node Kubernetes contrôle chaque noeud; vous interagirez rarement directement avec les nœuds. + +#### Metadonnées des objets Kubernetes + +* [Annotations](/docs/concepts/overview/working-with-objects/annotations/) + +{{% /capture %}} + +{{% capture whatsnext %}} + +Si vous souhaitez écrire une page de concept, consultez +[Utilisation de modèles de page](/docs/home/contribute/page-templates/) +pour plus d'informations sur le type de page pour la documentation d'un concept. + +{{% /capture %}} diff --git a/content/fr/docs/concepts/architecture/_index.md b/content/fr/docs/concepts/architecture/_index.md new file mode 100755 index 0000000000..ef6bd42ed8 --- /dev/null +++ b/content/fr/docs/concepts/architecture/_index.md @@ -0,0 +1,4 @@ +--- +title: Architecture de Kubernetes +weight: 30 +--- diff --git a/content/fr/docs/concepts/architecture/master-node-communication.md b/content/fr/docs/concepts/architecture/master-node-communication.md new file mode 100644 index 0000000000..075cabaa7f --- /dev/null +++ b/content/fr/docs/concepts/architecture/master-node-communication.md @@ -0,0 +1,76 @@ +--- +reviewers: +- sieben +title: Communication Master-Node +content_template: templates/concept +weight: 20 +--- + +{{% capture overview %}} + +Ce document répertorie les canaux de communication entre l'API du noeud maître (apiserver of master node en anglais) et le rester du cluster Kubernetes. +L'objectif est de permettre aux utilisateurs de personnaliser leur installation afin de sécuriser la configuration réseau, de sorte que le cluster puisse être exécuté sur un réseau non approuvé (ou sur des adresses IP entièrement publiques d'un fournisseur de cloud). + +{{% /capture %}} + +{{% capture body %}} + +## Communication du Cluster vers le Master + +Tous les canaux de communication du cluster au master se terminent au apiserver (aucun des autres composants principaux n'est conçu pour exposer des services distants). +Dans un déploiement typique, l'apiserver est configuré pour écouter les connexions distantes sur un port HTTPS sécurisé (443) avec un ou plusieurs types d'[authentification](/docs/reference/access-authn-authz/authentication/) client. +Une ou plusieurs formes d'[autorisation](/docs/reference/access-authn-authz/authorization/) devraient être activée, notamment si les [requêtes anonymes](/docs/reference/access-authn-authz/authentication/#anonymous-requests) ou [jeton de compte de service](/docs/reference/access-authn-authz/authentication/#service-account-tokens) sont autorisés. + +Le certificat racine public du cluster doit être configuré pour que les nœuds puissent se connecter en toute sécurité à l'apiserver avec des informations d'identification client valides. +Par exemple, dans un déploiement GKE par défaut, les informations d'identification client fournies au kubelet sont sous la forme d'un certificat client. +Consultez [amorçage TLS de kubelet](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) pour le provisioning automatisé des certificats de client Kubelet. + +Les pods qui souhaitent se connecter à l'apiserver peuvent le faire de manière sécurisée en utilisant un compte de service afin que Kubernetes injecte automatiquement le certificat racine public et un jeton de support valide dans le pod lorsqu'il est instancié. +Le service `kubernetes` (dans tous les namespaces) est configuré avec une adresse IP virtuelle redirigée (via kube-proxy) vers le point de terminaison HTTPS sur le apiserver. + +Les composants du master communiquent également avec l'apiserver du cluster via le port sécurisé. + +Par conséquent, le mode de fonctionnement par défaut pour les connexions du cluster (nœuds et pods s'exécutant sur les nœuds) au master est sécurisé par défaut et peut s'exécuter sur des réseaux non sécurisés et/ou publics. + +## Communication du Master vers le Cluster + +Il existe deux voies de communication principales du master (apiserver) au cluster. +La première est du processus apiserver au processus kubelet qui s'exécute sur chaque nœud du cluster. +La seconde part de l'apiserver vers n'importe quel nœud, pod ou service via la fonctionnalité proxy de l'apiserver. + +### Communication de l'apiserver vers le kubelet + +Les connexions de l'apiserver au kubelet sont utilisées pour: + + * Récupérer les logs des pods. + * S'attacher (via kubectl) à des pods en cours d'exécution. + * Fournir la fonctionnalité de transfert de port du kubelet. + +Ces connexions se terminent au point de terminaison HTTPS du kubelet. +Par défaut, l'apiserver ne vérifie pas le certificat du kubelet, ce qui rend la connexion sujette aux attaques de type "man-in-the-middle", et **non sûre** sur des réseaux non approuvés et/ou publics. + +Pour vérifier cette connexion, utilisez l'argument `--kubelet-certificate-authority` pour fournir à apiserver un ensemble de certificats racine à utiliser pour vérifier le certificat du kubelet. + +Si ce n'est pas possible, utilisez [SSH tunneling](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) entre l'apiserver et le kubelet si nécessaire pour éviter la connexion sur un réseau non sécurisé ou public. + +Finalement, l'[authentification et/ou autorisation du Kubelet](/docs/admin/kubelet-authentication-authorization/) devrait être activé pour sécuriser l'API kubelet. + +### apiserver vers nodes, pods et services + +Les connexions de l'apiserver à un nœud, à un pod ou à un service sont définies par défaut en connexions HTTP. +Elles ne sont donc ni authentifiées ni chiffrées. +Elles peuvent être exécutées sur une connexion HTTPS sécurisée en préfixant `https:` au nom du nœud, du pod ou du service dans l'URL de l'API. +Cependant ils ne valideront pas le certificat fourni par le point de terminaison HTTPS ni ne fourniront les informations d'identification du client. +De plus, aucune garantie d'intégrité n'est fournie. +Ces connexions **ne sont actuellement pas sûres** pour fonctionner sur des réseaux non sécurisés et/ou publics. + +### SSH Tunnels + +Kubernetes prend en charge les tunnels SSH pour protéger les communications master -> cluster. +Dans cette configuration, l'apiserver initie un tunnel SSH vers chaque nœud du cluster (en se connectant au serveur ssh sur le port 22) et transmet tout le trafic destiné à un kubelet, un nœud, un pod ou un service via un tunnel. +Ce tunnel garantit que le trafic n'est pas exposé en dehors du réseau dans lequel les nœuds sont en cours d'exécution. + +Les tunnels SSH étant actuellement obsolètes, vous ne devriez pas choisir de les utiliser à moins de savoir ce que vous faites. +Un remplacement pour ce canal de communication est en cours de conception. + +{{% /capture %}} diff --git a/content/fr/docs/concepts/architecture/nodes.md b/content/fr/docs/concepts/architecture/nodes.md new file mode 100644 index 0000000000..e1fcf69ac5 --- /dev/null +++ b/content/fr/docs/concepts/architecture/nodes.md @@ -0,0 +1,231 @@ +--- +reviewers: +- sieben +title: Noeuds +content_template: templates/concept +weight: 10 +--- + +{{% capture overview %}} + +Un nœud est une machine de travail dans Kubernetes, connue auparavant sous le nom de `minion`. +Un nœud peut être une machine virtuelle ou une machine physique, selon le cluster. +Chaque nœud contient les services nécessaires à l'exécution de [pods](/docs/concepts/workloads/pods/pod/) et est géré par les composants du master. +Les services sur un nœud incluent le [container runtime](/docs/concepts/overview/components/#node-components), kubelet and kube-proxy. +Consultez la section [Le Nœud Kubernetes](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node) dans le document de conception de l'architecture pour plus de détails. + +{{% /capture %}} + +{{% capture body %}} + +## Statut du nœud + +Le statut d'un nœud contient les informations suivantes: + +* [Addresses](#addresses) +* [Condition](#condition) +* [Capacity](#capacity) +* [Info](#info) + +Chaque section est décrite en détail ci-dessous. + +### Adresses + +L'utilisation de ces champs varie en fonction de votre fournisseur de cloud ou de votre configuration physique. + +* HostName: Le nom d'hôte tel que rapporté par le noyau du nœud. Peut être remplacé via le paramètre kubelet `--hostname-override`. +* ExternalIP: En règle générale, l'adresse IP du nœud pouvant être routé en externe (disponible de l'extérieur du cluster). +* InternalIP: En règle générale, l'adresse IP du nœud pouvant être routé uniquement dans le cluster. + +### Condition + +Le champ `conditions` décrit le statut de tous les nœuds `Running`. + +| Node Condition | Description | +|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `OutOfDisk` | `True` si l'espace disponible sur le nœud est insuffisant pour l'ajout de nouveaux pods, sinon `False` | +| `Ready` | `True` si le noeud est sain et prêt à accepter des pods, `False` si le noeud n'est pas sain et n'accepte pas de pods, et `Unknown` si le contrôleur de noeud n'a pas reçu d'information du noeud depuis `node-monitor-grace-period` (la valeur par défaut est de 40 secondes) | +| `MemoryPressure` | `True` s'il existe une pression sur la mémoire du noeud, c'est-à-dire si la mémoire du noeud est faible; autrement `False` | +| `PIDPressure` | `True` s'il existe une pression sur le nombre de processus, c'est-à-dire s'il y a trop de processus sur le nœud; autrement `False` | +| `DiskPressure` | `True` s'il existe une pression sur la taille du disque, c'est-à-dire si la capacité du disque est faible; autrement `False` | +| `NetworkUnavailable` | `True` si le réseau pour le noeud n'est pas correctement configuré, sinon `False` | + +La condition de noeud est représentée sous la forme d'un objet JSON. +Par exemple, la réponse suivante décrit un nœud sain. + +```json +"conditions": [ + { + "type": "Ready", + "status": "True" + } +] +``` + +Si le statut de l'état Ready reste `Unknown` ou `False` plus longtemps que `pod-eviction-timeout`, un argument est passé au [kube-controller-manager](/docs/admin/kube-controller-manager/) et les pods sur le nœud sont programmés pour être supprimés par le contrôleur du nœud. +Le délai d’expulsion par défaut est de **cinq minutes**.. +Dans certains cas, lorsque le nœud est inaccessible, l'apiserver est incapable de communiquer avec le kubelet sur le nœud. +La décision de supprimer les pods ne peut pas être communiquée au kublet tant que la communication avec l'apiserver n'est pas rétablie. +Entre-temps, les pods dont la suppression est planifiée peuvent continuer à s'exécuter sur le nœud inaccessible. + +Dans les versions de Kubernetes antérieures à 1.5, le contrôleur de noeud [forcait la suppression](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods) de ces pods inaccessibles de l'apiserver. +Toutefois, dans la version 1.5 et ultérieure, le contrôleur de noeud ne force pas la suppression des pods tant qu'il n'est pas confirmé qu'ils ont cessé de fonctionner dans le cluster. +Vous pouvez voir que les pods en cours d'exécution sur un nœud inaccessible sont dans l'état `Terminating` ou` Unknown`. +Dans les cas où Kubernetes ne peut pas déduire de l'infrastructure sous-jacente si un nœud a définitivement quitté un cluster, l'administrateur du cluster peut avoir besoin de supprimer l'objet nœud à la main. +La suppression de l'objet nœud de Kubernetes entraîne la suppression de tous les objets Pod exécutés sur le nœud de l'apiserver et libère leurs noms. + +Dans la version 1.12, la fonctionnalité `TaintNodesByCondition` est promue en version bêta, ce qui permet au contrôleur de cycle de vie du nœud de créer automatiquement des [marquages](/docs/concepts/configuration/taint-and-toleration/) (taints en anglais) qui représentent des conditions. +De même, l'ordonnanceur ignore les conditions lors de la prise en compte d'un nœud; au lieu de cela, il regarde les taints du nœud et les tolérances d'un pod. + +Les utilisateurs peuvent désormais choisir entre l'ancien modèle de planification et un nouveau modèle de planification plus flexible. +Un pod qui n’a aucune tolérance est programmé selon l’ancien modèle. +Mais un pod qui tolère les taints d'un nœud particulier peut être programmé sur ce nœud. + +{{< caution >}} +L'activation de cette fonctionnalité crée un léger délai entre le moment où une condition est observée et le moment où une taint est créée. +Ce délai est généralement inférieur à une seconde, mais il peut augmenter le nombre de pods programmés avec succès mais rejetés par le kubelet. +{{< /caution >}} + +### Capacité + +Décrit les ressources disponibles sur le nœud: CPU, mémoire et nombre maximal de pods pouvant être planifiés sur le nœud. + +### Info + +Informations générales sur le noeud, telles que la version du noyau, la version de Kubernetes (versions de kubelet et kube-proxy), la version de Docker (si utilisée), le nom du système d'exploitation. +Les informations sont collectées par Kubelet à partir du noeud. + +## Gestion + +Contrairement aux [pods](/docs/concepts/workloads/pods/) et aux [services] (/docs/concepts/services-networking/service/), un nœud n'est pas créé de manière inhérente par Kubernetes: il est créé de manière externe par un cloud tel que Google Compute Engine, ou bien il existe dans votre pool de machines physiques ou virtuelles. +Ainsi, lorsque Kubernetes crée un nœud, il crée un objet qui représente le nœud. +Après la création, Kubernetes vérifie si le nœud est valide ou non. +Par exemple, si vous essayez de créer un nœud à partir du contenu suivant: + +```json +{ + "kind": "Node", + "apiVersion": "v1", + "metadata": { + "name": "10.240.79.157", + "labels": { + "name": "my-first-k8s-node" + } + } +} +``` + +Kubernetes crée un objet noeud en interne (la représentation) et valide le noeud en vérifiant son intégrité en fonction du champ `metadata.name`. +Si le nœud est valide, c'est-à-dire si tous les services nécessaires sont en cours d'exécution, il est éligible pour exécuter un pod. +Sinon, il est ignoré pour toute activité de cluster jusqu'à ce qu'il devienne valide. + +{{< note >}} +Kubernetes conserve l'objet pour le nœud non valide et vérifie s'il devient valide. +Vous devez explicitement supprimer l'objet Node pour arrêter ce processus. +{{< /note >}} + +Actuellement, trois composants interagissent avec l'interface de noeud Kubernetes: le contrôleur de noeud, kubelet et kubectl. + +### Contrôleur de nœud + +Le contrôleur de noeud (node controller en anglais) est un composant du master Kubernetes qui gère divers aspects des noeuds. + +Le contrôleur de nœud a plusieurs rôles dans la vie d'un nœud. +La première consiste à affecter un bloc CIDR au nœud lorsqu’il est enregistré (si l’affectation CIDR est activée). + +La seconde consiste à tenir à jour la liste interne des nœuds du contrôleur de nœud avec la liste des machines disponibles du fournisseur de cloud. +Lorsqu'il s'exécute dans un environnement de cloud, chaque fois qu'un nœud est en mauvaise santé, le contrôleur de nœud demande au fournisseur de cloud si la machine virtuelle de ce nœud est toujours disponible. +Sinon, le contrôleur de nœud supprime le nœud de sa liste de nœuds. + +La troisième est la surveillance de la santé des nœuds. +Le contrôleur de noeud est responsable de la mise à jour de la condition NodeReady de NodeStatus vers ConditionUnknown lorsqu'un noeud devient inaccessible (le contrôleur de noeud cesse de recevoir des heartbeats pour une raison quelconque, par exemple en raison d'une panne du noeud), puis de l'éviction ultérieure de tous les pods du noeud. (en utilisant une terminaison propre) si le nœud continue d’être inaccessible. +(Les délais d'attente par défaut sont de 40 secondes pour commencer à signaler ConditionUnknown et de 5 minutes après cela pour commencer à expulser les pods.) +Le contrôleur de nœud vérifie l'état de chaque nœud toutes les `--node-monitor-period` secondes. + +Dans les versions de Kubernetes antérieures à 1.13, NodeStatus correspond au heartbeat du nœud. +À partir de Kubernetes 1.13, la fonctionnalité de bail de nœud (node lease en anglais) est introduite en tant que fonctionnalité alpha (feature gate `NodeLease`, [KEP-0009](https://github.com/kubernetes/community/blob/master/keps/sig-node/0009-node-heartbeat.md)). +Lorsque la fonction de node lease est activée, chaque noeud a un objet `Lease` associé dans le namespace `kube-node-lease` qui est renouvelé périodiquement par le noeud, et NodeStatus et le node lease sont traités comme des heartbeat du noeud. +Les node leases sont renouvelés fréquemment lorsque NodeStatus est signalé de nœud à master uniquement lorsque des modifications ont été apportées ou que suffisamment de temps s'est écoulé (la valeur par défaut est 1 minute, ce qui est plus long que le délai par défaut de 40 secondes pour les nœuds inaccessibles). +Étant donné qu'un node lease est beaucoup plus léger qu'un NodeStatus, cette fonctionnalité rends le heartbeat d'un nœud nettement moins coûteux, tant du point de vue de l'évolutivité que des performances. + +Dans Kubernetes 1.4, nous avons mis à jour la logique du contrôleur de noeud afin de mieux gérer les cas où un grand nombre de noeuds rencontrent des difficultés pour atteindre le master (par exemple parce que le master a un problème de réseau). +À partir de la version 1.4, le contrôleur de noeud examine l’état de tous les noeuds du cluster lorsqu’il prend une décision concernant l’éviction des pods. + +Dans la plupart des cas, le contrôleur de noeud limite le taux d’expulsion à `--node-eviction-rate` (0,1 par défaut) par seconde, ce qui signifie qu’il n’expulsera pas les pods de plus d’un nœud toutes les 10 secondes. + +Le comportement d'éviction de noeud change lorsqu'un noeud d'une zone de disponibilité donnée devient défaillant. +Le contrôleur de nœud vérifie quel pourcentage de nœuds de la zone est défaillant (la condition NodeReady est ConditionUnknown ou ConditionFalse) en même temps. +Si la fraction de nœuds défaillant est au moins `--unhealthy-zone-threshold` (valeur par défaut de 0,55), le taux d'expulsion est réduit: si le cluster est petit (c'est-à-dire inférieur ou égal à ` --large-cluster-size-threshold` noeuds - valeur par défaut 50) puis les expulsions sont arrêtées, sinon le taux d'expulsion est réduit à `--secondary-node-eviction-rate` (valeur par défaut de 0,01) par seconde. +Ces stratégies sont implémentées par zone de disponibilité car une zone de disponibilité peut être partitionnée à partir du master, tandis que les autres restent connectées. +Si votre cluster ne s'étend pas sur plusieurs zones de disponibilité de fournisseur de cloud, il n'existe qu'une seule zone de disponibilité (la totalité du cluster). + +L'une des principales raisons de la répartition de vos nœuds entre les zones de disponibilité est de pouvoir déplacer la charge de travail vers des zones saines lorsqu'une zone entière tombe en panne. +Par conséquent, si tous les nœuds d’une zone sont défaillants, le contrôleur de nœud expulse à la vitesse normale `--node-eviction-rate`. +Le cas pathologique se produit lorsque toutes les zones sont complètement défaillantes (c'est-à-dire qu'il n'y a pas de nœuds sains dans le cluster). +Dans ce cas, le contrôleur de noeud suppose qu'il existe un problème de connectivité au master et arrête toutes les expulsions jusqu'à ce que la connectivité soit restaurée. + +À partir de Kubernetes 1.6, NodeController est également responsable de l'expulsion des pods s'exécutant sur des noeuds avec des marques `NoExecute`, lorsque les pods ne tolèrent pas ces marques. +De plus, en tant que fonctionnalité alpha désactivée par défaut, NodeController est responsable de l'ajout de marques correspondant aux problèmes de noeud tels que les noeuds inaccessibles ou non prêts. +Voir [cette documentation](/docs/concepts/configuration/taint-and-toleration/) pour plus de détails sur les marques `NoExecute` et cette fonctionnalité alpha. + +À partir de la version 1.8, le contrôleur de noeud peut être chargé de créer des tâches représentant les conditions de noeud. +Ceci est une fonctionnalité alpha de la version 1.8. + +### Auto-enregistrement des nœuds + +Lorsque l'indicateur de kubelet `--register-node` est à true (valeur par défaut), le kubelet tente de s'enregistrer auprès du serveur d'API. +C'est le modèle préféré, utilisé par la plupart des distributions Linux. + +Pour l'auto-enregistrement (self-registration en anglais), le kubelet est lancé avec les options suivantes: + + - `--kubeconfig` - Chemin d'accès aux informations d'identification pour s'authentifier auprès de l'apiserver. + - `--cloud-provider` - Comment lire les métadonnées d'un fournisseur de cloud sur lui-même. + - `--register-node` - Enregistrement automatique avec le serveur API. + - `--register-with-taints` - Enregistrez le noeud avec la liste donnée de marques (comma separated `=:`). Sans effet si `register-node` est à false. + - `--node-ip` - Adresse IP du noeud. + - `--node-labels` - Labels à ajouter lors de l’enregistrement du noeud dans le cluster (voir Restrictions des labels appliquées par le [plugin NodeRestriction admission](/docs/reference/access-authn-authz/admission-controllers/#noderestriction) dans les versions 1.13+). + - `--node-status-update-frequency` - Spécifie la fréquence à laquelle kubelet publie le statut de nœud sur master. + +Quand le mode [autorisation de nœud](/docs/reference/access-authn-authz/node/) et [plugin NodeRestriction admission](/docs/reference/access-authn-authz/admission-controllers/#noderestriction) sont activés, les kubelets sont uniquement autorisés à créer / modifier leur propre ressource de noeud. + +#### Administration manuelle de noeuds + +Un administrateur de cluster peut créer et modifier des objets de nœud. + +Si l'administrateur souhaite créer des objets de noeud manuellement, définissez l'argument de kubelet: `--register-node=false`. + +L'administrateur peut modifier les ressources du nœud (quel que soit le réglage de `--register-node`). +Les modifications comprennent la définition de labels sur le nœud et son marquage comme non programmable. + +Les étiquettes sur les nœuds peuvent être utilisées avec les sélecteurs de nœuds sur les pods pour contrôler la planification. Par exemple, pour contraindre un pod à ne pouvoir s'exécuter que sur un sous-ensemble de nœuds. + +Marquer un nœud comme non planifiable empêche la planification de nouveaux pods sur ce nœud, mais n'affecte pas les pods existants sur le nœud. +Ceci est utile comme étape préparatoire avant le redémarrage d'un nœud, etc. Par exemple, pour marquer un nœud comme non programmable, exécutez la commande suivante: + +```shell +kubectl cordon $NODENAME +``` + +{{< note >}} +Les pods créés par un contrôleur DaemonSet contournent le planificateur Kubernetes et ne respectent pas l'attribut unschedulable sur un nœud. +Cela suppose que les démons appartiennent à la machine même si celle-ci est en cours de vidage des applications pendant qu'elle se prépare au redémarrage. +{{< /note >}} + +### Capacité de nœud + +La capacité du nœud (nombre de CPU et quantité de mémoire) fait partie de l’objet Node. +Normalement, les nœuds s'enregistrent et indiquent leur capacité lors de la création de l'objet Node. +Si vous faites une [administration manuelle de nœud](#manual-node-administration), alors vous devez définir la capacité du nœud lors de l'ajout d'un nœud. + +Le scheduler Kubernetes veille à ce qu'il y ait suffisamment de ressources pour tous les pods d'un noeud. +Il vérifie que la somme des demandes des conteneurs sur le nœud n'est pas supérieure à la capacité du nœud. +Cela inclut tous les conteneurs lancés par le kubelet, mais pas les conteneurs lancés directement par le [conteneur runtime](/docs/concepts/overview/components/#noeud-composants), ni aucun processus exécuté en dehors des conteneurs. + +Si vous souhaitez réserver explicitement des ressources pour des processus autres que Pod, suivez ce tutoriel pour: [réserver des ressources pour les démons système](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved). + +## API Object + +L'objet Node est une ressource de niveau supérieur dans l'API REST de Kubernetes. +Plus de détails sur l'objet API peuvent être trouvés à l'adresse suivante: [Node API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core). + +{{% /capture %}} diff --git a/content/fr/docs/concepts/cluster-administration/_index.md b/content/fr/docs/concepts/cluster-administration/_index.md new file mode 100755 index 0000000000..b83ee60d5e --- /dev/null +++ b/content/fr/docs/concepts/cluster-administration/_index.md @@ -0,0 +1,5 @@ +--- +title: "Administration d'un cluster" +weight: 100 +--- + diff --git a/content/fr/docs/concepts/cluster-administration/certificates.md b/content/fr/docs/concepts/cluster-administration/certificates.md new file mode 100644 index 0000000000..c0a80b5bfd --- /dev/null +++ b/content/fr/docs/concepts/cluster-administration/certificates.md @@ -0,0 +1,248 @@ +--- +title: Certificats +content_template: templates/concept +weight: 20 +--- + + +{{% capture overview %}} + +Lorsque vous utilisez l'authentification par certificats client, vous pouvez générer des certificats +manuellement grâce à `easyrsa`, `openssl` ou `cfssl`. + +{{% /capture %}} + + +{{% capture body %}} + +### easyrsa + +**easyrsa** peut générer manuellement des certificats pour votre cluster. + +1. Téléchargez, décompressez et initialisez la version corrigée de easyrsa3. + + curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz + tar xzf easy-rsa.tar.gz + cd easy-rsa-master/easyrsa3 + ./easyrsa init-pki +1. Générez une CA. (`--batch` pour le mode automatique. `--req-cn` CN par défaut à utiliser) + + ./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass +1. Générer un certificat de serveur et une clé. + L' argument `--subject-alt-name` définit les adresses IP et noms DNS possibles par lesquels l'API + serveur peut être atteind. La `MASTER_CLUSTER_IP` est généralement la première adresse IP du CIDR des services + qui est spécifié en tant qu'argument `--service-cluster-ip-range` pour l'API Server et + le composant controller manager. L'argument `--days` est utilisé pour définir le nombre de jours + après lesquels le certificat expire. + L’exemple ci-dessous suppose également que vous utilisez `cluster.local` par défaut comme + nom de domaine DNS. + + ./easyrsa --subject-alt-name="IP:${MASTER_IP},"\ + "IP:${MASTER_CLUSTER_IP},"\ + "DNS:kubernetes,"\ + "DNS:kubernetes.default,"\ + "DNS:kubernetes.default.svc,"\ + "DNS:kubernetes.default.svc.cluster,"\ + "DNS:kubernetes.default.svc.cluster.local" \ + --days=10000 \ + build-server-full server nopass +1. Copiez `pki/ca.crt`, `pki/issued/server.crt`, et `pki/private/server.key` dans votre répertoire. +1. Personnalisez et ajoutez les lignes suivantes aux paramètres de démarrage de l'API Server: + + --client-ca-file=/yourdirectory/ca.crt + --tls-cert-file=/yourdirectory/server.crt + --tls-private-key-file=/yourdirectory/server.key + +### openssl + +**openssl** peut générer manuellement des certificats pour votre cluster. + +1. Générez ca.key en 2048bit: + + openssl genrsa -out ca.key 2048 +1. A partir de la clé ca.key générez ca.crt (utilisez -days pour définir la durée du certificat): + + openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt +1. Générez server.key en 2048bit: + + openssl genrsa -out server.key 2048 +1. Créez un fichier de configuration pour générer une demande de signature de certificat (CSR). + Assurez-vous de remplacer les valeurs marquées par des "< >" (par exemple, ``) + avec des valeurs réelles avant de l'enregistrer dans un fichier (par exemple, `csr.conf`). + Notez que la valeur de `MASTER_CLUSTER_IP` est celle du service Cluster IP pour l' + API Server comme décrit dans la sous-section précédente. + L’exemple ci-dessous suppose également que vous utilisez `cluster.local` par défaut comme + nom de domaine DNS. + + [ req ] + default_bits = 2048 + prompt = no + default_md = sha256 + req_extensions = req_ext + distinguished_name = dn + + [ dn ] + C = + ST = + L = + O = + OU = + CN = + + [ req_ext ] + subjectAltName = @alt_names + + [ alt_names ] + DNS.1 = kubernetes + DNS.2 = kubernetes.default + DNS.3 = kubernetes.default.svc + DNS.4 = kubernetes.default.svc.cluster + DNS.5 = kubernetes.default.svc.cluster.local + IP.1 = + IP.2 = + + [ v3_ext ] + authorityKeyIdentifier=keyid,issuer:always + basicConstraints=CA:FALSE + keyUsage=keyEncipherment,dataEncipherment + extendedKeyUsage=serverAuth,clientAuth + subjectAltName=@alt_names +1. Générez la demande de signature de certificat basée sur le fichier de configuration: + + openssl req -new -key server.key -out server.csr -config csr.conf +1. Générez le certificat de serveur en utilisant ca.key, ca.crt et server.csr: + + openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ + -CAcreateserial -out server.crt -days 10000 \ + -extensions v3_ext -extfile csr.conf +1. Vérifiez le certificat: + + openssl x509 -noout -text -in ./server.crt + +Enfin, ajoutez les mêmes paramètres aux paramètres de démarrage de l'API Server. + +### cfssl + +**cfssl** est un autre outil pour la génération de certificat. + +1. Téléchargez, décompressez et préparez les outils de ligne de commande comme indiqué ci-dessous. + Notez que vous devrez peut-être adapter les exemples de commandes en fonction du matériel, + de l'architecture et de la version de cfssl que vous utilisez. + + curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o cfssl + chmod +x cfssl + curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o cfssljson + chmod +x cfssljson + curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o cfssl-certinfo + chmod +x cfssl-certinfo +1. Créez un répertoire pour contenir les artefacts et initialiser cfssl: + + mkdir cert + cd cert + ../cfssl print-defaults config > config.json + ../cfssl print-defaults csr > csr.json +1. Créez un fichier JSON pour générer le fichier d'autorité de certification, par exemple, `ca-config.json`: + + { + "signing": { + "default": { + "expiry": "8760h" + }, + "profiles": { + "kubernetes": { + "usages": [ + "signing", + "key encipherment", + "server auth", + "client auth" + ], + "expiry": "8760h" + } + } + } + } +1. Créez un fichier JSON pour la demande de signature de certificat de l'autorité de certification, par exemple, + `ca-csr.json`. Assurez-vous de remplacer les valeurs marquées par des "< >" par + les vraies valeurs que vous voulez utiliser. + + { + "CN": "kubernetes", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names":[{ + "C": "", + "ST": "", + "L": "", + "O": "", + "OU": "" + }] + } +1. Générez la clé de CA (`ca-key.pem`) et le certificat (`ca.pem`): + + ../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca +1. Créer un fichier JSON pour générer des clés et des certificats pour l'API Server, + par exemple, `server-csr.json`. Assurez-vous de remplacer les valeurs entre "< >" par + les vraies valeurs que vous voulez utiliser. `MASTER_CLUSTER_IP` est le service Cluster IP + de l'API Server, comme décrit dans la sous-section précédente. + L’exemple ci-dessous suppose également que vous utilisez `cluster.local` par défaut comme + nom de domaine DNS. + + { + "CN": "kubernetes", + "hosts": [ + "127.0.0.1", + "", + "", + "kubernetes", + "kubernetes.default", + "kubernetes.default.svc", + "kubernetes.default.svc.cluster", + "kubernetes.default.svc.cluster.local" + ], + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [{ + "C": "", + "ST": "", + "L": "", + "O": "", + "OU": "" + }] + } +1. Générez la clé et le certificat pour l'API Server, qui sont par défaut + sauvegardés respectivement dans les fichiers `server-key.pem` et` server.pem`: + + ../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \ + --config=ca-config.json -profile=kubernetes \ + server-csr.json | ../cfssljson -bare server + + +## Distribuer un certificat auto-signé + +Un client peut refuser de reconnaître un certificat auto-signé comme valide. +Pour un déploiement hors production ou pour un déploiement exécuté derrière un +pare-feu d'entreprise, vous pouvez distribuer un certificat auto-signé à tous les clients et +actualiser la liste locale pour les certificats valides. + +Sur chaque client, effectuez les opérations suivantes: + +```bash +$ sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt +$ sudo update-ca-certificates +Updating certificates in /etc/ssl/certs... +1 added, 0 removed; done. +Running hooks in /etc/ca-certificates/update.d.... +done. +``` + +## API pour les certificats + +Vous pouvez utiliser l’API `certificates.k8s.io` pour faire créer des +Certificats x509 à utiliser pour l'authentification, comme documenté +[ici](/docs/tasks/tls/managing-tls-in-a-cluster). + +{{% /capture %}} diff --git a/content/fr/docs/concepts/cluster-administration/cluster-administration-overview.md b/content/fr/docs/concepts/cluster-administration/cluster-administration-overview.md new file mode 100644 index 0000000000..f7ce34b29b --- /dev/null +++ b/content/fr/docs/concepts/cluster-administration/cluster-administration-overview.md @@ -0,0 +1,68 @@ +--- +title: Vue d'ensemble de l'administration d'un cluster +content_template: templates/concept +weight: 10 +--- + +{{% capture overview %}} +La vue d'ensemble de l'administration d'un cluster est destinée à toute personne créant ou administrant un cluster Kubernetes. +Il suppose une certaine familiarité avec les [concepts](/docs/concepts/) de Kubernetes. +{{% /capture %}} + +{{% capture body %}} +## Planifier le déploiement d'un cluster + +Voir le guide: [choisir la bonne solution](/docs/setup/pick-right-solution/) pour des exemples de planification, de mise en place et de configuration de clusters Kubernetes. Les solutions répertoriées dans cet article s'appellent des *distributions*. + +Avant de choisir un guide, voici quelques considérations: + + - Voulez-vous simplement essayer Kubernetes sur votre machine ou voulez-vous créer un cluster haute disponibilité à plusieurs nœuds? Choisissez les distributions les mieux adaptées à vos besoins. + - **Si vous recherchez la haute disponibilité**, apprenez à configurer des [clusters multi zones](/docs/concepts/cluster-administration/federation/). + - Utiliserez-vous **un cluster Kubernetes hébergé**, comme [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/), ou **hébergerez-vous votre propre cluster**? + - Votre cluster sera-t-il **on-premises**, ou **sur un cloud (IaaS)**? Kubernetes ne prend pas directement en charge les clusters hybrides. Cependant, vous pouvez configurer plusieurs clusters. + - **Si vous configurez Kubernetes on-premises**, choisissez le [modèle réseau](/docs/concepts/cluster-administration/networking/) qui vous convient le mieux. + - Voulez-vous faire tourner Kubernetes sur du **bare metal** ou sur des **machines virtuelles (VMs)**? + - Voulez-vous **simplement faire tourner un cluster**, ou vous attendez-vous à faire du **développement actif sur le code du projet Kubernetes**? Dans ce dernier cas, choisissez une distribution activement développée. Certaines distributions n’utilisent que des versions binaires, mais offrent une plus grande variété de choix. + - Familiarisez-vous avec les [composants](/docs/admin/cluster-components/) nécessaires pour faire tourner un cluster. + +A noter: Toutes les distributions ne sont pas activement maintenues. Choisissez des distributions qui ont été testées avec une version récente de Kubernetes. + +## Gérer un cluster + +* [Gérer un cluster](/docs/tasks/administer-cluster/cluster-management/) décrit plusieurs rubriques relatives au cycle de vie d’un cluster: création d’un nouveau cluster, mise à niveau des nœuds maître et des workers de votre cluster, maintenance des nœuds (mises à niveau du noyau, par exemple) et mise à niveau de la version de l’API Kubernetes d’un cluster en cours d’exécution. + +* Apprenez comment [gérer les nœuds](/docs/concepts/nodes/node/). + +* Apprenez à configurer et gérer les [quotas de ressources](/docs/concepts/policy/resource-quotas/) pour les clusters partagés. + +## Sécuriser un cluster + +* La rubrique [Certificats](/docs/concepts/cluster-administration/certificates/) décrit les étapes à suivre pour générer des certificats à l’aide de différentes suites d'outils. + +* L' [Environnement de conteneur dans Kubernetes](/docs/concepts/containers/container-environment-variables/) décrit l'environnement des conteneurs gérés par la Kubelet sur un nœud Kubernetes. + +* Le [Contrôle de l'accès à l'API Kubernetes](/docs/reference/access-authn-authz/controlling-access/) explique comment configurer les autorisations pour les utilisateurs et les comptes de service. + +* La rubrique [Authentification](/docs/reference/access-authn-authz/authentication/) explique l'authentification dans Kubernetes, y compris les différentes options d'authentification. + +* [Autorisations](/docs/reference/access-authn-authz/authorization/) est distinct de l'authentification et contrôle le traitement des appels HTTP. + +* [Utiliser les Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/) explique les plug-ins qui interceptent les requêtes adressées au serveur d'API Kubernetes après authentification et autorisation. + +* [Utiliser Sysctls dans un cluster Kubernetes](/docs/concepts/cluster-administration/sysctl-cluster/) explique aux administrateurs comment utiliser l'outil de ligne de commande `sysctl` pour définir les paramètres du noyau. + +* [Auditer](/docs/tasks/debug-application-cluster/audit/) explique comment interagir avec les journaux d'audit de Kubernetes. + +### Sécuriser la Kubelet + * [Communication Master-Node](/docs/concepts/architecture/master-node-communication/) + * [TLS bootstrapping](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) + * [Kubelet authentification/autorisations](/docs/admin/kubelet-authentication-authorization/) + +## Services de cluster optionnels + +* [Integration DNS](/docs/concepts/services-networking/dns-pod-service/) décrit comment résoudre un nom DNS directement vers un service Kubernetes. + +* [Journalisation et surveillance de l'activité du cluster](/docs/concepts/cluster-administration/logging/) explique le fonctionnement de la connexion à Kubernetes et son implémentation. +{{% /capture %}} + + diff --git a/content/fr/docs/concepts/containers/_index.md b/content/fr/docs/concepts/containers/_index.md new file mode 100644 index 0000000000..9a86e2af74 --- /dev/null +++ b/content/fr/docs/concepts/containers/_index.md @@ -0,0 +1,4 @@ +--- +title: "Les conteneurs" +weight: 40 +--- \ No newline at end of file diff --git a/content/fr/docs/concepts/containers/container-environment-variables.md b/content/fr/docs/concepts/containers/container-environment-variables.md new file mode 100644 index 0000000000..efe686422b --- /dev/null +++ b/content/fr/docs/concepts/containers/container-environment-variables.md @@ -0,0 +1,69 @@ +--- +reviewers: +- sieben +- perriea +- lledru +- awkif +- yastij +- rbenzair +- oussemos +title: Les variables d’environnement du conteneur +content_template: templates/concept +weight: 20 +--- + +{{% capture overview %}} + +Cette page décrit les ressources disponibles pour les conteneurs dans l'environnement de conteneur. + +{{% /capture %}} + + +{{% capture body %}} + +## L'environnement du conteneur + +L’environnement Kubernetes conteneur fournit plusieurs ressources importantes aux conteneurs: + +* Un système de fichier, qui est une combinaison d'une [image](/docs/concepts/containers/images/) et un ou plusieurs [volumes](/docs/concepts/storage/volumes/). +* Informations sur le conteneur lui-même. +* Informations sur les autres objets du cluster. + +### Informations sur le conteneur + +Le nom d'*hôte* d'un conteneur est le nom du pod dans lequel le conteneur est en cours d'exécution. +Il est disponible via la commande `hostname` ou +[`gethostname`](http://man7.org/linux/man-pages/man2/gethostname.2.html) +dans libc. + +Le nom du pod et le namespace sont disponibles en tant que variables d'environnement via +[l'API downward](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/). + +Les variables d'environnement définies par l'utilisateur à partir de la définition de pod sont également disponibles pour le conteneur, +de même que toutes les variables d'environnement spécifiées de manière statique dans l'image Docker. + +### Informations sur le cluster + +Une liste de tous les services en cours d'exécution lors de la création d'un conteneur est disponible pour ce conteneur en tant que variables d'environnement. +Ces variables d'environnement correspondent à la syntaxe des liens Docker. + +Pour un service nommé *foo* qui correspond à un conteneur *bar*, +les variables suivantes sont définies: + +```shell +FOO_SERVICE_HOST= +FOO_SERVICE_PORT= +``` + +Les services ont des adresses IP dédiées et sont disponibles pour le conteneur avec le DNS, +si le [module DNS](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/) est activé.  + +{{% /capture %}} + +{{% capture whatsnext %}} + +* En savoir plus sur [les hooks du cycle de vie d'un conteneur](/docs/concepts/containers/container-lifecycle-hooks/). +* Acquérir une expérience pratique + [en attachant les handlers aux événements du cycle de vie du conteneur](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/). + +{{% /capture %}} diff --git a/content/fr/docs/concepts/containers/runtime-class.md b/content/fr/docs/concepts/containers/runtime-class.md new file mode 100644 index 0000000000..915d08e5ac --- /dev/null +++ b/content/fr/docs/concepts/containers/runtime-class.md @@ -0,0 +1,122 @@ +--- +reviewers: +- sieben +- perriea +- lledru +- awkif +- yastij +- rbenzair +- oussemos +title: Classe d'exécution (Runtime Class) +content_template: templates/concept +weight: 20 +--- + +{{% capture overview %}} + +{{< feature-state for_k8s_version="v1.12" state="alpha" >}} + +Cette page décrit la ressource RuntimeClass et le mécanisme de sélection d'exécution (runtime). + +{{% /capture %}} + + +{{% capture body %}} + +## Runtime Class + +La RuntimeClass est une fonctionnalité alpha permettant de sélectionner la configuration d'exécution du conteneur +à utiliser pour exécuter les conteneurs d'un pod. + +### Installation + +En tant que nouvelle fonctionnalité alpha, certaines étapes de configuration supplémentaires doivent +être suivies pour utiliser la RuntimeClass: + +1. Activer la fonctionnalité RuntimeClass (sur les apiservers et les kubelets, nécessite la version 1.12+) +2. Installer la RuntimeClass CRD +3. Configurer l'implémentation CRI sur les nœuds (dépend du runtime) +4. Créer les ressources RuntimeClass correspondantes + +#### 1. Activer RuntimeClass feature gate (portail de fonctionnalité) + +Voir [Feature Gates](/docs/reference/command-line-tools-reference/feature-gates/) pour une explication +sur l'activation des feature gates. La `RuntimeClass` feature gate doit être activée sur les API servers _et_ +les kubelets. + +#### 2. Installer la CRD RuntimeClass + +La RuntimeClass [CustomResourceDefinition][] (CRD) se trouve dans le répertoire addons du dépôt +Git Kubernetes: [kubernetes/cluster/addons/runtimeclass/runtimeclass_crd.yaml][runtimeclass_crd] + +Installer la CRD avec `kubectl apply -f runtimeclass_crd.yaml`. + +[CustomResourceDefinition]: /docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ +[runtimeclass_crd]: https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/runtimeclass/runtimeclass_crd.yaml + + +#### 3. Configurer l'implémentation CRI sur les nœuds + +Les configurations à sélectionner avec RuntimeClass dépendent de l'implémentation CRI. Consultez +la documentation correspondante pour votre implémentation CRI pour savoir comment le configurer. +Comme c'est une fonctionnalité alpha, tous les CRI ne prennent pas encore en charge plusieurs RuntimeClasses. + +{{< note >}} +La RuntimeClass suppose actuellement une configuration de nœud homogène sur l'ensemble du cluster +(ce qui signifie que tous les nœuds sont configurés de la même manière en ce qui concerne les environnements d'exécution de conteneur). Toute hétérogénéité (configuration variable) doit être +gérée indépendamment de RuntimeClass via des fonctions de planification (scheduling features) (voir [Affectation de pods sur les nœuds](/docs/concepts/configuration/assign-pod-node/)). +{{< /note >}} + +Les configurations ont un nom `RuntimeHandler` correspondant , référencé par la RuntimeClass. +Le RuntimeHandler doit être un sous-domaine DNS valide selon la norme RFC 1123 (alphanumériques + `-` et `.` caractères). + +#### 4. Créer les ressources RuntimeClass correspondantes + +Les configurations effectuées à l'étape 3 doivent chacune avoir un nom `RuntimeHandler` associé, qui +identifie la configuration. Pour chaque RuntimeHandler (et optionellement les handlers vides `""`), +créez un objet RuntimeClass correspondant. + +La ressource RuntimeClass ne contient actuellement que 2 champs significatifs: le nom RuntimeClass +(`metadata.name`) et le RuntimeHandler (`spec.runtimeHandler`). la définition de l'objet ressemble à ceci: + +```yaml +apiVersion: node.k8s.io/v1alpha1 # La RuntimeClass est définie dans le groupe d'API node.k8s.io +kind: RuntimeClass +metadata: + name: myclass # Le nom avec lequel la RuntimeClass sera référencée + # La RuntimeClass est une ressource non cantonnées à un namespace +spec: + runtimeHandler: myconfiguration # Le nom de la configuration CRI correspondante +``` + + +{{< note >}} +Il est recommandé de limiter les opérations d'écriture sur la RuntimeClass (create/update/patch/delete) à +l'administrateur du cluster. C'est la configuration par défault. Voir [Vue d'ensemble d'autorisation](https://kubernetes.io/docs/reference/access-authn-authz/authorization/) pour plus de détails. +{{< /note >}} + +### Usage + +Une fois que les RuntimeClasses sont configurées pour le cluster, leur utilisation est très simple. +Spécifiez `runtimeClassName` dans la spécficiation du pod. Par exemple: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + runtimeClassName: myclass + # ... +``` + +Cela indiquera à la kubelet d'utiliser la RuntimeClass spécifiée pour exécuter ce pod. Si la +RuntimeClass n'existe pas, ou si la CRI ne peut pas exécuter le handler correspondant, le pod passera finalement à +[l'état](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase) `failed`. Recherchez +[l'événement](/docs/tasks/debug-application-cluster/debug-application-introspection/) correspondant pour un +message d'erreur. + +Si aucun `runtimeClassName` n'est spécifié, le RuntimeHandler par défault sera utilisé, qui équivaut +au comportement lorsque la fonctionnalité RuntimeClass est désactivée. + +{{% /capture %}} diff --git a/content/fr/docs/concepts/overview/_index.md b/content/fr/docs/concepts/overview/_index.md new file mode 100644 index 0000000000..df9dc83e3d --- /dev/null +++ b/content/fr/docs/concepts/overview/_index.md @@ -0,0 +1,4 @@ +--- +title: "Vue d'ensemble" +weight: 20 +--- diff --git a/content/fr/docs/concepts/overview/what-is-kubernetes.md b/content/fr/docs/concepts/overview/what-is-kubernetes.md new file mode 100644 index 0000000000..a6166f73a9 --- /dev/null +++ b/content/fr/docs/concepts/overview/what-is-kubernetes.md @@ -0,0 +1,136 @@ +--- +reviewers: + - jygastaud + - lledru + - sieben +title: Qu'est-ce-que Kubernetes ? +content_template: templates/concept +weight: 10 +card: + name: concepts + weight: 10 +--- + +{{% capture overview %}} +Cette page est une vue d'ensemble de Kubernetes. +{{% /capture %}} + +{{% capture body %}} +Kubernetes est une plate-forme open-source extensible et portable pour la gestion de charges de travail (workloads) et des services conteneurisés. +Elle favorise à la fois l'écriture de configuration déclarative (declarative configuration) et l'automatisation. +C'est un large écosystème en rapide expansion. +Les services, le support et les outils Kubernetes sont largement disponibles. + +Google a rendu open-source le projet Kubernetes en 2014. +Le développement de Kubernetes est basé sur une [décennie et demie d’expérience de Google avec la gestion de la charge et de la mise à l'échelle (scale) en production](https://research.google.com/pubs/pub43438.html), associé aux meilleures idées et pratiques de la communauté. + +## Pourquoi ai-je besoin de Kubernetes et que peut-il faire ? + +Kubernetes a un certain nombre de fonctionnalités. Il peut être considéré comme: + +- une plate-forme de conteneur +- une plate-forme de microservices +- une plate-forme cloud portable +et beaucoup plus. + +Kubernetes fournit un environnement de gestion **focalisé sur le conteneur** (container-centric). +Il orchestre les ressources machines (computing), la mise en réseau et l’infrastructure de stockage sur les workloads des utilisateurs. +Cela permet de se rapprocher de la simplicité des Platform as a Service (PaaS) avec la flexibilité des solutions d'Infrastructure as a Service (IaaS), tout en gardant de la portabilité entre les différents fournisseurs d'infrastructures (providers). + +## Comment Kubernetes est-il une plate-forme ? + +Même si Kubernetes fournit de nombreuses fonctionnalités, il existe toujours de nouveaux scénarios qui bénéficieraient de fonctionnalités complémentaires. +Ces workflows spécifiques à une application permettent d'accélérer la vitesse de développement. +Si l'orchestration fournie de base est acceptable pour commencer, il est souvent nécessaire d'avoir une automatisation robuste lorsque l'on doit la faire évoluer. +C'est pourquoi Kubernetes a également été conçu pour servir de plate-forme et favoriser la construction d’un écosystème de composants et d’outils facilitant le déploiement, la mise à l’échelle et la gestion des applications. + +[Les Labels](/docs/concepts/overview/working-with-objects/labels/) permettent aux utilisateurs d'organiser leurs ressources comme ils/elles le souhaitent. +[Les Annotations](/docs/concepts/overview/working-with-objects/annotations/) autorisent les utilisateurs à définir des informations personnalisées sur les ressources pour faciliter leurs workflows et fournissent un moyen simple aux outils de gérer la vérification d'un état (checkpoint state). + +De plus, le [plan de contrôle Kubernetes (control +plane)](/docs/concepts/overview/components/) est construit sur les mêmes [APIs](/docs/reference/using-api/api-overview/) que celles accessibles aux développeurs et utilisateurs. +Les utilisateurs peuvent écrire leurs propres controlleurs (controllers), tels que les [ordonnanceurs (schedulers)](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/devel/scheduler.md), +avec [leurs propres APIs](/docs/concepts/api-extension/custom-resources/) qui peuvent être utilisés par un [outil en ligne de commande](/docs/user-guide/kubectl-overview/). + +Ce choix de [conception](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md) a permis de construire un ensemble d'autres systèmes par dessus Kubernetes. + +## Ce que Kubernetes n'est pas + +Kubernetes n’est pas une solution PaaS (Platform as a Service). +Kubernetes opérant au niveau des conteneurs plutôt qu'au niveau du matériel, il fournit une partie des fonctionnalités des offres PaaS, telles que le déploiement, la mise à l'échelle, l'équilibrage de charge (load balancing), la journalisation (logging) et la surveillance (monitoring). +Cependant, Kubernetes n'est pas monolithique. +Ces implémentations par défaut sont optionnelles et interchangeables. Kubernetes fournit les bases permettant de construire des plates-formes orientées développeurs, en laissant la possibilité à l'utilisateur de faire ses propres choix. + +Kubernetes: + +- Ne limite pas les types d'applications supportées. Kubernetes prend en charge des workloads extrêmement divers, dont des applications stateless, stateful ou orientées traitement de données (data-processing). +Si l'application peut fonctionner dans un conteneur, elle devrait bien fonctionner sur Kubernetes. +- Ne déploie pas de code source et ne build pas d'application non plus. Les workflows d'Intégration Continue, de Livraison Continue et de Déploiement Continu (CI/CD) sont réalisés en fonction de la culture d'entreprise, des préférences ou des pré-requis techniques. +- Ne fournit pas nativement de services au niveau applicatif tels que des middlewares (e.g., message buses), des frameworks de traitement de données (par exemple, Spark), des bases de données (e.g., mysql), caches, ou systèmes de stockage clusterisés (e.g., Ceph). +Ces composants peuvent être lancés dans Kubernetes et/ou être accessibles à des applications tournant dans Kubernetes via des mécaniques d'intermédiation tel que Open Service Broker. +- N'impose pas de solutions de logging, monitoring, ou alerting. +Kubernetes fournit quelques intégrations primaires et des mécanismes de collecte et export de métriques. +- Ne fournit ou n'impose un langague/système de configuration (e.g., [jsonnet](https://github.com/google/jsonnet)). +Il fournit une API déclarative qui peut être ciblée par n'importe quelle forme de spécifications déclaratives. +- Ne fournit ou n'adopte aucune mécanique de configuration des machines, de maintenance, de gestion ou de contrôle de la santé des systèmes. + +De plus, Kubernetes n'est pas vraiment un _système d'orchestration_. En réalité, il élimine le besoin d'orchestration. +Techniquement, l'_orchestration_ se définie par l'exécution d'un workflow défini : premièrement faire A, puis B, puis C. +Kubernetes quant à lui est composé d'un ensemble de processus de contrôle qui pilote l'état courant vers l'état désiré. +Peu importe comment on arrive du point A au point C. +Un contrôle centralisé n'est pas non plus requis. +Cela abouti à un système plus simple à utiliser et plus puissant, robuste, résiliant et extensible. + +## Pourquoi les conteneurs ? + +Vous cherchez des raisons d'utiliser des conteneurs ? + +![Pourquoi les conteneurs ?](/images/docs/why_containers.svg) + +L'_ancienne façon (old way)_ de déployer des applications consistait à installer les applications sur un hôte en utilisant les systèmes de gestions de paquets natifs. +Cela avait pour principale inconvénient de lier fortement les exécutables, la configuration, les librairies et le cycle de vie de chacun avec l'OS. +Il est bien entendu possible de construire une image de machine virtuelle (VM) immuable pour arriver à produire des publications (rollouts) ou retours arrières (rollbacks), mais les VMs sont lourdes et non-portables. + +La _nouvelle façon (new way)_ consiste à déployer des conteneurs basés sur une virtualisation au niveau du système d'opération (operation-system-level) plutôt que de la virtualisation hardware. +Ces conteneurs sont isolés les uns des autres et de l'hôte : +ils ont leurs propres systèmes de fichiers, ne peuvent voir que leurs propres processus et leur usage des ressources peut être contraint. +Ils sont aussi plus facile à construire que des VMs, et vu qu'ils sont décorrélés de l'infrastructure sous-jacente et du système de fichiers de l'hôte, ils sont aussi portables entre les différents fournisseurs de Cloud et les OS. + +Étant donné que les conteneurs sont petits et rapides, une application peut être packagées dans chaque image de conteneurs. +Cette relation application-image tout-en-un permet de bénéficier de tous les bénéfices des conteneurs. Avec les conteneurs, des images immuables de conteneur peuvent être créées au moment du build/release plutôt qu'au déploiement, vu que chaque application ne dépend pas du reste de la stack applicative et n'est pas liée à l'environnement de production. +La génération d'images de conteneurs au moment du build permet d'obtenir un environnement constant qui peut être déployé tant en développement qu'en production. De la même manière, les conteneurs sont bien plus transparents que les VMs, ce qui facilite le monitoring et le management. +Cela est particulièrement vrai lorsque le cycle de vie des conteneurs est géré par l'infrastructure plutôt que caché par un gestionnaire de processus à l'intérieur du conteneur. Avec une application par conteneur, gérer ces conteneurs équivaut à gérer le déploiement de son application. + +Résumé des bénéfices des conteneurs : + +- **Création et déploiement agile d'application** : + Augmente la simplicité et l'efficacité de la création d'images par rapport à l'utilisation d'image de VM. +- **Développement, intégration et déploiement Continus**: + Fournit un processus pour constuire et déployer fréquemment et de façon fiable avec la capacité de faire des rollbacks rapide et simple (grâce à l'immuabilité de l'image). +- **Séparation des besoins entre Dev et Ops**: + Création d'images applicatives au moment du build plutôt qu'au déploiement, tout en séparant l'application de l'infrastructure. +- **Observabilité** + Pas seulement des informations venant du système d'exploitation sous-jacent mais aussi des signaux propres de l'application. +- **Consistance entre les environnements de développement, tests et production**: + Fonctionne de la même manière que ce soit sur un poste local que chez un fournisseur d'hébergement / dans le Cloud. +- **Portabilité entre Cloud et distribution système**: + Fonctionne sur Ubuntu, RHEL, CoreOS, on-prem, Google Kubernetes Engine, et n'importe où. +- **Gestion centrée Application**: + Bascule le niveau d'abstraction d'une virtualisation hardware liée à l'OS à une logique de ressources orientée application. +- **[Micro-services](https://martinfowler.com/articles/microservices.html) faiblement couplés, distribués, élastiques**: + Les applications sont séparées en petits morceaux indépendants et peuvent être déployés et gérés dynamiquement -- pas une stack monolithique dans une seule machine à tout faire. +- **Isolation des ressources**: + Performances de l'application prédictible. +- **Utilisation des ressources**: + Haute efficacité et densité. + +## Qu'est-ce-que Kubenetes signifie ? K8s ? + +Le nom **Kubernetes** tire son origine du grec ancien, signifiant _capitaine_ ou _pilôte_ et est la racine de _gouverneur_ et [cybernetic](http://www.etymonline.com/index.php?term=cybernetics). _K8s_ est l'abréviation dérivée par le remplacement des 8 lettres "ubernete" par "8". + +{{% /capture %}} + +{{% capture whatsnext %}} +* Prêt à [commencer](/docs/setup/) ? +* Pour plus de détails, voir la [documentation Kubernetes](/docs/home/). +{{% /capture %}} diff --git a/content/fr/docs/home/_index.md b/content/fr/docs/home/_index.md new file mode 100644 index 0000000000..46b0678291 --- /dev/null +++ b/content/fr/docs/home/_index.md @@ -0,0 +1,19 @@ +--- +approvers: +- chenopis +title: Documentation de Kubernetes +noedit: true +cid: docsHome +layout: docsportal_home +class: gridPage +linkTitle: "Home" +main_menu: true +weight: 10 +hide_feedback: true +menu: + main: + title: "Documentation" + weight: 20 + post: > +

      Apprenez à utiliser Kubernetes à l'aide d'une documentation conceptuelle, didactique et de référence. Vous pouvez même aider en contribuant à la documentation!

      +--- diff --git a/content/fr/docs/home/supported-doc-versions.md b/content/fr/docs/home/supported-doc-versions.md new file mode 100644 index 0000000000..3be5b0d2d8 --- /dev/null +++ b/content/fr/docs/home/supported-doc-versions.md @@ -0,0 +1,22 @@ +--- +title: Versions supportées de la documentation Kubernetes +content_template: templates/concept +--- + +{{% capture overview %}} + +Ce site contient la documentation de la version actuelle de Kubernetes et les quatre versions précédentes de Kubernetes. + +{{% /capture %}} + +{{% capture body %}} + +## Version courante + +La version actuelle est [{{< param "version" >}}](/). + +## Versions précédentes + +{{< versions-other >}} + +{{% /capture %}} diff --git a/content/fr/docs/reference/kubectl/_index.md b/content/fr/docs/reference/kubectl/_index.md new file mode 100755 index 0000000000..0c3d7882f6 --- /dev/null +++ b/content/fr/docs/reference/kubectl/_index.md @@ -0,0 +1,5 @@ +--- +title: "CLI kubectl" +weight: 60 +--- + diff --git a/content/fr/docs/reference/kubectl/cheatsheet.md b/content/fr/docs/reference/kubectl/cheatsheet.md new file mode 100644 index 0000000000..d8252970e7 --- /dev/null +++ b/content/fr/docs/reference/kubectl/cheatsheet.md @@ -0,0 +1,342 @@ +--- +title: Aide-mémoire kubectl +content_template: templates/concept +card: + name: reference + weight: 30 +--- + +{{% capture overview %}} + +Voir aussi : [Aperçu Kubectl](/docs/reference/kubectl/overview/) et [Guide JsonPath](/docs/reference/kubectl/jsonpath). + +Cette page donne un aperçu de la commande `kubectl`. + +{{% /capture %}} + +{{% capture body %}} + +# Aide-mémoire kubectl + +## Auto-complétion avec Kubectl + +### BASH + +```bash +source <(kubectl completion bash) # active l'auto-complétion pour bash dans le shell courant, le paquet bash-completion devant être installé au préalable +echo "source <(kubectl completion bash)" >> ~/.bashrc # ajoute l'auto-complétion de manière permanente à votre shell bash +``` + +Vous pouvez de plus déclarer un alias pour `kubectl` qui fonctionne aussi avec l'auto-complétion : + +```bash +alias k=kubectl +complete -F __start_kubectl k +``` + +### ZSH + +```bash +source <(kubectl completion zsh) # active l'auto-complétion pour zsh dans le shell courant +echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc # ajoute l'auto-complétion de manière permanente à votre shell zsh +``` + +## Contexte et configuration de Kubectl + +Indique avec quel cluster Kubernetes `kubectl` communique et modifie les informations de configuration. Voir la documentation [Authentification multi-clusters avec kubeconfig](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) pour des informations détaillées sur le fichier de configuration. + +```bash +kubectl config view # Affiche les paramètres fusionnés de kubeconfig + +# Utilise plusieurs fichiers kubeconfig en même temps et affiche la configuration fusionnée +KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 kubectl config view + +# Affiche le mot de passe pour l'utilisateur e2e +kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}' + +kubectl config current-context # Affiche le contexte courant (current-context) +kubectl config use-context my-cluster-name # Définit my-cluster-name comme contexte courant + +# Ajoute un nouveau cluster à votre kubeconf, prenant en charge l'authentification de base (basic auth) +kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword + +# Définit et utilise un contexte qui utilise un nom d'utilisateur et un namespace spécifiques +kubectl config set-context gce --user=cluster-admin --namespace=foo \ + && kubectl config use-context gce +``` + +## Création d'objets + +Les manifests Kubernetes peuvent être définis en json ou yaml. Les extensions de fichier `.yaml`, +`.yml`, et `.json` peuvent être utilisés. + +```bash +kubectl create -f ./my-manifest.yaml # crée une ou plusieurs ressources +kubectl create -f ./my1.yaml -f ./my2.yaml # crée depuis plusieurs fichiers +kubectl create -f ./dir # crée une ou plusieurs ressources depuis tous les manifests dans dir +kubectl create -f https://git.io/vPieo # crée une ou plusieurs ressources depuis une url +kubectl create deployment nginx --image=nginx # démarre une instance unique de nginx +kubectl explain pods,svc # affiche la documentation pour les manifests pod et svc + +# Crée plusieurs objets YAML depuis l'entrée standard (stdin) +cat </dev/null; printf "\n"; done + +# Vérifie quels noeuds sont prêts +JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \ + && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True" + +# Liste tous les Secrets actuellement utilisés par un pod +kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq + +# Liste les événements (Events) classés par timestamp +kubectl get events --sort-by=.metadata.creationTimestamp +``` + +## Mise à jour de ressources + +Depuis la version 1.11, `rolling-update` a été déprécié (voir [CHANGELOG-1.11.md](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md)), utilisez plutôt `rollout`. + +```bash +kubectl set image deployment/frontend www=image:v2 # Rolling update du conteneur "www" du déploiement "frontend", par mise à jour de son image +kubectl rollout undo deployment/frontend # Rollback du déploiement précédent +kubectl rollout status -w deployment/frontend # Écoute (Watch) le status du rolling update du déploiement "frontend" jusqu'à ce qu'il se termine + +# déprécié depuis la version 1.11 +kubectl rolling-update frontend-v1 -f frontend-v2.json # (déprécié) Rolling update des pods de frontend-v1 +kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 # (déprécié) Modifie le nom de la ressource et met à jour l'image +kubectl rolling-update frontend --image=image:v2 # (déprécié) Met à jour l'image du pod du déploiement frontend +kubectl rolling-update frontend-v1 frontend-v2 --rollback # (déprécié) Annule (rollback) le rollout en cours + +cat pod.json | kubectl replace -f - # Remplace un pod, en utilisant un JSON passé en entrée standard + +# Remplace de manière forcée (Force replace), supprime puis re-crée la ressource. Provoque une interruption de service. +kubectl replace --force -f ./pod.json + +# Crée un service pour un nginx repliqué, qui rend le service sur le port 80 et se connecte aux conteneurs sur le port 8000 +kubectl expose rc nginx --port=80 --target-port=8000 + +# Modifie la version (tag) de l'image du conteneur unique du pod à v4 +kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f - + +kubectl label pods my-pod new-label=awesome # Ajoute un Label +kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Ajoute une annotation +kubectl autoscale deployment foo --min=2 --max=10 # Mise à l'échelle automatique (Auto scale) d'un déploiement "foo" +``` + +## Mise à jour partielle de ressources + +```bash +kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # Met à jour partiellement un noeud + +# Met à jour l'image d'un conteneur ; spec.containers[*].name est requis car c'est une clé du merge +kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}' + +# Met à jour l'image d'un conteneur en utilisant un patch json avec tableaux indexés +kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]' + +# Désactive la livenessProbe d'un déploiement en utilisant un patch json avec tableaux indexés +kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]' + +# Ajoute un nouvel élément à un tableau indexé +kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]' +``` + +## Édition de ressources +Ceci édite n'importe quelle ressource de l'API dans un éditeur. + +```bash +kubectl edit svc/docker-registry # Édite le service nommé docker-registry +KUBE_EDITOR="nano" kubectl edit svc/docker-registry # Utilise un autre éditeur +``` + +## Mise à l'échelle de ressources + +```bash +kubectl scale --replicas=3 rs/foo # Scale un replicaset nommé 'foo' à 3 +kubectl scale --replicas=3 -f foo.yaml # Scale une ressource spécifiée dans foo.yaml" à 3 +kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # Si la taille du déploiement nommé mysql est actuellement 2, scale mysql à 3 +kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Scale plusieurs contrôleurs de réplication +``` + +## Suppression de ressources + +```bash +kubectl delete -f ./pod.json # Supprime un pod en utilisant le type et le nom spécifiés dans pod.json +kubectl delete pod,service baz foo # Supprime les pods et services ayant les mêmes noms "baz" et "foo" +kubectl delete pods,services -l name=myLabel # Supprime les pods et services ayant le label name=myLabel +kubectl delete pods,services -l name=myLabel --include-uninitialized # Supprime les pods et services, dont ceux non initialisés, ayant le label name=myLabel +kubectl -n my-ns delete po,svc --all # Supprime tous les pods et services, dont ceux non initialisés, dans le namespace my-ns +``` + +## Interaction avec des Pods en cours d'exécution + +```bash +kubectl logs my-pod # Affiche les logs du pod (stdout) +kubectl logs my-pod --previous # Affiche les logs du pod (stdout) pour une instance précédente du conteneur +kubectl logs my-pod -c my-container # Affiche les logs d'un conteneur particulier du pod (stdout, cas d'un pod multi-conteneurs) +kubectl logs my-pod -c my-container --previous # Affiche les logs d'un conteneur particulier du pod (stdout, cas d'un pod multi-conteneurs) pour une instance précédente du conteneur +kubectl logs -f my-pod # Fait défiler (stream) les logs du pod (stdout) +kubectl logs -f my-pod -c my-container # Fait défiler (stream) les logs d'un conteneur particulier du pod (stdout, cas d'un pod multi-conteneurs) +kubectl run -i --tty busybox --image=busybox -- sh # Exécute un pod comme un shell interactif +kubectl attach my-pod -i # Attache à un conteneur en cours d'exécution +kubectl port-forward my-pod 5000:6000 # Écoute le port 5000 de la machine locale et forwarde vers le port 6000 de my-pod +kubectl exec my-pod -- ls / # Exécute une commande dans un pod existant (cas d'un seul conteneur) +kubectl exec my-pod -c my-container -- ls / # Exécute une commande dans un pod existant (cas multi-conteneurs) +kubectl top pod POD_NAME --containers # Affiche les métriques pour un pod donné et ses conteneurs +``` + +## Interaction avec des Noeuds et Clusters + +```bash +kubectl cordon mon-noeud # Marque mon-noeud comme non assignable (unschedulable) +kubectl drain mon-noeud # Draine mon-noeud en préparation d'une mise en maintenance +kubectl uncordon mon-noeud # Marque mon-noeud comme assignable +kubectl top node mon-noeud # Affiche les métriques pour un noeud donné +kubectl cluster-info # Affiche les adresses du master et des services +kubectl cluster-info dump # Affiche l'état courant du cluster sur stdout +kubectl cluster-info dump --output-directory=/path/to/cluster-state # Affiche l'état courant du cluster sur /path/to/cluster-state + +# Si une teinte avec cette clé et cet effet existe déjà, sa valeur est remplacée comme spécifié. +kubectl taint nodes foo dedicated=special-user:NoSchedule +``` + +### Types de ressources + +Liste tous les types de ressources pris en charge avec leurs noms courts (shortnames), [groupe d'API (API group)](/docs/concepts/overview/kubernetes-api/#api-groups), si elles sont [cantonnées à un namespace (namespaced)](/docs/concepts/overview/working-with-objects/namespaces), et leur [Genre (Kind)](/docs/concepts/overview/working-with-objects/kubernetes-objects): + +```bash +kubectl api-resources +``` + +Autres opérations pour explorer les ressources de l'API : + +```bash +kubectl api-resources --namespaced=true # Toutes les ressources cantonnées à un namespace +kubectl api-resources --namespaced=false # Toutes les ressources non cantonnées à un namespace +kubectl api-resources -o name # Toutes les ressources avec un affichage simple (uniquement le nom de la ressource) +kubectl api-resources -o wide # Toutes les ressources avec un affichage étendu (alias "wide") +kubectl api-resources --verbs=list,get # Toutes les ressources prenant en charge les verbes de requête "list" et "get" +kubectl api-resources --api-group=extensions # Toutes les ressources dans le groupe d'API "extensions" +``` + +### Formattage de l'affichage + +Pour afficher les détails sur votre terminal dans un format spécifique, vous pouvez utiliser une des options `-o` ou `--output` avec les commandes `kubectl` qui les prennent en charge. + +| Format d'affichage | Description | +|-------------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| `-o=custom-columns=` | Affiche un tableau en spécifiant une liste de colonnes séparées par des virgules | +| `-o=custom-columns-file=` | Affiche un tableau en utilisant les colonnes spécifiées dans le fichier `` | +| `-o=json` | Affiche un objet de l'API formaté en JSON | +| `-o=jsonpath=
--encryption-provider-config string
The file containing configuration for encryption providers to be used for storing secrets in etcd
--external-hostname string
--storage-backend string
The storage backend for persistence. Options: 'etcd3' (default)The storage backend for persistence. Options: 'etcd3' (default).
--kubeconfig string
Path to a kubeconfig file, specifying how to connect to the API server. (default "/var/lib/kubelet/kubeconfig")Path to a kubeconfig file, specifying how to connect to the API server. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode.