Merge remote-tracking branch 'upstream/master' into HEAD
This commit is contained in:
+3
-2
@@ -41,7 +41,6 @@ aliases:
|
|||||||
sig-docs-en-owners: # Admins for English content
|
sig-docs-en-owners: # Admins for English content
|
||||||
- bradtopol
|
- bradtopol
|
||||||
- daminisatya
|
- daminisatya
|
||||||
- gochist
|
|
||||||
- jaredbhatti
|
- jaredbhatti
|
||||||
- jimangel
|
- jimangel
|
||||||
- kbarnard10
|
- kbarnard10
|
||||||
@@ -59,7 +58,6 @@ aliases:
|
|||||||
sig-docs-en-reviews: # PR reviews for English content
|
sig-docs-en-reviews: # PR reviews for English content
|
||||||
- bradtopol
|
- bradtopol
|
||||||
- daminisatya
|
- daminisatya
|
||||||
- gochist
|
|
||||||
- jaredbhatti
|
- jaredbhatti
|
||||||
- jimangel
|
- jimangel
|
||||||
- kbarnard10
|
- kbarnard10
|
||||||
@@ -67,6 +65,7 @@ aliases:
|
|||||||
- makoscafee
|
- makoscafee
|
||||||
- onlydole
|
- onlydole
|
||||||
- rajakavitha1
|
- rajakavitha1
|
||||||
|
- rajeshdeshpande02
|
||||||
- sftim
|
- sftim
|
||||||
- steveperry-53
|
- steveperry-53
|
||||||
- tengqm
|
- tengqm
|
||||||
@@ -192,10 +191,12 @@ aliases:
|
|||||||
- femrtnz
|
- femrtnz
|
||||||
- jcjesus
|
- jcjesus
|
||||||
- devlware
|
- devlware
|
||||||
|
- jhonmike
|
||||||
sig-docs-pt-reviews: # PR reviews for Portugese content
|
sig-docs-pt-reviews: # PR reviews for Portugese content
|
||||||
- femrtnz
|
- femrtnz
|
||||||
- jcjesus
|
- jcjesus
|
||||||
- devlware
|
- devlware
|
||||||
|
- jhonmike
|
||||||
sig-docs-vi-owners: # Admins for Vietnamese content
|
sig-docs-vi-owners: # Admins for Vietnamese content
|
||||||
- huynguyennovem
|
- huynguyennovem
|
||||||
- ngtuna
|
- ngtuna
|
||||||
|
|||||||
+4
-4
@@ -9,7 +9,7 @@ Selamat datang! Repositori ini merupakan wadah bagi semua komponen yang dibutuhk
|
|||||||
|
|
||||||
Pertama, kamu dapat menekan tombol **Fork** yang berada pada bagian atas layar, untuk menyalin repositori pada akun Github-mu. Salinan ini disebut sebagai **fork**. Kamu dapat menambahkan konten pada **fork** yang kamu miliki, setelah kamu merasa cukup untuk menambahkan konten yang kamu miliki dan ingin memberikan konten tersebut pada kami, kamu dapat melihat **fork** yang telah kamu buat dan membuat **pull request** untuk memberi tahu kami bahwa kamu ingin menambahkan konten yang telah kamu buat.
|
Pertama, kamu dapat menekan tombol **Fork** yang berada pada bagian atas layar, untuk menyalin repositori pada akun Github-mu. Salinan ini disebut sebagai **fork**. Kamu dapat menambahkan konten pada **fork** yang kamu miliki, setelah kamu merasa cukup untuk menambahkan konten yang kamu miliki dan ingin memberikan konten tersebut pada kami, kamu dapat melihat **fork** yang telah kamu buat dan membuat **pull request** untuk memberi tahu kami bahwa kamu ingin menambahkan konten yang telah kamu buat.
|
||||||
|
|
||||||
Setelah kamu membuat sebuah **pull request**, seorang **reviewer** akan memberikan masukan terhadap konten yang kamu sediakan serta beberapa hal yang dapat kamu lakukan apabila perbaikan diperlukan terhadap konten yang telah kamu sediakan. Sebagai seorang yang membuat **pull request**, **sudah menjadi kewajiban kamu untuk melakukan modifikasi terhadap konten yang kamu berikan sesuai dengan masukan yang diberikan oleh seorang reviewer Kubernetes**. Perlu kamu ketahui bahwa kamu dapat saja memiliki lebih dari satu orang **reviewer Kubernetes** atau dalam kasus kamu bisa saja mendapatkan **reviewer Kubernetes** yang berbeda dengan **reviewer Kubernetes** awal yang ditugaskan untuk memberikan masukan terhadap konten yang kamu sediakan. Selain itu, seorang **reviewer Kubernetes** bisa saja meminta masukan teknis dari [reviewer teknis Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) jika diperlukan.
|
Setelah kamu membuat sebuah **pull request**, seorang **reviewer** akan memberikan masukan terhadap konten yang kamu sediakan serta beberapa hal yang dapat kamu lakukan apabila perbaikan diperlukan terhadap konten yang telah kamu sediakan. Sebagai seorang yang membuat **pull request**, **sudah menjadi kewajiban kamu untuk melakukan modifikasi terhadap konten yang kamu berikan sesuai dengan masukan yang diberikan oleh seorang reviewer Kubernetes**. Perlu kamu ketahui bahwa kamu dapat saja memiliki lebih dari satu orang **reviewer Kubernetes** atau dalam kasus kamu bisa saja mendapatkan **reviewer Kubernetes** yang berbeda dengan **reviewer Kubernetes** awal yang ditugaskan untuk memberikan masukan terhadap konten yang kamu sediakan. Selain itu, seorang **reviewer Kubernetes** bisa saja meminta masukan teknis dari [reviewer teknis Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) jika diperlukan.
|
||||||
|
|
||||||
Untuk informasi lebih lanjut mengenai tata cara melakukan kontribusi, kamu dapat melihat tautan di bawah ini:
|
Untuk informasi lebih lanjut mengenai tata cara melakukan kontribusi, kamu dapat melihat tautan di bawah ini:
|
||||||
|
|
||||||
@@ -21,11 +21,11 @@ Untuk informasi lebih lanjut mengenai tata cara melakukan kontribusi, kamu dapat
|
|||||||
|
|
||||||
## Menjalankan Dokumentasi Kubernetes pada Mesin Lokal Kamu
|
## Menjalankan Dokumentasi Kubernetes pada Mesin Lokal Kamu
|
||||||
|
|
||||||
Petunjuk yang disarankan untuk menjalankan Dokumentasi Kubernetes pada mesin lokal kamus adalah dengan menggunakan [Docker](https://docker.com) **image** yang memiliki **package** [Hugo](https://gohugo.io), **Hugo** sendiri merupakan generator website statis.
|
Petunjuk yang disarankan untuk menjalankan Dokumentasi Kubernetes pada mesin lokal kamus adalah dengan menggunakan [Docker](https://docker.com) **image** yang memiliki **package** [Hugo](https://gohugo.io), **Hugo** sendiri merupakan generator website statis.
|
||||||
|
|
||||||
> Jika kamu menggunakan Windows, kamu mungkin membutuhkan beberapa langkah tambahan untuk melakukan instalasi perangkat lunak yang dibutuhkan. Instalasi ini dapat dilakukan dengan menggunakan [Chocolatey](https://chocolatey.org). `choco install make`
|
> Jika kamu menggunakan Windows, kamu mungkin membutuhkan beberapa langkah tambahan untuk melakukan instalasi perangkat lunak yang dibutuhkan. Instalasi ini dapat dilakukan dengan menggunakan [Chocolatey](https://chocolatey.org). `choco install make`
|
||||||
|
|
||||||
> Jika kamu ingin menjalankan **website** tanpa menggunakan **Docker**, kamu dapat melihat tautan berikut [Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo](#petunjuk-untuk-menjalankan-website-pada-mesin-lokal-denga-menggunakan-hugo) di bagian bawah.
|
> Jika kamu ingin menjalankan **website** tanpa menggunakan **Docker**, kamu dapat melihat tautan berikut [Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo](#petunjuk-untuk-menjalankan-website-pada-mesin-lokal-dengan-menggunakan-hugo) di bagian bawah.
|
||||||
|
|
||||||
Jika kamu sudah memiliki **Docker** [yang sudah dapat digunakan](https://www.docker.com/get-started), kamu dapat melakukan **build** `kubernetes-hugo` **Docker image** secara lokal:
|
Jika kamu sudah memiliki **Docker** [yang sudah dapat digunakan](https://www.docker.com/get-started), kamu dapat melakukan **build** `kubernetes-hugo` **Docker image** secara lokal:
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ Buka **browser** kamu ke http://localhost:1313 untuk melihat laman dokumentasi.
|
|||||||
|
|
||||||
## Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo
|
## Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo
|
||||||
|
|
||||||
Kamu dapat melihat [dokumentasi resmi Hugo](https://gohugo.io/getting-started/installing/) untuk mengetahui langkah yang diperlukan untuk melakukan instalasi **Hugo**. Pastikan kamu melakukan instalasi versi **Hugo** sesuai dengan versi yang tersedia pada **environment variable** `HUGO_VERSION` pada **file**[`netlify.toml`](netlify.toml#L9).
|
Kamu dapat melihat [dokumentasi resmi Hugo](https://gohugo.io/getting-started/installing/) untuk mengetahui langkah yang diperlukan untuk melakukan instalasi **Hugo**. Pastikan kamu melakukan instalasi versi **Hugo** sesuai dengan versi yang tersedia pada **environment variable** `HUGO_VERSION` pada **file**[`netlify.toml`](netlify.toml#L9).
|
||||||
|
|
||||||
Untuk menjalankan laman pada mesin lokal setelah instalasi **Hugo**, kamu dapat menjalankan perintah berikut:
|
Untuk menjalankan laman pada mesin lokal setelah instalasi **Hugo**, kamu dapat menjalankan perintah berikut:
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ Cách được đề xuất để chạy trang web Kubernetes cục bộ là dù
|
|||||||
|
|
||||||
> Nếu bạn làm việc trên môi trường Windows, bạn sẽ cần thêm môt vài công cụ mà bạn có thể cài đặt với [Chocolatey](https://chocolatey.org). `choco install make`
|
> Nếu bạn làm việc trên môi trường Windows, bạn sẽ cần thêm môt vài công cụ mà bạn có thể cài đặt với [Chocolatey](https://chocolatey.org). `choco install make`
|
||||||
|
|
||||||
> Nếu bạn không muốn dùng Docker để chạy trang web cục bộ, hãy xem [Chạy website cục bộ dùng Hugo](#Chạy website cục bộ dùng Hugo) dưới đây.
|
> Nếu bạn không muốn dùng Docker để chạy trang web cục bộ, hãy xem [Chạy website cục bộ dùng Hugo](#chạy-website-cục-bộ-dùng-hugo) dưới đây.
|
||||||
|
|
||||||
Nếu bạn có Docker đang [up và running](https://www.docker.com/get-started), build `kubernetes-hugo` Docker image cục bộ:
|
Nếu bạn có Docker đang [up và running](https://www.docker.com/get-started), build `kubernetes-hugo` Docker image cục bộ:
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ header
|
|||||||
box-shadow: 0 0 0 transparent
|
box-shadow: 0 0 0 transparent
|
||||||
transition: 0.3s
|
transition: 0.3s
|
||||||
text-align: center
|
text-align: center
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
|
||||||
.logo
|
.logo
|
||||||
@@ -244,8 +245,7 @@ header
|
|||||||
background-color: white
|
background-color: white
|
||||||
|
|
||||||
#mainNav
|
#mainNav
|
||||||
display: none
|
|
||||||
|
|
||||||
h5
|
h5
|
||||||
color: $blue
|
color: $blue
|
||||||
font-weight: normal
|
font-weight: normal
|
||||||
|
|||||||
@@ -23,30 +23,30 @@ The **v1.16** release will stop serving the following deprecated API versions in
|
|||||||
Existing persisted data can be retrieved/updated via the new version.
|
Existing persisted data can be retrieved/updated via the new version.
|
||||||
* Notable changes:
|
* Notable changes:
|
||||||
* `spec.templateGeneration` is removed
|
* `spec.templateGeneration` is removed
|
||||||
* `spec.selector` is now required and immutable after creation
|
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||||
* `spec.updateStrategy.type` now defaults to `RollingUpdate`
|
* `spec.updateStrategy.type` now defaults to `RollingUpdate` (the default in `extensions/v1beta1` was `OnDelete`)
|
||||||
* Deployment in the **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions is no longer served
|
* Deployment in the **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions is no longer served
|
||||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||||
Existing persisted data can be retrieved/updated via the new version.
|
Existing persisted data can be retrieved/updated via the new version.
|
||||||
* Notable changes:
|
* Notable changes:
|
||||||
* `spec.rollbackTo` is removed
|
* `spec.rollbackTo` is removed
|
||||||
* `spec.selector` is now required and immutable after creation
|
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||||
* `spec.progressDeadlineSeconds` now defaults to `600` seconds
|
* `spec.progressDeadlineSeconds` now defaults to `600` seconds (the default in `extensions/v1beta1` was no deadline)
|
||||||
* `spec.revisionHistoryLimit` now defaults to `10`
|
* `spec.revisionHistoryLimit` now defaults to `10` (the default in `apps/v1beta1` was `2`, the default in `extensions/v1beta1` was to retain all)
|
||||||
* `maxSurge` and `maxUnavailable` now default to `25%`
|
* `maxSurge` and `maxUnavailable` now default to `25%` (the default in `extensions/v1beta1` was `1`)
|
||||||
* StatefulSet in the **apps/v1beta1** and **apps/v1beta2** API versions is no longer served
|
* StatefulSet in the **apps/v1beta1** and **apps/v1beta2** API versions is no longer served
|
||||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||||
Existing persisted data can be retrieved/updated via the new version.
|
Existing persisted data can be retrieved/updated via the new version.
|
||||||
* Notable changes:
|
* Notable changes:
|
||||||
* `spec.selector` is now required and immutable after creation
|
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||||
* `spec.updateStrategy.type` now defaults to `RollingUpdate`
|
* `spec.updateStrategy.type` now defaults to `RollingUpdate` (the default in `apps/v1beta1` was `OnDelete`)
|
||||||
* ReplicaSet in the **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions is no longer served
|
* ReplicaSet in the **extensions/v1beta1**, **apps/v1beta1**, and **apps/v1beta2** API versions is no longer served
|
||||||
* Migrate to use the **apps/v1** API version, available since v1.9.
|
* Migrate to use the **apps/v1** API version, available since v1.9.
|
||||||
Existing persisted data can be retrieved/updated via the new version.
|
Existing persisted data can be retrieved/updated via the new version.
|
||||||
* Notable changes:
|
* Notable changes:
|
||||||
* `spec.selector` is now required and immutable after creation
|
* `spec.selector` is now required and immutable after creation; use the existing template labels as the selector for seamless upgrades
|
||||||
|
|
||||||
The **v1.20** release will stop serving the following deprecated API versions in favor of newer and more stable API versions:
|
The **v1.22** release will stop serving the following deprecated API versions in favor of newer and more stable API versions:
|
||||||
|
|
||||||
* Ingress in the **extensions/v1beta1** API version will no longer be served
|
* Ingress in the **extensions/v1beta1** API version will no longer be served
|
||||||
* Migrate to use the **networking.k8s.io/v1beta1** API version, available since v1.14.
|
* Migrate to use the **networking.k8s.io/v1beta1** API version, available since v1.14.
|
||||||
@@ -84,8 +84,8 @@ apiserver startup arguments:
|
|||||||
|
|
||||||
Deprecations are announced in the Kubernetes release notes. You can see these
|
Deprecations are announced in the Kubernetes release notes. You can see these
|
||||||
announcements in
|
announcements in
|
||||||
[1.14](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#deprecations)
|
[1.14](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.14.md#deprecations)
|
||||||
and [1.15](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.15.md#deprecations-and-removals).
|
and [1.15](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.15.md#deprecations-and-removals).
|
||||||
|
|
||||||
You can read more [in our deprecation policy document](https://kubernetes.io/docs/reference/using-api/deprecation-policy/#deprecating-parts-of-the-api)
|
You can read more [in our deprecation policy document](https://kubernetes.io/docs/reference/using-api/deprecation-policy/#deprecating-parts-of-the-api)
|
||||||
about the deprecation policies for Kubernetes APIs, and other Kubernetes components.
|
about the deprecation policies for Kubernetes APIs, and other Kubernetes components.
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: nginx:1.13-alpine
|
image: nginx:1.16-alpine
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: Join SIG Scalability and Learn Kubernetes the Hard Way
|
||||||
|
date: 2020-03-19
|
||||||
|
slug: join-sig-scalability
|
||||||
|
---
|
||||||
|
|
||||||
|
**Authors:** Alex Handy
|
||||||
|
|
||||||
|
Contributing to SIG Scalability is a great way to learn Kubernetes in all its depth and breadth, and the team would love to have you [join as a contributor](https://github.com/kubernetes/community/tree/master/sig-scalability#scalability-special-interest-group). I took a look at the value of learning the hard way and interviewed the current SIG chairs to give you an idea of what contribution feels like.
|
||||||
|
|
||||||
|
## The value of Learning The Hard Way
|
||||||
|
|
||||||
|
There is a belief in the software development community that pushes for the most challenging and rigorous possible method of learning a new language or system. These tend to go by the moniker of "Learn \_\_ the Hard Way." Examples abound: Learn Code the Hard Way, Learn Python the Hard Way, and many others originating with Zed Shaw's courses in the topic.
|
||||||
|
|
||||||
|
While there are folks out there who offer you a "Learn Kubernetes the Hard Way" type experience (most notably [Kelsey Hightower's](https://github.com/kelseyhightower/kubernetes-the-hard-way)), any "Hard Way" project should attempt to cover every aspect of the core topic's principles.
|
||||||
|
|
||||||
|
Therefore, the real way to "Learn Kubernetes the Hard Way," is to join the CNCF and get involved in the project itself. And there is only one SIG that could genuinely offer a full-stack learning experience for Kubernetes: SIG Scalability.
|
||||||
|
|
||||||
|
The team behind SIG Scalability is responsible for detecting and dealing with issues that arise when Kubernetes clusters are working with upwards of a thousand nodes. Said [Wojiciech Tyczynski](https://github.com/wojtek-t), a staff software engineer at Google and a member of SIG Scalability, the standard size for a test cluster for this SIG is over 5,000 nodes.
|
||||||
|
|
||||||
|
And yet, this SIG is not composed of Ph.D.'s in highly scalable systems designs. Many of the folks working with Tyczynski, for example, joined the SIG knowing very little about these types of issues, and often, very little about Kubernetes.
|
||||||
|
|
||||||
|
Working on SIG Scalability is like jumping into the deep end of the pool to learn to swim, and the SIG is inherently concerned with the entire Kubernetes project. SIG Scalability focuses on how Kubernetes functions as a whole and at scale. The SIG Scalability team members have an impetus to learn about every system and to understand how all systems interact with one another.
|
||||||
|
|
||||||
|
## A complex and rewarding contributor experience
|
||||||
|
|
||||||
|
While that may sound complicated (and it is!), that doesn't mean it's outside the reach of an average developer, tester, or administrator. Google software developer Matt Matejczyk has only been on the team since the beginning of 2019, and he's been a valued member of the team since then, ferreting out bugs.
|
||||||
|
|
||||||
|
"I am new here," said Matejczyk. "I joined the team in January [2019]. Before that, I worked on AdWords at Google in New York. Why did I join? I knew some people there, so that was one of the decisions for me to move. I thought at that time that Kubernetes is a unique, cutting edge technology. I thought it'd be cool to work on that."
|
||||||
|
|
||||||
|
Matejczyk was correct about the coolness. "It's cool," he said. "So actually, ramping up on scalability is not easy. There are many things you need to understand. You need to understand Kubernetes very well. It can use every part of Kubernetes. I am still ramping up after these 8 months. I think it took me maybe 3 months to get up to decent speed."
|
||||||
|
|
||||||
|
When Matejczyk spoke to what he had worked on during those 8 months, he answered, "An interesting example is a regression I have been working on recently. We noticed the overall slowness of Kubernetes control plane in specific scenarios, and we couldn't attribute it to any particular component. In the end, we realized that everything boiled down to the memory allocation on the golang level. It was very counterintuitive to have two completely separate pieces of code (running as a part of the same binary) affecting the performance of each other only because one of them was allocating memory too fast. But connecting all the dots and getting to the bottom of regression like this gives great satisfaction."
|
||||||
|
|
||||||
|
Tyczynski said that "It's not only debugging regressions, but it's also debugging and finding bottlenecks. In general, those can be regressions, but those can be things we can improve. The other significant area is extending what we want to guarantee to users. Extending SLA and SLO coverage of the system so users can rely on what they can expect from the system in terms of performance and scalability. Matt is doing much work in extending our tests to be more representative and cover more Kubernetes concepts."
|
||||||
|
|
||||||
|
## Give SIG Scalability a try
|
||||||
|
|
||||||
|
The SIG Scalability team is always in need of new members, and if you're the sort of developer or tester who loves taking on new complex challenges, and perhaps loves learning things the hard way, consider joining this SIG. As the team points out, adding Kubernetes expertise to your resume is never a bad idea, and this is the one SIG where you can learn it all from top to bottom.
|
||||||
|
|
||||||
|
See [the SIG's documentation](https://github.com/kubernetes/community/tree/master/sig-scalability#scalability-special-interest-group) to learn about upcoming meetings, its charter, and more. You can also join the [#sig-scalability Slack channel](https://kubernetes.slack.com/archives/C09QZTRH7) to see what it's like. We hope to see you join in to take advantage of this great opportunity to learn Kubernetes and contribute back at the same time.
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
---
|
||||||
|
layout: blog
|
||||||
|
title: 'Kong Ingress Controller and Service Mesh: Setting up Ingress to Istio on Kubernetes'
|
||||||
|
date: 2020-03-18
|
||||||
|
slug: kong-ingress-controller-and-istio-service-mesh
|
||||||
|
---
|
||||||
|
|
||||||
|
**Author:** Kevin Chen, Kong
|
||||||
|
|
||||||
|
Kubernetes has become the de facto way to orchestrate containers and the services within services. But how do we give services outside our cluster access to what is within? Kubernetes comes with the Ingress API object that manages external access to services within a cluster.
|
||||||
|
|
||||||
|
Ingress is a group of rules that will proxy inbound connections to endpoints defined by a backend. However, Kubernetes does not know what to do with Ingress resources without an Ingress controller, which is where an open source controller can come into play. In this post, we are going to use one option for this: the Kong Ingress Controller. The Kong Ingress Controller was open-sourced a year ago and recently reached one million downloads. In the recent 0.7 release, service mesh support was also added. Other features of this release include:
|
||||||
|
|
||||||
|
* **Built-In Kubernetes Admission Controller**, which validates Custom Resource Definitions (CRD) as they are created or updated and rejects any invalid configurations.
|
||||||
|
* **In-memory Mode** - Each pod’s controller actively configures the Kong container in its pod, which limits the blast radius of failure of a single container of Kong or controller container to that pod only.
|
||||||
|
* **Native gRPC Routing** - gRPC traffic can now be routed via Kong Ingress Controller natively with support for method-based routing.
|
||||||
|
|
||||||
|

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

|
||||||
|
|
||||||
|
### Part 0: Set up Istio on Kubernetes
|
||||||
|
|
||||||
|
This blog will assume you have Istio set up on Kubernetes. If you need to catch up to this point, please check out the [Istio documentation](https://istio.io/docs/setup/). It will walk you through setting up Istio on Kubernetes.
|
||||||
|
|
||||||
|
### 1. Install the Bookinfo Application
|
||||||
|
|
||||||
|
First, we need to label the namespaces that will host our application and Kong proxy. To label our default namespace where the bookinfo app sits, run this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl label namespace default istio-injection=enabled
|
||||||
|
namespace/default labeled
|
||||||
|
```
|
||||||
|
|
||||||
|
Then create a new namespace that will be hosting our Kong gateway and the Ingress controller:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl create namespace kong
|
||||||
|
namespace/kong created
|
||||||
|
```
|
||||||
|
|
||||||
|
Because Kong will be sitting outside the default namespace, be sure you also label the Kong namespace with istio-injection enabled as well:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl label namespace kong istio-injection=enabled
|
||||||
|
namespace/kong labeled
|
||||||
|
```
|
||||||
|
|
||||||
|
Having both namespaces labeled `istio-injection=enabled` is necessary. Or else the default configuration will not inject a sidecar container into the pods of your namespaces.
|
||||||
|
|
||||||
|
Now deploy your BookInfo application with the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl apply -f http://bit.ly/bookinfoapp
|
||||||
|
service/details created
|
||||||
|
serviceaccount/bookinfo-details created
|
||||||
|
deployment.apps/details-v1 created
|
||||||
|
service/ratings created
|
||||||
|
serviceaccount/bookinfo-ratings created
|
||||||
|
deployment.apps/ratings-v1 created
|
||||||
|
service/reviews created
|
||||||
|
serviceaccount/bookinfo-reviews created
|
||||||
|
deployment.apps/reviews-v1 created
|
||||||
|
deployment.apps/reviews-v2 created
|
||||||
|
deployment.apps/reviews-v3 created
|
||||||
|
service/productpage created
|
||||||
|
serviceaccount/bookinfo-productpage created
|
||||||
|
deployment.apps/productpage-v1 created
|
||||||
|
```
|
||||||
|
|
||||||
|
Let’s double-check our Services and Pods to make sure that we have it all set up correctly:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl get services
|
||||||
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
|
details ClusterIP 10.97.125.254 <none> 9080/TCP 29s
|
||||||
|
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29h
|
||||||
|
productpage ClusterIP 10.97.62.68 <none> 9080/TCP 28s
|
||||||
|
ratings ClusterIP 10.96.15.180 <none> 9080/TCP 28s
|
||||||
|
reviews ClusterIP 10.104.207.136 <none> 9080/TCP 28s
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see four new services: details, productpage, ratings, and reviews. None of them have an external IP so we will use the [Kong gateway](https://github.com/Kong/kong) to expose the necessary services. And to check pods, run the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl get pods
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
details-v1-c5b5f496d-9wm29 2/2 Running 0 101s
|
||||||
|
productpage-v1-7d6cfb7dfd-5mc96 2/2 Running 0 100s
|
||||||
|
ratings-v1-f745cf57b-hmkwf 2/2 Running 0 101s
|
||||||
|
reviews-v1-85c474d9b8-kqcpt 2/2 Running 0 101s
|
||||||
|
reviews-v2-ccffdd984-9jnsj 2/2 Running 0 101s
|
||||||
|
reviews-v3-98dc67b68-nzw97 2/2 Running 0 101s
|
||||||
|
```
|
||||||
|
|
||||||
|
This command outputs useful data, so let’s take a second to understand it. If you examine the READY column, each pod has two containers running: the service and an Envoy sidecar injected alongside it. Another thing to highlight is that there are three review pods but only 1 review service. The Envoy sidecar will load balance the traffic to three different review pods that contain different versions, giving us the ability to A/B test our changes. With that said, you should now be able to access your product page!
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
|
||||||
|
<title>Simple Bookstore App</title>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Kong Kubernetes Ingress Controller Without Database
|
||||||
|
|
||||||
|
To expose your services to the world, we will deploy Kong as the north-south traffic gateway. [Kong 1.1](https://github.com/Kong/kong/releases/tag/1.1.2) released with declarative configuration and DB-less mode. Declarative configuration allows you to specify the desired system state through a YAML or JSON file instead of a sequence of API calls. Using declarative config provides several key benefits to reduce complexity, increase automation and enhance system performance. And with the Kong Ingress Controller, any Ingress rules you apply to the cluster will automatically be configured on the Kong proxy. Let’s set up the Kong Ingress Controller and the actual Kong proxy first like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl apply -f https://bit.ly/k4k8s
|
||||||
|
namespace/kong configured
|
||||||
|
customresourcedefinition.apiextensions.k8s.io/kongconsumers.configuration.konghq.com created
|
||||||
|
customresourcedefinition.apiextensions.k8s.io/kongcredentials.configuration.konghq.com created
|
||||||
|
customresourcedefinition.apiextensions.k8s.io/kongingresses.configuration.konghq.com created
|
||||||
|
customresourcedefinition.apiextensions.k8s.io/kongplugins.configuration.konghq.com created
|
||||||
|
serviceaccount/kong-serviceaccount created
|
||||||
|
clusterrole.rbac.authorization.k8s.io/kong-ingress-clusterrole created
|
||||||
|
clusterrolebinding.rbac.authorization.k8s.io/kong-ingress-clusterrole-nisa-binding created
|
||||||
|
configmap/kong-server-blocks created
|
||||||
|
service/kong-proxy created
|
||||||
|
service/kong-validation-webhook created
|
||||||
|
deployment.apps/ingress-kong created
|
||||||
|
```
|
||||||
|
|
||||||
|
To check if the Kong pod is up and running, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl get pods -n kong
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
pod/ingress-kong-8b44c9856-9s42v 3/3 Running 0 2m26s
|
||||||
|
```
|
||||||
|
|
||||||
|
There will be three containers within this pod. The first container is the Kong Gateway that will be the Ingress point to your cluster. The second container is the Ingress controller. It uses Ingress resources and updates the proxy to follow rules defined in the resource. And lastly, the third container is the Envoy proxy injected by Istio. Kong will route traffic through the Envoy sidecar proxy to the appropriate service. To send requests into the cluster via our newly deployed Kong Gateway, setup an environment variable with the a URL based on the IP address at which Kong is accessible.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ export PROXY_URL="$(minikube service -n kong kong-proxy --url | head -1)"
|
||||||
|
$ echo $PROXY_URL
|
||||||
|
http://192.168.99.100:32728
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, we need to change some configuration so that the side-car Envoy process can route the request correctly based on the host/authority header of the request. Run the following to stop the route from preserving host:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ echo "
|
||||||
|
apiVersion: configuration.konghq.com/v1
|
||||||
|
kind: KongIngress
|
||||||
|
metadata:
|
||||||
|
name: do-not-preserve-host
|
||||||
|
route:
|
||||||
|
preserve_host: false
|
||||||
|
" | kubectl apply -f -
|
||||||
|
kongingress.configuration.konghq.com/do-not-preserve-host created
|
||||||
|
```
|
||||||
|
|
||||||
|
And annotate the existing productpage service to set service-upstream as true:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ kubectl annotate svc productpage Ingress.kubernetes.io/service-upstream="true"
|
||||||
|
service/productpage annotated
|
||||||
|
```
|
||||||
|
|
||||||
|
Now that we have everything set up, we can look at how to use the Ingress resource to help route external traffic to the services within your Istio mesh. We’ll create an Ingress rule that routes all traffic with the path of `/` to our productpage service:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ echo "
|
||||||
|
apiVersion: extensions/v1beta1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: productpage
|
||||||
|
annotations:
|
||||||
|
configuration.konghq.com: do-not-preserve-host
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
backend:
|
||||||
|
serviceName: productpage
|
||||||
|
servicePort: 9080
|
||||||
|
" | kubectl apply -f -
|
||||||
|
ingress.extensions/productpage created
|
||||||
|
```
|
||||||
|
|
||||||
|
And just like that, the Kong Ingress Controller is able to understand the rules you defined in the Ingress resource and routes it to the productpage service! To view the product page service’s GUI, go to `$PROXY_URL/productpage` in your browser. Or to test it in your command line, try:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl $PROXY_URL/productpage
|
||||||
|
```
|
||||||
|
|
||||||
|
That is all I have for this walk-through. If you enjoyed the technologies used in this post, please check out their repositories since they are all open source and would love to have more contributors! Here are their links for your convenience:
|
||||||
|
|
||||||
|
* Kong: [[GitHub](https://github.com/Kong/kubernetes-ingress-controller)] [[Twitter](https://twitter.com/thekonginc)]
|
||||||
|
* Kubernetes: [[GitHub](https://github.com/kubernetes/kubernetes)] [[Twitter](https://twitter.com/kubernetesio)]
|
||||||
|
* Istio: [[GitHub](https://github.com/istio/istio)] [[Twitter](https://twitter.com/IstioMesh)]
|
||||||
|
* Envoy: [[GitHub](https://github.com/envoyproxy/envoy)] [[Twitter](https://twitter.com/EnvoyProxy)]
|
||||||
|
|
||||||
|
Thank you for following along!
|
||||||
@@ -184,7 +184,7 @@ a Lease object.
|
|||||||
timeout for unreachable nodes).
|
timeout for unreachable nodes).
|
||||||
- The kubelet creates and then updates its Lease object every 10 seconds
|
- The kubelet creates and then updates its Lease object every 10 seconds
|
||||||
(the default update interval). Lease updates occur independently from the
|
(the default update interval). Lease updates occur independently from the
|
||||||
`NodeStatus` updates.
|
`NodeStatus` updates. If the Lease update fails, the kubelet retries with exponential backoff starting at 200 milliseconds and capped at 7 seconds.
|
||||||
|
|
||||||
#### Reliability
|
#### Reliability
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Note: Not all distros are actively maintained. Choose distros which have been te
|
|||||||
|
|
||||||
* [Certificates](/docs/concepts/cluster-administration/certificates/) describes the steps to generate certificates using different tool chains.
|
* [Certificates](/docs/concepts/cluster-administration/certificates/) describes the steps to generate certificates using different tool chains.
|
||||||
|
|
||||||
* [Kubernetes Container Environment](/docs/concepts/containers/container-environment-variables/) describes the environment for Kubelet managed containers on a Kubernetes node.
|
* [Kubernetes Container Environment](/docs/concepts/containers/container-environment/) describes the environment for Kubelet managed containers on a Kubernetes node.
|
||||||
|
|
||||||
* [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/) describes how to set up permissions for users and service accounts.
|
* [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/) describes how to set up permissions for users and service accounts.
|
||||||
|
|
||||||
|
|||||||
@@ -1,186 +0,0 @@
|
|||||||
---
|
|
||||||
title: Federation
|
|
||||||
content_template: templates/concept
|
|
||||||
weight: 80
|
|
||||||
---
|
|
||||||
|
|
||||||
{{% capture overview %}}
|
|
||||||
|
|
||||||
{{< deprecationfilewarning >}}
|
|
||||||
{{< include "federation-deprecation-warning-note.md" >}}
|
|
||||||
{{< /deprecationfilewarning >}}
|
|
||||||
|
|
||||||
This page explains why and how to manage multiple Kubernetes clusters using
|
|
||||||
federation.
|
|
||||||
{{% /capture %}}
|
|
||||||
|
|
||||||
{{% capture body %}}
|
|
||||||
## Why federation
|
|
||||||
|
|
||||||
Federation makes it easy to manage multiple clusters. It does so by providing 2
|
|
||||||
major building blocks:
|
|
||||||
|
|
||||||
* Sync resources across clusters: Federation provides the ability to keep
|
|
||||||
resources in multiple clusters in sync. For example, you can ensure that the same deployment exists in multiple clusters.
|
|
||||||
* Cross cluster discovery: Federation provides the ability to auto-configure DNS servers and load balancers with backends from all clusters. For example, you can ensure that a global VIP or DNS record can be used to access backends from multiple clusters.
|
|
||||||
|
|
||||||
Some other use cases that federation enables are:
|
|
||||||
|
|
||||||
* High Availability: By spreading load across clusters and auto configuring DNS
|
|
||||||
servers and load balancers, federation minimises the impact of cluster
|
|
||||||
failure.
|
|
||||||
* Avoiding provider lock-in: By making it easier to migrate applications across
|
|
||||||
clusters, federation prevents cluster provider lock-in.
|
|
||||||
|
|
||||||
|
|
||||||
Federation is not helpful unless you have multiple clusters. Some of the reasons
|
|
||||||
why you might want multiple clusters are:
|
|
||||||
|
|
||||||
* Low latency: Having clusters in multiple regions minimises latency by serving
|
|
||||||
users from the cluster that is closest to them.
|
|
||||||
* Fault isolation: It might be better to have multiple small clusters rather
|
|
||||||
than a single large cluster for fault isolation (for example: multiple
|
|
||||||
clusters in different availability zones of a cloud provider).
|
|
||||||
* Scalability: There are scalability limits to a single kubernetes cluster (this
|
|
||||||
should not be the case for most users. For more details:
|
|
||||||
[Kubernetes Scaling and Performance Goals](https://git.k8s.io/community/sig-scalability/goals.md)).
|
|
||||||
* [Hybrid cloud](#hybrid-cloud-capabilities): You can have multiple clusters on different cloud providers or
|
|
||||||
on-premises data centers.
|
|
||||||
|
|
||||||
### Caveats
|
|
||||||
|
|
||||||
While there are a lot of attractive use cases for federation, there are also
|
|
||||||
some caveats:
|
|
||||||
|
|
||||||
* Increased network bandwidth and cost: The federation control plane watches all
|
|
||||||
clusters to ensure that the current state is as expected. This can lead to
|
|
||||||
significant network cost if the clusters are running in different regions on
|
|
||||||
a cloud provider or on different cloud providers.
|
|
||||||
* Reduced cross cluster isolation: A bug in the federation control plane can
|
|
||||||
impact all clusters. This is mitigated by keeping the logic in federation
|
|
||||||
control plane to a minimum. It mostly delegates to the control plane in
|
|
||||||
kubernetes clusters whenever it can. The design and implementation also errs
|
|
||||||
on the side of safety and avoiding multi-cluster outage.
|
|
||||||
* Maturity: The federation project is relatively new and is not very mature.
|
|
||||||
Not all resources are available and many are still alpha. [Issue
|
|
||||||
88](https://github.com/kubernetes/federation/issues/88) enumerates
|
|
||||||
known issues with the system that the team is busy solving.
|
|
||||||
|
|
||||||
### Hybrid cloud capabilities
|
|
||||||
|
|
||||||
Federations of Kubernetes Clusters can include clusters running in
|
|
||||||
different cloud providers (e.g. Google Cloud, AWS), and on-premises
|
|
||||||
(e.g. on OpenStack). [Kubefed](/docs/tasks/federation/set-up-cluster-federation-kubefed/) is the recommended way to deploy federated clusters.
|
|
||||||
|
|
||||||
Thereafter, your [API resources](#api-resources) can span different clusters
|
|
||||||
and cloud providers.
|
|
||||||
|
|
||||||
## Setting up federation
|
|
||||||
|
|
||||||
To be able to federate multiple clusters, you first need to set up a federation
|
|
||||||
control plane.
|
|
||||||
Follow the [setup guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) to set up the
|
|
||||||
federation control plane.
|
|
||||||
|
|
||||||
## API resources
|
|
||||||
|
|
||||||
Once you have the control plane set up, you can start creating federation API
|
|
||||||
resources.
|
|
||||||
The following guides explain some of the resources in detail:
|
|
||||||
|
|
||||||
* [Cluster](/docs/tasks/federation/administer-federation/cluster/)
|
|
||||||
* [ConfigMap](/docs/tasks/federation/administer-federation/configmap/)
|
|
||||||
* [DaemonSets](/docs/tasks/federation/administer-federation/daemonset/)
|
|
||||||
* [Deployment](/docs/tasks/federation/administer-federation/deployment/)
|
|
||||||
* [Events](/docs/tasks/federation/administer-federation/events/)
|
|
||||||
* [Hpa](/docs/tasks/federation/administer-federation/hpa/)
|
|
||||||
* [Ingress](/docs/tasks/federation/administer-federation/ingress/)
|
|
||||||
* [Jobs](/docs/tasks/federation/administer-federation/job/)
|
|
||||||
* [Namespaces](/docs/tasks/federation/administer-federation/namespaces/)
|
|
||||||
* [ReplicaSets](/docs/tasks/federation/administer-federation/replicaset/)
|
|
||||||
* [Secrets](/docs/tasks/federation/administer-federation/secret/)
|
|
||||||
* [Services](/docs/concepts/cluster-administration/federation-service-discovery/)
|
|
||||||
|
|
||||||
|
|
||||||
The [API reference docs](/docs/reference/federation/) list all the
|
|
||||||
resources supported by federation apiserver.
|
|
||||||
|
|
||||||
## Cascading deletion
|
|
||||||
|
|
||||||
Kubernetes version 1.6 includes support for cascading deletion of federated
|
|
||||||
resources. With cascading deletion, when you delete a resource from the
|
|
||||||
federation control plane, you also delete the corresponding resources in all underlying clusters.
|
|
||||||
|
|
||||||
Cascading deletion is not enabled by default when using the REST API. To enable
|
|
||||||
it, set the option `DeleteOptions.orphanDependents=false` when you delete a
|
|
||||||
resource from the federation control plane using the REST API. Using `kubectl
|
|
||||||
delete`
|
|
||||||
enables cascading deletion by default. You can disable it by running `kubectl
|
|
||||||
delete --cascade=false`
|
|
||||||
|
|
||||||
Note: Kubernetes version 1.5 included cascading deletion support for a subset of
|
|
||||||
federation resources.
|
|
||||||
|
|
||||||
## Scope of a single cluster
|
|
||||||
|
|
||||||
On IaaS providers such as Google Compute Engine or Amazon Web Services, a VM exists in a
|
|
||||||
[zone](https://cloud.google.com/compute/docs/zones) or [availability
|
|
||||||
zone](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html).
|
|
||||||
We suggest that all the VMs in a Kubernetes cluster should be in the same availability zone, because:
|
|
||||||
|
|
||||||
- compared to having a single global Kubernetes cluster, there are fewer single-points of failure.
|
|
||||||
- compared to a cluster that spans availability zones, it is easier to reason about the availability properties of a
|
|
||||||
single-zone cluster.
|
|
||||||
- when the Kubernetes developers are designing the system (e.g. making assumptions about latency, bandwidth, or
|
|
||||||
correlated failures) they are assuming all the machines are in a single data center, or otherwise closely connected.
|
|
||||||
|
|
||||||
It is recommended to run fewer clusters with more VMs per availability zone; but it is possible to run multiple clusters per availability zones.
|
|
||||||
|
|
||||||
Reasons to prefer fewer clusters per availability zone are:
|
|
||||||
|
|
||||||
- improved bin packing of Pods in some cases with more nodes in one cluster (less resource fragmentation).
|
|
||||||
- reduced operational overhead (though the advantage is diminished as ops tooling and processes mature).
|
|
||||||
- reduced costs for per-cluster fixed resource costs, for example apiserver VMs (but small as a percentage
|
|
||||||
of overall cluster cost for medium to large clusters).
|
|
||||||
|
|
||||||
Reasons to have multiple clusters include:
|
|
||||||
|
|
||||||
- strict security policies requiring isolation of one class of work from another (but, see Partitioning Clusters
|
|
||||||
below).
|
|
||||||
- test clusters to canary new Kubernetes releases or other cluster software.
|
|
||||||
|
|
||||||
## Selecting the right number of clusters
|
|
||||||
|
|
||||||
The selection of the number of Kubernetes clusters may be a relatively static choice, only revisited occasionally.
|
|
||||||
By contrast, the number of nodes in a cluster and the number of pods in a service may change frequently according to
|
|
||||||
load and growth.
|
|
||||||
|
|
||||||
To pick the number of clusters, first, decide which regions you need to be in to have adequate latency to all your end users, for services that will run
|
|
||||||
on Kubernetes (if you use a Content Distribution Network, the latency requirements for the CDN-hosted content need not
|
|
||||||
be considered). Legal issues might influence this as well. For example, a company with a global customer base might decide to have clusters in US, EU, AP, and SA regions.
|
|
||||||
Call the number of regions to be in `R`.
|
|
||||||
|
|
||||||
Second, decide how many clusters should be able to be unavailable at the same time, while still being available. Call
|
|
||||||
the number that can be unavailable `U`. If you are not sure, then 1 is a fine choice.
|
|
||||||
|
|
||||||
If it is allowable for load-balancing to direct traffic to any region in the event of a cluster failure, then
|
|
||||||
you need at least the larger of `R` or `U + 1` clusters. If it is not (e.g. you want to ensure low latency for all
|
|
||||||
users in the event of a cluster failure), then you need to have `R * (U + 1)` clusters
|
|
||||||
(`U + 1` in each of `R` regions). In any case, try to put each cluster in a different zone.
|
|
||||||
|
|
||||||
Finally, if any of your clusters would need more than the maximum recommended number of nodes for a Kubernetes cluster, then
|
|
||||||
you may need even more clusters. Kubernetes v1.3 supports clusters up to 1000 nodes in size. Kubernetes v1.8 supports
|
|
||||||
clusters up to 5000 nodes. See [Building Large Clusters](/docs/setup/best-practices/cluster-large/) for more guidance.
|
|
||||||
|
|
||||||
{{% /capture %}}
|
|
||||||
|
|
||||||
{{% capture whatsnext %}}
|
|
||||||
* Learn more about the [Federation
|
|
||||||
proposal](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/multicluster/federation.md).
|
|
||||||
* See this [setup guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) for cluster federation.
|
|
||||||
* See this [Kubecon2016 talk on federation](https://www.youtube.com/watch?v=pq9lbkmxpS8)
|
|
||||||
* See this [Kubecon2017 Europe update on federation](https://www.youtube.com/watch?v=kwOvOLnFYck)
|
|
||||||
* See this [Kubecon2018 Europe update on sig-multicluster](https://www.youtube.com/watch?v=vGZo5DaThQU)
|
|
||||||
* See this [Kubecon2018 Europe Federation-v2 prototype presentation](https://youtu.be/q27rbaX5Jis?t=7m20s)
|
|
||||||
* See this [Federation-v2 Userguide](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md)
|
|
||||||
{{% /capture %}}
|
|
||||||
@@ -424,16 +424,16 @@ At some point, you'll eventually need to update your deployed application, typic
|
|||||||
|
|
||||||
We'll guide you through how to create and update applications with Deployments.
|
We'll guide you through how to create and update applications with Deployments.
|
||||||
|
|
||||||
Let's say you were running version 1.7.9 of nginx:
|
Let's say you were running version 1.14.2 of nginx:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl run my-nginx --image=nginx:1.7.9 --replicas=3
|
kubectl run my-nginx --image=nginx:1.14.2 --replicas=3
|
||||||
```
|
```
|
||||||
```shell
|
```shell
|
||||||
deployment.apps/my-nginx created
|
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.
|
To update to version 1.16.1, simply change `.spec.template.spec.containers[0].image` from `nginx:1.14.2` to `nginx:1.16.1`, with the kubectl commands we learned above.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl edit deployment/my-nginx
|
kubectl edit deployment/my-nginx
|
||||||
|
|||||||
@@ -111,9 +111,10 @@ For example, `example.com.node-restriction.kubernetes.io/fips=true` or `example.
|
|||||||
`nodeSelector` provides a very simple way to constrain pods to nodes with particular labels. The affinity/anti-affinity
|
`nodeSelector` provides a very simple way to constrain pods to nodes with particular labels. The affinity/anti-affinity
|
||||||
feature, greatly expands the types of constraints you can express. The key enhancements are
|
feature, greatly expands the types of constraints you can express. The key enhancements are
|
||||||
|
|
||||||
1. the language is more expressive (not just "AND or exact match")
|
1. The affinity/anti-affinity language is more expressive. The language offers more matching rules
|
||||||
|
besides exact matches created with a logical AND operation;
|
||||||
2. you can indicate that the rule is "soft"/"preference" rather than a hard requirement, so if the scheduler
|
2. you can indicate that the rule is "soft"/"preference" rather than a hard requirement, so if the scheduler
|
||||||
can't satisfy it, the pod will still be scheduled
|
can't satisfy it, the pod will still be scheduled;
|
||||||
3. you can constrain against labels on other pods running on the node (or other topological domain),
|
3. you can constrain against labels on other pods running on the node (or other topological domain),
|
||||||
rather than against labels on the node itself, which allows rules about which pods can and cannot be co-located
|
rather than against labels on the node itself, which allows rules about which pods can and cannot be co-located
|
||||||
|
|
||||||
@@ -159,9 +160,9 @@ You can use `NotIn` and `DoesNotExist` to achieve node anti-affinity behavior, o
|
|||||||
If you specify both `nodeSelector` and `nodeAffinity`, *both* must be satisfied for the pod
|
If you specify both `nodeSelector` and `nodeAffinity`, *both* must be satisfied for the pod
|
||||||
to be scheduled onto a candidate node.
|
to be scheduled onto a candidate node.
|
||||||
|
|
||||||
If you specify multiple `nodeSelectorTerms` associated with `nodeAffinity` types, then the pod can be scheduled onto a node **if one of** the `nodeSelectorTerms` is satisfied.
|
If you specify multiple `nodeSelectorTerms` associated with `nodeAffinity` types, then the pod can be scheduled onto a node **only if all** `nodeSelectorTerms` can be satisfied.
|
||||||
|
|
||||||
If you specify multiple `matchExpressions` associated with `nodeSelectorTerms`, then the pod can be scheduled onto a node **only if all** `matchExpressions` can be satisfied.
|
If you specify multiple `matchExpressions` associated with `nodeSelectorTerms`, then the pod can be scheduled onto a node **if one of** the `matchExpressions` is satisfied.
|
||||||
|
|
||||||
If you remove or change the label of the node where the pod is scheduled, the pod won't be removed. In other words, the affinity selection works only at the time of scheduling the pod.
|
If you remove or change the label of the node where the pod is scheduled, the pod won't be removed. In other words, the affinity selection works only at the time of scheduling the pod.
|
||||||
|
|
||||||
@@ -228,7 +229,7 @@ for performance and security reasons, there are some constraints on topologyKey:
|
|||||||
1. For affinity and for `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity,
|
1. For affinity and for `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity,
|
||||||
empty `topologyKey` is not allowed.
|
empty `topologyKey` is not allowed.
|
||||||
2. For `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, the admission controller `LimitPodHardAntiAffinityTopology` was introduced to limit `topologyKey` to `kubernetes.io/hostname`. If you want to make it available for custom topologies, you may modify the admission controller, or simply disable it.
|
2. For `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, the admission controller `LimitPodHardAntiAffinityTopology` was introduced to limit `topologyKey` to `kubernetes.io/hostname`. If you want to make it available for custom topologies, you may modify the admission controller, or simply disable it.
|
||||||
3. For `preferredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, empty `topologyKey` is interpreted as "all topologies" ("all topologies" here is now limited to the combination of `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone` and `failure-domain.beta.kubernetes.io/region`).
|
3. For `preferredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, empty `topologyKey` is not allowed.
|
||||||
4. Except for the above cases, the `topologyKey` can be any legal label-key.
|
4. Except for the above cases, the `topologyKey` can be any legal label-key.
|
||||||
|
|
||||||
In addition to `labelSelector` and `topologyKey`, you can optionally specify a list `namespaces`
|
In addition to `labelSelector` and `topologyKey`, you can optionally specify a list `namespaces`
|
||||||
@@ -318,7 +319,7 @@ spec:
|
|||||||
topologyKey: "kubernetes.io/hostname"
|
topologyKey: "kubernetes.io/hostname"
|
||||||
containers:
|
containers:
|
||||||
- name: web-app
|
- name: web-app
|
||||||
image: nginx:1.12-alpine
|
image: nginx:1.16-alpine
|
||||||
```
|
```
|
||||||
|
|
||||||
If we create the above two deployments, our three node cluster should look like below.
|
If we create the above two deployments, our three node cluster should look like below.
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ spec:
|
|||||||
### How Pods with ephemeral-storage requests are scheduled
|
### How Pods with ephemeral-storage requests are scheduled
|
||||||
|
|
||||||
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
|
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
|
||||||
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. For more information, see ["Node Allocatable"](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. For more information, see ["Node Allocatable"](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||||
|
|
||||||
The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node.
|
The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node.
|
||||||
|
|
||||||
|
|||||||
@@ -16,42 +16,25 @@ importance of a Pod relative to other Pods. If a Pod cannot be scheduled, the
|
|||||||
scheduler tries to preempt (evict) lower priority Pods to make scheduling of the
|
scheduler tries to preempt (evict) lower priority Pods to make scheduling of the
|
||||||
pending Pod possible.
|
pending Pod possible.
|
||||||
|
|
||||||
In Kubernetes 1.9 and later, Priority also affects scheduling order of Pods and
|
|
||||||
out-of-resource eviction ordering on the Node.
|
|
||||||
|
|
||||||
Pod priority and preemption graduated to beta in Kubernetes 1.11 and to GA in
|
|
||||||
Kubernetes 1.14. They have been enabled by default since 1.11.
|
|
||||||
|
|
||||||
In Kubernetes versions where Pod priority and preemption is still an alpha-level
|
|
||||||
feature, you need to explicitly enable it. To use these features in the older
|
|
||||||
versions of Kubernetes, follow the instructions in the documentation for your
|
|
||||||
Kubernetes version, by going to the documentation archive version for your
|
|
||||||
Kubernetes version.
|
|
||||||
|
|
||||||
Kubernetes Version | Priority and Preemption State | Enabled by default
|
|
||||||
------------------ | :---------------------------: | :----------------:
|
|
||||||
1.8 | alpha | no
|
|
||||||
1.9 | alpha | no
|
|
||||||
1.10 | alpha | no
|
|
||||||
1.11 | beta | yes
|
|
||||||
1.14 | stable | yes
|
|
||||||
|
|
||||||
{{< warning >}}In a cluster where not all users are trusted, a
|
|
||||||
malicious user could create pods at the highest possible priorities, causing
|
|
||||||
other pods to be evicted/not get scheduled. To resolve this issue,
|
|
||||||
[ResourceQuota](/docs/concepts/policy/resource-quotas/) is
|
|
||||||
augmented to support Pod priority. An admin can create ResourceQuota for users
|
|
||||||
at specific priority levels, preventing them from creating pods at high
|
|
||||||
priorities. This feature is in beta since Kubernetes 1.12.
|
|
||||||
{{< /warning >}}
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
|
|
||||||
|
{{< warning >}}
|
||||||
|
In a cluster where not all users are trusted, a malicious user could create Pods
|
||||||
|
at the highest possible priorities, causing other Pods to be evicted/not get
|
||||||
|
scheduled.
|
||||||
|
An administrator can use ResourceQuota to prevent users from creating pods at
|
||||||
|
high priorities.
|
||||||
|
|
||||||
|
See [limit Priority Class consumption by default](/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default)
|
||||||
|
for details.
|
||||||
|
{{< /warning >}}
|
||||||
|
|
||||||
## How to use priority and preemption
|
## How to use priority and preemption
|
||||||
|
|
||||||
To use priority and preemption in Kubernetes 1.11 and later, follow these steps:
|
To use priority and preemption:
|
||||||
|
|
||||||
1. Add one or more [PriorityClasses](#priorityclass).
|
1. Add one or more [PriorityClasses](#priorityclass).
|
||||||
|
|
||||||
@@ -77,21 +60,20 @@ Pods.
|
|||||||
|
|
||||||
## How to disable preemption
|
## How to disable preemption
|
||||||
|
|
||||||
{{< note >}}
|
{{< caution >}}
|
||||||
In Kubernetes 1.12+, critical pods rely on scheduler preemption to be scheduled
|
Critical pods rely on scheduler preemption to be scheduled when a cluster
|
||||||
when a cluster is under resource pressure. For this reason, it is not
|
is under resource pressure. For this reason, it is not recommended to
|
||||||
recommended to disable preemption.
|
disable preemption.
|
||||||
{{< /note >}}
|
{{< /caution >}}
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
In Kubernetes 1.15 and later,
|
In Kubernetes 1.15 and later, if the feature `NonPreemptingPriority` is enabled,
|
||||||
if the feature `NonPreemptingPriority` is enabled,
|
|
||||||
PriorityClasses have the option to set `preemptionPolicy: Never`.
|
PriorityClasses have the option to set `preemptionPolicy: Never`.
|
||||||
This will prevent pods of that PriorityClass from preempting other pods.
|
This will prevent pods of that PriorityClass from preempting other pods.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
In Kubernetes 1.11 and later, preemption is controlled by a kube-scheduler flag
|
Preemption is controlled by a kube-scheduler flag `disablePreemption`, which is
|
||||||
`disablePreemption`, which is set to `false` by default.
|
set to `false` by default.
|
||||||
If you want to disable preemption despite the above note, you can set
|
If you want to disable preemption despite the above note, you can set
|
||||||
`disablePreemption` to `true`.
|
`disablePreemption` to `true`.
|
||||||
|
|
||||||
@@ -117,6 +99,9 @@ priority class name to the integer value of the priority. The name is specified
|
|||||||
in the `name` field of the PriorityClass object's metadata. The value is
|
in the `name` field of the PriorityClass object's metadata. The value is
|
||||||
specified in the required `value` field. The higher the value, the higher the
|
specified in the required `value` field. The higher the value, the higher the
|
||||||
priority.
|
priority.
|
||||||
|
The name of a PriorityClass object must be a valid
|
||||||
|
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names),
|
||||||
|
and it cannot be prefixed with `system-`.
|
||||||
|
|
||||||
A PriorityClass object can have any 32-bit integer value smaller than or equal
|
A PriorityClass object can have any 32-bit integer value smaller than or equal
|
||||||
to 1 billion. Larger numbers are reserved for critical system Pods that should
|
to 1 billion. Larger numbers are reserved for critical system Pods that should
|
||||||
@@ -237,12 +222,12 @@ spec:
|
|||||||
|
|
||||||
### Effect of Pod priority on scheduling order
|
### Effect of Pod priority on scheduling order
|
||||||
|
|
||||||
In Kubernetes 1.9 and later, when Pod priority is enabled, scheduler orders
|
When Pod priority is enabled, the scheduler orders pending Pods by
|
||||||
pending Pods by their priority and a pending Pod is placed ahead of other
|
their priority and a pending Pod is placed ahead of other pending Pods
|
||||||
pending Pods with lower priority in the scheduling queue. As a result, the
|
with lower priority in the scheduling queue. As a result, the higher
|
||||||
higher priority Pod may be scheduled sooner than Pods with lower priority if its
|
priority Pod may be scheduled sooner than Pods with lower priority if
|
||||||
scheduling requirements are met. If such Pod cannot be scheduled, scheduler will
|
its scheduling requirements are met. If such Pod cannot be scheduled,
|
||||||
continue and tries to schedule other lower priority Pods.
|
scheduler will continue and tries to schedule other lower priority Pods.
|
||||||
|
|
||||||
## Preemption
|
## Preemption
|
||||||
|
|
||||||
@@ -288,12 +273,12 @@ point that scheduler preempts victims and the time that Pod P is scheduled. In
|
|||||||
order to minimize this gap, one can set graceful termination period of lower
|
order to minimize this gap, one can set graceful termination period of lower
|
||||||
priority Pods to zero or a small number.
|
priority Pods to zero or a small number.
|
||||||
|
|
||||||
#### PodDisruptionBudget is supported, but not guaranteed!
|
#### PodDisruptionBudget is supported, but not guaranteed
|
||||||
|
|
||||||
A [Pod Disruption Budget (PDB)](/docs/concepts/workloads/pods/disruptions/)
|
A [Pod Disruption Budget (PDB)](/docs/concepts/workloads/pods/disruptions/)
|
||||||
allows application owners to limit the number of Pods of a replicated application
|
allows application owners to limit the number of Pods of a replicated application
|
||||||
that are down simultaneously from voluntary disruptions. Kubernetes 1.9 supports
|
that are down simultaneously from voluntary disruptions. Kubernetes supports
|
||||||
PDB when preempting Pods, but respecting PDB is best effort. The Scheduler tries
|
PDB when preempting Pods, but respecting PDB is best effort. The scheduler tries
|
||||||
to find victims whose PDB are not violated by preemption, but if no such victims
|
to find victims whose PDB are not violated by preemption, but if no such victims
|
||||||
are found, preemption will still happen, and lower priority Pods will be removed
|
are found, preemption will still happen, and lower priority Pods will be removed
|
||||||
despite their PDBs being violated.
|
despite their PDBs being violated.
|
||||||
@@ -344,28 +329,23 @@ gone, and Pod P could possibly be scheduled on Node N.
|
|||||||
We may consider adding cross Node preemption in future versions if there is
|
We may consider adding cross Node preemption in future versions if there is
|
||||||
enough demand and if we find an algorithm with reasonable performance.
|
enough demand and if we find an algorithm with reasonable performance.
|
||||||
|
|
||||||
## Debugging Pod Priority and Preemption
|
## Troubleshooting
|
||||||
|
|
||||||
Pod Priority and Preemption is a major feature that could potentially disrupt
|
Pod priority and pre-emption can have unwanted side effects. Here are some
|
||||||
Pod scheduling if it has bugs.
|
examples of potential problems and ways to deal with them.
|
||||||
|
|
||||||
### Potential problems caused by Priority and Preemption
|
### Pods are preempted unnecessarily
|
||||||
|
|
||||||
The followings are some of the potential problems that could be caused by bugs
|
|
||||||
in the implementation of the feature. This list is not exhaustive.
|
|
||||||
|
|
||||||
#### Pods are preempted unnecessarily
|
|
||||||
|
|
||||||
Preemption removes existing Pods from a cluster under resource pressure to make
|
Preemption removes existing Pods from a cluster under resource pressure to make
|
||||||
room for higher priority pending Pods. If a user gives high priorities to
|
room for higher priority pending Pods. If you give high priorities to
|
||||||
certain Pods by mistake, these unintentional high priority Pods may cause
|
certain Pods by mistake, these unintentionally high priority Pods may cause
|
||||||
preemption in the cluster. As mentioned above, Pod priority is specified by
|
preemption in your cluster. Pod priority is specified by setting the
|
||||||
setting the `priorityClassName` field of `podSpec`. The integer value of
|
`priorityClassName` field in the Pod's specification. The integer value for
|
||||||
priority is then resolved and populated to the `priority` field of `podSpec`.
|
priority is then resolved and populated to the `priority` field of `podSpec`.
|
||||||
|
|
||||||
To resolve the problem, `priorityClassName` of the Pods must be changed to use
|
To address the problem, you can change the `priorityClassName` for those Pods
|
||||||
lower priority classes or should be left empty. Empty `priorityClassName` is
|
to use lower priority classes, or leave that field empty. An empty
|
||||||
resolved to zero by default.
|
`priorityClassName` is resolved to zero by default.
|
||||||
|
|
||||||
When a Pod is preempted, there will be events recorded for the preempted Pod.
|
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
|
Preemption should happen only when a cluster does not have enough resources for
|
||||||
@@ -374,29 +354,31 @@ Pod (preemptor) is higher than the victim Pods. Preemption must not happen when
|
|||||||
there is no pending Pod, or when the pending Pods have equal or lower priority
|
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.
|
than the victims. If preemption happens in such scenarios, please file an issue.
|
||||||
|
|
||||||
#### Pods are preempted, but the preemptor is not scheduled
|
### Pods are preempted, but the preemptor is not scheduled
|
||||||
|
|
||||||
When pods are preempted, they receive their requested graceful termination
|
When pods are preempted, they receive their requested graceful termination
|
||||||
period, which is by default 30 seconds, but it can be any different value as
|
period, which is by default 30 seconds. If the victim Pods do not terminate within
|
||||||
specified in the PodSpec. If the victim Pods do not terminate within this period,
|
this period, they are forcibly terminated. Once all the victims go away, the
|
||||||
they are force-terminated. Once all the victims go away, the preemptor Pod can
|
preemptor Pod can be scheduled.
|
||||||
be scheduled.
|
|
||||||
|
|
||||||
While the preemptor Pod is waiting for the victims to go away, a higher priority
|
While the preemptor Pod is waiting for the victims to go away, a higher priority
|
||||||
Pod may be created that fits on the same node. In this case, the scheduler will
|
Pod may be created that fits on the same Node. In this case, the scheduler will
|
||||||
schedule the higher priority Pod instead of the preemptor.
|
schedule the higher priority Pod instead of the preemptor.
|
||||||
|
|
||||||
In the absence of such a higher priority Pod, we expect the preemptor Pod to be
|
This is expected behavior: the Pod with the higher priority should take the place
|
||||||
scheduled after the graceful termination period of the victims is over.
|
of a Pod with a lower priority. Other controller actions, such as
|
||||||
|
[cluster autoscaling](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaling),
|
||||||
|
may eventually provide capacity to schedule the pending Pods.
|
||||||
|
|
||||||
#### Higher priority Pods are preempted before lower priority pods
|
### Higher priority Pods are preempted before lower priority pods
|
||||||
|
|
||||||
The scheduler tries to find nodes that can run a pending Pod and if no node is
|
The scheduler tries to find nodes that can run a pending Pod. If no node is
|
||||||
found, it tries to remove Pods with lower priority from one node to make room
|
found, the scheduler tries to remove Pods with lower priority from an arbitrary
|
||||||
for the pending pod. If a node with low priority Pods is not feasible to run the
|
node in order to make room for the pending pod.
|
||||||
pending Pod, the scheduler may choose another node with higher priority Pods
|
If a node with low priority Pods is not feasible to run the pending Pod, the scheduler
|
||||||
(compared to the Pods on the other node) for preemption. The victims must still
|
may choose another node with higher priority Pods (compared to the Pods on the
|
||||||
have lower priority than the preemptor Pod.
|
other node) for preemption. The victims must still have lower priority than the
|
||||||
|
preemptor Pod.
|
||||||
|
|
||||||
When there are multiple nodes available for preemption, the scheduler tries to
|
When there are multiple nodes available for preemption, the scheduler tries to
|
||||||
choose the node with a set of Pods with lowest priority. However, if such Pods
|
choose the node with a set of Pods with lowest priority. However, if such Pods
|
||||||
@@ -404,13 +386,11 @@ have PodDisruptionBudget that would be violated if they are preempted then the
|
|||||||
scheduler may choose another node with higher priority Pods.
|
scheduler may choose another node with higher priority Pods.
|
||||||
|
|
||||||
When multiple nodes exist for preemption and none of the above scenarios apply,
|
When multiple nodes exist for preemption and none of the above scenarios apply,
|
||||||
we expect the scheduler to choose a node with the lowest priority. If that is
|
the scheduler chooses a node with the lowest priority.
|
||||||
not the case, it may indicate a bug in the scheduler.
|
|
||||||
|
|
||||||
## Interactions of Pod priority and QoS
|
## Interactions between Pod priority and quality of service {#interactions-of-pod-priority-and-qos}
|
||||||
|
|
||||||
Pod priority and
|
Pod priority and {{< glossary_tooltip text="QoS class" term_id="qos-class" >}}
|
||||||
[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
|
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
|
setting the priority of a Pod based on its QoS classes. The scheduler's
|
||||||
preemption logic does not consider QoS when choosing preemption targets.
|
preemption logic does not consider QoS when choosing preemption targets.
|
||||||
@@ -421,15 +401,20 @@ to schedule the preemptor Pod, or if the lowest priority Pods are protected by
|
|||||||
`PodDisruptionBudget`.
|
`PodDisruptionBudget`.
|
||||||
|
|
||||||
The only component that considers both QoS and Pod priority is
|
The only component that considers both QoS and Pod priority is
|
||||||
[Kubelet out-of-resource eviction](/docs/tasks/administer-cluster/out-of-resource/).
|
[kubelet out-of-resource eviction](/docs/tasks/administer-cluster/out-of-resource/).
|
||||||
The kubelet ranks Pods for eviction first by whether or not their usage of the
|
The kubelet ranks Pods for eviction first by whether or not their usage of the
|
||||||
starved resource exceeds requests, then by Priority, and then by the consumption
|
starved resource exceeds requests, then by Priority, and then by the consumption
|
||||||
of the starved compute resource relative to the Pods’ scheduling requests.
|
of the starved compute resource relative to the Pods’ scheduling requests.
|
||||||
See
|
See
|
||||||
[Evicting end-user pods](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)
|
[evicting end-user pods](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)
|
||||||
for more details. Kubelet out-of-resource eviction does not evict Pods whose
|
for more details.
|
||||||
|
|
||||||
|
kubelet out-of-resource eviction does not evict Pods wheir their
|
||||||
usage does not exceed their requests. If a Pod with lower priority is not
|
usage does not exceed their requests. If a Pod with lower priority is not
|
||||||
exceeding its requests, it won't be evicted. Another Pod with higher priority
|
exceeding its requests, it won't be evicted. Another Pod with higher priority
|
||||||
that exceeds its requests may be evicted.
|
that exceeds its requests may be evicted.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
{{% capture whatsnext %}}
|
||||||
|
* Read about using ResourceQuotas in connection with PriorityClasses: [limit Priority Class consumption by default](/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default)
|
||||||
|
{{% /capture %}}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
reviewers:
|
reviewers:
|
||||||
- mikedanese
|
- mikedanese
|
||||||
- thockin
|
- thockin
|
||||||
title: Container Environment Variables
|
title: Container Environment
|
||||||
content_template: templates/concept
|
content_template: templates/concept
|
||||||
weight: 20
|
weight: 20
|
||||||
---
|
---
|
||||||
@@ -116,7 +116,7 @@ Events:
|
|||||||
|
|
||||||
{{% capture whatsnext %}}
|
{{% capture whatsnext %}}
|
||||||
|
|
||||||
* Learn more about the [Container environment](/docs/concepts/containers/container-environment-variables/).
|
* Learn more about the [Container environment](/docs/concepts/containers/container-environment/).
|
||||||
* Get hands-on experience
|
* Get hands-on experience
|
||||||
[attaching handlers to Container lifecycle events](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/).
|
[attaching handlers to Container lifecycle events](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/).
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
reviewers:
|
||||||
|
- erictune
|
||||||
|
- thockin
|
||||||
|
title: Containers overview
|
||||||
|
content_template: templates/concept
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
{{% capture overview %}}
|
||||||
|
|
||||||
|
Containers are a technnology for packaging the (compiled) code for an
|
||||||
|
application along with the dependencies it needs at run time. Each
|
||||||
|
container that you run is repeatable; the standardisation from having
|
||||||
|
dependencies included means that you get the same behavior wherever you
|
||||||
|
run it.
|
||||||
|
|
||||||
|
Containers decouple applications from underlying host infrastructure.
|
||||||
|
This makes deployment easier in different cloud or OS environments.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
|
{{% capture body %}}
|
||||||
|
|
||||||
|
## Container images
|
||||||
|
A [container image](/docs/concepts/containers/images/) is a ready-to-run
|
||||||
|
software package, containing everything needed to run an application:
|
||||||
|
the code and any runtime it requires, application and system libraries,
|
||||||
|
and default values for any essential settings.
|
||||||
|
|
||||||
|
By design, a container is immutable: you cannot change the code of a
|
||||||
|
container that is already running. If you have a containerized application
|
||||||
|
and want to make changes, you need to build a new container that includes
|
||||||
|
the change, then recreate the container to start from the updated image.
|
||||||
|
|
||||||
|
## Container runtimes
|
||||||
|
|
||||||
|
{{< glossary_definition term_id="container-runtime" length="all" >}}
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
{{% capture whatsnext %}}
|
||||||
|
* Read about [container images](/docs/concepts/containers/images/)
|
||||||
|
* Read about [Pods](/docs/concepts/workloads/pods/)
|
||||||
|
{{% /capture %}}
|
||||||
@@ -82,6 +82,9 @@ metadata:
|
|||||||
handler: myconfiguration # The name of the corresponding CRI configuration
|
handler: myconfiguration # The name of the corresponding CRI configuration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The name of a RuntimeClass object must be a valid
|
||||||
|
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
It is recommended that RuntimeClass write operations (create/update/patch/delete) be
|
It is recommended that RuntimeClass write operations (create/update/patch/delete) be
|
||||||
restricted to the cluster administrator. This is typically the default. See [Authorization
|
restricted to the cluster administrator. This is typically the default. See [Authorization
|
||||||
|
|||||||
@@ -5,30 +5,34 @@ reviewers:
|
|||||||
- cheftako
|
- cheftako
|
||||||
- chenopis
|
- chenopis
|
||||||
content_template: templates/concept
|
content_template: templates/concept
|
||||||
weight: 10
|
weight: 20
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
|
|
||||||
The aggregation layer allows Kubernetes to be extended with additional APIs, beyond what is offered by the core Kubernetes APIs.
|
The aggregation layer allows Kubernetes to be extended with additional APIs, beyond what is offered by the core Kubernetes APIs.
|
||||||
|
The additional APIs can either be ready-made solutions such as [service-catalog](/docs/concepts/extend-kubernetes/service-catalog/), or APIs that you develop yourself.
|
||||||
|
|
||||||
|
The aggregation layer is different from [Custom Resources](/docs/concepts/extend-kubernetes/api-extension/custom-resources/), which are a way to make the {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver" >}} recognise new kinds of object.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
## Overview
|
## Aggregation layer
|
||||||
|
|
||||||
The aggregation layer enables installing additional Kubernetes-style APIs in your cluster. These can either be pre-built, existing 3rd party solutions, such as [service-catalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/README.md), or user-created APIs like [apiserver-builder](https://github.com/kubernetes-incubator/apiserver-builder/blob/master/README.md), which can get you started.
|
The aggregation layer runs in-process with the kube-apiserver. Until an extension resource is registered, the aggregation layer will do nothing. To register an API, you add an _APIService_ object, which "claims" the URL path in the Kubernetes API. At that point, the aggregation layer will proxy anything sent to that API path (e.g. `/apis/myextension.mycompany.io/v1/…`) to the registered APIService.
|
||||||
|
|
||||||
The aggregation layer runs in-process with the kube-apiserver. Until an extension resource is registered, the aggregation layer will do nothing. To register an API, users must add an APIService object, which "claims" the URL path in the Kubernetes API. At that point, the aggregation layer will proxy anything sent to that API path (e.g. /apis/myextension.mycompany.io/v1/…) to the registered APIService.
|
The most common way to implement the APIService is to run an *extension API server* in Pod(s) that run in your cluster. If you're using the extension API server to manage resources in your cluster, the extension API server (also written as "extension-apiserver") is typically paired with one or more {{< glossary_tooltip text="controllers" term_id="controller" >}}. The apiserver-builder library provides a skeleton for both extension API servers and the associated controller(s).
|
||||||
|
|
||||||
Ordinarily, the APIService will be implemented by an *extension-apiserver* in a pod running in the cluster. This extension-apiserver will normally need to be paired with one or more controllers if active management of the added resources is needed. As a result, the apiserver-builder will actually provide a skeleton for both. As another example, when the service-catalog is installed, it provides both the extension-apiserver and controller for the services it provides.
|
### Response latency
|
||||||
|
|
||||||
Extension-apiservers should have low latency connections to and from the kube-apiserver.
|
Extension API servers should have low latency networking to and from the kube-apiserver.
|
||||||
In particular, discovery requests are required to round-trip from the kube-apiserver in five seconds or less.
|
Discovery requests are required to round-trip from the kube-apiserver in five seconds or less.
|
||||||
If your deployment cannot achieve this, you should consider how to change it. For now, setting the
|
|
||||||
`EnableAggregatedDiscoveryTimeout=false` feature gate on the kube-apiserver
|
If your extension API server cannot achieve that latency requirement, consider making changes that let you meet it. You can also set the
|
||||||
will disable the timeout restriction. It will be removed in a future release.
|
`EnableAggregatedDiscoveryTimeout=false` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) on the kube-apiserver
|
||||||
|
to disable the timeout restriction. This deprecated feature gate will be removed in a future release.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
@@ -37,7 +41,6 @@ will disable the timeout restriction. It will be removed in a future release.
|
|||||||
* To get the aggregator working in your environment, [configure the aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/).
|
* To get the aggregator working in your environment, [configure the aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/).
|
||||||
* Then, [setup an extension api-server](/docs/tasks/access-kubernetes-api/setup-extension-api-server/) to work with the aggregation layer.
|
* Then, [setup an extension api-server](/docs/tasks/access-kubernetes-api/setup-extension-api-server/) to work with the aggregation layer.
|
||||||
* Also, learn how to [extend the Kubernetes API using Custom Resource Definitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
|
* Also, learn how to [extend the Kubernetes API using Custom Resource Definitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
|
||||||
|
* Read the specification for [APIService](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#apiservice-v1-apiregistration-k8s-io)
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ reviewers:
|
|||||||
- enisoc
|
- enisoc
|
||||||
- deads2k
|
- deads2k
|
||||||
content_template: templates/concept
|
content_template: templates/concept
|
||||||
weight: 20
|
weight: 10
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
@@ -167,7 +167,7 @@ CRDs are easier to create than Aggregated APIs.
|
|||||||
|
|
||||||
| CRDs | Aggregated API |
|
| CRDs | Aggregated API |
|
||||||
| --------------------------- | -------------- |
|
| --------------------------- | -------------- |
|
||||||
| Do not require programming. Users can choose any language for a CRD controller. | Requires programming in Go and building binary and image. Users can choose any language for a CRD controller. |
|
| Do not require programming. Users can choose any language for a CRD controller. | Requires programming in Go and building binary and image. |
|
||||||
| No additional service to run; CRs are handled by API Server. | An additional service to create and that could fail. |
|
| No additional service to run; CRs are handled by API Server. | An additional service to create and that could fail. |
|
||||||
| No ongoing support once the CRD is created. Any bug fixes are picked up as part of normal Kubernetes Master upgrades. | May need to periodically pickup bug fixes from upstream and rebuild and update the Aggregated APIserver. |
|
| No ongoing support once the CRD is created. Any bug fixes are picked up as part of normal Kubernetes Master upgrades. | May need to periodically pickup bug fixes from upstream and rebuild and update the Aggregated APIserver. |
|
||||||
| No need to handle multiple versions of your API. For example: when you control the client for this resource, you can upgrade it in sync with the API. | You need to handle multiple versions of your API, for example: when developing an extension to share with the world. |
|
| No need to handle multiple versions of your API. For example: when you control the client for this resource, you can upgrade it in sync with the API. | You need to handle multiple versions of your API, for example: when developing an extension to share with the world. |
|
||||||
|
|||||||
+55
-61
@@ -1,117 +1,111 @@
|
|||||||
---
|
---
|
||||||
title: Poseidon-Firmament - An alternate scheduler
|
title: Poseidon-Firmament Scheduler
|
||||||
content_template: templates/concept
|
content_template: templates/concept
|
||||||
weight: 80
|
weight: 80
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
|
|
||||||
**Current release of Poseidon-Firmament scheduler is an <code> alpha </code> release.**
|
{{< feature-state for_k8s_version="v1.6" state="alpha" >}}
|
||||||
|
|
||||||
Poseidon-Firmament scheduler is an alternate scheduler that can be deployed alongside the default Kubernetes scheduler.
|
The Poseidon-Firmament scheduler is an alternate scheduler that can be deployed alongside the default Kubernetes scheduler.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
|
|
||||||
## Introduction
|
## 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.
|
Poseidon is a service that acts as the integration glue between the [Firmament scheduler](https://github.com/Huawei-PaaS/firmament) and Kubernetes. Poseidon-Firmament augments the current Kubernetes scheduling capabilities. It incorporates novel flow network graph based scheduling capabilities alongside the default Kubernetes scheduler. The Firmament scheduler models workloads and clusters as flow networks and runs min-cost flow optimizations over these networks to make scheduling decisions.
|
||||||
|
|
||||||
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.
|
Firmament models the scheduling problem as a constraint-based optimization over a flow network graph. This is achieved by reducing scheduling to a min-cost max-flow optimization problem. The Poseidon-Firmament scheduler dynamically refines the workload placements.
|
||||||
|
|
||||||
Poseidon-Firmament scheduler runs alongside the default Kubernetes Scheduler as an alternate scheduler, so multiple schedulers run simultaneously.
|
Poseidon-Firmament scheduler runs alongside the default Kubernetes scheduler as an alternate scheduler. You can simultaneously run multiple, different schedulers.
|
||||||
|
|
||||||
## Key Advantages
|
Flow graph scheduling with the Poseidon-Firmament scheduler provides the following advantages:
|
||||||
|
|
||||||
### Flow graph scheduling based Poseidon-Firmament scheduler provides the following key advantages:
|
- Workloads (Pods) are bulk scheduled to enable scheduling at massive scale.
|
||||||
- Workloads (pods) are bulk scheduled to enable scheduling at massive scale..
|
The Poseidon-Firmament scheduler outperforms the Kubernetes default scheduler by a wide margin when it comes to throughput performance for scenarios where compute resource requirements are somewhat uniform across your workload (Deployments, ReplicaSets, Jobs).
|
||||||
- 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.
|
- The Poseidon-Firmament's scheduler's end-to-end throughput performance and bind time improves as the number of nodes in a cluster increases. As you scale out, Poseidon-Firmament scheduler is able to amortize more and more work across workloads.
|
||||||
- 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.
|
- Scheduling in Poseidon-Firmament is dynamic; it keeps cluster resources in a global optimal state during every scheduling run.
|
||||||
|
- The Poseidon-Firmament scheduler supports scheduling complex rule constraints.
|
||||||
|
|
||||||
- Availability of complex rule constraints.
|
## How the Poseidon-Firmament scheduler works
|
||||||
- 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
|
Kubernetes supports [using multiple schedulers](/docs/tasks/administer-cluster/configure-multiple-schedulers/). You can specify, for a particular Pod, that it is scheduled by a custom scheduler (“poseidon” for this case), by setting the `schedulerName` field in the PodSpec at the time of pod creation. The default scheduler will ignore that Pod and allow Poseidon-Firmament scheduler to schedule the Pod on a relevant node.
|
||||||
|
|
||||||
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.
|
For example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
|
|
||||||
...
|
...
|
||||||
spec:
|
spec:
|
||||||
schedulerName: poseidon
|
schedulerName: poseidon
|
||||||
```
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Batch scheduling
|
||||||
{{< note >}}
|
|
||||||
For details about the design of this project see the [design document](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/design/README.md).
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
## Possible Use Case Scenarios - When to use it
|
|
||||||
|
|
||||||
As mentioned earlier, Poseidon-Firmament scheduler enables an extremely high throughput scheduling environment at scale due to its bulk scheduling approach versus Kubernetes pod-at-a-time approach. In our extensive tests, we have observed substantial throughput benefits as long as resource requirements (CPU/Memory) for incoming Pods are uniform across jobs (Replicasets/Deployments/Jobs), mainly due to efficient amortization of work across jobs.
|
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:
|
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.
|
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).
|
2. Service or batch jobs where workload resource requirements are uniform across jobs (Replicasets/Deployments/Jobs).
|
||||||
|
|
||||||
## Current Project Stage
|
## Feature state
|
||||||
|
|
||||||
- **Alpha Release - Incubation repo.** at https://github.com/kubernetes-sigs/poseidon.
|
Poseidon-Firmament is designed to work with Kubernetes release 1.6 and all subsequent releases.
|
||||||
- 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
|
{{< caution >}}
|
||||||
|
Poseidon-Firmament scheduler does not provide support for high availability; its implementation assumes that the scheduler cannot fail.
|
||||||
|
{{< /caution >}}
|
||||||
|
|
||||||
|
## Feature comparison {#feature-comparison-matrix}
|
||||||
|
|
||||||
|
{{< table caption="Feature comparison of Kubernetes and Poseidon-Firmament schedulers." >}}
|
||||||
|Feature|Kubernetes Default Scheduler|Poseidon-Firmament Scheduler|Notes|
|
|Feature|Kubernetes Default Scheduler|Poseidon-Firmament Scheduler|Notes|
|
||||||
|--- |--- |--- |--- |
|
|--- |--- |--- |--- |
|
||||||
|Node Affinity/Anti-Affinity|Y|Y||
|
|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.|
|
|Pod Affinity/Anti-Affinity - including support for pod anti-affinity symmetry|Y|Y|The default scheduler outperforms the Poseidon-Firmament scheduler pod affinity/anti-affinity functionality.|
|
||||||
|Taints & Tolerations|Y|Y||
|
|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.|
|
|Baseline Scheduling capability in accordance to available compute resources (CPU & Memory) on a node|Y|Y†|**†** Not all Predicates & Priorities are supported with Poseidon-Firmament.|
|
||||||
|Extreme Throughput at scale|Y**|Y|Bulk scheduling approach scales or increases workload placement. 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.|
|
|Extreme Throughput at scale|Y†|Y|**†** Bulk scheduling approach scales or increases workload placement. Firmament scheduler offers high throughput when resource requirements (CPU/Memory) for incoming Pods are uniform across ReplicaSets/Deployments/Jobs.|
|
||||||
|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||
|
||||||
|Colocation Interference Avoidance|N|N**|Planned in Poseidon-Firmament.|
|
|Priority Preemption|Y|N†|**†** Partially exists in Poseidon-Firmament versus extensive support in Kubernetes default scheduler.|
|
||||||
|Priority Pre-emption|Y|N**|Partially exists in Poseidon-Firmament versus extensive support in Kubernetes default scheduler.|
|
|Inherent Rescheduling|N|Y†|**†** Poseidon-Firmament scheduler supports workload re-scheduling. In each scheduling run, Poseidon-Firmament considers all Pods, including running Pods, and as a result can migrate or evict Pods – a globally optimal scheduling environment.|
|
||||||
|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||
|
|Gang Scheduling|N|Y||
|
||||||
|Support for Pre-bound Persistence Volume Scheduling|Y|Y||
|
|Support for Pre-bound Persistence Volume Scheduling|Y|Y||
|
||||||
|Support for Local Volume & Dynamic Persistence Volume Binding Scheduling|Y|N**|Planned.|
|
|Support for Local Volume & Dynamic Persistence Volume Binding Scheduling|Y|N||
|
||||||
|High Availability|Y|N**|Planned.|
|
|High Availability|Y|N||
|
||||||
|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".|
|
|Real-time metrics based scheduling|N|Y†|**†** Partially supported in Poseidon-Firmament using Heapster (now deprecated) for placing Pods using actual cluster utilization statistics rather than reservations.|
|
||||||
|Support for Max-Pod per node|Y|Y|Poseidon-Firmament scheduler seamlessly co-exists with Kubernetes default scheduler.|
|
|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||
|
|Support for Ephemeral Storage, in addition to CPU/Memory|Y|Y||
|
||||||
|
{{< /table >}}
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
## Installation
|
The [Poseidon-Firmament installation guide](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/install/README.md#Installation) explains how to deploy Poseidon-Firmament to your cluster.
|
||||||
|
|
||||||
For in-cluster installation of Poseidon, please start at the [Installation instructions](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/install/README.md).
|
## Performance comparison
|
||||||
|
|
||||||
|
|
||||||
## 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 >}}
|
{{< 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.
|
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 >}}
|
{{< /note >}}
|
||||||
|
|
||||||
|
Pod-by-pod schedulers, such as the Kubernetes default scheduler, process Pods in small batches (typically one at a time). These schedulers have the following crucial drawbacks:
|
||||||
|
|
||||||
|
1. The scheduler commits to a pod placement early and restricts the choices for other pods that wait to be placed.
|
||||||
|
2. There is limited opportunities for amortizing work across pods because they are considered for placement individually.
|
||||||
|
|
||||||
|
These downsides of pod-by-pod schedulers are addressed by batching or bulk scheduling in Poseidon-Firmament scheduler. Processing several pods in a batch allows the scheduler to jointly consider their placement, and thus to find the best trade-off for the whole batch instead of one pod. At the same time it amortizes work across pods resulting in much higher throughput.
|
||||||
|
|
||||||
|
{{% /capture %}}
|
||||||
|
{{% capture whatsnext %}}
|
||||||
|
* See [Poseidon-Firmament](https://github.com/kubernetes-sigs/poseidon#readme) on GitHub for more information.
|
||||||
|
* See the [design document](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/design/README.md) for Poseidon.
|
||||||
|
* Read [Firmament: Fast, Centralized Cluster Scheduling at Scale](https://www.usenix.org/system/files/conference/osdi16/osdi16-gog.pdf), the academic paper on the Firmament scheduling design.
|
||||||
|
* If you'd like to contribute to Poseidon-Firmament, refer to the [developer setup instructions](https://github.com/kubernetes-sigs/poseidon/blob/master/docs/devel/README.md).
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -121,21 +121,22 @@ There are two supported paths to extending the API with [custom resources](/docs
|
|||||||
to make it seamless for clients.
|
to make it seamless for clients.
|
||||||
|
|
||||||
|
|
||||||
## Enabling API groups
|
## Enabling or disabling API groups
|
||||||
|
|
||||||
Certain resources and API groups are enabled by default. They can be enabled or disabled by setting `--runtime-config`
|
Certain resources and API groups are enabled by default. They can be enabled or disabled by setting `--runtime-config`
|
||||||
on apiserver. `--runtime-config` accepts comma separated values. For ex: to disable batch/v1, set
|
on apiserver. `--runtime-config` accepts comma separated values. For example: to disable batch/v1, set
|
||||||
`--runtime-config=batch/v1=false`, to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`.
|
`--runtime-config=batch/v1=false`, to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`.
|
||||||
The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver.
|
The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver.
|
||||||
|
|
||||||
IMPORTANT: Enabling or disabling groups or resources requires restarting apiserver and controller-manager
|
{{< note >}}Enabling or disabling groups or resources requires restarting apiserver and controller-manager
|
||||||
to pick up the `--runtime-config` changes.
|
to pick up the `--runtime-config` changes.{{< /note >}}
|
||||||
|
|
||||||
## Enabling resources in the groups
|
## Enabling specific resources in the extensions/v1beta1 group
|
||||||
|
|
||||||
DaemonSets, Deployments, HorizontalPodAutoscalers, Ingresses, Jobs and ReplicaSets are enabled by default.
|
DaemonSets, Deployments, StatefulSet, NetworkPolicies, PodSecurityPolicies and ReplicaSets in the `extensions/v1beta1` API group are disabled by default.
|
||||||
Other extensions resources can be enabled by setting `--runtime-config` on
|
For example: to enable deployments and daemonsets, set
|
||||||
apiserver. `--runtime-config` accepts comma separated values. For example: to disable deployments and ingress, set
|
`--runtime-config=extensions/v1beta1/deployments=true,extensions/v1beta1/daemonsets=true`.
|
||||||
`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/ingresses=false`
|
|
||||||
|
{{< note >}}Individual resource enablement/disablement is only supported in the `extensions/v1beta1` API group for legacy reasons.{{< /note >}}
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ reviewers:
|
|||||||
- bgrant0607
|
- bgrant0607
|
||||||
- mikedanese
|
- mikedanese
|
||||||
title: What is Kubernetes
|
title: What is Kubernetes
|
||||||
|
description: >
|
||||||
|
Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
|
||||||
content_template: templates/concept
|
content_template: templates/concept
|
||||||
weight: 10
|
weight: 10
|
||||||
card:
|
card:
|
||||||
@@ -17,9 +19,10 @@ This page is an overview of Kubernetes.
|
|||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
|
Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
|
||||||
|
|
||||||
The name Kubernetes originates from Greek, meaning helmsman or pilot. Google open-sourced the Kubernetes project in 2014. Kubernetes builds upon a [decade and a half of experience that Google has with running production workloads at scale](https://ai.google/research/pubs/pub43438), combined with best-of-breed ideas and practices from the community.
|
The name Kubernetes originates from Greek, meaning helmsman or pilot. Google open-sourced the Kubernetes project in 2014. Kubernetes combines [over 15 years of Google's experience](/blog/2015/04/borg-predecessor-to-kubernetes/) running production workloads at scale with best-of-breed ideas and practices from the community.
|
||||||
|
|
||||||
## Going back in time
|
## Going back in time
|
||||||
|
|
||||||
Let's take a look at why Kubernetes is so useful by going back in time.
|
Let's take a look at why Kubernetes is so useful by going back in time.
|
||||||
|
|
||||||

|

|
||||||
@@ -42,13 +45,13 @@ Containers have become popular because they provide extra benefits, such as:
|
|||||||
* Dev and Ops separation of concerns: create application container images at build/release time rather than deployment time, thereby decoupling applications from infrastructure.
|
* Dev and Ops separation of concerns: create application container images at build/release time rather than deployment time, thereby decoupling applications from infrastructure.
|
||||||
* Observability not only surfaces OS-level information and metrics, but also application health and other signals.
|
* Observability not only surfaces OS-level information and metrics, but also application health and other signals.
|
||||||
* Environmental consistency across development, testing, and production: Runs the same on a laptop as it does in the cloud.
|
* Environmental consistency across development, testing, and production: Runs the same on a laptop as it does in the cloud.
|
||||||
* Cloud and OS distribution portability: Runs on Ubuntu, RHEL, CoreOS, on-prem, Google Kubernetes Engine, and anywhere else.
|
* Cloud and OS distribution portability: Runs on Ubuntu, RHEL, CoreOS, on-premises, on major public clouds, and anywhere else.
|
||||||
* Application-centric management: Raises the level of abstraction from running an OS on virtual hardware to running an application on an OS using logical resources.
|
* Application-centric management: Raises the level of abstraction from running an OS on virtual hardware to running an application on an OS using logical resources.
|
||||||
* Loosely coupled, distributed, elastic, liberated micro-services: applications are broken into smaller, independent pieces and can be deployed and managed dynamically – not a monolithic stack running on one big single-purpose machine.
|
* Loosely coupled, distributed, elastic, liberated micro-services: applications are broken into smaller, independent pieces and can be deployed and managed dynamically – not a monolithic stack running on one big single-purpose machine.
|
||||||
* Resource isolation: predictable application performance.
|
* Resource isolation: predictable application performance.
|
||||||
* Resource utilization: high efficiency and density.
|
* Resource utilization: high efficiency and density.
|
||||||
|
|
||||||
## Why you need Kubernetes and what can it do
|
## Why you need Kubernetes and what it can do {#why-you-need-kubernetes-and-what-can-it-do}
|
||||||
|
|
||||||
Containers are a good way to bundle and run your applications. In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime. For example, if a container goes down, another container needs to start. Wouldn't it be easier if this behavior was handled by a system?
|
Containers are a good way to bundle and run your applications. In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime. For example, if a container goes down, another container needs to start. Wouldn't it be easier if this behavior was handled by a system?
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: nginx:1.7.9
|
image: nginx:1.14.2
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,27 @@ To work with Kubernetes objects--whether to create, modify, or delete them--you'
|
|||||||
|
|
||||||
### Object Spec and Status
|
### Object Spec and Status
|
||||||
|
|
||||||
Every Kubernetes object includes two nested object fields that govern the object's configuration: the object *spec* and the object *status*. The *spec*, which you must provide, describes your desired state for the object--the characteristics that you want the object to have. The *status* describes the *actual state* of the object, and is supplied and updated by the Kubernetes system. At any given time, the Kubernetes Control Plane actively manages an object's actual state to match the desired state you supplied.
|
Almost every Kubernetes object includes two nested object fields that govern
|
||||||
|
the object's configuration: the object *`spec`* and the object *`status`*.
|
||||||
|
For objects that have a `spec`, you have to set this when you create the object,
|
||||||
|
providing a description of the characteristics you want the resource to have:
|
||||||
|
its _desired state_.
|
||||||
|
|
||||||
|
The `status` describes the _current state_ of the object, supplied and updated
|
||||||
|
by the Kubernetes and its components. The Kubernetes
|
||||||
|
{{< glossary_tooltip text="control plane" term_id="control-plane" >}} continually
|
||||||
|
and actively manages every object's actual state to match the desired state you
|
||||||
|
supplied.
|
||||||
|
|
||||||
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 example: in Kubernetes, a 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/sig-architecture/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).
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: nginx:1.7.9
|
image: nginx:1.14.2
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: nginx:1.7.9
|
image: nginx:1.14.2
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 80
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -9,55 +9,58 @@ weight: 10
|
|||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
|
|
||||||
By default, containers run with unbounded [compute resources](/docs/user-guide/compute-resources) on a Kubernetes cluster.
|
By default, containers run with unbounded [compute resources](/docs/user-guide/compute-resources) on a Kubernetes cluster.
|
||||||
With Resource quotas, cluster administrators can restrict the resource consumption and creation on a namespace basis.
|
With resource quotas, cluster administrators can restrict resource consumption and creation on a namespace basis.
|
||||||
Within a namespace, a Pod or Container can consume as much CPU and memory as defined by the namespace's resource quota. There is a concern that one Pod or Container could monopolize all of the resources. Limit Range is a policy to constrain resource by Pod or Container in a namespace.
|
Within a namespace, a Pod or Container can consume as much CPU and memory as defined by the namespace's resource quota. There is a concern that one Pod or Container could monopolize all available resources. A LimitRange is a policy to constrain resource allocations (to Pods or Containers) in a namespace.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
A limit range, defined by a `LimitRange` object, provides constraints that can:
|
A _LimitRange_ provides constraints that can:
|
||||||
|
|
||||||
- Enforce minimum and maximum compute resources usage per Pod or Container in a namespace.
|
- Enforce minimum and maximum compute resources usage per Pod or Container in a namespace.
|
||||||
- Enforce minimum and maximum storage request per PersistentVolumeClaim in a namespace.
|
- Enforce minimum and maximum storage request per PersistentVolumeClaim in a namespace.
|
||||||
- Enforce a ratio between request and limit for a resource in a namespace.
|
- Enforce a ratio between request and limit for a resource in a namespace.
|
||||||
- Set default request/limit for compute resources in a namespace and automatically inject them to Containers at runtime.
|
- Set default request/limit for compute resources in a namespace and automatically inject them to Containers at runtime.
|
||||||
|
|
||||||
## Enabling Limit Range
|
## Enabling LimitRange
|
||||||
|
|
||||||
Limit Range support is enabled by default for many Kubernetes distributions. It is
|
LimitRange support is enabled by default for many Kubernetes distributions. It is
|
||||||
enabled when the apiserver `--enable-admission-plugins=` flag has `LimitRanger` admission controller as
|
enabled when the apiserver `--enable-admission-plugins=` flag has `LimitRanger` admission controller as
|
||||||
one of its arguments.
|
one of its arguments.
|
||||||
|
|
||||||
A limit range is enforced in a particular namespace when there is a
|
A LimitRange is enforced in a particular namespace when there is a
|
||||||
`LimitRange` object in that namespace.
|
LimitRange object in that namespace.
|
||||||
|
|
||||||
|
The name of a LimitRange object must be a valid
|
||||||
|
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||||
|
|
||||||
### Overview of Limit Range
|
### Overview of Limit Range
|
||||||
|
|
||||||
- The administrator creates one `LimitRange` in one namespace.
|
- The administrator creates one `LimitRange` in one namespace.
|
||||||
- Users create resources like Pods, Containers, and PersistentVolumeClaims in the namespace.
|
- Users create resources like Pods, Containers, and PersistentVolumeClaims in the namespace.
|
||||||
- The `LimitRanger` admission controller enforces defaults limits for all Pods and Container that do not set compute resource requirements and tracks usage to ensure it does not exceed resource minimum , maximum and ratio defined in any `LimitRange` present in the namespace.
|
- The `LimitRanger` admission controller enforces defaults and limits for all Pods and Containers that do not set compute resource requirements and tracks usage to ensure it does not exceed resource minimum, maximum and ratio defined in any LimitRange present in the namespace.
|
||||||
- If creating or updating a resource (Pod, Container, PersistentVolumeClaim) violates a limit range constraint, the request to the API server will fail with HTTP status code `403 FORBIDDEN` and a message explaining the constraint that would have been violated.
|
- If creating or updating a resource (Pod, Container, PersistentVolumeClaim) that violates a LimitRange constraint, the request to the API server will fail with an HTTP status code `403 FORBIDDEN` and a message explaining the constraint that have been violated.
|
||||||
- If limit range is activated in a namespace for compute resources like `cpu` and `memory`, users must specify
|
- If a LimitRange is activated in a namespace for compute resources like `cpu` and `memory`, users must specify
|
||||||
requests or limits for those values; otherwise, the system may reject pod creation.
|
requests or limits for those values. Otherwise, the system may reject Pod creation.
|
||||||
- LimitRange validations occurs only at Pod Admission stage, not on Running pods.
|
- LimitRange validations occurs only at Pod Admission stage, not on Running Pods.
|
||||||
|
|
||||||
Examples of policies that could be created using limit range are:
|
Examples of policies that could be created using limit range are:
|
||||||
|
|
||||||
- In a 2 node cluster with a capacity of 8 GiB RAM, and 16 cores, constrain Pods in a namespace to request 100m and not exceeds 500m for CPU , request 200Mi and not exceed 600Mi
|
- In a 2 node cluster with a capacity of 8 GiB RAM and 16 cores, constrain Pods in a namespace to request 100m of CPU with a max limit of 500m for CPU and request 200Mi for Memory with a max limit of 600Mi for Memory.
|
||||||
- Define default CPU limits and request to 150m and Memory default request to 300Mi for containers started with no cpu and memory requests in their spec.
|
- Define default CPU limit and request to 150m and memory default request to 300Mi for Containers started with no cpu and memory requests in their specs.
|
||||||
|
|
||||||
In the case where the total limits of the namespace is less than the sum of the limits of the Pods/Containers,
|
In the case where the total limits of the namespace is less than the sum of the limits of the Pods/Containers,
|
||||||
there may be contention for resources; The Containers or Pods will not be created.
|
there may be contention for resources. In this case, the Containers or Pods will not be created.
|
||||||
|
|
||||||
Neither contention nor changes to limitrange will affect already created resources.
|
Neither contention nor changes to a LimitRange will affect already created resources.
|
||||||
|
|
||||||
## Limiting Container compute resources
|
## Limiting Container compute resources
|
||||||
|
|
||||||
The following section discusses the creation of a LimitRange acting at Container Level.
|
The following section discusses the creation of a LimitRange acting at Container Level.
|
||||||
A Pod with 04 containers is first created; each container within the Pod has a specific `spec.resource` configuration
|
A Pod with 04 Containers is first created. Each Container within the Pod has a specific `spec.resource` configuration.
|
||||||
each container within the pod is handled differently by the LimitRanger admission controller.
|
Each Container within the Pod is handled differently by the `LimitRanger` admission controller.
|
||||||
|
|
||||||
Create a namespace `limitrange-demo` using the following kubectl command:
|
Create a namespace `limitrange-demo` using the following kubectl command:
|
||||||
|
|
||||||
@@ -74,9 +77,7 @@ kubectl config set-context --current --namespace=limitrange-demo
|
|||||||
Here is the configuration file for a LimitRange object:
|
Here is the configuration file for a LimitRange object:
|
||||||
{{< codenew file="admin/resource/limit-mem-cpu-container.yaml" >}}
|
{{< codenew file="admin/resource/limit-mem-cpu-container.yaml" >}}
|
||||||
|
|
||||||
This object defines minimum and maximum Memory/CPU limits, default cpu/Memory requests and default limits for CPU/Memory resources to be apply to containers.
|
This object defines minimum and maximum CPU/Memory limits, default CPU/Memory requests, and default limits for CPU/Memory resources to be apply to containers.
|
||||||
The name of a LimitRange object must be a valid
|
|
||||||
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
|
||||||
|
|
||||||
Create the `limit-mem-cpu-per-container` LimitRange in the `limitrange-demo` namespace with the following kubectl command:
|
Create the `limit-mem-cpu-per-container` LimitRange in the `limitrange-demo` namespace with the following kubectl command:
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ Container cpu 100m 800m 110m 700m -
|
|||||||
Container memory 99Mi 1Gi 111Mi 900Mi -
|
Container memory 99Mi 1Gi 111Mi 900Mi -
|
||||||
```
|
```
|
||||||
|
|
||||||
Here is the configuration file for a Pod with 04 containers to demonstrate LimitRange features :
|
Here is the configuration file for a Pod with 04 Containers to demonstrate LimitRange features:
|
||||||
{{< codenew file="admin/resource/limit-range-pod-1.yaml" >}}
|
{{< codenew file="admin/resource/limit-range-pod-1.yaml" >}}
|
||||||
|
|
||||||
Create the `busybox1` Pod:
|
Create the `busybox1` Pod:
|
||||||
@@ -126,9 +127,9 @@ kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[0].res
|
|||||||
```
|
```
|
||||||
|
|
||||||
- The `busybox-cnt01` Container inside `busybox` Pod defined `requests.cpu=100m` and `requests.memory=100Mi`.
|
- The `busybox-cnt01` Container inside `busybox` Pod defined `requests.cpu=100m` and `requests.memory=100Mi`.
|
||||||
- `100m <= 500m <= 800m` , The container cpu limit (500m) falls inside the authorized CPU limit range.
|
- `100m <= 500m <= 800m` , The Container cpu limit (500m) falls inside the authorized CPU LimitRange.
|
||||||
- `99Mi <= 200Mi <= 1Gi` , The container memory limit (200Mi) falls inside the authorized Memory limit range.
|
- `99Mi <= 200Mi <= 1Gi` , The Container memory limit (200Mi) falls inside the authorized Memory LimitRange.
|
||||||
- No request/limits ratio validation for CPU/Memory , thus the container is valid and created.
|
- No request/limits ratio validation for CPU/Memory, so the Container is valid and created.
|
||||||
|
|
||||||
|
|
||||||
### Container spec with a valid CPU/Memory requests but no limits
|
### Container spec with a valid CPU/Memory requests but no limits
|
||||||
@@ -152,14 +153,15 @@ kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[1].res
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
- The `busybox-cnt02` Container inside `busybox1` Pod defined `requests.cpu=100m` and `requests.memory=100Mi` but not limits for cpu and memory.
|
- The `busybox-cnt02` Container inside `busybox1` Pod defined `requests.cpu=100m` and `requests.memory=100Mi` but not limits for cpu and memory.
|
||||||
- The container do not have a limits section, the default limits defined in the limit-mem-cpu-per-container LimitRange object are injected to this container `limits.cpu=700mi` and `limits.memory=900Mi`.
|
- The Container does not have a limits section. The default limits defined in the `limit-mem-cpu-per-container` LimitRange object are injected in to this Container: `limits.cpu=700mi` and `limits.memory=900Mi`.
|
||||||
- `100m <= 700m <= 800m` , The container cpu limit (700m) falls inside the authorized CPU limit range.
|
- `100m <= 700m <= 800m` , The Container cpu limit (700m) falls inside the authorized CPU limit range.
|
||||||
- `99Mi <= 900Mi <= 1Gi` , The container memory limit (900Mi) falls inside the authorized Memory limit range.
|
- `99Mi <= 900Mi <= 1Gi` , The Container memory limit (900Mi) falls inside the authorized Memory limit range.
|
||||||
- No request/limits ratio set , thus the container is valid and created.
|
- No request/limits ratio set, so the Container is valid and created.
|
||||||
|
|
||||||
|
|
||||||
### Container spec with a valid CPU/Memory limits but no requests
|
### Container spec with a valid CPU/Memory limits but no requests
|
||||||
View the `busybox-cnt03` resource configuration
|
|
||||||
|
View the `busybox-cnt03` resource configuration:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[2].resources"
|
kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[2].resources"
|
||||||
@@ -178,10 +180,10 @@ kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[2].res
|
|||||||
```
|
```
|
||||||
|
|
||||||
- The `busybox-cnt03` Container inside `busybox1` Pod defined `limits.cpu=500m` and `limits.memory=200Mi` but no `requests` for cpu and memory.
|
- The `busybox-cnt03` Container inside `busybox1` Pod defined `limits.cpu=500m` and `limits.memory=200Mi` but no `requests` for cpu and memory.
|
||||||
- The container do not define a request section, the defaultRequest defined in the limit-mem-cpu-per-container LimitRange is not used to fill its limits section but the limits defined by the container are set as requests `limits.cpu=500m` and `limits.memory=200Mi`.
|
- The Container does not define a request section. The default request defined in the limit-mem-cpu-per-container LimitRange is not used to fill its limits section, but the limits defined by the Container are set as requests `limits.cpu=500m` and `limits.memory=200Mi`.
|
||||||
- `100m <= 500m <= 800m` , The container cpu limit (500m) falls inside the authorized CPU limit range.
|
- `100m <= 500m <= 800m` , The Container cpu limit (500m) falls inside the authorized CPU limit range.
|
||||||
- `99Mi <= 200Mi <= 1Gi` , The container memory limit (200Mi) falls inside the authorized Memory limit range.
|
- `99Mi <= 200Mi <= 1Gi` , The Container memory limit (200Mi) falls inside the authorized Memory limit range.
|
||||||
- No request/limits ratio set , thus the container is valid and created.
|
- No request/limits ratio set, so the Container is valid and created.
|
||||||
|
|
||||||
### Container spec with no CPU/Memory requests/limits
|
### Container spec with no CPU/Memory requests/limits
|
||||||
|
|
||||||
@@ -205,27 +207,27 @@ kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[3].res
|
|||||||
```
|
```
|
||||||
|
|
||||||
- The `busybox-cnt04` Container inside `busybox1` define neither `limits` nor `requests`.
|
- The `busybox-cnt04` Container inside `busybox1` define neither `limits` nor `requests`.
|
||||||
- The container do not define a limit section, the default limit defined in the limit-mem-cpu-per-container LimitRange is used to fill its request
|
- The Container do not define a limit section, the default limit defined in the limit-mem-cpu-per-container LimitRange is used to fill its request
|
||||||
`limits.cpu=700m and` `limits.memory=900Mi` .
|
`limits.cpu=700m and` `limits.memory=900Mi` .
|
||||||
- The container do not define a request section, the defaultRequest defined in the limit-mem-cpu-per-container LimitRange is used to fill its request section requests.cpu=110m and requests.memory=111Mi
|
- The Container do not define a request section, the defaultRequest defined in the `limit-mem-cpu-per-container` LimitRange is used to fill its request section requests.cpu=110m and requests.memory=111Mi
|
||||||
- `100m <= 700m <= 800m` , The container cpu limit (700m) falls inside the authorized CPU limit range.
|
- `100m <= 700m <= 800m` , The Container cpu limit (700m) falls inside the authorized CPU limit range.
|
||||||
- `99Mi <= 900Mi <= 1Gi` , The container memory limit (900Mi) falls inside the authorized Memory limitrange .
|
- `99Mi <= 900Mi <= 1Gi` , The Container memory limit (900Mi) falls inside the authorized Memory limit range .
|
||||||
- No request/limits ratio set , thus the container is valid and created.
|
- No request/limits ratio set, so the Container is valid and created.
|
||||||
|
|
||||||
All containers defined in the `busybox` Pod passed LimitRange validations, this the Pod is valid and create in the namespace.
|
All Containers defined in the `busybox` Pod passed LimitRange validations, so this the Pod is valid and created in the namespace.
|
||||||
|
|
||||||
## Limiting Pod compute resources
|
## Limiting Pod compute resources
|
||||||
|
|
||||||
The following section discusses how to constrain resources at Pod level.
|
The following section discusses how to constrain resources at the Pod level.
|
||||||
|
|
||||||
{{< codenew file="admin/resource/limit-mem-cpu-pod.yaml" >}}
|
{{< codenew file="admin/resource/limit-mem-cpu-pod.yaml" >}}
|
||||||
|
|
||||||
Without having to delete `busybox1` Pod, create the `limit-mem-cpu-pod` LimitRange in the `limitrange-demo` namespace:
|
Without having to delete the `busybox1` Pod, create the `limit-mem-cpu-pod` LimitRange in the `limitrange-demo` namespace:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/examples/admin/resource/limit-mem-cpu-pod.yaml -n limitrange-demo
|
kubectl apply -f https://k8s.io/examples/admin/resource/limit-mem-cpu-pod.yaml -n limitrange-demo
|
||||||
```
|
```
|
||||||
The limitrange is created and limits CPU to 2 Core and Memory to 2Gi per Pod:
|
The LimitRange is created and limits CPU to 2 Core and Memory to 2Gi per Pod:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
limitrange/limit-mem-cpu-per-pod created
|
limitrange/limit-mem-cpu-per-pod created
|
||||||
@@ -254,7 +256,7 @@ Now create the `busybox2` Pod:
|
|||||||
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-2.yaml -n limitrange-demo
|
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-2.yaml -n limitrange-demo
|
||||||
```
|
```
|
||||||
|
|
||||||
The `busybox2` Pod definition is identical to `busybox1` but an error is reported since Pod's resources are now limited:
|
The `busybox2` Pod definition is identical to `busybox1`, but an error is reported since the Pod's resources are now limited:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]
|
Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]
|
||||||
@@ -268,12 +270,12 @@ kubectl get po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[].reso
|
|||||||
"900Mi"
|
"900Mi"
|
||||||
```
|
```
|
||||||
|
|
||||||
`busybox2` Pod will not be admitted on the cluster since the total memory limit of its container is greater than the limit defined in the LimitRange.
|
`busybox2` Pod will not be admitted on the cluster since the total memory limit of its Container is greater than the limit defined in the LimitRange.
|
||||||
`busybox1` will not be evicted since it was created and admitted on the cluster before the LimitRange creation.
|
`busybox1` will not be evicted since it was created and admitted on the cluster before the LimitRange creation.
|
||||||
|
|
||||||
## Limiting Storage resources
|
## Limiting Storage resources
|
||||||
|
|
||||||
You can enforce minimum and maximum size of [storage resources](/docs/concepts/storage/persistent-volumes/) that can be requested by each PersistentVolumeClaim in a namespace using a LimitRange:
|
You can enforce minimum and maximum size of [storage resources](/docs/concepts/storage/persistent-volumes/) that can be requested by each PersistentVolumeClaim in a namespace using a LimitRange:
|
||||||
|
|
||||||
{{< codenew file="admin/resource/storagelimits.yaml" >}}
|
{{< codenew file="admin/resource/storagelimits.yaml" >}}
|
||||||
|
|
||||||
@@ -329,9 +331,9 @@ Error from server (Forbidden): error when creating "pvc-limit-greater.yaml": per
|
|||||||
|
|
||||||
## Limits/Requests Ratio
|
## Limits/Requests Ratio
|
||||||
|
|
||||||
If `LimitRangeItem.maxLimitRequestRatio` is specified in the `LimitRangeSpec`, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value
|
If `LimitRangeItem.maxLimitRequestRatio` is specified in the `LimitRangeSpec`, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value.
|
||||||
|
|
||||||
The following `LimitRange` enforces memory limit to be at most twice the amount of the memory request for any pod in the namespace.
|
The following LimitRange enforces memory limit to be at most twice the amount of the memory request for any Pod in the namespace:
|
||||||
|
|
||||||
{{< codenew file="admin/resource/limit-memory-ratio-pod.yaml" >}}
|
{{< codenew file="admin/resource/limit-memory-ratio-pod.yaml" >}}
|
||||||
|
|
||||||
@@ -353,7 +355,7 @@ Type Resource Min Max Default Request Default Limit Max Limit/Reques
|
|||||||
Pod memory - - - - 2
|
Pod memory - - - - 2
|
||||||
```
|
```
|
||||||
|
|
||||||
Let's create a pod with `requests.memory=100Mi` and `limits.memory=300Mi`:
|
Create a pod with `requests.memory=100Mi` and `limits.memory=300Mi`:
|
||||||
|
|
||||||
{{< codenew file="admin/resource/limit-range-pod-3.yaml" >}}
|
{{< codenew file="admin/resource/limit-range-pod-3.yaml" >}}
|
||||||
|
|
||||||
@@ -361,9 +363,9 @@ Let's create a pod with `requests.memory=100Mi` and `limits.memory=300Mi`:
|
|||||||
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-3.yaml
|
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-3.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The pod creation failed as the ratio here (`3`) is greater than the enforced limit (`2`) in `limit-memory-ratio-pod` LimitRange
|
The pod creation failed as the ratio here (`3`) is greater than the enforced limit (`2`) in `limit-memory-ratio-pod` LimitRange:
|
||||||
|
|
||||||
```shell
|
```
|
||||||
Error from server (Forbidden): error when creating "limit-range-pod-3.yaml": pods "busybox3" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 3.000000.
|
Error from server (Forbidden): error when creating "limit-range-pod-3.yaml": pods "busybox3" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 3.000000.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,8 @@ alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n
|
|||||||
|
|
||||||
Define the example PodSecurityPolicy object in a file. This is a policy that
|
Define the example PodSecurityPolicy object in a file. This is a policy that
|
||||||
simply prevents the creation of privileged pods.
|
simply prevents the creation of privileged pods.
|
||||||
|
The name of a PodSecurityPolicy object must be a valid
|
||||||
|
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||||
|
|
||||||
{{< codenew file="policy/example-psp.yaml" >}}
|
{{< codenew file="policy/example-psp.yaml" >}}
|
||||||
|
|
||||||
@@ -419,8 +421,10 @@ The **recommended minimum set** of allowed volumes for new PSPs are:
|
|||||||
- projected
|
- projected
|
||||||
|
|
||||||
{{< warning >}}
|
{{< warning >}}
|
||||||
PodSecurityPolicy does not limit the types of `PersistentVolume` objects that may be referenced by a `PersistentVolumeClaim`.
|
PodSecurityPolicy does not limit the types of `PersistentVolume` objects that
|
||||||
Only trusted users should be granted permission to create `PersistentVolume` objects.
|
may be referenced by a `PersistentVolumeClaim`, and hostPath type
|
||||||
|
`PersistentVolumes` do not support read-only access mode. Only trusted users
|
||||||
|
should be granted permission to create `PersistentVolume` objects.
|
||||||
{{< /warning >}}
|
{{< /warning >}}
|
||||||
|
|
||||||
**FSGroup** - Controls the supplemental group applied to some volumes.
|
**FSGroup** - Controls the supplemental group applied to some volumes.
|
||||||
|
|||||||
@@ -422,10 +422,8 @@ LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.el
|
|||||||
|
|
||||||
{{% capture whatsnext %}}
|
{{% capture whatsnext %}}
|
||||||
|
|
||||||
Kubernetes also supports Federated Services, which can span multiple
|
* Learn more about [Using a Service to Access an Application in a Cluster](/docs/tasks/access-application-cluster/service-access-application-cluster/)
|
||||||
clusters and cloud providers, to provide increased availability,
|
* Learn more about [Connecting a Front End to a Back End Using a Service](/docs/tasks/access-application-cluster/connecting-frontend-backend/)
|
||||||
better fault tolerance and greater scalability for your services. See
|
* Learn more about [Creating an External Load Balancer](/docs/tasks/access-application-cluster/create-external-load-balancer/)
|
||||||
the [Federated Services User Guide](/docs/concepts/cluster-administration/federation-service-discovery/)
|
|
||||||
for further information.
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ Traffic routing is controlled by rules defined on the Ingress resource.
|
|||||||
[ Services ]
|
[ Services ]
|
||||||
```
|
```
|
||||||
|
|
||||||
An Ingress can be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name based virtual hosting. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers) is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.
|
An Ingress may be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name based virtual hosting. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers) is responsible for fulfilling the Ingress, usually with a load balancer, 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
|
uses a service of type [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) or
|
||||||
|
|||||||
@@ -1189,19 +1189,6 @@ SCTP is not supported on Windows based nodes.
|
|||||||
The kube-proxy does not support the management of SCTP associations when it is in userspace mode.
|
The kube-proxy does not support the management of SCTP associations when it is in userspace mode.
|
||||||
{{< /warning >}}
|
{{< /warning >}}
|
||||||
|
|
||||||
## Future work
|
|
||||||
|
|
||||||
In the future, the proxy policy for Services can become more nuanced than
|
|
||||||
simple round-robin balancing, for example master-elected or sharded. We also
|
|
||||||
envision that some Services will have "real" load balancers, in which case the
|
|
||||||
virtual IP address will simply transport the packets there.
|
|
||||||
|
|
||||||
The Kubernetes project intends to improve support for L7 (HTTP) Services.
|
|
||||||
|
|
||||||
The Kubernetes project intends to have more flexible ingress modes for Services
|
|
||||||
that encompass the current ClusterIP, NodePort, and LoadBalancer modes and more.
|
|
||||||
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture whatsnext %}}
|
{{% capture whatsnext %}}
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ To enable dynamic provisioning, a cluster administrator needs to pre-create
|
|||||||
one or more StorageClass objects for users.
|
one or more StorageClass objects for users.
|
||||||
StorageClass objects define which provisioner should be used and what parameters
|
StorageClass objects define which provisioner should be used and what parameters
|
||||||
should be passed to that provisioner when dynamic provisioning is invoked.
|
should be passed to that provisioner when dynamic provisioning is invoked.
|
||||||
|
The name of a StorageClass object must be a valid
|
||||||
|
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||||
|
|
||||||
The following manifest creates a storage class "slow" which provisions standard
|
The following manifest creates a storage class "slow" which provisions standard
|
||||||
disk-like persistent disks.
|
disk-like persistent disks.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ reviewers:
|
|||||||
- saad-ali
|
- saad-ali
|
||||||
- thockin
|
- thockin
|
||||||
- msau42
|
- msau42
|
||||||
|
- xing-yang
|
||||||
title: Persistent Volumes
|
title: Persistent Volumes
|
||||||
feature:
|
feature:
|
||||||
title: Storage orchestration
|
title: Storage orchestration
|
||||||
@@ -672,7 +673,7 @@ Only statically provisioned volumes are supported for alpha release. Administrat
|
|||||||
|
|
||||||
## Volume Snapshot and Restore Volume from Snapshot Support
|
## Volume Snapshot and Restore Volume from Snapshot Support
|
||||||
|
|
||||||
{{< feature-state for_k8s_version="v1.12" state="alpha" >}}
|
{{< feature-state for_k8s_version="v1.17" state="beta" >}}
|
||||||
|
|
||||||
Volume snapshot feature was added to support CSI Volume Plugins only. For details, see [volume snapshots](/docs/concepts/storage/volume-snapshots/).
|
Volume snapshot feature was added to support CSI Volume Plugins only. For details, see [volume snapshots](/docs/concepts/storage/volume-snapshots/).
|
||||||
|
|
||||||
@@ -747,5 +748,17 @@ and need persistent storage, it is recommended that you use the following patter
|
|||||||
dynamic storage support (in which case the user should create a matching PV)
|
dynamic storage support (in which case the user should create a matching PV)
|
||||||
or the cluster has no storage system (in which case the user cannot deploy
|
or the cluster has no storage system (in which case the user cannot deploy
|
||||||
config requiring PVCs).
|
config requiring PVCs).
|
||||||
|
{{% /capture %}}
|
||||||
|
{{% capture whatsnext %}}
|
||||||
|
|
||||||
|
* Learn more about [Creating a Persistent Volume](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume).
|
||||||
|
* Learn more about [Creating a Persistent Volume Claim](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolumeclaim).
|
||||||
|
* Read the [Persistent Storage design document](https://git.k8s.io/community/contributors/design-proposals/storage/persistent-storage.md).
|
||||||
|
|
||||||
|
### Reference
|
||||||
|
|
||||||
|
* [PersistentVolume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolume-v1-core)
|
||||||
|
* [PersistentVolumeSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumespec-v1-core)
|
||||||
|
* [PersistentVolumeClaim](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaim-v1-core)
|
||||||
|
* [PersistentVolumeClaimSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaimspec-v1-core)
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -605,6 +605,38 @@ spec:
|
|||||||
type: Directory
|
type: Directory
|
||||||
```
|
```
|
||||||
|
|
||||||
|
{{< caution >}}
|
||||||
|
It should be noted that the `FileOrCreate` mode does not create the parent directory of the file. If the parent directory of the mounted file does not exist, the pod fails to start. To ensure that this mode works, you can try to mount directories and files separately, as shown below.
|
||||||
|
{{< /caution >}}
|
||||||
|
|
||||||
|
#### Example Pod FileOrCreate
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: test-webserver
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: test-webserver
|
||||||
|
image: k8s.gcr.io/test-webserver:latest
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /var/local/aaa
|
||||||
|
name: mydir
|
||||||
|
- mountPath: /var/local/aaa/1.txt
|
||||||
|
name: myfile
|
||||||
|
volumes:
|
||||||
|
- name: mydir
|
||||||
|
hostPath:
|
||||||
|
# Ensure the file directory is created.
|
||||||
|
path: /var/local/aaa
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
- name: myfile
|
||||||
|
hostPath:
|
||||||
|
path: /var/local/aaa/1.txt
|
||||||
|
type: FileOrCreate
|
||||||
|
```
|
||||||
|
|
||||||
### iscsi {#iscsi}
|
### iscsi {#iscsi}
|
||||||
|
|
||||||
An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted
|
An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ In this example:
|
|||||||
* The Pods are labeled `app: nginx`using the `labels` field.
|
* The Pods are labeled `app: nginx`using the `labels` field.
|
||||||
* The Pod template's specification, or `.template.spec` field, indicates that
|
* The Pod template's specification, or `.template.spec` field, indicates that
|
||||||
the Pods run one container, `nginx`, which runs the `nginx`
|
the Pods run one container, `nginx`, which runs the `nginx`
|
||||||
[Docker Hub](https://hub.docker.com/) image at version 1.7.9.
|
[Docker Hub](https://hub.docker.com/) image at version 1.14.2.
|
||||||
* Create one container and name it `nginx` using the `name` field.
|
* Create one container and name it `nginx` using the `name` field.
|
||||||
|
|
||||||
Follow the steps given below to create the above Deployment:
|
Follow the steps given below to create the above Deployment:
|
||||||
@@ -153,15 +153,15 @@ is changed, for example if the labels or container images of the template are up
|
|||||||
|
|
||||||
Follow the steps given below to update your Deployment:
|
Follow the steps given below to update your Deployment:
|
||||||
|
|
||||||
1. Let's update the nginx Pods to use the `nginx:1.9.1` image instead of the `nginx:1.7.9` image.
|
1. Let's update the nginx Pods to use the `nginx:1.16.1` image instead of the `nginx:1.14.2` image.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
|
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
|
||||||
```
|
```
|
||||||
or simply use the following command:
|
or simply use the following command:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record
|
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record
|
||||||
```
|
```
|
||||||
|
|
||||||
The output is similar to this:
|
The output is similar to this:
|
||||||
@@ -169,7 +169,7 @@ Follow the steps given below to update your Deployment:
|
|||||||
deployment.apps/nginx-deployment image updated
|
deployment.apps/nginx-deployment 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`:
|
Alternatively, you can `edit` the Deployment and change `.spec.template.spec.containers[0].image` from `nginx:1.14.2` to `nginx:1.16.1`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl edit deployment.v1.apps/nginx-deployment
|
kubectl edit deployment.v1.apps/nginx-deployment
|
||||||
@@ -265,7 +265,7 @@ up to 3 replicas, as well as scaling down the old ReplicaSet to 0 replicas.
|
|||||||
Labels: app=nginx
|
Labels: app=nginx
|
||||||
Containers:
|
Containers:
|
||||||
nginx:
|
nginx:
|
||||||
Image: nginx:1.9.1
|
Image: nginx:1.16.1
|
||||||
Port: 80/TCP
|
Port: 80/TCP
|
||||||
Environment: <none>
|
Environment: <none>
|
||||||
Mounts: <none>
|
Mounts: <none>
|
||||||
@@ -306,11 +306,11 @@ If you update a Deployment while an existing rollout is in progress, the Deploym
|
|||||||
as per the update and start scaling that up, and rolls over the ReplicaSet that it was scaling up previously
|
as per the update and start scaling that up, and rolls over the ReplicaSet that it was scaling up previously
|
||||||
-- it will add it to its list of old ReplicaSets and start scaling it down.
|
-- it will add it to its list of old ReplicaSets and start scaling it down.
|
||||||
|
|
||||||
For example, suppose you create a Deployment to create 5 replicas of `nginx:1.7.9`,
|
For example, suppose you create a Deployment to create 5 replicas of `nginx:1.14.2`,
|
||||||
but then update the Deployment to create 5 replicas of `nginx:1.9.1`, when only 3
|
but then update the Deployment to create 5 replicas of `nginx:1.16.1`, when only 3
|
||||||
replicas of `nginx:1.7.9` had been created. In that case, the Deployment immediately starts
|
replicas of `nginx:1.14.2` had been created. In that case, the Deployment immediately starts
|
||||||
killing the 3 `nginx:1.7.9` Pods that it had created, and starts creating
|
killing the 3 `nginx:1.14.2` Pods that it had created, and starts creating
|
||||||
`nginx:1.9.1` Pods. It does not wait for the 5 replicas of `nginx:1.7.9` to be created
|
`nginx:1.16.1` Pods. It does not wait for the 5 replicas of `nginx:1.14.2` to be created
|
||||||
before changing course.
|
before changing course.
|
||||||
|
|
||||||
### Label selector updates
|
### Label selector updates
|
||||||
@@ -347,10 +347,10 @@ This means that when you roll back to an earlier revision, only the Deployment's
|
|||||||
rolled back.
|
rolled back.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
* 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`:
|
* Suppose that you made a typo while updating the Deployment, by putting the image name as `nginx:1.161` instead of `nginx:1.16.1`:
|
||||||
|
|
||||||
```shell
|
```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.161 --record=true
|
||||||
```
|
```
|
||||||
|
|
||||||
The output is similar to this:
|
The output is similar to this:
|
||||||
@@ -427,7 +427,7 @@ rolled back.
|
|||||||
Labels: app=nginx
|
Labels: app=nginx
|
||||||
Containers:
|
Containers:
|
||||||
nginx:
|
nginx:
|
||||||
Image: nginx:1.91
|
Image: nginx:1.161
|
||||||
Port: 80/TCP
|
Port: 80/TCP
|
||||||
Host Port: 0/TCP
|
Host Port: 0/TCP
|
||||||
Environment: <none>
|
Environment: <none>
|
||||||
@@ -468,13 +468,13 @@ Follow the steps given below to check the rollout history:
|
|||||||
deployments "nginx-deployment"
|
deployments "nginx-deployment"
|
||||||
REVISION CHANGE-CAUSE
|
REVISION CHANGE-CAUSE
|
||||||
1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
|
1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
|
||||||
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
|
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
|
||||||
3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
|
3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true
|
||||||
```
|
```
|
||||||
|
|
||||||
`CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You can specify the`CHANGE-CAUSE` message by:
|
`CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You can specify the`CHANGE-CAUSE` message by:
|
||||||
|
|
||||||
* Annotating the Deployment with `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"`
|
* Annotating the Deployment with `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.16.1"`
|
||||||
* Append the `--record` flag to save the `kubectl` command that is making changes to the resource.
|
* Append the `--record` flag to save the `kubectl` command that is making changes to the resource.
|
||||||
* Manually editing the manifest of the resource.
|
* Manually editing the manifest of the resource.
|
||||||
|
|
||||||
@@ -488,10 +488,10 @@ Follow the steps given below to check the rollout history:
|
|||||||
deployments "nginx-deployment" revision 2
|
deployments "nginx-deployment" revision 2
|
||||||
Labels: app=nginx
|
Labels: app=nginx
|
||||||
pod-template-hash=1159050644
|
pod-template-hash=1159050644
|
||||||
Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
|
Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
|
||||||
Containers:
|
Containers:
|
||||||
nginx:
|
nginx:
|
||||||
Image: nginx:1.9.1
|
Image: nginx:1.16.1
|
||||||
Port: 80/TCP
|
Port: 80/TCP
|
||||||
QoS Tier:
|
QoS Tier:
|
||||||
cpu: BestEffort
|
cpu: BestEffort
|
||||||
@@ -549,7 +549,7 @@ Follow the steps given below to rollback the Deployment from the current version
|
|||||||
CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500
|
CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500
|
||||||
Labels: app=nginx
|
Labels: app=nginx
|
||||||
Annotations: deployment.kubernetes.io/revision=4
|
Annotations: deployment.kubernetes.io/revision=4
|
||||||
kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
|
kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
|
||||||
Selector: app=nginx
|
Selector: app=nginx
|
||||||
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
|
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
|
||||||
StrategyType: RollingUpdate
|
StrategyType: RollingUpdate
|
||||||
@@ -559,7 +559,7 @@ Follow the steps given below to rollback the Deployment from the current version
|
|||||||
Labels: app=nginx
|
Labels: app=nginx
|
||||||
Containers:
|
Containers:
|
||||||
nginx:
|
nginx:
|
||||||
Image: nginx:1.9.1
|
Image: nginx:1.16.1
|
||||||
Port: 80/TCP
|
Port: 80/TCP
|
||||||
Host Port: 0/TCP
|
Host Port: 0/TCP
|
||||||
Environment: <none>
|
Environment: <none>
|
||||||
@@ -722,7 +722,7 @@ apply multiple fixes in between pausing and resuming without triggering unnecess
|
|||||||
|
|
||||||
* Then update the image of the Deployment:
|
* Then update the image of the Deployment:
|
||||||
```shell
|
```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.16.1
|
||||||
```
|
```
|
||||||
|
|
||||||
The output is similar to this:
|
The output is similar to this:
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ It takes around 10s to complete.
|
|||||||
You can run the example with this command:
|
You can run the example with this command:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/examples/controllers/job.yaml
|
kubectl apply -f https://kubernetes.io/examples/controllers/job.yaml
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
job.batch/pi created
|
job.batch/pi created
|
||||||
|
|||||||
@@ -122,10 +122,10 @@ spec:
|
|||||||
initContainers:
|
initContainers:
|
||||||
- name: init-myservice
|
- name: init-myservice
|
||||||
image: busybox:1.28
|
image: busybox:1.28
|
||||||
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
|
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
|
||||||
- name: init-mydb
|
- name: init-mydb
|
||||||
image: busybox:1.28
|
image: busybox:1.28
|
||||||
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
|
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
|
||||||
```
|
```
|
||||||
|
|
||||||
You can start this Pod by running:
|
You can start this Pod by running:
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ 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. 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. 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. (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 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. 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) one-time extended grace period. You must modify `terminationGracePeriodSeconds` if the `preStop` hook needs longer to complete.
|
||||||
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. 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. (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. When the grace period expires, any processes still running in the Pod are killed with SIGKILL.
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Get a local clone of the following repositories:
|
|||||||
go get -u github.com/spf13/pflag
|
go get -u github.com/spf13/pflag
|
||||||
go get -u github.com/spf13/cobra
|
go get -u github.com/spf13/cobra
|
||||||
go get -u gopkg.in/yaml.v2
|
go get -u gopkg.in/yaml.v2
|
||||||
go get -u kubernetes-sigs/reference-docs
|
go get -u github.com/kubernetes-sigs/reference-docs
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don't already have the kubernetes/website repository, get it now:
|
If you don't already have the kubernetes/website repository, get it now:
|
||||||
@@ -140,15 +140,15 @@ need to work with someone who can set the label and milestone for you.
|
|||||||
Go to `<rdocs-base>`. On you command line, set the following environment variables.
|
Go to `<rdocs-base>`. On you command line, set the following environment variables.
|
||||||
|
|
||||||
* Set `K8S_ROOT` to `<k8s-base>`.
|
* Set `K8S_ROOT` to `<k8s-base>`.
|
||||||
* Set `WEB_ROOT` to `<web-base>`.
|
* Set `K8S_WEBROOT` to `<web-base>`.
|
||||||
* Set `K8S_RELEASE` to the version of the docs you want to build.
|
* Set `K8S_RELEASE` to the version of the docs you want to build.
|
||||||
For example, if you want to build docs for Kubernetes 1.17, set `K8S_RELEASE` to 1.17.
|
For example, if you want to build docs for Kubernetes 1.17, set `K8S_RELEASE` to 1.17.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
export WEB_ROOT=$(GOPATH)/src/github.com/<your-username>/website
|
export K8S_WEBROOT=$GOPATH/src/github.com/<your-username>/website
|
||||||
export K8S_ROOT=$(GOPATH)/src/k8s.io/kubernetes
|
export K8S_ROOT=$GOPATH/src/k8s.io/kubernetes
|
||||||
export K8S_RELEASE=1.17
|
export K8S_RELEASE=1.17
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -911,8 +911,8 @@ deadlines. Some deadlines related to documentation are:
|
|||||||
|
|
||||||
If your feature is an Alpha feature and is behind a feature gate, make sure you
|
If your feature is an Alpha feature and is behind a feature gate, make sure you
|
||||||
add it to [Feature gates](/docs/reference/command-line-tools-reference/feature-gates/)
|
add it to [Feature gates](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||||
as part of your pull request. If your feature is moving out of Alpha, make sure to
|
as part of your pull request. If your feature is moving to Beta
|
||||||
remove it from that file.
|
or to General Availability, update the feature gates file.
|
||||||
|
|
||||||
## Contribute to other repos
|
## Contribute to other repos
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ to base your work on. Use these guidelines to make the decision:
|
|||||||
- Some localization teams work with a series of long-lived branches, and
|
- Some localization teams work with a series of long-lived branches, and
|
||||||
periodically merge these to `master`. This kind of branch has a name like
|
periodically merge these to `master`. This kind of branch has a name like
|
||||||
dev-\<version>-\<language code>.\<team milestone>; for example:
|
dev-\<version>-\<language code>.\<team milestone>; for example:
|
||||||
`dev-{{< release-branch >}}-ja.1`.
|
`dev-{{< latest-semver >}}-ja.1`
|
||||||
- If you're writing or updating documentation for a feature change release,
|
- If you're writing or updating documentation for a feature change release,
|
||||||
then you need to know the major and minor version of Kubernetes that
|
then you need to know the major and minor version of Kubernetes that
|
||||||
the change will first appear in.
|
the change will first appear in.
|
||||||
@@ -217,8 +217,8 @@ to base your work on. Use these guidelines to make the decision:
|
|||||||
to beta in the next minor version, you need to know what the next minor
|
to beta in the next minor version, you need to know what the next minor
|
||||||
version number is.
|
version number is.
|
||||||
- Find the release branch named for that version. For example, features that
|
- Find the release branch named for that version. For example, features that
|
||||||
changed in the v{{< release-branch >}} release got documented in the branch
|
changed in the {{< latest-version >}} release got documented in the branch
|
||||||
named `dev-{{< release-branch >}}`.
|
named `dev-{{< latest-semver >}}`.
|
||||||
|
|
||||||
If you're still not sure which branch to choose, ask in `#sig-docs` on Slack or
|
If you're still not sure which branch to choose, ask in `#sig-docs` on Slack or
|
||||||
attend a weekly SIG Docs meeting to get clarity.
|
attend a weekly SIG Docs meeting to get clarity.
|
||||||
|
|||||||
@@ -10,107 +10,68 @@ card:
|
|||||||
---
|
---
|
||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
This page contains guidelines for adding content to the Kubernetes documentation.
|
|
||||||
If you have questions about allowed content, join the [Kubernetes Slack](http://slack.k8s.io/) #sig-docs channel and ask! Use your best judgment, and feel free to
|
|
||||||
propose changes to this document in a pull request.
|
|
||||||
|
|
||||||
For additional information on creating new content for the Kubernetes
|
This page contains guidelines for Kubernetes documentation.
|
||||||
docs, follow the instructions in the [Style guide](/docs/contribute/style/style-guide).
|
|
||||||
|
If you have questions about what's allowed, join the #sig-docs channel in
|
||||||
|
[Kubernetes Slack](http://slack.k8s.io/) and ask!
|
||||||
|
|
||||||
|
You can register for Kubernetes Slack at http://slack.k8s.io/.
|
||||||
|
|
||||||
|
For information on creating new content for the Kubernetes
|
||||||
|
docs, follow the [style guide](/docs/contribute/style/style-guide).
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
## Contributing content
|
|
||||||
|
|
||||||
The Kubernetes documentation comprises the content of the
|
## Overview
|
||||||
[kubernetes/website](https://github.com/kubernetes/website) source repository.
|
|
||||||
|
Source for the Kubernetes website, including the docs, resides in the
|
||||||
|
[kubernetes/website](https://github.com/kubernetes/website) repository.
|
||||||
|
|
||||||
Located in the `kubernetes/website/content/<language_code>/docs` folder, the
|
Located in the `kubernetes/website/content/<language_code>/docs` folder, the
|
||||||
majority of the Kubernetes documentation is specific to the [Kubernetes
|
majority of Kubernetes documentation is specific to the [Kubernetes
|
||||||
project](https://github.com/kubernetes/kubernetes). The Kubernetes
|
project](https://github.com/kubernetes/kubernetes).
|
||||||
documentation may also include content from projects in the
|
|
||||||
[kubernetes](https://github.com/kubernetes) and
|
|
||||||
[kubernetes-sigs](https://github.com/kubernetes-sigs) GitHub organizations if
|
|
||||||
those projects do not have their own documentation. Linking to active kubernetes,
|
|
||||||
kubernetes-sigs, and ({{< glossary_tooltip text="CNCF" term_id="cncf" >}}) projects from the Kubernetes documentation is always
|
|
||||||
allowed, but linking to vendor-specific products is not. Check the CNCF project lists
|
|
||||||
([Graduated/Incubating](https://www.cncf.io/projects/),
|
|
||||||
[Sandbox](https://www.cncf.io/sandbox-projects/),
|
|
||||||
[Archived](https://www.cncf.io/archived-projects/)) if you are unsure of a
|
|
||||||
project's CNCF status.
|
|
||||||
|
|
||||||
### Dual-sourced content
|
## What's allowed
|
||||||
|
|
||||||
Kubernetes documentation does not include duplicate content sourced from multiple
|
Kubernetes docs permit only some kinds of content.
|
||||||
locations (*dual-sourced* content). Dual-sourced content requires duplicated
|
|
||||||
effort from project maintainers and tends to become outdated more quickly.
|
|
||||||
Before adding content, ask yourself this:
|
|
||||||
|
|
||||||
- Is the content about an active CNCF project OR a project in the kubernetes or kubernetes-sigs GitHub organizations?
|
### Third party content
|
||||||
- If yes, then:
|
Kubernetes documentation includes applied examples of projects in the Kubernetes project&emdash;projects that live in the [kubernetes](https://github.com/kubernetes) and
|
||||||
- Does the project have its own documentation?
|
[kubernetes-sigs](https://github.com/kubernetes-sigs) GitHub organizations.
|
||||||
- if yes, link to the project's documentation from the Kubernetes documentation
|
|
||||||
- if no, add the content to the project's repository if possible and then link to it from the Kubernetes documentation
|
|
||||||
- If no, then:
|
|
||||||
- Stop!
|
|
||||||
- Adding content about vendor-specific products is not allowed
|
|
||||||
- Linking to vendor-specific documentation and websites is not allowed
|
|
||||||
|
|
||||||
### What is and isn't allowed
|
Links to active content in the Kubernetes project are always allowed.
|
||||||
|
|
||||||
There are some scenarios in which the Kubernetes documentation includes content from non-Kubernetes projects.
|
Kubernetes requires some third party content to function. Examples include container runtimes (containerd, CRI-O, Docker),
|
||||||
Below are general categories of non-Kubernetes project content along with guidelines of what is and is not allowed:
|
[networking policy](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) (CNI plugins), [Ingress controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/), and [logging](https://kubernetes.io/docs/concepts/cluster-administration/logging/).
|
||||||
|
|
||||||
1. Instructional content involving non-Kubernetes projects during setup or operation of Kubernetes
|
Docs can link to third-party open source software (OSS) outside the Kubernetes project if it's necessary for Kubernetes to function.
|
||||||
- Allowed:
|
|
||||||
- Referring to or linking to existing documentation about a CNCF project or a project in the kubernetes or kubernetes-sigs GitHub organizations
|
|
||||||
- Example: for installating Kubernetes in a learning environment, including a prerequisite stating that successful installation and configuration of minikube is required and linking to the relevant minikube documentation
|
|
||||||
- Adding content for kubernetes or kubernetes-sigs projects that don't have their own instructional content
|
|
||||||
- Example: including [kubeadm](https://github.com/kubernetes/kubeadm) installation and troubleshooting instructions
|
|
||||||
- Not Allowed:
|
|
||||||
- Adding content that duplicates documentation in another repository
|
|
||||||
- Examples:
|
|
||||||
- Including minikube installation and configuration instructions; minikube has its own [documentation](https://minikube.sigs.k8s.io/docs/) that provides those instructions
|
|
||||||
- Including instructions for installing Docker, CRI-O, containerd, and other container runtimes on various operating systems
|
|
||||||
- Including instructions for installing Kubernetes on production environments using various projects:
|
|
||||||
- Kubernetes Rebar Integrated Bootstrap (KRIB) is a vendor-specific project and content belongs in the vendor's documentation
|
|
||||||
- [Kubernetes Operations (kops)](https://github.com/kubernetes/kops) has installation instructions and tutorials in its GitHub repository
|
|
||||||
- [Kubespray](https://kubespray.io) has its own documentation
|
|
||||||
- Adding a tutorial that explains how to perform a task using a vendor-specific product or an open source project that is not a CNCF project or a project in the kubernetes or kubnetes-sigs GitHub organizations
|
|
||||||
- Adding a tutorial on how to use a CNCF project or a project in the kubernetes or kubnetes-sigs GitHub organizations if the project has its own documentation
|
|
||||||
1. Detailed technical content about how to use a non-Kubernetes project or how that project is designed
|
|
||||||
|
|
||||||
Adding this type of content to the Kubernetes documentation is not allowed.
|
### Dual sourced content
|
||||||
1. Content that describes a non-Kubernetes project
|
|
||||||
- Allowed:
|
Wherever possible, Kubernetes docs link to canonical sources instead of hosting
|
||||||
- Adding a brief introductory paragraph about a CNCF project or a project in the kubernetes or kubernetes-sigs GitHub organizations; the paragraph may contain links to the project
|
dual-sourced content.
|
||||||
- Not Allowed:
|
|
||||||
- Adding content describing a vendor-specific product
|
Dual-sourced content requires double the effort (or more!) to maintain
|
||||||
- Adding content describing an open source project that is not a CNCF project or a project in the kubernetes or kubnetes-sigs GitHub organizations
|
and grows stale more quickly.
|
||||||
- Adding content that duplicates documentation from another project, regardless of source repository
|
|
||||||
- Example: adding [Kubernetes in Docker (KinD)](https://kind.sigs.k8s.io) documentation to the Kubernetes documentation
|
{{< note >}}
|
||||||
1. Content that simply links to information about a non-Kubernetes project
|
|
||||||
- Allowed:
|
If you're a maintainer for a Kubernetes project and need help hosting your own docs,
|
||||||
- Linking to projects in the kubernetes and kubernetes-sigs GitHub organizations
|
ask for help in [#sig-docs on Kubernetes Slack](https://kubernetes.slack.com/messages/C1J0BPD2M/).
|
||||||
- Example: linking to Kubernetes in Docker (KinD) [documentation](https://kind.sigs.k8s.io/docs/user/quick-start), which resides in the kubernetes-sigs GitHub organization
|
|
||||||
- Linking to active CNCF projects
|
{{< /note >}}
|
||||||
- Example: linking to the Prometheus [documentation](https://prometheus.io/docs/introduction/overview/); Prometheus is an active CNCF project
|
|
||||||
- Not Allowed:
|
### More information
|
||||||
- Linking to vendor-specific products
|
|
||||||
- Linking to archived CNCF projects
|
|
||||||
- Linking to inactive projects in the kubernetes and kubernetes-sigs GitHub organizations
|
|
||||||
- Linking to open source projects that are not CNCF projects or do not reside in the kubernetes or kubernetes-sigs GitHub organizations
|
|
||||||
1. Content about training courses
|
|
||||||
- Allowed:
|
|
||||||
- Linking to vendor-neutral Kubernetes training courses offered by the [CNCF](https://www.cncf.io/), the [Linux Foundation](https://www.linuxfoundation.org/), and the [Linux Academy](https://linuxacademy.com/), which is a partner of the Linux Foundation
|
|
||||||
- Example: linking to Linux Academy courses such as [Kubernetes Quick Start](https://linuxacademy.com/course/kubernetes-quick-start/) and [Kubernetes Security](https://linuxacademy.com/course/kubernetes-security/)
|
|
||||||
- Not Allowed:
|
|
||||||
- Linking to online training outside of the CNCF, the Linux Foundation, or the Linux Academy; the Kubernetes documentation does not link to third-party content
|
|
||||||
- Example: linking to Kubernetes tutorials or courses on Medium, KodeKloud, Udacity, Coursera, learnk8s, and similar websites
|
|
||||||
- Linking to vendor-specific tutorials regardless of the training provider
|
|
||||||
- Example: linking to Linux Academy courses such as [Google Kubernetes Engine Deep Dive](https://linuxacademy.com/google-cloud-platform/training/course/name/google-kubernetes-engine-deep-dive) and [Amazon EKS Deep Dive](https://linuxacademy.com/course/amazon-eks-deep-dive/)
|
|
||||||
|
|
||||||
If you have questions about allowed content, join the [Kubernetes Slack](http://slack.k8s.io/) #sig-docs channel and ask!
|
If you have questions about allowed content, join the [Kubernetes Slack](http://slack.k8s.io/) #sig-docs channel and ask!
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture whatsnext %}}
|
{{% capture whatsnext %}}
|
||||||
|
|
||||||
* Read the [Style guide](/docs/contribute/style/style-guide).
|
* Read the [Style guide](/docs/contribute/style/style-guide).
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ Another widely used example is the `includes` bundle. It sets `headless: true` i
|
|||||||
```bash
|
```bash
|
||||||
en/includes
|
en/includes
|
||||||
├── default-storage-class-prereqs.md
|
├── default-storage-class-prereqs.md
|
||||||
├── federated-task-tutorial-prereqs.md
|
|
||||||
├── index.md
|
├── index.md
|
||||||
├── partner-script.js
|
├── partner-script.js
|
||||||
├── partner-style.css
|
├── partner-style.css
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ For field values of type string or integer, use normal style without quotation m
|
|||||||
Do | Don't
|
Do | Don't
|
||||||
:--| :-----
|
:--| :-----
|
||||||
Set the value of `imagePullPolicy` to Always. | Set the value of `imagePullPolicy` to "Always".
|
Set the value of `imagePullPolicy` to Always. | Set the value of `imagePullPolicy` to "Always".
|
||||||
Set the value of `image` to nginx:1.8. | Set the value of `image` to `nginx:1.8`.
|
Set the value of `image` to nginx:1.16. | Set the value of `image` to `nginx:1.16`.
|
||||||
Set the value of the `replicas` field to 2. | Set the value of the `replicas` field to `2`.
|
Set the value of the `replicas` field to 2. | Set the value of the `replicas` field to `2`.
|
||||||
{{< /table >}}
|
{{< /table >}}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ menu:
|
|||||||
weight: 20
|
weight: 20
|
||||||
post: >
|
post: >
|
||||||
<p>Learn how to use Kubernetes with conceptual, tutorial, and reference documentation. You can even <a href="/editdocs/" data-auto-burger-exclude>help contribute to the docs</a>!</p>
|
<p>Learn how to use Kubernetes with conceptual, tutorial, and reference documentation. You can even <a href="/editdocs/" data-auto-burger-exclude>help contribute to the docs</a>!</p>
|
||||||
|
description: >
|
||||||
|
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.
|
||||||
overview: >
|
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 (<a href="https://www.cncf.io/about">CNCF</a>).
|
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 (<a href="https://www.cncf.io/about">CNCF</a>).
|
||||||
cards:
|
cards:
|
||||||
@@ -36,9 +38,14 @@ cards:
|
|||||||
button_path: "/docs/setup"
|
button_path: "/docs/setup"
|
||||||
- name: tasks
|
- name: tasks
|
||||||
title: "Learn how to use Kubernetes"
|
title: "Learn how to use Kubernetes"
|
||||||
description: "Look up common tasks and how to perform them using a short sequence of steps."
|
description: "Look up common tasks and how to perform them using a short sequence of steps."
|
||||||
button: "View Tasks"
|
button: "View Tasks"
|
||||||
button_path: "/docs/tasks"
|
button_path: "/docs/tasks"
|
||||||
|
- name: training
|
||||||
|
title: "Training"
|
||||||
|
description: "Get certified in Kubernetes and make your cloud native projects successful!"
|
||||||
|
button: "View training"
|
||||||
|
button_path: "/training"
|
||||||
- name: reference
|
- name: reference
|
||||||
title: Look up reference information
|
title: Look up reference information
|
||||||
description: Browse terminology, command line syntax, API resource types, and setup tool documentation.
|
description: Browse terminology, command line syntax, API resource types, and setup tool documentation.
|
||||||
|
|||||||
@@ -669,21 +669,30 @@ for more information.
|
|||||||
|
|
||||||
### PodTolerationRestriction {#podtolerationrestriction}
|
### PodTolerationRestriction {#podtolerationrestriction}
|
||||||
|
|
||||||
This admission controller first verifies any conflict between a pod's tolerations and its
|
The PodTolerationRestriction admission controller verifies any conflict between tolerations of a pod and the tolerations of its namespace.
|
||||||
namespace's tolerations, and rejects the pod request if there is a conflict.
|
It rejects the pod request if there is a conflict.
|
||||||
It then merges the namespace's tolerations into the pod's tolerations.
|
It then merges the tolerations annotated on the namespace into the tolerations of the pod.
|
||||||
The resulting tolerations are checked against the namespace's whitelist of
|
The resulting tolerations are checked against a whitelist of tolerations annotated to the namespace.
|
||||||
tolerations. If the check succeeds, the pod request is admitted otherwise
|
If the check succeeds, the pod request is admitted otherwise it is rejected.
|
||||||
rejected.
|
|
||||||
|
|
||||||
If the pod's namespace does not have any associated default or whitelist of
|
If the namespace of the pod does not have any associated default tolerations or a whitelist of
|
||||||
tolerations, then the cluster-level default or whitelist of tolerations are used
|
tolerations annotated, the cluster-level default tolerations or cluster-level whitelist of tolerations are used
|
||||||
instead if specified.
|
instead if they are specified.
|
||||||
|
|
||||||
Tolerations to a namespace are assigned via the
|
Tolerations to a namespace are assigned via the `scheduler.alpha.kubernetes.io/defaultTolerations` annotation key.
|
||||||
`scheduler.alpha.kubernetes.io/defaultTolerations` and
|
The whitelist can be added via the `scheduler.alpha.kubernetes.io/tolerationsWhitelist` annotation key.
|
||||||
`scheduler.alpha.kubernetes.io/tolerationsWhitelist`
|
|
||||||
annotation keys.
|
Example for namespace annotations:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: apps-that-need-nodes-exclusively
|
||||||
|
annotations:
|
||||||
|
scheduler.alpha.kubernetes.io/defaultTolerations: '{"operator": "Exists", "effect": "NoSchedule", "key": "dedicated-node"}'
|
||||||
|
scheduler.alpha.kubernetes.io/tolerationsWhitelist: '{"operator": "Exists", "effect": "NoSchedule", "key": "dedicated-node"}'
|
||||||
|
```
|
||||||
|
|
||||||
### Priority {#priority}
|
### Priority {#priority}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ stored as `Secrets`, which are mounted into pods allowing in-cluster processes
|
|||||||
to talk to the Kubernetes API.
|
to talk to the Kubernetes API.
|
||||||
|
|
||||||
API requests are tied to either a normal user or a service account, or are treated
|
API requests are tied to either a normal user or a service account, or are treated
|
||||||
as anonymous requests. This means every process inside or outside the cluster, from
|
as [anonymous requests](#anonymous-requests). This means every process inside or outside the cluster, from
|
||||||
a human user typing `kubectl` on a workstation, to `kubelets` on nodes, to members
|
a human user typing `kubectl` on a workstation, to `kubelets` on nodes, to members
|
||||||
of the control plane, must authenticate when making requests to the API server,
|
of the control plane, must authenticate when making requests to the API server,
|
||||||
or be treated as an anonymous user.
|
or be treated as an anonymous user.
|
||||||
@@ -208,7 +208,7 @@ spec:
|
|||||||
serviceAccountName: bob-the-bot
|
serviceAccountName: bob-the-bot
|
||||||
containers:
|
containers:
|
||||||
- name: nginx
|
- name: nginx
|
||||||
image: nginx:1.7.9
|
image: nginx:1.14.2
|
||||||
```
|
```
|
||||||
|
|
||||||
Service account bearer tokens are perfectly valid to use outside the cluster and
|
Service account bearer tokens are perfectly valid to use outside the cluster and
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ webhooks:
|
|||||||
service:
|
service:
|
||||||
namespace: "example-namespace"
|
namespace: "example-namespace"
|
||||||
name: "example-service"
|
name: "example-service"
|
||||||
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate>...tLS0K"
|
caBundle: "Ci0tLS0tQk...<`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.>...tLS0K"
|
||||||
admissionReviewVersions: ["v1", "v1beta1"]
|
admissionReviewVersions: ["v1", "v1beta1"]
|
||||||
sideEffects: None
|
sideEffects: None
|
||||||
timeoutSeconds: 5
|
timeoutSeconds: 5
|
||||||
@@ -139,7 +139,7 @@ webhooks:
|
|||||||
service:
|
service:
|
||||||
namespace: "example-namespace"
|
namespace: "example-namespace"
|
||||||
name: "example-service"
|
name: "example-service"
|
||||||
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate>...tLS0K"
|
caBundle: "Ci0tLS0tQk...<`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate>...tLS0K"
|
||||||
admissionReviewVersions: ["v1beta1"]
|
admissionReviewVersions: ["v1beta1"]
|
||||||
timeoutSeconds: 5
|
timeoutSeconds: 5
|
||||||
```
|
```
|
||||||
@@ -1122,7 +1122,7 @@ kind: MutatingWebhookConfiguration
|
|||||||
webhooks:
|
webhooks:
|
||||||
- name: my-webhook.example.com
|
- name: my-webhook.example.com
|
||||||
clientConfig:
|
clientConfig:
|
||||||
caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate>...tLS0K"
|
caBundle: "Ci0tLS0tQk...<`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate>...tLS0K"
|
||||||
service:
|
service:
|
||||||
namespace: my-service-namespace
|
namespace: my-service-namespace
|
||||||
name: my-service-name
|
name: my-service-name
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,5 +14,5 @@ tags:
|
|||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
The metadata in an annotation can be small or large, structured or unstructured, and can include characters not permitted by labels. Clients such as tools and libraries can retrieve this metadata.
|
The metadata in an annotation can be small or large, structured or unstructured, and can include characters not permitted by {{< glossary_tooltip text="labels" term_id="label" >}}. Clients such as tools and libraries can retrieve this metadata.
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ short_description: >
|
|||||||
|
|
||||||
aka:
|
aka:
|
||||||
tags:
|
tags:
|
||||||
- operations
|
- operation
|
||||||
---
|
---
|
||||||
The infrastructure layer provides and maintains VMs, networking, security groups and others.
|
The infrastructure layer provides and maintains VMs, networking, security groups and others.
|
||||||
|
|||||||
@@ -4,10 +4,18 @@ id: cluster-operations
|
|||||||
date: 2019-05-12
|
date: 2019-05-12
|
||||||
full_link:
|
full_link:
|
||||||
short_description: >
|
short_description: >
|
||||||
Activities such as upgrading the clusters, implementing security, storage, ingress, networking, logging and monitoring, and other operations involved in managing a Kubernetes cluster.
|
The work involved in managing a Kubernetes cluster.
|
||||||
|
|
||||||
aka:
|
aka:
|
||||||
tags:
|
tags:
|
||||||
- operations
|
- operation
|
||||||
---
|
---
|
||||||
Activities such as upgrading the clusters, implementing security, storage, ingress, networking, logging and monitoring, and other operations involved in managing a Kubernetes cluster.
|
The work involved in managing a Kubernetes cluster: managing
|
||||||
|
day-to-day operations, and co-ordinating upgrades.
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
Examples of cluster operations work include: deploying new Nodes to
|
||||||
|
scale the cluster; performing software upgrades; implementing security
|
||||||
|
controls; adding or removing storage; configuring cluster networking;
|
||||||
|
managing cluster-wide observability; and responding to events.
|
||||||
|
|||||||
@@ -11,7 +11,13 @@ tags:
|
|||||||
- fundamental
|
- fundamental
|
||||||
- operation
|
- operation
|
||||||
---
|
---
|
||||||
A set of worker machines, called nodes, that run containerized applications. Every cluster has at least one worker node.
|
A set of worker machines, called {{< glossary_tooltip text="nodes" term_id="node" >}},
|
||||||
|
that run containerized applications. Every cluster has at least one worker node.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
The worker node(s) host the pods that are the components of the application. The Control Plane manages the worker nodes and the pods in the cluster. In production environments, the Control Plane usually runs across multiple computers and a cluster usually runs multiple nodes, providing fault-tolerance and high availability.
|
The worker node(s) host the {{< glossary_tooltip text="Pods" term_id="pod" >}} that are
|
||||||
|
the components of the application workload. The
|
||||||
|
{{< glossary_tooltip text="control plane" term_id="control-plane" >}} manages the worker
|
||||||
|
nodes and the Pods in the cluster. In production environments, the control plane usually
|
||||||
|
runs across multiple computers and a cluster usually runs multiple nodes, providing
|
||||||
|
fault-tolerance and high availability.
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- fundamental
|
- fundamental
|
||||||
---
|
---
|
||||||
Container environment variables are name=value pairs that provide useful information into containers running in a Pod.
|
Container environment variables are name=value pairs that provide useful information into containers running in a {{< glossary_tooltip text="pod" term_id="pod" >}}
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Container environment variables provide information that is required by the running containerized applications along with information about important resources to the {{< glossary_tooltip text="Containers" term_id="container" >}}. For example, file system details, information about the container itself, and other cluster resources such as service endpoints.
|
Container environment variables provide information that is required by the running containerized applications along with information about important resources to the {{< glossary_tooltip text="containers" term_id="container" >}}. For example, file system details, information about the container itself, and other cluster resources such as service endpoints.
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ tags:
|
|||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Each replica is represented by a {{< glossary_tooltip term_id="pod" >}}, and the Pods are distributed among the nodes of a cluster.
|
Each replica is represented by a {{< glossary_tooltip term_id="pod" >}}, and the Pods are distributed among the {{< glossary_tooltip text="nodes" term_id="node" >}} of a cluster.
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- operation
|
- operation
|
||||||
---
|
---
|
||||||
An API resource that automatically scales the number of pod replicas based on targeted CPU utilization or custom metric targets.
|
An API resource that automatically scales the number of {{< glossary_tooltip term_id="pod" >}} replicas based on targeted CPU utilization or custom metric targets.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
HPA is typically used with {{< glossary_tooltip text="Replication Controllers" term_id="replication-controller" >}}, {{< glossary_tooltip text="Deployments" term_id="deployment" >}}, or Replica Sets. It cannot be applied to objects that cannot be scaled, for example {{< glossary_tooltip text="DaemonSets" term_id="daemonset" >}}.
|
HPA is typically used with {{< glossary_tooltip text="ReplicationControllers" term_id="replication-controller" >}}, {{< glossary_tooltip text="Deployments" term_id="deployment" >}}, or {{< glossary_tooltip text="ReplicaSets" term_id="replica-set" >}}. It cannot be applied to objects that cannot be scaled, for example {{< glossary_tooltip text="DaemonSets" term_id="daemonset" >}}.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- operation
|
- operation
|
||||||
---
|
---
|
||||||
A HostAliases is a mapping between the IP address and hostname to be injected into a Pod's hosts file.
|
A HostAliases is a mapping between the IP address and hostname to be injected into a {{< glossary_tooltip text="Pod" term_id="pod" >}}'s hosts file.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- fundamental
|
- fundamental
|
||||||
---
|
---
|
||||||
Stored instance of a container that holds a set of software needed to run an application.
|
Stored instance of a {{< glossary_tooltip term_id="container" >}} that holds a set of software needed to run an application.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
A way of packaging software that allows it to be stored in a container registry, pulled to a local system, and run as an application. Meta data is included in the image that can indicate what executable to run, who built it, and other information.
|
A way of packaging software that allows it to be stored in a container registry, pulled to a local system, and run as an application. Meta data is included in the image that can indicate what executable to run, who built it, and other information.
|
||||||
|
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ tags:
|
|||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Ingress can provide load balancing, SSL termination and name-based virtual hosting.
|
Ingress may provide load balancing, SSL termination and name-based virtual hosting.
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ id: init-container
|
|||||||
date: 2018-04-12
|
date: 2018-04-12
|
||||||
full_link:
|
full_link:
|
||||||
short_description: >
|
short_description: >
|
||||||
One or more initialization containers that must run to completion before any app containers run.
|
One or more initialization containers that must run to completion before any app containers run.
|
||||||
|
|
||||||
aka:
|
aka:
|
||||||
tags:
|
tags:
|
||||||
- fundamental
|
- fundamental
|
||||||
---
|
---
|
||||||
One or more initialization containers that must run to completion before any app containers run.
|
One or more initialization {{< glossary_tooltip text="containers" term_id="container" >}} that must run to completion before any app containers run.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Initialization (init) containers are like regular app containers, with one difference: init containers must run to completion before any app containers can start. Init containers run in series: each init container must run to completion before the next init container begins.
|
Initialization (init) containers are like regular app containers, with one difference: init containers must run to completion before any app containers can start. Init containers run in series: each init container must run to completion before the next init container begins.
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,17 @@ tags:
|
|||||||
- fundamental
|
- fundamental
|
||||||
- networking
|
- networking
|
||||||
---
|
---
|
||||||
[kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) is a
|
kube-proxy is a network proxy that runs on each
|
||||||
network proxy that runs on each node in your cluster, implementing part of
|
{{< glossary_tooltip text="node" term_id="node" >}} in your cluster,
|
||||||
the Kubernetes {{< glossary_tooltip term_id="service">}} concept.
|
implementing part of the Kubernetes
|
||||||
|
{{< glossary_tooltip term_id="service">}} concept.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
kube-proxy maintains network rules on nodes. These network rules allow
|
[kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/)
|
||||||
network communication to your Pods from network sessions inside or outside
|
maintains network rules on nodes. These network rules allow network
|
||||||
of your cluster.
|
communication to your Pods from network sessions inside or outside of
|
||||||
|
your cluster.
|
||||||
|
|
||||||
kube-proxy uses the operating system packet filtering layer if there is one
|
kube-proxy uses the operating system packet filtering layer if there is one
|
||||||
and it's available. Otherwise, kube-proxy forwards the traffic itself.
|
and it's available. Otherwise, kube-proxy forwards the traffic itself.
|
||||||
|
|||||||
@@ -4,15 +4,20 @@ id: kube-scheduler
|
|||||||
date: 2018-04-12
|
date: 2018-04-12
|
||||||
full_link: /docs/reference/generated/kube-scheduler/
|
full_link: /docs/reference/generated/kube-scheduler/
|
||||||
short_description: >
|
short_description: >
|
||||||
Control Plane component that watches for newly created pods with no assigned node, and selects a node for them to run on.
|
Control plane component that watches for newly created pods with no assigned node, and selects a node for them to run on.
|
||||||
|
|
||||||
aka:
|
aka:
|
||||||
tags:
|
tags:
|
||||||
- architecture
|
- architecture
|
||||||
---
|
---
|
||||||
Control Plane component that watches for newly created pods with no assigned node, and selects a node for them to run on.
|
Control plane component that watches for newly created
|
||||||
|
{{< glossary_tooltip term_id="pod" text="Pods" >}} with no assigned
|
||||||
|
{{< glossary_tooltip term_id="node" text="node">}}, and selects a node for them
|
||||||
|
to run on.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Factors taken into account for scheduling decisions include individual and collective resource requirements, hardware/software/policy constraints, affinity and anti-affinity specifications, data locality, inter-workload interference and deadlines.
|
|
||||||
|
|
||||||
|
Factors taken into account for scheduling decisions include:
|
||||||
|
individual and collective resource requirements, hardware/software/policy
|
||||||
|
constraints, affinity and anti-affinity specifications, data locality,
|
||||||
|
inter-workload interference, and deadlines.
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ tags:
|
|||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
You can use kubeadm to install both the control plane and the worker node components.
|
You can use kubeadm to install both the control plane and the {{< glossary_tooltip text="worker node" term_id="node" >}} components.
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ tags:
|
|||||||
- fundamental
|
- fundamental
|
||||||
- core-object
|
- core-object
|
||||||
---
|
---
|
||||||
An agent that runs on each node in the cluster. It makes sure that containers are running in a pod.
|
An agent that runs on each {{< glossary_tooltip text="node" term_id="node" >}} in the cluster. It makes sure that {{< glossary_tooltip text="containers" term_id="container" >}} are running in a {{< glossary_tooltip text="Pod" term_id="pod" >}}.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
The kubelet takes a set of PodSpecs that are provided through various mechanisms and ensures that the containers described in those PodSpecs are running and healthy. The kubelet doesn’t manage containers which were not created by Kubernetes.
|
The kubelet takes a set of PodSpecs that are provided through various mechanisms and ensures that the containers described in those PodSpecs are running and healthy. The kubelet doesn’t manage containers which were not created by Kubernetes.
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ tags:
|
|||||||
- core-object
|
- core-object
|
||||||
- storage
|
- storage
|
||||||
---
|
---
|
||||||
Claims storage resources defined in a PersistentVolume so that it can be mounted as a volume in a container.
|
Claims storage resources defined in a {{< glossary_tooltip text="PersistentVolume" term_id="persistent-volume" >}} so that it can be mounted as a volume in a {{< glossary_tooltip text="container" term_id="container" >}}.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Specifies the amount of storage, how the storage will be accessed (read-only, read-write and/or exclusive) and how it is reclaimed (retained, recycled or deleted). Details of the storage itself are in the PersistentVolume specification.
|
Specifies the amount of storage, how the storage will be accessed (read-only, read-write and/or exclusive) and how it is reclaimed (retained, recycled or deleted). Details of the storage itself are described in the PersistentVolume object.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- operation
|
- operation
|
||||||
---
|
---
|
||||||
Pod Priority indicates the importance of a Pod relative to other Pods.
|
Pod Priority indicates the importance of a {{< glossary_tooltip term_id="pod" >}} relative to other Pods.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- operation
|
- operation
|
||||||
---
|
---
|
||||||
An API object that injects information such as secrets, volume mounts, and environment variables into pods at creation time.
|
An API object that injects information such as secrets, volume mounts, and environment variables into {{< glossary_tooltip text="Pods" term_id="pod" >}} at creation time.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
This object chooses the pods to inject information into using standard selectors. This allows the podspec definitions to be nonspecific, decoupling the podspec from environment specific configuration.
|
This object chooses the Pods to inject information into using standard selectors. This allows the podspec definitions to be nonspecific, decoupling the podspec from environment specific configuration.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- operation
|
- operation
|
||||||
---
|
---
|
||||||
Preemption logic in Kubernetes helps a pending Pod to find a suitable Node by evicting low priority Pods existing on that Node.
|
Preemption logic in Kubernetes helps a pending {{< glossary_tooltip term_id="pod" >}} to find a suitable {{< glossary_tooltip term_id="node" >}} by evicting low priority Pods existing on that Node.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ tags:
|
|||||||
- workload
|
- workload
|
||||||
- core-object
|
- core-object
|
||||||
---
|
---
|
||||||
Kubernetes service that ensures a specific number of instances of a pod are always running.
|
Kubernetes service that ensures a specific number of instances of a {{< glossary_tooltip text="Pod" term_id="pod" >}} are always running.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,20 @@ id: security-context
|
|||||||
date: 2018-04-12
|
date: 2018-04-12
|
||||||
full_link: /docs/tasks/configure-pod-container/security-context/
|
full_link: /docs/tasks/configure-pod-container/security-context/
|
||||||
short_description: >
|
short_description: >
|
||||||
The securityContext field defines privilege and access control settings for a Pod or Container, including the runtime UID and GID.
|
The securityContext field defines privilege and access control settings for a Pod or container.
|
||||||
|
|
||||||
aka:
|
aka:
|
||||||
tags:
|
tags:
|
||||||
- security
|
- security
|
||||||
---
|
---
|
||||||
The securityContext field defines privilege and access control settings for a Pod or Container, including the runtime UID and GID.
|
The `securityContext` field defines privilege and access control settings for
|
||||||
|
a {{< glossary_tooltip text="Pod" term_id="pod" >}} or
|
||||||
|
{{< glossary_tooltip text="container" term_id="container" >}}.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
The securityContext field in a {{< glossary_tooltip term_id="pod" >}} (applying to all containers) or container is used to set the user, groups, capabilities, privilege settings, and security policies (SELinux/AppArmor/Seccomp) and more that container processes use.
|
In a `securityContext`, you can define: the user that processes run as,
|
||||||
|
the group that processes run as, and privilege settings.
|
||||||
|
You can also configure security policies (for example: SELinux, AppArmor or seccomp).
|
||||||
|
|
||||||
|
The `PodSpec.securityContext` setting applies to all containers in a Pod.
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ aka:
|
|||||||
tags:
|
tags:
|
||||||
- fundamental
|
- fundamental
|
||||||
---
|
---
|
||||||
Allows users to filter a list of resources based on labels.
|
Allows users to filter a list of resources based on {{< glossary_tooltip text="labels" term_id="label" >}}.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
Selectors are applied when querying lists of resources to filter them by {{< glossary_tooltip text="Labels" term_id="label" >}}.
|
Selectors are applied when querying lists of resources to filter them by labels.
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ tags:
|
|||||||
- core-object
|
- core-object
|
||||||
- fundamental
|
- fundamental
|
||||||
---
|
---
|
||||||
A core object consisting of three required properties: key, value, and effect. Taints prevent the scheduling of pods on nodes or node groups.
|
A core object consisting of three required properties: key, value, and effect. Taints prevent the scheduling of {{< glossary_tooltip text="Pods" term_id="pod" >}} on {{< glossary_tooltip text="nodes" term_id="node" >}} or node groups.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
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" >}}. A node should only schedule a pod with the matching tolerations for the configured taints.
|
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 node. A node should only schedule a Pod with the matching tolerations for the configured taints.
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ tags:
|
|||||||
- core-object
|
- core-object
|
||||||
- fundamental
|
- fundamental
|
||||||
---
|
---
|
||||||
A directory containing data, accessible to the containers in a {{< glossary_tooltip text="pod" term_id="pod" >}}.
|
A directory containing data, accessible to the {{< glossary_tooltip text="containers" term_id="container" >}} in a {{< glossary_tooltip term_id="pod" >}}.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
|
|
||||||
A Kubernetes volume lives as long as the {{< glossary_tooltip text="pod" term_id="pod" >}} that encloses it. Consequently, a volume outlives any {{< glossary_tooltip text="containers" term_id="container" >}} that run within the {{< glossary_tooltip text="pod" term_id="pod" >}}, and data is preserved across {{< glossary_tooltip text="container" term_id="container" >}} restarts.
|
A Kubernetes volume lives as long as the Pod that encloses it. Consequently, a volume outlives any containers that run within the Pod, and data in the volume is preserved across container restarts.
|
||||||
|
|
||||||
|
See [storage](https://kubernetes.io/docs/concepts/storage/) for more information.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ complete -F __start_kubectl k
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
source <(kubectl completion zsh) # setup autocomplete in zsh into the current shell
|
source <(kubectl completion zsh) # setup autocomplete in zsh into the current shell
|
||||||
echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc # add autocomplete permanently to your zsh shell
|
echo "[[ $commands[kubectl] ]] && source <(kubectl completion zsh)" >> ~/.zshrc # add autocomplete permanently to your zsh shell
|
||||||
```
|
```
|
||||||
|
|
||||||
## Kubectl Context and Configuration
|
## Kubectl Context and Configuration
|
||||||
@@ -95,7 +95,7 @@ kubectl apply -f ./my1.yaml -f ./my2.yaml # create from multiple files
|
|||||||
kubectl apply -f ./dir # create resource(s) in all manifest files in dir
|
kubectl apply -f ./dir # create resource(s) in all manifest files in dir
|
||||||
kubectl apply -f https://git.io/vPieo # create resource(s) from url
|
kubectl apply -f https://git.io/vPieo # create resource(s) from url
|
||||||
kubectl create deployment 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
|
kubectl explain pods # get the documentation for pod manifests
|
||||||
|
|
||||||
# Create multiple YAML objects from stdin
|
# Create multiple YAML objects from stdin
|
||||||
cat <<EOF | kubectl apply -f -
|
cat <<EOF | kubectl apply -f -
|
||||||
@@ -148,7 +148,6 @@ kubectl get pods -o wide # List all pods in the current nam
|
|||||||
kubectl get deployment my-dep # List a particular deployment
|
kubectl get deployment my-dep # List a particular deployment
|
||||||
kubectl get pods # List all pods in the namespace
|
kubectl get pods # List all pods in the namespace
|
||||||
kubectl get pod my-pod -o yaml # Get a pod's YAML
|
kubectl get pod my-pod -o yaml # Get a pod's YAML
|
||||||
kubectl get pod my-pod -o yaml --export # Get a pod's YAML without cluster specific information
|
|
||||||
|
|
||||||
# Describe commands with verbose output
|
# Describe commands with verbose output
|
||||||
kubectl describe nodes my-node
|
kubectl describe nodes my-node
|
||||||
@@ -192,6 +191,10 @@ JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.ty
|
|||||||
# List all Secrets currently in use by a pod
|
# List all Secrets currently in use by a pod
|
||||||
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
|
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
|
||||||
|
|
||||||
|
# List all containerIDs of initContainer of all pods
|
||||||
|
# Helpful when cleaning up stopped containers, while avoiding removal of initContainers.
|
||||||
|
kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3
|
||||||
|
|
||||||
# List Events sorted by timestamp
|
# List Events sorted by timestamp
|
||||||
kubectl get events --sort-by=.metadata.creationTimestamp
|
kubectl get events --sort-by=.metadata.creationTimestamp
|
||||||
|
|
||||||
|
|||||||
@@ -91,12 +91,14 @@ The two paths that support extending the API with [custom resources](/docs/conce
|
|||||||
- [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md) for a full set of Kubernetes API semantics to implement their own apiserver.
|
- [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md) for a full set of Kubernetes API semantics to implement their own apiserver.
|
||||||
|
|
||||||
|
|
||||||
## Enabling API groups
|
## Enabling or disabling API groups
|
||||||
|
|
||||||
Certain resources and API groups are enabled by default. You can enable or disable them by setting `--runtime-config`
|
Certain resources and API groups are enabled by default. You can enable or disable them by setting `--runtime-config`
|
||||||
on the apiserver. `--runtime-config` accepts comma separated values. For example:
|
on the apiserver. `--runtime-config` accepts comma separated values. For example:
|
||||||
|
|
||||||
- to disable batch/v1, set `--runtime-config=batch/v1=false`
|
- to disable batch/v1, set `--runtime-config=batch/v1=false`
|
||||||
- to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`
|
- to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`
|
||||||
|
|
||||||
The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver.
|
The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver.
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
@@ -104,12 +106,10 @@ When you enable or disable groups or resources, you need to restart the apiserve
|
|||||||
to pick up the `--runtime-config` changes.
|
to pick up the `--runtime-config` changes.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
## Enabling resources in the groups
|
## Enabling specific resources in the extensions/v1beta1 group
|
||||||
|
|
||||||
DaemonSets, Deployments, HorizontalPodAutoscalers, Ingress, Jobs and ReplicaSets are enabled by default.
|
|
||||||
You can enable other extensions resources by setting `--runtime-config` on
|
|
||||||
apiserver. `--runtime-config` accepts comma separated values. For example, to disable deployments and jobs, set
|
|
||||||
`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/jobs=false`
|
|
||||||
{{% /capture %}}
|
|
||||||
|
|
||||||
|
DaemonSets, Deployments, StatefulSet, NetworkPolicies, PodSecurityPolicies and ReplicaSets in the `extensions/v1beta1` API group are disabled by default.
|
||||||
|
For example: to enable deployments and daemonsets, set
|
||||||
|
`--runtime-config=extensions/v1beta1/deployments=true,extensions/v1beta1/daemonsets=true`.
|
||||||
|
|
||||||
|
{{< note >}}Individual resource enablement/disablement is only supported in the `extensions/v1beta1` API group for legacy reasons.{{< /note >}}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ their authors, not the Kubernetes team.
|
|||||||
| PHP | [github.com/allansun/kubernetes-php-client](https://github.com/allansun/kubernetes-php-client) |
|
| PHP | [github.com/allansun/kubernetes-php-client](https://github.com/allansun/kubernetes-php-client) |
|
||||||
| PHP | [github.com/travisghansen/kubernetes-client-php](https://github.com/travisghansen/kubernetes-client-php) |
|
| PHP | [github.com/travisghansen/kubernetes-client-php](https://github.com/travisghansen/kubernetes-client-php) |
|
||||||
| Python | [github.com/eldarion-gondor/pykube](https://github.com/eldarion-gondor/pykube) |
|
| Python | [github.com/eldarion-gondor/pykube](https://github.com/eldarion-gondor/pykube) |
|
||||||
|
| Python | [github.com/fiaas/k8s](https://github.com/fiaas/k8s) |
|
||||||
| Python | [github.com/mnubo/kubernetes-py](https://github.com/mnubo/kubernetes-py) |
|
| Python | [github.com/mnubo/kubernetes-py](https://github.com/mnubo/kubernetes-py) |
|
||||||
| Python | [github.com/tomplus/kubernetes_asyncio](https://github.com/tomplus/kubernetes_asyncio) |
|
| Python | [github.com/tomplus/kubernetes_asyncio](https://github.com/tomplus/kubernetes_asyncio) |
|
||||||
| Ruby | [github.com/Ch00k/kuber](https://github.com/Ch00k/kuber) |
|
| Ruby | [github.com/Ch00k/kuber](https://github.com/Ch00k/kuber) |
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ This section covers different options to set up and run Kubernetes.
|
|||||||
|
|
||||||
Different Kubernetes solutions meet different requirements: ease of maintenance, security, control, available resources, and expertise required to operate and manage a cluster.
|
Different Kubernetes solutions meet different requirements: ease of maintenance, security, control, available resources, and expertise required to operate and manage a cluster.
|
||||||
|
|
||||||
You can deploy a Kubernetes cluster on a local machine, cloud, on-prem datacenter; or choose a managed Kubernetes cluster. You can also create custom solutions across a wide range of cloud providers, or bare metal environments.
|
You can deploy a Kubernetes cluster on a local machine, cloud, on-prem datacenter, or choose a managed Kubernetes cluster. You can also create custom solutions across a wide range of cloud providers, or bare metal environments.
|
||||||
|
|
||||||
More simply, you can create a Kubernetes cluster in learning and production environments.
|
More simply, you can create a Kubernetes cluster in learning and production environments.
|
||||||
|
|
||||||
@@ -53,63 +53,6 @@ If you're learning Kubernetes, use the Docker-based solutions: tools supported b
|
|||||||
|
|
||||||
When evaluating a solution for a production environment, consider which aspects of operating a Kubernetes cluster (or _abstractions_) you want to manage yourself or offload to a provider.
|
When evaluating a solution for a production environment, consider which aspects of operating a Kubernetes cluster (or _abstractions_) you want to manage yourself or offload to a provider.
|
||||||
|
|
||||||
Some possible abstractions of a Kubernetes cluster are {{< glossary_tooltip text="applications" term_id="applications" >}}, {{< glossary_tooltip text="data plane" term_id="data-plane" >}}, {{< glossary_tooltip text="control plane" term_id="control-plane" >}}, {{< glossary_tooltip text="cluster infrastructure" term_id="cluster-infrastructure" >}}, and {{< glossary_tooltip text="cluster operations" term_id="cluster-operations" >}}.
|
For a list of [Certified Kubernetes](https://github.com/cncf/k8s-conformance/#certified-kubernetes) providers, see "[Partners](https://kubernetes.io/partners/#conformance)".
|
||||||
|
|
||||||
The following diagram lists the possible abstractions of a Kubernetes cluster and whether an abstraction is self-managed or managed by a provider.
|
|
||||||
|
|
||||||
Production environment solutions
|
|
||||||
|
|
||||||
{{< table caption="Production environment solutions table lists the providers and the solutions." >}}
|
|
||||||
The following production environment solutions table lists the providers and the solutions that they offer.
|
|
||||||
|
|
||||||
|Providers | Managed | Turnkey cloud | On-prem datacenter | Custom (cloud) | Custom (On-premises VMs)| Custom (Bare Metal) |
|
|
||||||
| --------- | ------ | ------ | ------ | ------ | ------ | ----- |
|
|
||||||
| [Agile Stacks](https://www.agilestacks.com/products/kubernetes)| | ✔ | ✔ | | |
|
|
||||||
| [Alibaba Cloud](https://www.alibabacloud.com/product/kubernetes)| | ✔ | | | |
|
|
||||||
| [Amazon](https://aws.amazon.com) | [Amazon EKS](https://aws.amazon.com/eks/) |[Amazon EC2](https://aws.amazon.com/ec2/) | | | |
|
|
||||||
| [AppsCode](https://appscode.com/products/pharmer/) | ✔ | | | | |
|
|
||||||
| [APPUiO](https://appuio.ch/) | ✔ | ✔ | ✔ | | | |
|
|
||||||
| [Banzai Cloud Pipeline Kubernetes Engine (PKE)](https://banzaicloud.com/products/pke/) | | ✔ | | ✔ | ✔ | ✔ |
|
|
||||||
| [CenturyLink Cloud](https://www.ctl.io/) | | ✔ | | | |
|
|
||||||
| [Cisco Container Platform](https://cisco.com/go/containers) | | | ✔ | | |
|
|
||||||
| [Cloud Foundry Container Runtime (CFCR)](https://docs-cfcr.cfapps.io/) | | | | ✔ |✔ |
|
|
||||||
| [CloudStack](https://cloudstack.apache.org/) | | | | | ✔|
|
|
||||||
| [Canonical](https://ubuntu.com/kubernetes) | ✔ | ✔ | ✔ | ✔ |✔ | ✔
|
|
||||||
| [Containership](https://containership.io) | ✔ |✔ | | | |
|
|
||||||
| [D2iQ](https://d2iq.com/) | | [Kommander](https://d2iq.com/solutions/ksphere) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) |
|
|
||||||
| [Digital Rebar](https://provision.readthedocs.io/en/tip/README.html) | | | | | | ✔
|
|
||||||
| [DigitalOcean](https://www.digitalocean.com/products/kubernetes/) | ✔ | | | | |
|
|
||||||
| [Docker Enterprise](https://www.docker.com/products/docker-enterprise) | |✔ | ✔ | | | ✔
|
|
||||||
| [Gardener](https://gardener.cloud/) | ✔ | ✔ | ✔ | ✔ | ✔ | [Custom Extensions](https://github.com/gardener/gardener/blob/master/docs/extensions/overview.md) |
|
|
||||||
| [Giant Swarm](https://www.giantswarm.io/) | ✔ | ✔ | ✔ | |
|
|
||||||
| [Google](https://cloud.google.com/) | [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/) | [Google Compute Engine (GCE)](https://cloud.google.com/compute/)|[GKE On-Prem](https://cloud.google.com/gke-on-prem/) | | | | | | | |
|
|
||||||
| [Hidora](https://hidora.com/) | ✔ | ✔| ✔ | | | | | | | |
|
|
||||||
| [IBM](https://www.ibm.com/in-en/cloud) | [IBM Cloud Kubernetes Service](https://cloud.ibm.com/kubernetes/catalog/cluster)| |[IBM Cloud Private](https://www.ibm.com/in-en/cloud/private) | |
|
|
||||||
| [Ionos](https://www.ionos.com/enterprise-cloud) | [Ionos Managed Kubernetes](https://www.ionos.com/enterprise-cloud/managed-kubernetes) | [Ionos Enterprise Cloud](https://www.ionos.com/enterprise-cloud) | |
|
|
||||||
| [Kontena Pharos](https://www.kontena.io/pharos/) | |✔| ✔ | | |
|
|
||||||
| [KubeOne](https://kubeone.io/) | | ✔ | ✔ | ✔ | ✔ | ✔ |
|
|
||||||
| [Kubermatic](https://kubermatic.io/) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
|
|
||||||
| [KubeSail](https://kubesail.com/) | ✔ | | | | |
|
|
||||||
| [Kubespray](https://kubespray.io/#/) | | | |✔ | ✔ | ✔ |
|
|
||||||
| [Kublr](https://kublr.com/) |✔ | ✔ |✔ |✔ |✔ |✔ |
|
|
||||||
| [Microsoft Azure](https://azure.microsoft.com) | [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service/) | | | | |
|
|
||||||
| [Mirantis Cloud Platform](https://www.mirantis.com/software/kubernetes/) | | | ✔ | | |
|
|
||||||
| [NetApp Kubernetes Service (NKS)](https://cloud.netapp.com/kubernetes-service) | ✔ | ✔ | ✔ | | |
|
|
||||||
| [Nirmata](https://www.nirmata.com/) | | ✔ | ✔ | | |
|
|
||||||
| [Nutanix](https://www.nutanix.com/en) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | | | [Nutanix AHV](https://www.nutanix.com/products/acropolis/virtualization) |
|
|
||||||
| [OpenNebula](https://www.opennebula.org) |[OpenNebula Kubernetes](https://marketplace.opennebula.systems/docs/service/kubernetes.html) | | | | |
|
|
||||||
| [OpenShift](https://www.openshift.com) |[OpenShift Dedicated](https://www.openshift.com/products/dedicated/) and [OpenShift Online](https://www.openshift.com/products/online/) | | [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) | | [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) |[OpenShift Container Platform](https://www.openshift.com/products/container-platform/)
|
|
||||||
| [Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE)](https://docs.cloud.oracle.com/iaas/Content/ContEng/Concepts/contengoverview.htm) | ✔ | ✔ | | | |
|
|
||||||
| [oVirt](https://www.ovirt.org/) | | | | | ✔ |
|
|
||||||
| [Pivotal](https://pivotal.io/) | | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | | |
|
|
||||||
| [Platform9](https://platform9.com/) | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | ✔ | ✔ | ✔
|
|
||||||
| [Rancher](https://rancher.com/) | | [Rancher 2.x](https://rancher.com/docs/rancher/v2.x/en/) | | [Rancher Kubernetes Engine (RKE)](https://rancher.com/docs/rke/latest/en/) | | [k3s](https://k3s.io/)
|
|
||||||
| [Supergiant](https://supergiant.io/) | |✔ | | | |
|
|
||||||
| [SUSE](https://www.suse.com/) | | ✔ | | | |
|
|
||||||
| [SysEleven](https://www.syseleven.io/) | ✔ | | | | |
|
|
||||||
| [Tencent Cloud](https://intl.cloud.tencent.com/) | [Tencent Kubernetes Engine](https://intl.cloud.tencent.com/product/tke) | ✔ | ✔ | | | ✔ |
|
|
||||||
| [VEXXHOST](https://vexxhost.com/) | ✔ | ✔ | | | |
|
|
||||||
| [VMware](https://cloud.vmware.com/) | [VMware Cloud PKS](https://cloud.vmware.com/vmware-cloud-pks) |[VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) | [VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) | [VMware Essential PKS](https://cloud.vmware.com/vmware-essential-pks) | |[VMware Essential PKS](https://cloud.vmware.com/vmware-essential-pks)
|
|
||||||
| [Z.A.R.V.I.S.](https://zarvis.ai/) | ✔ | | | | | |
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ kubernetes-minion-wf8i Ready <none> 2m v1.13.0
|
|||||||
|
|
||||||
Create a volume using the dynamic volume creation (only PersistentVolumes are supported for zone affinity):
|
Create a volume using the dynamic volume creation (only PersistentVolumes are supported for zone affinity):
|
||||||
|
|
||||||
```json
|
```bash
|
||||||
kubectl apply -f - <<EOF
|
kubectl apply -f - <<EOF
|
||||||
{
|
{
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Minikube supports the following Kubernetes features:
|
|||||||
* NodePorts
|
* NodePorts
|
||||||
* ConfigMaps and Secrets
|
* ConfigMaps and Secrets
|
||||||
* Dashboards
|
* Dashboards
|
||||||
* Container Runtime: Docker, [CRI-O](https://cri-o.io/), and [containerd](https://github.com/containerd/containerd)
|
* Container Runtime: [Docker](https://www.docker.com/), [CRI-O](https://cri-o.io/), and [containerd](https://github.com/containerd/containerd)
|
||||||
* Enabling CNI (Container Network Interface)
|
* Enabling CNI (Container Network Interface)
|
||||||
* Ingress
|
* Ingress
|
||||||
|
|
||||||
|
|||||||
@@ -49,14 +49,12 @@ Download the latest release with the command:
|
|||||||
curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-darwin-amd64
|
curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-darwin-amd64
|
||||||
```
|
```
|
||||||
|
|
||||||
To download a specific version, replace the
|
To download a specific version, replace the following portion of the command with the specific kops version.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)
|
$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||||
```
|
```
|
||||||
|
|
||||||
portion of the command with the specific version.
|
|
||||||
|
|
||||||
For example, to download kops version v1.15.0 type:
|
For example, to download kops version v1.15.0 type:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|||||||
@@ -344,10 +344,6 @@ Please refer to this installation guide: [Contiv-VPP Manual Installation](https:
|
|||||||
|
|
||||||
For `flannel` to work correctly, you must pass `--pod-network-cidr=10.244.0.0/16` to `kubeadm init`.
|
For `flannel` to work correctly, you must pass `--pod-network-cidr=10.244.0.0/16` to `kubeadm init`.
|
||||||
|
|
||||||
Set `/proc/sys/net/bridge/bridge-nf-call-iptables` to `1` by running `sysctl net.bridge.bridge-nf-call-iptables=1`
|
|
||||||
to pass bridged IPv4 traffic to iptables' chains. This is a requirement for some CNI plugins to work, for more information
|
|
||||||
please see [Network Plugin Requirements](/docs/concepts/cluster-administration/network-plugins/#network-plugin-requirements).
|
|
||||||
|
|
||||||
Make sure that your firewall rules allow UDP ports 8285 and 8472 traffic for all hosts participating in the overlay network. The [Firewall](https://coreos.com/flannel/docs/latest/troubleshooting.html#firewalls) section of Flannel's troubleshooting guide explains about this in more detail.
|
Make sure that your firewall rules allow UDP ports 8285 and 8472 traffic for all hosts participating in the overlay network. The [Firewall](https://coreos.com/flannel/docs/latest/troubleshooting.html#firewalls) section of Flannel's troubleshooting guide explains about this in more detail.
|
||||||
|
|
||||||
Flannel works on `amd64`, `arm`, `arm64`, `ppc64le` and `s390x` architectures under Linux.
|
Flannel works on `amd64`, `arm`, `arm64`, `ppc64le` and `s390x` architectures under Linux.
|
||||||
@@ -362,9 +358,6 @@ For more information about `flannel`, see [the CoreOS flannel repository on GitH
|
|||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
|
|
||||||
{{% tab name="Kube-router" %}}
|
{{% tab name="Kube-router" %}}
|
||||||
Set `/proc/sys/net/bridge/bridge-nf-call-iptables` to `1` by running `sysctl net.bridge.bridge-nf-call-iptables=1`
|
|
||||||
to pass bridged IPv4 traffic to iptables' chains. This is a requirement for some CNI plugins to work, for more information
|
|
||||||
please see [Network Plugin Requirements](/docs/concepts/cluster-administration/network-plugins/#network-plugin-requirements).
|
|
||||||
|
|
||||||
Kube-router relies on kube-controller-manager to allocate Pod CIDR for the nodes. Therefore, use `kubeadm init` with the `--pod-network-cidr` flag.
|
Kube-router relies on kube-controller-manager to allocate Pod CIDR for the nodes. Therefore, use `kubeadm init` with the `--pod-network-cidr` flag.
|
||||||
|
|
||||||
@@ -374,9 +367,6 @@ For information on using the `kubeadm` tool to set up a Kubernetes cluster with
|
|||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
|
|
||||||
{{% tab name="Weave Net" %}}
|
{{% tab name="Weave Net" %}}
|
||||||
Set `/proc/sys/net/bridge/bridge-nf-call-iptables` to `1` by running `sysctl net.bridge.bridge-nf-call-iptables=1`
|
|
||||||
to pass bridged IPv4 traffic to iptables' chains. This is a requirement for some CNI plugins to work, for more information
|
|
||||||
please see [Network Plugin Requirements](/docs/concepts/cluster-administration/network-plugins/#network-plugin-requirements).
|
|
||||||
|
|
||||||
For more information on setting up your Kubernetes cluster with Weave Net, please see [Integrating Kubernetes via the Addon]((https://www.weave.works/docs/net/latest/kube-addon/).
|
For more information on setting up your Kubernetes cluster with Weave Net, please see [Integrating Kubernetes via the Addon]((https://www.weave.works/docs/net/latest/kube-addon/).
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,23 @@ may [fail](https://github.com/kubernetes/kubeadm/issues/31).
|
|||||||
If you have more than one network adapter, and your Kubernetes components are not reachable on the default
|
If you have more than one network adapter, and your Kubernetes components are not reachable on the default
|
||||||
route, we recommend you add IP route(s) so Kubernetes cluster addresses go via the appropriate adapter.
|
route, we recommend you add IP route(s) so Kubernetes cluster addresses go via the appropriate adapter.
|
||||||
|
|
||||||
|
## Letting iptables see bridged traffic
|
||||||
|
|
||||||
|
As a requirement for your Linux Node's iptables to correctly see bridged traffic, you should ensure `net.bridge.bridge-nf-call-iptables` is set to 1 in your `sysctl` config, e.g.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat <<EOF > /etc/sysctl.d/k8s.conf
|
||||||
|
net.bridge.bridge-nf-call-ip6tables = 1
|
||||||
|
net.bridge.bridge-nf-call-iptables = 1
|
||||||
|
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`.
|
||||||
|
|
||||||
|
For more details please see the [Network Plugin Requirements](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#network-plugin-requirements) page.
|
||||||
|
|
||||||
|
|
||||||
## Ensure iptables tooling does not use the nftables backend
|
## Ensure iptables tooling does not use the nftables backend
|
||||||
|
|
||||||
In Linux, nftables is available as a modern replacement for the kernel's iptables subsystem. The
|
In Linux, nftables is available as a modern replacement for the kernel's iptables subsystem. The
|
||||||
@@ -230,17 +247,7 @@ systemctl enable --now kubelet
|
|||||||
- Setting SELinux in permissive mode by running `setenforce 0` and `sed ...` effectively disables it.
|
- Setting SELinux in permissive mode by running `setenforce 0` and `sed ...` effectively disables it.
|
||||||
This is required to allow containers to access the host filesystem, which is needed by pod networks for example.
|
This is required to allow containers to access the host filesystem, which is needed by pod networks for example.
|
||||||
You have to do this until SELinux support is improved in the kubelet.
|
You have to do this until SELinux support is improved in the kubelet.
|
||||||
- Some users on RHEL/CentOS 7 have reported issues with traffic being routed incorrectly due to iptables being bypassed. You should ensure
|
|
||||||
`net.bridge.bridge-nf-call-iptables` is set to 1 in your `sysctl` config, e.g.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat <<EOF > /etc/sysctl.d/k8s.conf
|
|
||||||
net.bridge.bridge-nf-call-ip6tables = 1
|
|
||||||
net.bridge.bridge-nf-call-iptables = 1
|
|
||||||
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 %}}
|
||||||
{{% tab name="Container Linux" %}}
|
{{% tab name="Container Linux" %}}
|
||||||
Install CNI plugins (required for most pod network):
|
Install CNI plugins (required for most pod network):
|
||||||
|
|||||||
+3
-3
@@ -307,17 +307,17 @@ The tracking issue for this problem is [here](https://github.com/kubernetes/kube
|
|||||||
|
|
||||||
*Note: This [issue](https://github.com/kubernetes/kubeadm/issues/1358) only applies to tools that marshal kubeadm types (e.g. to a YAML configuration file). It will be fixed in kubeadm API v1beta2.*
|
*Note: This [issue](https://github.com/kubernetes/kubeadm/issues/1358) only applies to tools that marshal kubeadm types (e.g. to a YAML configuration file). It will be fixed in kubeadm API v1beta2.*
|
||||||
|
|
||||||
By default, kubeadm applies the `role.kubernetes.io/master:NoSchedule` taint to control-plane nodes.
|
By default, kubeadm applies the `node-role.kubernetes.io/master:NoSchedule` taint to control-plane nodes.
|
||||||
If you prefer kubeadm to not taint the control-plane node, and set `InitConfiguration.NodeRegistration.Taints` to an empty slice,
|
If you prefer kubeadm to not taint the control-plane node, and set `InitConfiguration.NodeRegistration.Taints` to an empty slice,
|
||||||
the field will be omitted when marshalling. When the field is omitted, kubeadm applies the default taint.
|
the field will be omitted when marshalling. When the field is omitted, kubeadm applies the default taint.
|
||||||
|
|
||||||
There are at least two workarounds:
|
There are at least two workarounds:
|
||||||
|
|
||||||
1. Use the `role.kubernetes.io/master:PreferNoSchedule` taint instead of an empty slice. [Pods will get scheduled on masters](/docs/concepts/configuration/taint-and-toleration/), unless other nodes have capacity.
|
1. Use the `node-role.kubernetes.io/master:PreferNoSchedule` taint instead of an empty slice. [Pods will get scheduled on masters](/docs/concepts/configuration/taint-and-toleration/), unless other nodes have capacity.
|
||||||
|
|
||||||
2. Remove the taint after kubeadm init exits:
|
2. Remove the taint after kubeadm init exits:
|
||||||
```bash
|
```bash
|
||||||
kubectl taint nodes NODE_NAME role.kubernetes.io/master:NoSchedule-
|
kubectl taint nodes NODE_NAME node-role.kubernetes.io/master:NoSchedule-
|
||||||
```
|
```
|
||||||
|
|
||||||
## `/usr` is mounted read-only on nodes {#usr-mounted-read-only}
|
## `/usr` is mounted read-only on nodes {#usr-mounted-read-only}
|
||||||
|
|||||||
@@ -107,6 +107,14 @@ Port mapping is also supported, but for simplicity in this example the container
|
|||||||
Windows container hosts are not able to access the IP of services scheduled on them due to current platform limitations of the Windows networking stack. Only Windows pods are able to access service IPs.
|
Windows container hosts are not able to access the IP of services scheduled on them due to current platform limitations of the Windows networking stack. Only Windows pods are able to access service IPs.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
|
## Observability
|
||||||
|
|
||||||
|
### Capturing logs from workloads
|
||||||
|
|
||||||
|
Logs are an important element of observability; they enable users to gain insights into the operational aspect of workloads and are a key ingredient to troubleshooting issues. Because Windows containers and workloads inside Windows containers behave differently from Linux containers, users had a hard time collecting logs, limiting operational visibility. Windows workloads for example are usually configured to log to ETW (Event Tracing for Windows) or push entries to the application event log. [LogMonitor](https://github.com/microsoft/windows-container-tools/tree/master/LogMonitor), an open source tool by Microsoft, is the recommended way to monitor configured log sources inside a Windows container. LogMonitor supports monitoring event logs, ETW providers, and custom application logs, piping them to STDOUT for consumption by `kubectl logs <pod>`.
|
||||||
|
|
||||||
|
Follow the instructions in the LogMonitor GitHub page to copy its binaries and configuration files to all your containers and add the necessary entrypoints for LogMonitor to push your logs to STDOUT.
|
||||||
|
|
||||||
## Using configurable Container usernames
|
## Using configurable Container usernames
|
||||||
|
|
||||||
Starting with Kubernetes v1.16, Windows containers can be configured to run their entrypoints and processes with different usernames than the image defaults. The way this is achieved is a bit different from the way it is done for Linux containers. Learn more about it [here](/docs/tasks/configure-pod-container/configure-runasusername/).
|
Starting with Kubernetes v1.16, Windows containers can be configured to run their entrypoints and processes with different usernames than the image defaults. The way this is achieved is a bit different from the way it is done for Linux containers. Learn more about it [here](/docs/tasks/configure-pod-container/configure-runasusername/).
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ frontend and backend are connected using a Kubernetes
|
|||||||
|
|
||||||
{{% capture lessoncontent %}}
|
{{% capture lessoncontent %}}
|
||||||
|
|
||||||
### Creating the backend using a Deployment
|
## Creating the backend using a Deployment
|
||||||
|
|
||||||
The backend is a simple hello greeter microservice. Here is the configuration
|
The backend is a simple hello greeter microservice. Here is the configuration
|
||||||
file for the backend Deployment:
|
file for the backend Deployment:
|
||||||
@@ -95,7 +95,7 @@ Events:
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating the backend Service object
|
## Creating the backend Service object
|
||||||
|
|
||||||
The key to connecting a frontend to a backend is the backend
|
The key to connecting a frontend to a backend is the backend
|
||||||
Service. A Service creates a persistent IP address and DNS name entry
|
Service. A Service creates a persistent IP address and DNS name entry
|
||||||
@@ -119,7 +119,7 @@ kubectl apply -f https://k8s.io/examples/service/access/hello-service.yaml
|
|||||||
At this point, you have a backend Deployment running, and you have a
|
At this point, you have a backend Deployment running, and you have a
|
||||||
Service that can route traffic to it.
|
Service that can route traffic to it.
|
||||||
|
|
||||||
### Creating the frontend
|
## Creating the frontend
|
||||||
|
|
||||||
Now that you have your backend, you can create a frontend that connects to the backend.
|
Now that you have your backend, you can create a frontend that connects to the backend.
|
||||||
The frontend connects to the backend worker Pods by using the DNS name
|
The frontend connects to the backend worker Pods by using the DNS name
|
||||||
@@ -158,7 +158,7 @@ be to use a
|
|||||||
so that you can change the configuration more easily.
|
so that you can change the configuration more easily.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
### Interact with the frontend Service
|
## Interact with the frontend Service
|
||||||
|
|
||||||
Once you’ve created a Service of type LoadBalancer, you can use this
|
Once you’ve created a Service of type LoadBalancer, you can use this
|
||||||
command to find the external IP:
|
command to find the external IP:
|
||||||
@@ -186,7 +186,7 @@ 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
|
That IP can now be used to interact with the `frontend` service from outside the
|
||||||
cluster.
|
cluster.
|
||||||
|
|
||||||
### Send traffic through the frontend
|
## Send traffic through the frontend
|
||||||
|
|
||||||
The frontend and backends are now connected. You can hit the endpoint
|
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.
|
by using the curl command on the external IP of your frontend Service.
|
||||||
|
|||||||
+5
-5
@@ -23,7 +23,7 @@ In this exercise you will use kubectl to fetch all of the Pods
|
|||||||
running in a cluster, and format the output to pull out the list
|
running in a cluster, and format the output to pull out the list
|
||||||
of Containers for each.
|
of Containers for each.
|
||||||
|
|
||||||
## List all Containers in all namespaces
|
## List all Container images in all namespaces
|
||||||
|
|
||||||
- Fetch all Pods in all namespaces using `kubectl get pods --all-namespaces`
|
- Fetch all Pods in all namespaces using `kubectl get pods --all-namespaces`
|
||||||
- Format the output to include only the list of Container image names
|
- Format the output to include only the list of Container image names
|
||||||
@@ -68,7 +68,7 @@ the `.items[*]` portion of the path should be omitted because a single
|
|||||||
Pod is returned instead of a list of items.
|
Pod is returned instead of a list of items.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
## List Containers by Pod
|
## List Container images by Pod
|
||||||
|
|
||||||
The formatting can be controlled further by using the `range` operation to
|
The formatting can be controlled further by using the `range` operation to
|
||||||
iterate over elements individually.
|
iterate over elements individually.
|
||||||
@@ -78,7 +78,7 @@ kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata
|
|||||||
sort
|
sort
|
||||||
```
|
```
|
||||||
|
|
||||||
## List Containers filtering by Pod label
|
## List Container images filtering by Pod label
|
||||||
|
|
||||||
To target only Pods matching a specific label, use the -l flag. The
|
To target only Pods matching a specific label, use the -l flag. The
|
||||||
following matches only Pods with labels matching `app=nginx`.
|
following matches only Pods with labels matching `app=nginx`.
|
||||||
@@ -87,7 +87,7 @@ following matches only Pods with labels matching `app=nginx`.
|
|||||||
kubectl get pods --all-namespaces -o=jsonpath="{..image}" -l app=nginx
|
kubectl get pods --all-namespaces -o=jsonpath="{..image}" -l app=nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
## List Containers filtering by Pod namespace
|
## List Container images filtering by Pod namespace
|
||||||
|
|
||||||
To target only pods in a specific namespace, use the namespace flag. The
|
To target only pods in a specific namespace, use the namespace flag. The
|
||||||
following matches only Pods in the `kube-system` namespace.
|
following matches only Pods in the `kube-system` namespace.
|
||||||
@@ -96,7 +96,7 @@ following matches only Pods in the `kube-system` namespace.
|
|||||||
kubectl get pods --namespace kube-system -o jsonpath="{..image}"
|
kubectl get pods --namespace kube-system -o jsonpath="{..image}"
|
||||||
```
|
```
|
||||||
|
|
||||||
## List Containers using a go-template instead of jsonpath
|
## List Container images using a go-template instead of jsonpath
|
||||||
|
|
||||||
As an alternative to jsonpath, Kubectl supports using [go-templates](https://golang.org/pkg/text/template/)
|
As an alternative to jsonpath, Kubectl supports using [go-templates](https://golang.org/pkg/text/template/)
|
||||||
for formatting the output:
|
for formatting the output:
|
||||||
|
|||||||
+103
-52
@@ -2,6 +2,7 @@
|
|||||||
title: Use Port Forwarding to Access Applications in a Cluster
|
title: Use Port Forwarding to Access Applications in a Cluster
|
||||||
content_template: templates/task
|
content_template: templates/task
|
||||||
weight: 40
|
weight: 40
|
||||||
|
min-kubernetes-server-version: v1.10
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
@@ -26,104 +27,157 @@ for database debugging.
|
|||||||
|
|
||||||
## Creating Redis deployment and service
|
## Creating Redis deployment and service
|
||||||
|
|
||||||
1. Create a Redis deployment:
|
1. Create a Deployment that runs Redis:
|
||||||
|
|
||||||
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
|
```shell
|
||||||
|
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
|
||||||
|
```
|
||||||
|
|
||||||
The output of a successful command verifies that the deployment was created:
|
The output of a successful command verifies that the deployment was created:
|
||||||
|
|
||||||
deployment.apps/redis-master created
|
```
|
||||||
|
deployment.apps/redis-master created
|
||||||
|
```
|
||||||
|
|
||||||
View the pod status to check that it is ready:
|
View the pod status to check that it is ready:
|
||||||
|
|
||||||
kubectl get pods
|
```shell
|
||||||
|
kubectl get pods
|
||||||
|
```
|
||||||
|
|
||||||
The output displays the pod created:
|
The output displays the pod created:
|
||||||
|
|
||||||
NAME READY STATUS RESTARTS AGE
|
```
|
||||||
redis-master-765d459796-258hz 1/1 Running 0 50s
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
redis-master-765d459796-258hz 1/1 Running 0 50s
|
||||||
|
```
|
||||||
|
|
||||||
View the deployment status:
|
View the Deployment's status:
|
||||||
|
|
||||||
kubectl get deployment
|
```shell
|
||||||
|
kubectl get deployment
|
||||||
|
```
|
||||||
|
|
||||||
The output displays that the deployment was created:
|
The output displays that the Deployment was created:
|
||||||
|
|
||||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
```
|
||||||
redis-master 1/1 1 1 55s
|
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||||
|
redis-master 1/1 1 1 55s
|
||||||
|
```
|
||||||
|
|
||||||
View the replicaset status using:
|
The Deployment automatically manages a ReplicaSet.
|
||||||
|
View the ReplicaSet status using:
|
||||||
|
|
||||||
kubectl get rs
|
```shell
|
||||||
|
kubectl get replicaset
|
||||||
|
```
|
||||||
|
|
||||||
The output displays that the replicaset was created:
|
The output displays that the ReplicaSet was created:
|
||||||
|
|
||||||
NAME DESIRED CURRENT READY AGE
|
```
|
||||||
redis-master-765d459796 1 1 1 1m
|
NAME DESIRED CURRENT READY AGE
|
||||||
|
redis-master-765d459796 1 1 1 1m
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
2. Create a Redis service:
|
2. Create a Service to expose Redis on the network:
|
||||||
|
|
||||||
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
|
```shell
|
||||||
|
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
|
||||||
|
```
|
||||||
|
|
||||||
The output of a successful command verifies that the service was created:
|
The output of a successful command verifies that the Service was created:
|
||||||
|
|
||||||
service/redis-master created
|
```
|
||||||
|
service/redis-master created
|
||||||
|
```
|
||||||
|
|
||||||
Check the service created:
|
Check the Service created:
|
||||||
|
|
||||||
kubectl get svc | grep redis
|
```shell
|
||||||
|
kubectl get service redis-master
|
||||||
|
```
|
||||||
|
|
||||||
The output displays the service created:
|
The output displays the service created:
|
||||||
|
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
```
|
||||||
redis-master ClusterIP 10.0.0.213 <none> 6379/TCP 27s
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
|
redis-master ClusterIP 10.0.0.213 <none> 6379/TCP 27s
|
||||||
|
```
|
||||||
|
|
||||||
3. Verify that the Redis server is running in the pod and listening on port 6379:
|
3. Verify that the Redis server is running in the Pod, and listening on port 6379:
|
||||||
|
|
||||||
kubectl get pods redis-master-765d459796-258hz --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
|
```shell
|
||||||
|
# Change redis-master-765d459796-258hz to the name of the Pod
|
||||||
|
kubectl get pod redis-master-765d459796-258hz --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
|
||||||
|
```
|
||||||
|
|
||||||
The output displays the port:
|
The output displays the port for Redis in that Pod:
|
||||||
|
|
||||||
6379
|
```
|
||||||
|
6379
|
||||||
|
```
|
||||||
|
|
||||||
|
(this is the TCP port allocated to Redis on the internet).
|
||||||
|
|
||||||
|
## Forward a local port to a port on the Pod
|
||||||
|
|
||||||
|
1. `kubectl port-forward` allows using resource name, such as a pod name, to select a matching pod to port forward to.
|
||||||
|
|
||||||
|
|
||||||
## Forward a local port to a port on the pod
|
```shell
|
||||||
|
# Change redis-master-765d459796-258hz to the name of the Pod
|
||||||
1. `kubectl port-forward` allows using resource name, such as a pod name, to select a matching pod to port forward to since Kubernetes v1.10.
|
kubectl port-forward redis-master-765d459796-258hz 7000:6379
|
||||||
|
```
|
||||||
kubectl port-forward redis-master-765d459796-258hz 7000:6379
|
|
||||||
|
|
||||||
which is the same as
|
which is the same as
|
||||||
|
|
||||||
kubectl port-forward pods/redis-master-765d459796-258hz 7000:6379
|
```shell
|
||||||
|
kubectl port-forward pods/redis-master-765d459796-258hz 7000:6379
|
||||||
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
kubectl port-forward deployment/redis-master 7000:6379
|
```shell
|
||||||
|
kubectl port-forward deployment/redis-master 7000:6379
|
||||||
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
kubectl port-forward rs/redis-master 7000:6379
|
```shell
|
||||||
|
kubectl port-forward replicaset/redis-master 7000:6379
|
||||||
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
kubectl port-forward svc/redis-master 7000:6379
|
```shell
|
||||||
|
kubectl port-forward service/redis-master 7000:6379
|
||||||
|
```
|
||||||
|
|
||||||
Any of the above commands works. The output is similar to this:
|
Any of the above commands works. The output is similar to this:
|
||||||
|
|
||||||
I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:7000 -> 6379
|
```
|
||||||
I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:7000 -> 6379
|
I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:7000 -> 6379
|
||||||
|
I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:7000 -> 6379
|
||||||
|
```
|
||||||
|
|
||||||
2. Start the Redis command line interface:
|
2. Start the Redis command line interface:
|
||||||
|
|
||||||
redis-cli -p 7000
|
```shell
|
||||||
|
redis-cli -p 7000
|
||||||
|
```
|
||||||
|
|
||||||
3. At the Redis command line prompt, enter the `ping` command:
|
3. At the Redis command line prompt, enter the `ping` command:
|
||||||
|
|
||||||
127.0.0.1:7000>ping
|
```
|
||||||
|
ping
|
||||||
|
```
|
||||||
|
|
||||||
A successful ping request returns PONG.
|
A successful ping request returns:
|
||||||
|
|
||||||
|
```
|
||||||
|
PONG
|
||||||
|
```
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
@@ -132,15 +186,15 @@ for database debugging.
|
|||||||
|
|
||||||
## Discussion
|
## Discussion
|
||||||
|
|
||||||
Connections made to local port 7000 are forwarded to port 6379 of the pod that
|
Connections made to local port 7000 are forwarded to port 6379 of the Pod that
|
||||||
is running the Redis server. With this connection in place you can use your
|
is running the Redis server. With this connection in place, you can use your
|
||||||
local workstation to debug the database that is running in the pod.
|
local workstation to debug the database that is running in the Pod.
|
||||||
|
|
||||||
{{< warning >}}
|
{{< note >}}
|
||||||
Due to known limitations, port forward today only works for TCP protocol.
|
`kubectl port-forward` is implemented for TCP ports only.
|
||||||
The support to UDP protocol is being tracked in
|
The support for UDP protocol is tracked in
|
||||||
[issue 47862](https://github.com/kubernetes/kubernetes/issues/47862).
|
[issue 47862](https://github.com/kubernetes/kubernetes/issues/47862).
|
||||||
{{< /warning >}}
|
{{< /note >}}
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
@@ -148,6 +202,3 @@ The support to UDP protocol is being tracked in
|
|||||||
{{% capture whatsnext %}}
|
{{% capture whatsnext %}}
|
||||||
Learn more about [kubectl port-forward](/docs/reference/generated/kubectl/kubectl-commands/#port-forward).
|
Learn more about [kubectl port-forward](/docs/reference/generated/kubectl/kubectl-commands/#port-forward).
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,10 @@ for details about addon manager and how to disable individual addons.
|
|||||||
To mark a StorageClass as non-default, you need to change its value to `false`:
|
To mark a StorageClass as non-default, you need to change its value to `false`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl patch storageclass <your-class-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
|
kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
where `<your-class-name>` is the name of your chosen StorageClass.
|
where `standard` is the name of your chosen StorageClass.
|
||||||
|
|
||||||
1. Mark a StorageClass as default:
|
1. Mark a StorageClass as default:
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ for details about addon manager and how to disable individual addons.
|
|||||||
`storageclass.kubernetes.io/is-default-class=true`.
|
`storageclass.kubernetes.io/is-default-class=true`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl patch storageclass <your-class-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
|
kubectl patch storageclass gold -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
Please note that at most one StorageClass can be marked as default. If two
|
Please note that at most one StorageClass can be marked as default. If two
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ To install Kubernetes on a set of machines, consult one of the existing [Getting
|
|||||||
|
|
||||||
## Upgrading a cluster
|
## Upgrading a cluster
|
||||||
|
|
||||||
The current state of cluster upgrades is provider dependent, and some releases may require special care when upgrading. It is recommended that administrators consult both the [release notes](https://git.k8s.io/kubernetes/CHANGELOG.md), as well as the version specific upgrade notes prior to upgrading their clusters.
|
The current state of cluster upgrades is provider dependent, and some releases may require special care when upgrading. It is recommended that administrators consult both the [release notes](https://git.k8s.io/kubernetes/CHANGELOG/README.md), as well as the version specific upgrade notes prior to upgrading their clusters.
|
||||||
|
|
||||||
### Upgrading an Azure Kubernetes Service (AKS) cluster
|
### Upgrading an Azure Kubernetes Service (AKS) cluster
|
||||||
|
|
||||||
|
|||||||
@@ -265,15 +265,6 @@ work properly owing to a known issue with Alpine.
|
|||||||
Check [here](https://github.com/kubernetes/kubernetes/issues/30215)
|
Check [here](https://github.com/kubernetes/kubernetes/issues/30215)
|
||||||
for more information.
|
for more information.
|
||||||
|
|
||||||
## Kubernetes Federation (Multiple Zone support)
|
|
||||||
|
|
||||||
Release 1.3 introduced Cluster Federation support for multi-site Kubernetes
|
|
||||||
installations. This required some minor (backward-compatible) changes to the
|
|
||||||
way the Kubernetes cluster DNS server processes DNS queries, to facilitate
|
|
||||||
the lookup of federated services (which span multiple Kubernetes clusters).
|
|
||||||
See the [Cluster Federation Administrators' Guide](/docs/concepts/cluster-administration/federation/)
|
|
||||||
for more details on Cluster Federation and multi-site support.
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [DNS for Services and Pods](/docs/concepts/services-networking/dns-pod-service/)
|
- [DNS for Services and Pods](/docs/concepts/services-networking/dns-pod-service/)
|
||||||
|
|||||||
@@ -224,12 +224,14 @@ At this point, all requests we make to the Kubernetes cluster from the command l
|
|||||||
|
|
||||||
Let's create some contents.
|
Let's create some contents.
|
||||||
|
|
||||||
|
{{< codenew file="admin/snowflake-deployment.yaml" >}}
|
||||||
|
|
||||||
|
Apply the manifest to create a Deployment
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl run snowflake --image=k8s.gcr.io/serve_hostname --replicas=2
|
kubectl apply -f https://k8s.io/examples/admin/snowflake-deployment.yaml
|
||||||
```
|
```
|
||||||
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
|
```shell
|
||||||
kubectl get deployment
|
kubectl get deployment
|
||||||
|
|||||||
@@ -188,88 +188,22 @@ This delete is asynchronous, so for a time you will see the namespace in the `Te
|
|||||||
|
|
||||||
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
|
```shell
|
||||||
kubectl config view
|
kubectl run snowflake --image=k8s.gcr.io/serve_hostname --replicas=2 -n=development
|
||||||
```
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
|
||||||
clusters:
|
|
||||||
cluster:
|
|
||||||
certificate-authority-data: REDACTED
|
|
||||||
server: https://130.211.122.180
|
|
||||||
name: lithe-cocoa-92103_kubernetes
|
|
||||||
contexts:
|
|
||||||
context:
|
|
||||||
cluster: lithe-cocoa-92103_kubernetes
|
|
||||||
user: lithe-cocoa-92103_kubernetes
|
|
||||||
name: lithe-cocoa-92103_kubernetes
|
|
||||||
current-context: lithe-cocoa-92103_kubernetes
|
|
||||||
kind: Config
|
|
||||||
preferences: {}
|
|
||||||
users:
|
|
||||||
name: lithe-cocoa-92103_kubernetes
|
|
||||||
user:
|
|
||||||
client-certificate-data: REDACTED
|
|
||||||
client-key-data: REDACTED
|
|
||||||
token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
|
|
||||||
name: lithe-cocoa-92103_kubernetes-basic-auth
|
|
||||||
user:
|
|
||||||
password: h5M0FtUUIflBSdI7
|
|
||||||
username: admin
|
|
||||||
```
|
|
||||||
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
kubectl config use-context dev
|
|
||||||
```
|
|
||||||
|
|
||||||
You can verify your current context by doing the following:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
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.
|
|
||||||
|
|
||||||
Let's create some contents.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
kubectl run snowflake --image=k8s.gcr.io/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.
|
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.
|
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
|
```shell
|
||||||
kubectl get deployment
|
kubectl get deployment -n=development
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||||
snowflake 2/2 2 2 2m
|
snowflake 2/2 2 2 2m
|
||||||
```
|
```
|
||||||
```shell
|
```shell
|
||||||
kubectl get pods -l run=snowflake
|
kubectl get pods -l run=snowflake -n=development
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
@@ -281,23 +215,19 @@ This delete is asynchronous, so for a time you will see the namespace in the `Te
|
|||||||
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
```shell
|
||||||
kubectl get deployment
|
kubectl get deployment -n=production
|
||||||
kubectl get pods
|
kubectl get pods -n=production
|
||||||
```
|
```
|
||||||
|
|
||||||
Production likes to run cattle, so let's create some cattle pods.
|
Production likes to run cattle, so let's create some cattle pods.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl run cattle --image=k8s.gcr.io/serve_hostname --replicas=5
|
kubectl run cattle --image=k8s.gcr.io/serve_hostname --replicas=5 -n=production
|
||||||
|
|
||||||
kubectl get deployment
|
kubectl get deployment -n=production
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||||
@@ -305,7 +235,7 @@ This delete is asynchronous, so for a time you will see the namespace in the `Te
|
|||||||
```
|
```
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get pods -l run=cattle
|
kubectl get pods -l run=cattle -n=production
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
reviewers:
|
reviewers:
|
||||||
- bowei
|
- bowei
|
||||||
- zihongz
|
- zihongz
|
||||||
|
- sftim
|
||||||
title: Using NodeLocal DNSCache in Kubernetes clusters
|
title: Using NodeLocal DNSCache in Kubernetes clusters
|
||||||
content_template: templates/task
|
content_template: templates/task
|
||||||
---
|
---
|
||||||
@@ -47,18 +48,44 @@ This is the path followed by DNS Queries after NodeLocal DNSCache is enabled:
|
|||||||
{{< figure src="/images/docs/nodelocaldns.jpg" alt="NodeLocal DNSCache flow" title="Nodelocal DNSCache flow" caption="This image shows how NodeLocal DNSCache handles DNS queries." >}}
|
{{< figure src="/images/docs/nodelocaldns.jpg" alt="NodeLocal DNSCache flow" title="Nodelocal DNSCache flow" caption="This image shows how NodeLocal DNSCache handles DNS queries." >}}
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
{{< note >}} The local listen IP address for NodeLocal DNSCache can be any IP in the 169.254.20.0/16 space or any other IP address that can be guaranteed to not collide with any existing IP. This document uses 169.254.20.10 as an example.
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
This feature can be enabled using the command:
|
This feature can be enabled using the following steps:
|
||||||
|
|
||||||
`KUBE_ENABLE_NODELOCAL_DNS=true kubetest --up`
|
* Prepare a manifest similar to the sample [`nodelocaldns.yaml`](https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml) and save it as `nodelocaldns.yaml.`
|
||||||
|
* Substitute the variables in the manifest with the right values:
|
||||||
|
|
||||||
This works for e2e clusters created on GCE. On all other environments, the following steps will setup NodeLocal DNSCache:
|
* kubedns=`kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}`
|
||||||
|
|
||||||
|
* domain=`<cluster-domain>`
|
||||||
|
|
||||||
|
* localdns=`<node-local-address>`
|
||||||
|
|
||||||
|
`<cluster-domain>` is "cluster.local" by default. `<node-local-address>` is the local listen IP address chosen for NodeLocal DNSCache.
|
||||||
|
|
||||||
* A yaml similar to [this](https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml) can be applied using `kubectl create -f` command.
|
* If kube-proxy is running in IPTABLES mode:
|
||||||
* No need to modify the --cluster-dns flag since NodeLocal DNSCache listens on both the kube-dns service IP as well as a link-local IP (169.254.20.10 by default)
|
|
||||||
|
``` bash
|
||||||
|
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
`__PILLAR__CLUSTER__DNS__` and `__PILLAR__UPSTREAM__SERVERS__` will be populated by the node-local-dns pods.
|
||||||
|
In this mode, node-local-dns pods listen on both the kube-dns service IP as well as `<node-local-address>`, so pods can lookup DNS records using either IP address.
|
||||||
|
|
||||||
|
* If kube-proxy is running in IPVS mode:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml
|
||||||
|
```
|
||||||
|
In this mode, node-local-dns pods listen only on `<node-local-address>`. The node-local-dns interface cannot bind the kube-dns cluster IP since the interface used for IPVS loadbalancing already uses this address.
|
||||||
|
`__PILLAR__UPSTREAM__SERVERS__` will be populated by the node-local-dns pods.
|
||||||
|
|
||||||
|
* Run `kubectl create -f nodelocaldns.yaml`
|
||||||
|
* If using kube-proxy in IPVS mode, `--cluster-dns` flag to kubelet needs to be modified to use `<node-local-address>` that NodeLocal DNSCache is listening on.
|
||||||
|
Otherwise, there is no need to modify the value of the `--cluster-dns` flag, since NodeLocal DNSCache listens on both the kube-dns service IP as well as `<node-local-address>`.
|
||||||
|
|
||||||
Once enabled, node-local-dns Pods will run in the kube-system namespace on each of the cluster nodes. This Pod runs [CoreDNS](https://github.com/coredns/coredns) in cache mode, so all CoreDNS metrics exposed by the different plugins will be available on a per-node basis.
|
Once enabled, node-local-dns Pods will run in the kube-system namespace on each of the cluster nodes. This Pod runs [CoreDNS](https://github.com/coredns/coredns) in cache mode, so all CoreDNS metrics exposed by the different plugins will be available on a per-node basis.
|
||||||
|
|
||||||
The feature can be disabled by removing the daemonset, using `kubectl delete -f` command. On e2e clusters created on GCE, the daemonset can be removed by deleting the node-local-dns yaml from `/etc/kubernetes/addons/0-dns/nodelocaldns.yaml`
|
You can disable this feature by removing the DaemonSet, using `kubectl delete -f <manifest>` . You should also revert any changes you made to the kubelet configuration.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|||||||
@@ -98,13 +98,7 @@ be configured to use the `systemd` cgroup driver.
|
|||||||
`kube-reserved` is meant to capture resource reservation for kubernetes system
|
`kube-reserved` is meant to capture resource reservation for kubernetes system
|
||||||
daemons like the `kubelet`, `container runtime`, `node problem detector`, etc.
|
daemons like the `kubelet`, `container runtime`, `node problem detector`, etc.
|
||||||
It is not meant to reserve resources for system daemons that are run as pods.
|
It is not meant to reserve resources for system daemons that are run as pods.
|
||||||
`kube-reserved` is typically a function of `pod density` on the nodes. [This
|
`kube-reserved` is typically a function of `pod density` on the nodes.
|
||||||
performance dashboard](http://node-perf-dash.k8s.io/#/builds) exposes `cpu` and
|
|
||||||
`memory` usage profiles of `kubelet` and `docker engine` at multiple levels of
|
|
||||||
pod density. [This blog
|
|
||||||
post](https://kubernetes.io/blog/2016/11/visualize-kubelet-performance-with-node-dashboard)
|
|
||||||
explains how the dashboard can be interpreted to come up with a suitable
|
|
||||||
`kube-reserved` reservation.
|
|
||||||
|
|
||||||
In addition to `cpu`, `memory`, and `ephemeral-storage`, `pid` may be
|
In addition to `cpu`, `memory`, and `ephemeral-storage`, `pid` may be
|
||||||
specified to reserve the specified number of process IDs for
|
specified to reserve the specified number of process IDs for
|
||||||
|
|||||||
+31
-31
@@ -6,20 +6,20 @@ weight: 110
|
|||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
|
|
||||||
This page shows how to configure liveness, readiness and startup probes for Containers.
|
This page shows how to configure liveness, readiness and startup probes for containers.
|
||||||
|
|
||||||
The [kubelet](/docs/admin/kubelet/) uses liveness probes to know when to
|
The [kubelet](/docs/admin/kubelet/) uses liveness probes to know when to
|
||||||
restart a Container. For example, liveness probes could catch a deadlock,
|
restart a container. For example, liveness probes could catch a deadlock,
|
||||||
where an application is running, but unable to make progress. Restarting a
|
where an application is running, but unable to make progress. Restarting a
|
||||||
Container in such a state can help to make the application more available
|
container in such a state can help to make the application more available
|
||||||
despite bugs.
|
despite bugs.
|
||||||
|
|
||||||
The kubelet uses readiness probes to know when a Container is ready to start
|
The kubelet uses readiness probes to know when a container is ready to start
|
||||||
accepting traffic. A Pod is considered ready when all of its Containers are ready.
|
accepting traffic. A Pod is considered ready when all of its containers are ready.
|
||||||
One use of this signal is to control which Pods are used as backends for Services.
|
One use of this signal is to control which Pods are used as backends for Services.
|
||||||
When a Pod is not ready, it is removed from Service load balancers.
|
When a Pod is not ready, it is removed from Service load balancers.
|
||||||
|
|
||||||
The kubelet uses startup probes to know when a Container application has started.
|
The kubelet uses startup probes to know when a container application has started.
|
||||||
If such a probe is configured, it disables liveness and readiness checks until
|
If such a probe is configured, it disables liveness and readiness checks until
|
||||||
it succeeds, making sure those probes don't interfere with the application startup.
|
it succeeds, making sure those probes don't interfere with the application startup.
|
||||||
This can be used to adopt liveness checks on slow starting containers, avoiding them
|
This can be used to adopt liveness checks on slow starting containers, avoiding them
|
||||||
@@ -41,27 +41,27 @@ Many applications running for long periods of time eventually transition to
|
|||||||
broken states, and cannot recover except by being restarted. Kubernetes provides
|
broken states, and cannot recover except by being restarted. Kubernetes provides
|
||||||
liveness probes to detect and remedy such situations.
|
liveness probes to detect and remedy such situations.
|
||||||
|
|
||||||
In this exercise, you create a Pod that runs a Container based on the
|
In this exercise, you create a Pod that runs a container based on the
|
||||||
`k8s.gcr.io/busybox` image. Here is the configuration file for the Pod:
|
`k8s.gcr.io/busybox` image. Here is the configuration file for the Pod:
|
||||||
|
|
||||||
{{< codenew file="pods/probe/exec-liveness.yaml" >}}
|
{{< codenew file="pods/probe/exec-liveness.yaml" >}}
|
||||||
|
|
||||||
In the configuration file, you can see that the Pod has a single Container.
|
In the configuration file, you can see that the Pod has a single `Container`.
|
||||||
The `periodSeconds` field specifies that the kubelet should perform a liveness
|
The `periodSeconds` field specifies that the kubelet should perform a liveness
|
||||||
probe every 5 seconds. The `initialDelaySeconds` field tells the kubelet that it
|
probe every 5 seconds. The `initialDelaySeconds` field tells the kubelet that it
|
||||||
should wait 5 second before performing the first probe. To perform a probe, the
|
should wait 5 second before performing the first probe. To perform a probe, the
|
||||||
kubelet executes the command `cat /tmp/healthy` in the Container. If the
|
kubelet executes the command `cat /tmp/healthy` in the target container. If the
|
||||||
command succeeds, it returns 0, and the kubelet considers the Container to be alive and
|
command succeeds, it returns 0, and the kubelet considers the container to be alive and
|
||||||
healthy. If the command returns a non-zero value, the kubelet kills the Container
|
healthy. If the command returns a non-zero value, the kubelet kills the container
|
||||||
and restarts it.
|
and restarts it.
|
||||||
|
|
||||||
When the Container starts, it executes this command:
|
When the container starts, it executes this command:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
|
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
|
||||||
```
|
```
|
||||||
|
|
||||||
For the first 30 seconds of the Container's life, there is a `/tmp/healthy` file.
|
For the first 30 seconds of the container's life, there is a `/tmp/healthy` file.
|
||||||
So during the first 30 seconds, the command `cat /tmp/healthy` returns a success
|
So during the first 30 seconds, the command `cat /tmp/healthy` returns a success
|
||||||
code. After 30 seconds, `cat /tmp/healthy` returns a failure code.
|
code. After 30 seconds, `cat /tmp/healthy` returns a failure code.
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ kubectl describe pod liveness-exec
|
|||||||
|
|
||||||
The output indicates that no liveness probes have failed yet:
|
The output indicates that no liveness probes have failed yet:
|
||||||
|
|
||||||
```shell
|
```
|
||||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||||
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
|
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
|
||||||
@@ -98,7 +98,7 @@ kubectl describe pod liveness-exec
|
|||||||
At the bottom of the output, there are messages indicating that the liveness
|
At the bottom of the output, there are messages indicating that the liveness
|
||||||
probes have failed, and the containers have been killed and recreated.
|
probes have failed, and the containers have been killed and recreated.
|
||||||
|
|
||||||
```shell
|
```
|
||||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||||
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
|
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
|
||||||
@@ -109,7 +109,7 @@ FirstSeen LastSeen Count From SubobjectPath Type
|
|||||||
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
|
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
|
||||||
```
|
```
|
||||||
|
|
||||||
Wait another 30 seconds, and verify that the Container has been restarted:
|
Wait another 30 seconds, and verify that the container has been restarted:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get pod liveness-exec
|
kubectl get pod liveness-exec
|
||||||
@@ -117,7 +117,7 @@ kubectl get pod liveness-exec
|
|||||||
|
|
||||||
The output shows that `RESTARTS` has been incremented:
|
The output shows that `RESTARTS` has been incremented:
|
||||||
|
|
||||||
```shell
|
```
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
liveness-exec 1/1 Running 1 1m
|
liveness-exec 1/1 Running 1 1m
|
||||||
```
|
```
|
||||||
@@ -130,23 +130,23 @@ image.
|
|||||||
|
|
||||||
{{< codenew file="pods/probe/http-liveness.yaml" >}}
|
{{< codenew file="pods/probe/http-liveness.yaml" >}}
|
||||||
|
|
||||||
In the configuration file, you can see that the Pod has a single Container.
|
In the configuration file, you can see that the Pod has a single container.
|
||||||
The `periodSeconds` field specifies that the kubelet should perform a liveness
|
The `periodSeconds` field specifies that the kubelet should perform a liveness
|
||||||
probe every 3 seconds. The `initialDelaySeconds` field tells the kubelet that it
|
probe every 3 seconds. The `initialDelaySeconds` field tells the kubelet that it
|
||||||
should wait 3 seconds before performing the first probe. To perform a probe, the
|
should wait 3 seconds before performing the first probe. To perform a probe, the
|
||||||
kubelet sends an HTTP GET request to the server that is running in the Container
|
kubelet sends an HTTP GET request to the server that is running in the container
|
||||||
and listening on port 8080. If the handler for the server's `/healthz` path
|
and listening on port 8080. If the handler for the server's `/healthz` path
|
||||||
returns a success code, the kubelet considers the Container to be alive and
|
returns a success code, the kubelet considers the container to be alive and
|
||||||
healthy. If the handler returns a failure code, the kubelet kills the Container
|
healthy. If the handler returns a failure code, the kubelet kills the container
|
||||||
and restarts it.
|
and restarts it.
|
||||||
|
|
||||||
Any code greater than or equal to 200 and less than 400 indicates success. Any
|
Any code greater than or equal to 200 and less than 400 indicates success. Any
|
||||||
other code indicates failure.
|
other code indicates failure.
|
||||||
|
|
||||||
You can see the source code for the server in
|
You can see the source code for the server in
|
||||||
[server.go](https://github.com/kubernetes/kubernetes/blob/master/test/images/agnhost/liveness/server.go).
|
[server.go](https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/test/images/agnhost/liveness/server.go).
|
||||||
|
|
||||||
For the first 10 seconds that the Container is alive, the `/healthz` handler
|
For the first 10 seconds that the container is alive, the `/healthz` handler
|
||||||
returns a status of 200. After that, the handler returns a status of 500.
|
returns a status of 200. After that, the handler returns a status of 500.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@@ -162,9 +162,9 @@ http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The kubelet starts performing health checks 3 seconds after the Container starts.
|
The kubelet starts performing health checks 3 seconds after the container starts.
|
||||||
So the first couple of health checks will succeed. But after 10 seconds, the health
|
So the first couple of health checks will succeed. But after 10 seconds, the health
|
||||||
checks will fail, and the kubelet will kill and restart the Container.
|
checks will fail, and the kubelet will kill and restart the container.
|
||||||
|
|
||||||
To try the HTTP liveness check, create a Pod:
|
To try the HTTP liveness check, create a Pod:
|
||||||
|
|
||||||
@@ -173,21 +173,21 @@ kubectl apply -f https://k8s.io/examples/pods/probe/http-liveness.yaml
|
|||||||
```
|
```
|
||||||
|
|
||||||
After 10 seconds, view Pod events to verify that liveness probes have failed and
|
After 10 seconds, view Pod events to verify that liveness probes have failed and
|
||||||
the Container has been restarted:
|
the container has been restarted:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl describe pod liveness-http
|
kubectl describe pod liveness-http
|
||||||
```
|
```
|
||||||
|
|
||||||
In releases prior to v1.13 (including v1.13), if the environment variable
|
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,
|
`http_proxy` (or `HTTP_PROXY`) is set on the node where a Pod is running,
|
||||||
the HTTP liveness probe uses that proxy.
|
the HTTP liveness probe uses that proxy.
|
||||||
In releases after v1.13, local HTTP proxy environment variable settings do not
|
In releases after v1.13, local HTTP proxy environment variable settings do not
|
||||||
affect the HTTP liveness probe.
|
affect the HTTP liveness probe.
|
||||||
|
|
||||||
## Define a TCP liveness probe
|
## Define a TCP liveness probe
|
||||||
|
|
||||||
A third type of liveness probe uses a TCP Socket. With this configuration, the
|
A third type of liveness probe uses a TCP socket. With this configuration, the
|
||||||
kubelet will attempt to open a socket to your container on the specified port.
|
kubelet will attempt to open a socket to your container on the specified port.
|
||||||
If it can establish a connection, the container is considered healthy, if it
|
If it can establish a connection, the container is considered healthy, if it
|
||||||
can’t it is considered a failure.
|
can’t it is considered a failure.
|
||||||
@@ -197,7 +197,7 @@ can’t it is considered a failure.
|
|||||||
As you can see, configuration for a TCP check is quite similar to an HTTP check.
|
As you can see, configuration for a TCP check is quite similar to an HTTP check.
|
||||||
This example uses both readiness and liveness probes. The kubelet will send the
|
This example uses both readiness and liveness probes. The kubelet will send the
|
||||||
first readiness probe 5 seconds after the container starts. This will attempt to
|
first readiness probe 5 seconds after the container starts. This will attempt to
|
||||||
connect to the `goproxy` container on port 8080. If the probe succeeds, the pod
|
connect to the `goproxy` container on port 8080. If the probe succeeds, the Pod
|
||||||
will be marked as ready. The kubelet will continue to run this check every 10
|
will be marked as ready. The kubelet will continue to run this check every 10
|
||||||
seconds.
|
seconds.
|
||||||
|
|
||||||
@@ -351,7 +351,7 @@ port to perform the check. The kubelet sends the probe to the pod’s IP address
|
|||||||
unless the address is overridden by the optional `host` field in `httpGet`. If
|
unless the address is overridden by the optional `host` field in `httpGet`. If
|
||||||
`scheme` field is set to `HTTPS`, the kubelet sends an HTTPS request skipping the
|
`scheme` field is set to `HTTPS`, the kubelet sends an HTTPS request skipping the
|
||||||
certificate verification. In most scenarios, you do not want to set the `host` field.
|
certificate verification. In most scenarios, you do not want to set the `host` field.
|
||||||
Here's one scenario where you would set it. Suppose the Container listens on 127.0.0.1
|
Here's one scenario where you would set it. Suppose the container listens on 127.0.0.1
|
||||||
and the Pod's `hostNetwork` field is true. Then `host`, under `httpGet`, should be set
|
and the Pod's `hostNetwork` field is true. Then `host`, under `httpGet`, should be set
|
||||||
to 127.0.0.1. If your pod relies on virtual hosts, which is probably the more common
|
to 127.0.0.1. If your pod relies on virtual hosts, which is probably the more common
|
||||||
case, you should not use `host`, but rather set the `Host` header in `httpHeaders`.
|
case, you should not use `host`, but rather set the `Host` header in `httpHeaders`.
|
||||||
@@ -367,7 +367,7 @@ to resolve it.
|
|||||||
* Learn more about
|
* Learn more about
|
||||||
[Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes).
|
[Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes).
|
||||||
|
|
||||||
### Reference
|
You can also read the API references for:
|
||||||
|
|
||||||
* [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)
|
* [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)
|
||||||
* [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core)
|
* [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core)
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ kubectl get nodes
|
|||||||
|
|
||||||
And verify that all of the nodes you expect to see are present and that they are all in the `Ready` state.
|
And verify that all of the nodes you expect to see are present and that they are all in the `Ready` state.
|
||||||
|
|
||||||
|
To get detailed information about the overall health of your cluster, you can run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl cluster-info dump
|
||||||
|
```
|
||||||
## Looking at logs
|
## Looking at logs
|
||||||
|
|
||||||
For now, digging deeper into the cluster requires logging into the relevant machines. Here are the locations
|
For now, digging deeper into the cluster requires logging into the relevant machines. Here are the locations
|
||||||
|
|||||||
@@ -8,57 +8,30 @@ title: Debug Services
|
|||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
An issue that comes up rather frequently for new installations of Kubernetes is
|
An issue that comes up rather frequently for new installations of Kubernetes is
|
||||||
that a `Service` is not working properly. You've run your `Deployment` and
|
that a Service is not working properly. You've run your Pods through a
|
||||||
created a `Service`, but you get no response when you try to access it.
|
Deployment (or other workload controller) and created a Service, but you
|
||||||
This document will hopefully help you to figure out what's going wrong.
|
get no response when you try to access it. This document will hopefully help
|
||||||
|
you to figure out what's going wrong.
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
|
|
||||||
{{% capture body %}}
|
{{% capture body %}}
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
Throughout this doc you will see various commands that you can run. Some
|
|
||||||
commands need to be run within a `Pod`, others on a Kubernetes `Node`, and others
|
|
||||||
can run anywhere you have `kubectl` and credentials for the cluster. To make it
|
|
||||||
clear what is expected, this document will use the following conventions.
|
|
||||||
|
|
||||||
If the command "COMMAND" is expected to run in a `Pod` and produce "OUTPUT":
|
|
||||||
|
|
||||||
```shell
|
|
||||||
u@pod$ COMMAND
|
|
||||||
OUTPUT
|
|
||||||
```
|
|
||||||
|
|
||||||
If the command "COMMAND" is expected to run on a `Node` and produce "OUTPUT":
|
|
||||||
|
|
||||||
```shell
|
|
||||||
u@node$ COMMAND
|
|
||||||
OUTPUT
|
|
||||||
```
|
|
||||||
|
|
||||||
If the command is "kubectl ARGS":
|
|
||||||
|
|
||||||
```shell
|
|
||||||
kubectl ARGS
|
|
||||||
OUTPUT
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running commands in a Pod
|
## Running commands in a Pod
|
||||||
|
|
||||||
For many steps here you will want to see what a `Pod` running in the cluster
|
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 alpine `Pod`:
|
sees. The simplest way to do this is to run an interactive alpine Pod:
|
||||||
|
|
||||||
```none
|
```none
|
||||||
kubectl run -it --rm --restart=Never alpine --image=alpine sh
|
kubectl run -it --rm --restart=Never alpine --image=alpine sh
|
||||||
/ #
|
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
If you don't see a command prompt, try pressing enter.
|
If you don't see a command prompt, try pressing enter.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
If you already have a running `Pod` that you prefer to use, you can run a
|
If you already have a running Pod that you prefer to use, you can run a
|
||||||
command in it using:
|
command in it using:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -67,21 +40,23 @@ kubectl exec <POD-NAME> -c <CONTAINER-NAME> -- <COMMAND>
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
For the purposes of this walk-through, let's run some `Pods`. Since you're
|
For the purposes of this walk-through, let's run some Pods. Since you're
|
||||||
probably debugging your own `Service` you can substitute your own details, or you
|
probably debugging your own Service you can substitute your own details, or you
|
||||||
can follow along and get a second data point.
|
can follow along and get a second data point.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl run hostnames --image=k8s.gcr.io/serve_hostname \
|
kubectl run hostnames --image=k8s.gcr.io/serve_hostname \
|
||||||
--labels=app=hostnames \
|
--replicas=3
|
||||||
--port=9376 \
|
```
|
||||||
--replicas=3
|
```none
|
||||||
deployment.apps/hostnames created
|
deployment.apps/hostnames created
|
||||||
```
|
```
|
||||||
|
|
||||||
`kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands.
|
`kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands.
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
This is the same as if you started the `Deployment` with the following YAML:
|
This is the same as if you had started the Deployment with the following
|
||||||
|
YAML:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
@@ -91,61 +66,111 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: hostnames
|
run: hostnames
|
||||||
replicas: 3
|
replicas: 3
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app: hostnames
|
run: hostnames
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: hostnames
|
- name: hostnames
|
||||||
image: k8s.gcr.io/serve_hostname
|
image: k8s.gcr.io/serve_hostname
|
||||||
ports:
|
|
||||||
- containerPort: 9376
|
|
||||||
protocol: TCP
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The label "run" is automatically set by `kubectl run` to the name of the
|
||||||
|
Deployment.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
Confirm your `Pods` are running:
|
You can confirm your Pods are running:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get pods -l app=hostnames
|
kubectl get pods -l run=hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
hostnames-632524106-bbpiw 1/1 Running 0 2m
|
hostnames-632524106-bbpiw 1/1 Running 0 2m
|
||||||
hostnames-632524106-ly40y 1/1 Running 0 2m
|
hostnames-632524106-ly40y 1/1 Running 0 2m
|
||||||
hostnames-632524106-tlaok 1/1 Running 0 2m
|
hostnames-632524106-tlaok 1/1 Running 0 2m
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also confirm that your Pods are serving. You can get the list of
|
||||||
|
Pod IP addresses and test them directly.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get pods -l run=hostnames \
|
||||||
|
-o go-template='{{range .items}}{{.status.podIP}}{{"\n"}}{{end}}'
|
||||||
|
```
|
||||||
|
```none
|
||||||
|
10.244.0.5
|
||||||
|
10.244.0.6
|
||||||
|
10.244.0.7
|
||||||
|
```
|
||||||
|
|
||||||
|
The example container used for this walk-through simply serves its own hostname
|
||||||
|
via HTTP on port 9376, but if you are debugging your own app, you'll want to
|
||||||
|
use whatever port number your Pods are listening on.
|
||||||
|
|
||||||
|
From within a pod:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do
|
||||||
|
wget -qO- $ep
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
This should produce something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
hostnames-0uton
|
||||||
|
hostnames-bvc05
|
||||||
|
hostnames-yp2kp
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are not getting the responses you expect at this point, your Pods
|
||||||
|
might not be healthy or might not be listening on the port you think they are.
|
||||||
|
You might find `kubectl logs` to be useful for seeing what is happening, or
|
||||||
|
perhaps you need to `kubectl exec` directly into your Pods and debug from
|
||||||
|
there.
|
||||||
|
|
||||||
|
Assuming everything has gone to plan so far, you can start to investigate why
|
||||||
|
your Service doesn't work.
|
||||||
|
|
||||||
## Does the Service exist?
|
## Does the Service exist?
|
||||||
|
|
||||||
The astute reader will have noticed that we did not actually create a `Service`
|
The astute reader will have noticed that you did not actually create a Service
|
||||||
yet - that is intentional. This is a step that sometimes gets forgotten, and
|
yet - that is intentional. This is a step that sometimes gets forgotten, and
|
||||||
is the first thing to check.
|
is the first thing to check.
|
||||||
|
|
||||||
So what would happen if I tried to access a non-existent `Service`? Assuming you
|
What would happen if you tried to access a non-existent Service? If
|
||||||
have another `Pod` that consumes this `Service` by name you would get something
|
you have another Pod that consumes this Service by name you would get
|
||||||
like:
|
something like:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ wget -O- hostnames
|
wget -O- hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
Resolving hostnames (hostnames)... failed: Name or service not known.
|
Resolving hostnames (hostnames)... failed: Name or service not known.
|
||||||
wget: unable to resolve host address 'hostnames'
|
wget: unable to resolve host address 'hostnames'
|
||||||
```
|
```
|
||||||
|
|
||||||
So the first thing to check is whether that `Service` actually exists:
|
The first thing to check is whether that Service actually exists:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get svc hostnames
|
kubectl get svc hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
No resources found.
|
No resources found.
|
||||||
Error from server (NotFound): services "hostnames" not found
|
Error from server (NotFound): services "hostnames" not found
|
||||||
```
|
```
|
||||||
|
|
||||||
So we have a culprit, let's create the `Service`. As before, this is for the
|
Let's create the Service. As before, this is for the walk-through - you can
|
||||||
walk-through - you can use your own `Service`'s details here.
|
use your own Service's details here.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl expose deployment hostnames --port=80 --target-port=9376
|
kubectl expose deployment hostnames --port=80 --target-port=9376
|
||||||
|
```
|
||||||
|
```none
|
||||||
service/hostnames exposed
|
service/hostnames exposed
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -153,11 +178,16 @@ And read it back, just to be sure:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get svc hostnames
|
kubectl get svc hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
hostnames ClusterIP 10.0.1.175 <none> 80/TCP 5s
|
hostnames ClusterIP 10.0.1.175 <none> 80/TCP 5s
|
||||||
```
|
```
|
||||||
|
|
||||||
As before, this is the same as if you had started the `Service` with YAML:
|
Now you know that the Service exists.
|
||||||
|
|
||||||
|
{{< note >}}
|
||||||
|
As before, this is the same as if you had started the Service with YAML:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -166,7 +196,7 @@ metadata:
|
|||||||
name: hostnames
|
name: hostnames
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
app: hostnames
|
run: hostnames
|
||||||
ports:
|
ports:
|
||||||
- name: default
|
- name: default
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
@@ -174,25 +204,35 @@ spec:
|
|||||||
targetPort: 9376
|
targetPort: 9376
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you can confirm that the `Service` exists.
|
In order to highlight the full range of configuration, the Service you created
|
||||||
|
here uses a different port number than the Pods. For many real-world
|
||||||
|
Services, these values might be the same.
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
## Does the Service work by DNS?
|
## Does the Service work by DNS name?
|
||||||
|
|
||||||
From a `Pod` in the same `Namespace`:
|
One of the most common ways that clients consume a Service is through a DNS
|
||||||
|
name.
|
||||||
|
|
||||||
|
From a Pod in the same Namespace:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ nslookup hostnames
|
nslookup hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||||
|
|
||||||
Name: hostnames
|
Name: hostnames
|
||||||
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
|
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
|
||||||
```
|
```
|
||||||
|
|
||||||
If this fails, perhaps your `Pod` and `Service` are in different
|
If this fails, perhaps your Pod and Service are in different
|
||||||
`Namespaces`, try a namespace-qualified name:
|
Namespaces, try a namespace-qualified name (again, from within a Pod):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ nslookup hostnames.default
|
nslookup hostnames.default
|
||||||
|
```
|
||||||
|
```none
|
||||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||||
|
|
||||||
Name: hostnames.default
|
Name: hostnames.default
|
||||||
@@ -200,11 +240,13 @@ Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
|
|||||||
```
|
```
|
||||||
|
|
||||||
If this works, you'll need to adjust your app to use a cross-namespace name, or
|
If this works, you'll need to adjust your app to use a cross-namespace name, or
|
||||||
run your app and `Service` in the same `Namespace`. If this still fails, try a
|
run your app and Service in the same Namespace. If this still fails, try a
|
||||||
fully-qualified name:
|
fully-qualified name:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ nslookup hostnames.default.svc.cluster.local
|
nslookup hostnames.default.svc.cluster.local
|
||||||
|
```
|
||||||
|
```none
|
||||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||||
|
|
||||||
Name: hostnames.default.svc.cluster.local
|
Name: hostnames.default.svc.cluster.local
|
||||||
@@ -212,18 +254,20 @@ Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note the suffix here: "default.svc.cluster.local". The "default" is the
|
Note the suffix here: "default.svc.cluster.local". The "default" is the
|
||||||
`Namespace` we're operating in. The "svc" denotes that this is a `Service`.
|
Namespace you're operating in. The "svc" denotes that this is a Service.
|
||||||
The "cluster.local" is your cluster domain, which COULD be different in your
|
The "cluster.local" is your cluster domain, which COULD be different in your
|
||||||
own cluster.
|
own cluster.
|
||||||
|
|
||||||
You can also try this from a `Node` in the cluster:
|
You can also try this from a Node in the cluster:
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
10.0.0.10 is my DNS `Service`, yours might be different.
|
10.0.0.10 is the cluster's DNS Service IP, yours might be different.
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ nslookup hostnames.default.svc.cluster.local 10.0.0.10
|
nslookup hostnames.default.svc.cluster.local 10.0.0.10
|
||||||
|
```
|
||||||
|
```none
|
||||||
Server: 10.0.0.10
|
Server: 10.0.0.10
|
||||||
Address: 10.0.0.10#53
|
Address: 10.0.0.10#53
|
||||||
|
|
||||||
@@ -232,39 +276,49 @@ Address: 10.0.1.175
|
|||||||
```
|
```
|
||||||
|
|
||||||
If you are able to do a fully-qualified name lookup but not a relative one, you
|
If you are able to do a fully-qualified name lookup but not a relative one, you
|
||||||
need to check that your `/etc/resolv.conf` file is correct.
|
need to check that your `/etc/resolv.conf` file in your Pod is correct. From
|
||||||
|
within a Pod:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ cat /etc/resolv.conf
|
cat /etc/resolv.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see something like:
|
||||||
|
|
||||||
|
```
|
||||||
nameserver 10.0.0.10
|
nameserver 10.0.0.10
|
||||||
search default.svc.cluster.local svc.cluster.local cluster.local example.com
|
search default.svc.cluster.local svc.cluster.local cluster.local example.com
|
||||||
options ndots:5
|
options ndots:5
|
||||||
```
|
```
|
||||||
|
|
||||||
The `nameserver` line must indicate your cluster's DNS `Service`. This is
|
The `nameserver` line must indicate your cluster's DNS Service. This is
|
||||||
passed into `kubelet` with the `--cluster-dns` flag.
|
passed into `kubelet` with the `--cluster-dns` flag.
|
||||||
|
|
||||||
The `search` line must include an appropriate suffix for you to find the
|
The `search` line must include an appropriate suffix for you to find the
|
||||||
`Service` name. In this case it is looking for `Services` in the local
|
Service name. In this case it is looking for Services in the local
|
||||||
`Namespace` (`default.svc.cluster.local`), `Services` in all `Namespaces`
|
Namespace ("default.svc.cluster.local"), Services in all Namespaces
|
||||||
(`svc.cluster.local`), and the cluster (`cluster.local`). Depending on your own
|
("svc.cluster.local"), and lastly for names in the cluster ("cluster.local").
|
||||||
install you might have additional records after that (up to 6 total). The
|
Depending on your own install you might have additional records after that (up
|
||||||
cluster suffix is passed into `kubelet` with the `--cluster-domain` flag. We
|
to 6 total). The cluster suffix is passed into `kubelet` with the
|
||||||
assume that is "cluster.local" in this document, but yours might be different,
|
`--cluster-domain` flag. Throughout this document, the cluster suffix is
|
||||||
in which case you should change that in all of the commands above.
|
assumed to be "cluster.local". Your own clusters might be configured
|
||||||
|
differently, in which case you should change that in all of the previous
|
||||||
|
commands.
|
||||||
|
|
||||||
The `options` line must set `ndots` high enough that your DNS client library
|
The `options` line must set `ndots` high enough that your DNS client library
|
||||||
considers search paths at all. Kubernetes sets this to 5 by default, which is
|
considers search paths at all. Kubernetes sets this to 5 by default, which is
|
||||||
high enough to cover all of the DNS names it generates.
|
high enough to cover all of the DNS names it generates.
|
||||||
|
|
||||||
### Does any Service exist in DNS?
|
### Does any Service work by DNS name? {#does-any-service-exist-in-dns}
|
||||||
|
|
||||||
If the above still fails - DNS lookups are not working for your `Service` - we
|
If the above still fails, DNS lookups are not working for your Service. You
|
||||||
can take a step back and see what else is not working. The Kubernetes master
|
can take a step back and see what else is not working. The Kubernetes master
|
||||||
`Service` should always work:
|
Service should always work. From within a Pod:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ nslookup kubernetes.default
|
nslookup kubernetes.default
|
||||||
|
```
|
||||||
|
```none
|
||||||
Server: 10.0.0.10
|
Server: 10.0.0.10
|
||||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||||
|
|
||||||
@@ -272,34 +326,37 @@ Name: kubernetes.default
|
|||||||
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
|
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
|
||||||
```
|
```
|
||||||
|
|
||||||
If this fails, you might need to go to the kube-proxy section of this doc, or
|
If this fails, please see the [kube-proxy](#is-the-kube-proxy-working) section
|
||||||
even go back to the top of this document and start over, but instead of
|
of this document, or even go back to the top of this document and start over,
|
||||||
debugging your own `Service`, debug DNS.
|
but instead of debugging your own Service, debug the DNS Service.
|
||||||
|
|
||||||
## Does the Service work by IP?
|
## Does the Service work by IP?
|
||||||
|
|
||||||
Assuming we can confirm that DNS works, the next thing to test is whether your
|
Assuming you have confirmed that DNS works, the next thing to test is whether your
|
||||||
`Service` works at all. From a node in your cluster, access the `Service`'s
|
Service works by its IP address. From a Pod in your cluster, access the
|
||||||
IP (from `kubectl get` above).
|
Service's IP (from `kubectl get` above).
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ curl 10.0.1.175:80
|
for i in $(seq 1 3); do
|
||||||
hostnames-0uton
|
wget -qO- 10.0.1.175:80
|
||||||
|
done
|
||||||
u@node$ curl 10.0.1.175:80
|
|
||||||
hostnames-yp2kp
|
|
||||||
|
|
||||||
u@node$ curl 10.0.1.175:80
|
|
||||||
hostnames-bvc05
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If your `Service` is working, you should get correct responses. If not, there
|
This should produce something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
hostnames-0uton
|
||||||
|
hostnames-bvc05
|
||||||
|
hostnames-yp2kp
|
||||||
|
```
|
||||||
|
|
||||||
|
If your Service is working, you should get correct responses. If not, there
|
||||||
are a number of things that could be going wrong. Read on.
|
are a number of things that could be going wrong. Read on.
|
||||||
|
|
||||||
## Is the Service correct?
|
## Is the Service defined correctly?
|
||||||
|
|
||||||
It might sound silly, but you should really double and triple check that your
|
It might sound silly, but you should really double and triple check that your
|
||||||
`Service` is correct and matches your `Pod`'s port. Read back your `Service`
|
Service is correct and matches your Pod's port. Read back your Service
|
||||||
and verify it:
|
and verify it:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -316,7 +373,7 @@ kubectl get service hostnames -o json
|
|||||||
"resourceVersion": "347189",
|
"resourceVersion": "347189",
|
||||||
"creationTimestamp": "2015-07-07T15:24:29Z",
|
"creationTimestamp": "2015-07-07T15:24:29Z",
|
||||||
"labels": {
|
"labels": {
|
||||||
"app": "hostnames"
|
"run": "hostnames"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
@@ -330,7 +387,7 @@ kubectl get service hostnames -o json
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"selector": {
|
"selector": {
|
||||||
"app": "hostnames"
|
"run": "hostnames"
|
||||||
},
|
},
|
||||||
"clusterIP": "10.0.1.175",
|
"clusterIP": "10.0.1.175",
|
||||||
"type": "ClusterIP",
|
"type": "ClusterIP",
|
||||||
@@ -342,110 +399,116 @@ kubectl get service hostnames -o json
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
* Is the port you are trying to access in `spec.ports[]`?
|
* Is the Service port you are trying to access listed in `spec.ports[]`?
|
||||||
* Is the `targetPort` correct for your `Pods` (many `Pods` choose to use a different port than the `Service`)?
|
* Is the `targetPort` correct for your Pods (some Pods use a different port than the Service)?
|
||||||
* If you meant it to be a numeric port, is it a number (9376) or a
|
* If you meant to use a numeric port, is it a number (9376) or a string "9376"?
|
||||||
string "9376"?
|
* If you meant to use a named port, do your Pods expose a port with the same name?
|
||||||
* If you meant it to be a named port, do your `Pods` expose a port
|
* Is the port's `protocol` correct for your Pods?
|
||||||
with the same name?
|
|
||||||
* Is the port's `protocol` the same as the `Pod`'s?
|
|
||||||
|
|
||||||
## Does the Service have any Endpoints?
|
## Does the Service have any Endpoints?
|
||||||
|
|
||||||
If you got this far, we assume that you have confirmed that your `Service`
|
If you got this far, you have confirmed that your Service is correctly
|
||||||
exists and is resolved by DNS. Now let's check that the `Pods` you ran are
|
defined and is resolved by DNS. Now let's check that the Pods you ran are
|
||||||
actually being selected by the `Service`.
|
actually being selected by the Service.
|
||||||
|
|
||||||
Earlier we saw that the `Pods` were running. We can re-check that:
|
Earlier you saw that the Pods were running. You can re-check that:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get pods -l app=hostnames
|
kubectl get pods -l run=hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
hostnames-0uton 1/1 Running 0 1h
|
hostnames-0uton 1/1 Running 0 1h
|
||||||
hostnames-bvc05 1/1 Running 0 1h
|
hostnames-bvc05 1/1 Running 0 1h
|
||||||
hostnames-yp2kp 1/1 Running 0 1h
|
hostnames-yp2kp 1/1 Running 0 1h
|
||||||
```
|
```
|
||||||
|
|
||||||
The "AGE" column says that these `Pods` are about an hour old, which implies that
|
The `-l run=hostnames` argument is a label selector - just like our Service
|
||||||
|
has.
|
||||||
|
|
||||||
|
The "AGE" column says that these Pods are about an hour old, which implies that
|
||||||
they are running fine and not crashing.
|
they are running fine and not crashing.
|
||||||
|
|
||||||
The `-l app=hostnames` argument is a label selector - just like our `Service`
|
The "RESTARTS" column says that these pods are not crashing frequently or being
|
||||||
has. Inside the Kubernetes system is a control loop which evaluates the
|
restarted. Frequent restarts could lead to intermittent connectivity issues.
|
||||||
selector of every `Service` and saves the results into an `Endpoints` object.
|
If the restart count is high, read more about how to [debug pods](/docs/tasks/debug-application-cluster/debug-pod-replication-controller/#debugging-pods).
|
||||||
|
|
||||||
|
Inside the Kubernetes system is a control loop which evaluates the selector of
|
||||||
|
every Service and saves the results into a corresponding Endpoints object.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get endpoints hostnames
|
kubectl get endpoints hostnames
|
||||||
|
|
||||||
NAME ENDPOINTS
|
NAME ENDPOINTS
|
||||||
hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376
|
hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376
|
||||||
```
|
```
|
||||||
|
|
||||||
This confirms that the endpoints controller has found the correct `Pods` for
|
This confirms that the endpoints controller has found the correct Pods for
|
||||||
your `Service`. If the `hostnames` row is blank, you should check that the
|
your Service. If the `ENDPOINTS` column is `<none>`, you should check that
|
||||||
`spec.selector` field of your `Service` actually selects for `metadata.labels`
|
the `spec.selector` field of your Service actually selects for
|
||||||
values on your `Pods`. A common mistake is to have a typo or other error, such
|
`metadata.labels` values on your Pods. A common mistake is to have a typo or
|
||||||
as the `Service` selecting for `run=hostnames`, but the `Deployment` specifying
|
other error, such as the Service selecting for `app=hostnames`, but the
|
||||||
`app=hostnames`.
|
Deployment specifying `run=hostnames`.
|
||||||
|
|
||||||
## Are the Pods working?
|
## Are the Pods working?
|
||||||
|
|
||||||
At this point, we know that your `Service` exists and has selected your `Pods`.
|
At this point, you know that your Service exists and has selected your Pods.
|
||||||
Let's check that the `Pods` are actually working - we can bypass the `Service`
|
At the beginning of this walk-through, you verified the Pods themselves.
|
||||||
mechanism and go straight to the `Pods`.
|
Let's check again that the Pods are actually working - you can bypass the
|
||||||
|
Service mechanism and go straight to the Pods, as listed by the Endpoints
|
||||||
|
above.
|
||||||
|
|
||||||
{{< note >}}
|
{{< note >}}
|
||||||
These commands use the `Pod` port (9376), rather than the `Service` port (80).
|
These commands use the Pod port (9376), rather than the Service port (80).
|
||||||
{{< /note >}}
|
{{< /note >}}
|
||||||
|
|
||||||
|
From within a Pod:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@pod$ wget -qO- 10.244.0.5:9376
|
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do
|
||||||
|
wget -qO- $ep
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
This should produce something like:
|
||||||
|
|
||||||
|
```
|
||||||
hostnames-0uton
|
hostnames-0uton
|
||||||
|
|
||||||
pod $ wget -qO- 10.244.0.6:9376
|
|
||||||
hostnames-bvc05
|
hostnames-bvc05
|
||||||
|
|
||||||
u@pod$ wget -qO- 10.244.0.7:9376
|
|
||||||
hostnames-yp2kp
|
hostnames-yp2kp
|
||||||
```
|
```
|
||||||
|
|
||||||
We expect each `Pod` in the `Endpoints` list to return its own hostname. If
|
You expect each Pod in the Endpoints list to return its own hostname. If
|
||||||
this is not what happens (or whatever the correct behavior is for your own
|
this is not what happens (or whatever the correct behavior is for your own
|
||||||
`Pods`), you should investigate what's happening there. You might find
|
Pods), you should investigate what's happening there.
|
||||||
`kubectl logs` to be useful or `kubectl exec` directly to your `Pods` and check
|
|
||||||
service from there.
|
|
||||||
|
|
||||||
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
|
|
||||||
NAME READY STATUS RESTARTS AGE
|
|
||||||
hostnames-632524106-bbpiw 1/1 Running 0 2m
|
|
||||||
hostnames-632524106-ly40y 1/1 Running 0 2m
|
|
||||||
hostnames-632524106-tlaok 1/1 Running 0 2m
|
|
||||||
```
|
|
||||||
|
|
||||||
If the restart count is high, read more about how to [debug
|
|
||||||
pods](/docs/tasks/debug-application-cluster/debug-pod-replication-controller/#debugging-pods).
|
|
||||||
|
|
||||||
## Is the kube-proxy working?
|
## Is the kube-proxy working?
|
||||||
|
|
||||||
If you get here, your `Service` is running, has `Endpoints`, and your `Pods`
|
If you get here, your Service is running, has Endpoints, and your Pods
|
||||||
are actually serving. At this point, the whole `Service` proxy mechanism is
|
are actually serving. At this point, the whole Service proxy mechanism is
|
||||||
suspect. Let's confirm it, piece by piece.
|
suspect. Let's confirm it, piece by piece.
|
||||||
|
|
||||||
|
The default implementation of Services, and the one used on most clusters, is
|
||||||
|
kube-proxy. This is a program that runs on every node and configures one of a
|
||||||
|
small set of mechanisms for providing the Service abstraction. If your
|
||||||
|
cluster does not use kube-proxy, the following sections will not apply, and you
|
||||||
|
will have to investigate whatever implementation of Services you are using.
|
||||||
|
|
||||||
### Is kube-proxy running?
|
### Is kube-proxy running?
|
||||||
|
|
||||||
Confirm that `kube-proxy` is running on your `Nodes`. You should get something
|
Confirm that `kube-proxy` is running on your Nodes. Running directly on a
|
||||||
like the below:
|
Node, you should get something like the below:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ ps auxw | grep kube-proxy
|
ps auxw | grep kube-proxy
|
||||||
|
```
|
||||||
|
```none
|
||||||
root 4194 0.4 0.1 101864 17696 ? Sl Jul04 25:43 /usr/local/bin/kube-proxy --master=https://kubernetes-master --kubeconfig=/var/lib/kube-proxy/kubeconfig --v=2
|
root 4194 0.4 0.1 101864 17696 ? Sl Jul04 25:43 /usr/local/bin/kube-proxy --master=https://kubernetes-master --kubeconfig=/var/lib/kube-proxy/kubeconfig --v=2
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, confirm that it is not failing something obvious, like contacting the
|
Next, confirm that it is not failing something obvious, like contacting the
|
||||||
master. To do this, you'll have to look at the logs. Accessing the logs
|
master. To do this, you'll have to look at the logs. Accessing the logs
|
||||||
depends on your `Node` OS. On some OSes it is a file, such as
|
depends on your Node OS. On some OSes it is a file, such as
|
||||||
/var/log/kube-proxy.log, while other OSes use `journalctl` to access logs. You
|
/var/log/kube-proxy.log, while other OSes use `journalctl` to access logs. You
|
||||||
should see something like:
|
should see something like:
|
||||||
|
|
||||||
@@ -463,7 +526,7 @@ I1027 22:14:54.040223 5063 proxier.go:294] Adding new service "kube-system/ku
|
|||||||
```
|
```
|
||||||
|
|
||||||
If you see error messages about not being able to contact the master, you
|
If you see error messages about not being able to contact the master, you
|
||||||
should double-check your `Node` configuration and installation steps.
|
should double-check your Node configuration and installation steps.
|
||||||
|
|
||||||
One of the possible reasons that `kube-proxy` cannot run correctly is that the
|
One of the possible reasons that `kube-proxy` cannot run correctly is that the
|
||||||
required `conntrack` binary cannot be found. This may happen on some Linux
|
required `conntrack` binary cannot be found. This may happen on some Linux
|
||||||
@@ -472,36 +535,19 @@ installing Kubernetes from scratch. If this is the case, you need to manually
|
|||||||
install the `conntrack` package (e.g. `sudo apt install conntrack` on Ubuntu)
|
install the `conntrack` package (e.g. `sudo apt install conntrack` on Ubuntu)
|
||||||
and then retry.
|
and then retry.
|
||||||
|
|
||||||
### Is kube-proxy writing iptables rules?
|
Kube-proxy can run in one of a few modes. In the log listed above, the
|
||||||
|
line `Using iptables Proxier` indicates that kube-proxy is running in
|
||||||
|
"iptables" mode. The most common other mode is "ipvs". The older "userspace"
|
||||||
|
mode has largely been replaced by these.
|
||||||
|
|
||||||
One of the main responsibilities of `kube-proxy` is to write the `iptables`
|
#### Iptables mode
|
||||||
rules which implement `Services`. Let's check that those rules are getting
|
|
||||||
written.
|
|
||||||
|
|
||||||
The kube-proxy can run in "userspace" mode, "iptables" mode or "ipvs" mode.
|
In "iptables" mode, you should see something like the following on a Node:
|
||||||
Hopefully you are using the "iptables" mode or "ipvs" mode. You
|
|
||||||
should see one of the following cases.
|
|
||||||
|
|
||||||
#### Userspace
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ iptables-save | grep hostnames
|
iptables-save | grep hostnames
|
||||||
-A KUBE-PORTALS-CONTAINER -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j REDIRECT --to-ports 48577
|
|
||||||
-A KUBE-PORTALS-HOST -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j DNAT --to-destination 10.240.115.247:48577
|
|
||||||
```
|
```
|
||||||
|
```none
|
||||||
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
|
|
||||||
then look at the logs again.
|
|
||||||
|
|
||||||
Almost nobody should be using the "userspace" mode any more, so we won't spend
|
|
||||||
more time on it here.
|
|
||||||
|
|
||||||
#### Iptables
|
|
||||||
|
|
||||||
```shell
|
|
||||||
u@node$ iptables-save | grep hostnames
|
|
||||||
-A KUBE-SEP-57KPRZ3JQVENLNBR -s 10.244.3.6/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
|
-A KUBE-SEP-57KPRZ3JQVENLNBR -s 10.244.3.6/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
|
||||||
-A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.3.6:9376
|
-A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.3.6:9376
|
||||||
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 10.244.1.7/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
|
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 10.244.1.7/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
|
||||||
@@ -514,15 +560,20 @@ u@node$ iptables-save | grep hostnames
|
|||||||
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -j KUBE-SEP-57KPRZ3JQVENLNBR
|
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -j KUBE-SEP-57KPRZ3JQVENLNBR
|
||||||
```
|
```
|
||||||
|
|
||||||
There should be 1 rule in `KUBE-SERVICES`, 1 or 2 rules per endpoint in
|
For each port of each Service, there should be 1 rule in `KUBE-SERVICES` and
|
||||||
`KUBE-SVC-(hash)` (depending on `SessionAffinity`), one `KUBE-SEP-(hash)` chain
|
one `KUBE-SVC-<hash>` chain. For each Pod endpoint, there should be a small
|
||||||
per endpoint, and a few rules in each `KUBE-SEP-(hash)` chain. The exact rules
|
number of rules in that `KUBE-SVC-<hash>` and one `KUBE-SEP-<hash>` chain with
|
||||||
will vary based on your exact config (including node-ports and load-balancers).
|
a small number of rules in it. The exact rules will vary based on your exact
|
||||||
|
config (including node-ports and load-balancers).
|
||||||
|
|
||||||
#### IPVS
|
#### IPVS mode
|
||||||
|
|
||||||
|
In "ipvs" mode, you should see something like the following on a Node:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ ipvsadm -ln
|
ipvsadm -ln
|
||||||
|
```
|
||||||
|
```none
|
||||||
Prot LocalAddress:Port Scheduler Flags
|
Prot LocalAddress:Port Scheduler Flags
|
||||||
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
|
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
|
||||||
...
|
...
|
||||||
@@ -533,14 +584,39 @@ TCP 10.0.1.175:80 rr
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
IPVS proxy will create a virtual server for each service address(e.g. Cluster IP, External IP, NodePort IP, Load Balancer IP etc.) and some corresponding real servers for endpoints of the service, if any. In this example, service hostnames(`10.0.1.175:80`) has 3 endpoints(`10.244.0.5:9376`, `10.244.0.6:9376`, `10.244.0.7:9376`) and you'll get results similar to above.
|
For each port of each Service, plus any NodePorts, external IPs, and
|
||||||
|
load-balancer IPs, kube-proxy will create a virtual server. For each Pod
|
||||||
|
endpoint, it will create corresponding real servers. In this example, service
|
||||||
|
hostnames(`10.0.1.175:80`) has 3 endpoints(`10.244.0.5:9376`,
|
||||||
|
`10.244.0.6:9376`, `10.244.0.7:9376`).
|
||||||
|
|
||||||
|
#### Userspace mode
|
||||||
|
|
||||||
|
In rare cases, you may be using "userspace" mode. From your Node:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
iptables-save | grep hostnames
|
||||||
|
```
|
||||||
|
```none
|
||||||
|
-A KUBE-PORTALS-CONTAINER -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j REDIRECT --to-ports 48577
|
||||||
|
-A KUBE-PORTALS-HOST -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j DNAT --to-destination 10.240.115.247:48577
|
||||||
|
```
|
||||||
|
|
||||||
|
There should be 2 rules for each port of your Service (just one in this
|
||||||
|
example) - a "KUBE-PORTALS-CONTAINER" and a "KUBE-PORTALS-HOST".
|
||||||
|
|
||||||
|
Almost nobody should be using the "userspace" mode any more, so you won't spend
|
||||||
|
more time on it here.
|
||||||
|
|
||||||
### Is kube-proxy proxying?
|
### Is kube-proxy proxying?
|
||||||
|
|
||||||
Assuming you do see the above rules, try again to access your `Service` by IP:
|
Assuming you do see one the above cases, try again to access your Service by
|
||||||
|
IP from one of your Nodes:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ curl 10.0.1.175:80
|
curl 10.0.1.175:80
|
||||||
|
```
|
||||||
|
```none
|
||||||
hostnames-0uton
|
hostnames-0uton
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -548,31 +624,36 @@ If this fails and you are using the userspace proxy, you can try accessing the
|
|||||||
proxy directly. If you are using the iptables proxy, skip this section.
|
proxy directly. If you are using the iptables proxy, skip this section.
|
||||||
|
|
||||||
Look back at the `iptables-save` output above, and extract the
|
Look back at the `iptables-save` output above, and extract the
|
||||||
port number that `kube-proxy` is using for your `Service`. In the above
|
port number that `kube-proxy` is using for your Service. In the above
|
||||||
examples it is "48577". Now connect to that:
|
examples it is "48577". Now connect to that:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ curl localhost:48577
|
curl localhost:48577
|
||||||
|
```
|
||||||
|
```none
|
||||||
hostnames-yp2kp
|
hostnames-yp2kp
|
||||||
```
|
```
|
||||||
|
|
||||||
If this still fails, look at the `kube-proxy` logs for specific lines like:
|
If this still fails, look at the `kube-proxy` logs for specific lines like:
|
||||||
|
|
||||||
```shell
|
```none
|
||||||
Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376]
|
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.
|
then look at the logs again.
|
||||||
|
|
||||||
### A Pod cannot reach itself via Service IP
|
### Edge case: A Pod fails to reach itself via the Service IP {#a-pod-fails-to-reach-itself-via-the-service-ip}
|
||||||
|
|
||||||
|
This might sound unlikely, but it does happen and it is supposed to work.
|
||||||
|
|
||||||
This can happen when the network is not properly configured for "hairpin"
|
This can happen when the network is not properly configured for "hairpin"
|
||||||
traffic, usually when `kube-proxy` is running in `iptables` mode and Pods
|
traffic, usually when `kube-proxy` is running in `iptables` mode and Pods
|
||||||
are connected with bridge network. The `Kubelet` exposes a `hairpin-mode`
|
are connected with bridge network. The `Kubelet` exposes a `hairpin-mode`
|
||||||
[flag](/docs/admin/kubelet/) that allows endpoints of a Service to loadbalance back to themselves
|
[flag](/docs/admin/kubelet/) that allows endpoints of a Service to loadbalance
|
||||||
if they try to access their own Service VIP. The `hairpin-mode` flag must either be
|
back to themselves if they try to access their own Service VIP. The
|
||||||
set to `hairpin-veth` or `promiscuous-bridge`.
|
`hairpin-mode` flag must either be set to `hairpin-veth` or
|
||||||
|
`promiscuous-bridge`.
|
||||||
|
|
||||||
The common steps to trouble shoot this are as follows:
|
The common steps to trouble shoot this are as follows:
|
||||||
|
|
||||||
@@ -581,9 +662,10 @@ You should see something like the below. `hairpin-mode` is set to
|
|||||||
`promiscuous-bridge` in the following example.
|
`promiscuous-bridge` in the following example.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ ps auxw|grep kubelet
|
ps auxw | grep kubelet
|
||||||
|
```
|
||||||
|
```none
|
||||||
root 3392 1.1 0.8 186804 65208 ? Sl 00:51 11:11 /usr/local/bin/kubelet --enable-debugging-handlers=true --config=/etc/kubernetes/manifests --allow-privileged=True --v=4 --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --configure-cbr0=true --cgroup-root=/ --system-cgroups=/system --hairpin-mode=promiscuous-bridge --runtime-cgroups=/docker-daemon --kubelet-cgroups=/kubelet --babysit-daemons=true --max-pods=110 --serialize-image-pulls=false --outofdisk-transition-frequency=0
|
root 3392 1.1 0.8 186804 65208 ? Sl 00:51 11:11 /usr/local/bin/kubelet --enable-debugging-handlers=true --config=/etc/kubernetes/manifests --allow-privileged=True --v=4 --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --configure-cbr0=true --cgroup-root=/ --system-cgroups=/system --hairpin-mode=promiscuous-bridge --runtime-cgroups=/docker-daemon --kubelet-cgroups=/kubelet --babysit-daemons=true --max-pods=110 --serialize-image-pulls=false --outofdisk-transition-frequency=0
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* Confirm the effective `hairpin-mode`. To do this, you'll have to look at
|
* Confirm the effective `hairpin-mode`. To do this, you'll have to look at
|
||||||
@@ -594,7 +676,7 @@ match `--hairpin-mode` flag due to compatibility. Check if there is any log
|
|||||||
lines with key word `hairpin` in kubelet.log. There should be log lines
|
lines with key word `hairpin` in kubelet.log. There should be log lines
|
||||||
indicating the effective hairpin mode, like something below.
|
indicating the effective hairpin mode, like something below.
|
||||||
|
|
||||||
```shell
|
```none
|
||||||
I0629 00:51:43.648698 3252 kubelet.go:380] Hairpin mode set to "promiscuous-bridge"
|
I0629 00:51:43.648698 3252 kubelet.go:380] Hairpin mode set to "promiscuous-bridge"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -604,6 +686,8 @@ you should see something like:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
for intf in /sys/devices/virtual/net/cbr0/brif/*; do cat $intf/hairpin_mode; done
|
for intf in /sys/devices/virtual/net/cbr0/brif/*; do cat $intf/hairpin_mode; done
|
||||||
|
```
|
||||||
|
```none
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
@@ -615,20 +699,21 @@ has the permission to manipulate linux bridge on node. If `cbr0` bridge is
|
|||||||
used and configured properly, you should see:
|
used and configured properly, you should see:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
u@node$ ifconfig cbr0 |grep PROMISC
|
ifconfig cbr0 |grep PROMISC
|
||||||
|
```
|
||||||
|
```none
|
||||||
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1460 Metric:1
|
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1460 Metric:1
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* Seek help if none of above works out.
|
* Seek help if none of above works out.
|
||||||
|
|
||||||
## Seek help
|
## Seek help
|
||||||
|
|
||||||
If you get this far, something very strange is happening. Your `Service` is
|
If you get this far, something very strange is happening. Your Service is
|
||||||
running, has `Endpoints`, and your `Pods` are actually serving. You have DNS
|
running, has Endpoints, and your Pods are actually serving. You have DNS
|
||||||
working, `iptables` rules installed, and `kube-proxy` does not seem to be
|
working, and `kube-proxy` does not seem to be misbehaving. And yet your
|
||||||
misbehaving. And yet your `Service` is not working. You should probably let
|
Service is not working. Please let us know what is going on, so we can help
|
||||||
us know, so we can help investigate!
|
investigate!
|
||||||
|
|
||||||
Contact us on
|
Contact us on
|
||||||
[Slack](/docs/troubleshooting/#slack) or
|
[Slack](/docs/troubleshooting/#slack) or
|
||||||
|
|||||||
@@ -2,23 +2,19 @@
|
|||||||
reviewers:
|
reviewers:
|
||||||
- jessfraz
|
- jessfraz
|
||||||
title: Inject Information into Pods Using a PodPreset
|
title: Inject Information into Pods Using a PodPreset
|
||||||
|
min-kubernetes-server-version: v1.10
|
||||||
content_template: templates/task
|
content_template: templates/task
|
||||||
weight: 60
|
weight: 60
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% capture overview %}}
|
{{% capture overview %}}
|
||||||
|
|
||||||
You can use a `PodPreset` object to inject information like secrets, volume
|
This page shows how to use PodPreset objects to inject information like {{< glossary_tooltip text="Secrets" term_id="secret" >}}, volume mounts, and {{< glossary_tooltip text="environment variables" term_id="container-env-variables" >}} into Pods at creation time.
|
||||||
mounts, and environment variables etc into pods at creation time.
|
|
||||||
This task shows some examples on using the `PodPreset` resource.
|
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
|
|
||||||
{{% capture prerequisites %}}
|
{{% capture prerequisites %}}
|
||||||
|
|
||||||
Get an overview of PodPresets at
|
|
||||||
[Understanding Pod Presets](/docs/concepts/workloads/pods/podpreset/).
|
|
||||||
|
|
||||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||||
|
|
||||||
{{% /capture %}}
|
{{% /capture %}}
|
||||||
@@ -26,157 +22,298 @@ Get an overview of PodPresets at
|
|||||||
{{% capture steps %}}
|
{{% capture steps %}}
|
||||||
|
|
||||||
|
|
||||||
## Simple Pod Spec Example
|
## Use Pod presets to inject environment variables and volumes
|
||||||
|
|
||||||
This is a simple example to show how a Pod spec is modified by the Pod
|
In this step, you create a preset that has a volume mount and one environment variable.
|
||||||
Preset.
|
Here is the manifest for the PodPreset:
|
||||||
|
|
||||||
{{< codenew file="podpreset/preset.yaml" >}}
|
{{< codenew file="podpreset/preset.yaml" >}}
|
||||||
|
|
||||||
|
The name of a PodPreset object must be a valid
|
||||||
|
[DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
|
||||||
|
|
||||||
|
In the manifest, you can see that the preset has an environment variable definition called `DB_PORT`
|
||||||
|
and a volume mount definition called `cache-volume` which is mounted under `/cache`. The {{< glossary_tooltip text="selector" term_id="selector" >}} specifies that
|
||||||
|
the preset will act upon any Pod that is labeled `role:frontend`.
|
||||||
|
|
||||||
Create the PodPreset:
|
Create the PodPreset:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml
|
kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
Examine the created PodPreset:
|
Verify that the PodPreset has been created:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get podpreset
|
kubectl get podpreset
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
NAME AGE
|
NAME CREATED AT
|
||||||
allow-database 1m
|
allow-database 2020-01-24T08:54:29Z
|
||||||
```
|
```
|
||||||
|
|
||||||
The new PodPreset will act upon any pod that has label `role: frontend`.
|
This manifest defines a Pod labelled `role: frontend` (matching the PodPreset's selector):
|
||||||
|
|
||||||
{{< codenew file="podpreset/pod.yaml" >}}
|
{{< codenew file="podpreset/pod.yaml" >}}
|
||||||
|
|
||||||
Create a pod:
|
Create the Pod:
|
||||||
|
|
||||||
```shell
|
```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:
|
Verify that the Pod is running:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get pods
|
kubectl get pods
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The output shows that the Pod is running:
|
||||||
|
|
||||||
```
|
```
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
website 1/1 Running 0 4m
|
website 1/1 Running 0 4m
|
||||||
```
|
```
|
||||||
|
|
||||||
**Pod spec after admission controller:**
|
View the Pod spec altered by the admission controller in order to see the effects of the preset
|
||||||
|
having been applied:
|
||||||
{{< codenew file="podpreset/merged.yaml" >}}
|
|
||||||
|
|
||||||
To see above output, run the following command:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl get pod website -o yaml
|
kubectl get pod website -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pod Spec with ConfigMap Example
|
{{< codenew file="podpreset/merged.yaml" >}}
|
||||||
|
|
||||||
This is an example to show how a Pod spec is modified by the Pod Preset
|
The `DB_PORT` environment variable, the `volumeMount` and the `podpreset.admission.kubernetes.io` annotation
|
||||||
that defines a `ConfigMap` for Environment Variables.
|
of the Pod verify that the preset has been applied.
|
||||||
|
|
||||||
**User submitted pod spec:**
|
## Pod spec with ConfigMap example
|
||||||
|
|
||||||
{{< codenew file="podpreset/pod.yaml" >}}
|
This is an example to show how a Pod spec is modified by a Pod preset
|
||||||
|
that references a ConfigMap containing environment variables.
|
||||||
|
|
||||||
**User submitted `ConfigMap`:**
|
Here is the manifest containing the definition of the ConfigMap:
|
||||||
|
|
||||||
{{< codenew file="podpreset/configmap.yaml" >}}
|
{{< codenew file="podpreset/configmap.yaml" >}}
|
||||||
|
|
||||||
**Example Pod Preset:**
|
Create the ConfigMap:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl create -f https://k8s.io/examples/podpreset/configmap.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is a PodPreset manifest referencing that ConfigMap:
|
||||||
|
|
||||||
{{< codenew file="podpreset/allow-db.yaml" >}}
|
{{< codenew file="podpreset/allow-db.yaml" >}}
|
||||||
|
|
||||||
**Pod spec after admission controller:**
|
Create the preset that references the ConfigMap:
|
||||||
|
|
||||||
{{< codenew file="podpreset/allow-db-merged.yaml" >}}
|
```shell
|
||||||
|
kubectl create -f https://k8s.io/examples/podpreset/allow-db.yaml
|
||||||
|
```
|
||||||
|
|
||||||
## ReplicaSet with Pod Spec Example
|
The following manifest defines a Pod matching the PodPreset for this example:
|
||||||
|
|
||||||
The following example shows that only the pod spec is modified by the Pod
|
|
||||||
Preset.
|
|
||||||
|
|
||||||
**User submitted ReplicaSet:**
|
|
||||||
|
|
||||||
{{< codenew file="podpreset/replicaset.yaml" >}}
|
|
||||||
|
|
||||||
**Example Pod Preset:**
|
|
||||||
|
|
||||||
{{< codenew file="podpreset/preset.yaml" >}}
|
|
||||||
|
|
||||||
**Pod spec after admission controller:**
|
|
||||||
|
|
||||||
Note that the ReplicaSet spec was not changed, users have to check individual pods
|
|
||||||
to validate that the PodPreset has been applied.
|
|
||||||
|
|
||||||
{{< codenew file="podpreset/replicaset-merged.yaml" >}}
|
|
||||||
|
|
||||||
## Multiple PodPreset Example
|
|
||||||
|
|
||||||
This is an example to show how a Pod spec is modified by multiple Pod
|
|
||||||
Injection Policies.
|
|
||||||
|
|
||||||
**User submitted pod spec:**
|
|
||||||
|
|
||||||
{{< codenew file="podpreset/pod.yaml" >}}
|
{{< codenew file="podpreset/pod.yaml" >}}
|
||||||
|
|
||||||
**Example Pod Preset:**
|
Create the Pod:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl create -f https://k8s.io/examples/podpreset/pod.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
View the Pod spec altered by the admission controller in order to see the effects of the preset
|
||||||
|
having been applied:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get pod website -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< codenew file="podpreset/allow-db-merged.yaml" >}}
|
||||||
|
|
||||||
|
The `DB_PORT` environment variable and the `podpreset.admission.kubernetes.io` annotation of the Pod
|
||||||
|
verify that the preset has been applied.
|
||||||
|
|
||||||
|
## ReplicaSet with Pod spec example
|
||||||
|
|
||||||
|
This is an example to show that only Pod specs are modified by Pod presets. Other workload types
|
||||||
|
like ReplicaSets or Deployments are unaffected.
|
||||||
|
|
||||||
|
Here is the manifest for the PodPreset for this example:
|
||||||
|
|
||||||
{{< codenew file="podpreset/preset.yaml" >}}
|
{{< codenew file="podpreset/preset.yaml" >}}
|
||||||
|
|
||||||
**Another Pod Preset:**
|
Create the preset:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
This manifest defines a ReplicaSet that manages three application Pods:
|
||||||
|
|
||||||
|
{{< codenew file="podpreset/replicaset.yaml" >}}
|
||||||
|
|
||||||
|
Create the ReplicaSet:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl create -f https://k8s.io/examples/podpreset/replicaset.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify that the Pods created by the ReplicaSet are running:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get pods
|
||||||
|
```
|
||||||
|
|
||||||
|
The output shows that the Pods are running:
|
||||||
|
|
||||||
|
```
|
||||||
|
NAME READY STATUS RESTARTS AGE
|
||||||
|
frontend-2l94q 1/1 Running 0 2m18s
|
||||||
|
frontend-6vdgn 1/1 Running 0 2m18s
|
||||||
|
frontend-jzt4p 1/1 Running 0 2m18s
|
||||||
|
```
|
||||||
|
|
||||||
|
View the `spec` of the ReplicaSet:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get replicasets frontend -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< note >}}
|
||||||
|
The ReplicaSet object's `spec` was not changed, nor does the ReplicaSet contain a
|
||||||
|
`podpreset.admission.kubernetes.io` annotation. This is because a PodPreset only
|
||||||
|
applies to Pod objects.
|
||||||
|
|
||||||
|
To see the effects of the preset having been applied, you need to look at individual Pods.
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
|
The command to view the specs of the affected Pods is:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get pod --selector=role=frontend -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< codenew file="podpreset/replicaset-merged.yaml" >}}
|
||||||
|
|
||||||
|
Again the `podpreset.admission.kubernetes.io` annotation of the Pods
|
||||||
|
verifies that the preset has been applied.
|
||||||
|
|
||||||
|
## Multiple Pod presets example
|
||||||
|
|
||||||
|
This is an example to show how a Pod spec is modified by multiple Pod presets.
|
||||||
|
|
||||||
|
|
||||||
|
Here is the manifest for the first PodPreset:
|
||||||
|
|
||||||
|
{{< codenew file="podpreset/preset.yaml" >}}
|
||||||
|
|
||||||
|
Create the first PodPreset for this example:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is the manifest for the second PodPreset:
|
||||||
|
|
||||||
{{< codenew file="podpreset/proxy.yaml" >}}
|
{{< codenew file="podpreset/proxy.yaml" >}}
|
||||||
|
|
||||||
**Pod spec after admission controller:**
|
Create the second preset:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f https://k8s.io/examples/podpreset/proxy.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Here's a manifest containing the definition of an applicable Pod (matched by two PodPresets):
|
||||||
|
|
||||||
|
{{< codenew file="podpreset/pod.yaml" >}}
|
||||||
|
|
||||||
|
Create the Pod:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl create -f https://k8s.io/examples/podpreset/pod.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
View the Pod spec altered by the admission controller in order to see the effects of both presets
|
||||||
|
having been applied:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get pod website -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
{{< codenew file="podpreset/multi-merged.yaml" >}}
|
{{< codenew file="podpreset/multi-merged.yaml" >}}
|
||||||
|
|
||||||
## Conflict Example
|
The `DB_PORT` environment variable, the `proxy-volume` VolumeMount and the two `podpreset.admission.kubernetes.io`
|
||||||
|
annotations of the Pod verify that both presets have been applied.
|
||||||
|
|
||||||
This is an example to show how a Pod spec is not modified by the Pod Preset
|
## Conflict example
|
||||||
when there is a conflict.
|
|
||||||
|
|
||||||
**User submitted pod spec:**
|
This is an example to show how a Pod spec is not modified by a Pod preset when there is a conflict.
|
||||||
|
The conflict in this example consists of a `VolumeMount` in the PodPreset conflicting with a Pod that defines the same `mountPath`.
|
||||||
|
|
||||||
{{< codenew file="podpreset/conflict-pod.yaml" >}}
|
Here is the manifest for the PodPreset:
|
||||||
|
|
||||||
**Example Pod Preset:**
|
|
||||||
|
|
||||||
{{< codenew file="podpreset/conflict-preset.yaml" >}}
|
{{< codenew file="podpreset/conflict-preset.yaml" >}}
|
||||||
|
|
||||||
**Pod spec after admission controller will not change because of the conflict:**
|
Note the `mountPath` value of `/cache`.
|
||||||
|
|
||||||
|
Create the preset:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl apply -f https://k8s.io/examples/podpreset/conflict-preset.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is the manifest for the Pod:
|
||||||
|
|
||||||
{{< codenew file="podpreset/conflict-pod.yaml" >}}
|
{{< codenew file="podpreset/conflict-pod.yaml" >}}
|
||||||
|
|
||||||
**If we run `kubectl describe...` we can see the event:**
|
Note the volumeMount element with the same path as in the PodPreset.
|
||||||
|
|
||||||
|
Create the Pod:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl describe ...
|
kubectl create -f https://k8s.io/examples/podpreset/conflict-pod.yaml
|
||||||
```
|
|
||||||
```
|
|
||||||
....
|
|
||||||
Events:
|
|
||||||
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
|
||||||
Tue, 07 Feb 2017 16:56:12 -0700 Tue, 07 Feb 2017 16:56:12 -0700 1 {podpreset.admission.kubernetes.io/podpreset-allow-database } conflict Conflict on pod preset. Duplicate mountPath /cache.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deleting a Pod Preset
|
View the Pod spec:
|
||||||
|
|
||||||
Once you don't need a pod preset anymore, you can delete it with `kubectl`:
|
```shell
|
||||||
|
kubectl get pod website -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< codenew file="podpreset/conflict-pod.yaml" >}}
|
||||||
|
|
||||||
|
You can see there is no preset annotation (`podpreset.admission.kubernetes.io`). Seeing no annotation tells you that no preset has not been applied to the Pod.
|
||||||
|
|
||||||
|
However, the
|
||||||
|
[PodPreset admission controller](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#podpreset)
|
||||||
|
logs a warning containing details of the conflict.
|
||||||
|
You can view the warning using `kubectl`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl -n kube-system logs -l=component=kube-apiserver
|
||||||
|
```
|
||||||
|
|
||||||
|
The output should look similar to:
|
||||||
|
|
||||||
|
```
|
||||||
|
W1214 13:00:12.987884 1 admission.go:147] conflict occurred while applying podpresets: allow-database on pod: err: merging volume mounts for allow-database has a conflict on mount path /cache:
|
||||||
|
v1.VolumeMount{Name:"other-volume", ReadOnly:false, MountPath:"/cache", SubPath:"", MountPropagation:(*v1.MountPropagationMode)(nil), SubPathExpr:""}
|
||||||
|
does not match
|
||||||
|
core.VolumeMount{Name:"cache-volume", ReadOnly:false, MountPath:"/cache", SubPath:"", MountPropagation:(*core.MountPropagationMode)(nil), SubPathExpr:""}
|
||||||
|
in container
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the conflict message on the path for the VolumeMount.
|
||||||
|
|
||||||
|
## Deleting a PodPreset
|
||||||
|
|
||||||
|
Once you don't need a PodPreset anymore, you can delete it with `kubectl`:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
kubectl delete podpreset allow-database
|
kubectl delete podpreset allow-database
|
||||||
```
|
```
|
||||||
|
The output shows that the PodPreset was deleted:
|
||||||
```
|
```
|
||||||
podpreset "allow-database" deleted
|
podpreset "allow-database" deleted
|
||||||
```
|
```
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user