Merge branch 'master' into release-1.12

This commit is contained in:
zacharysarah
2018-10-17 19:10:16 -07:00
558 changed files with 71868 additions and 2594 deletions
+7 -3
View File
@@ -1,8 +1,12 @@
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Please delete this note before submitting the pull request.
> For 1.12 Features: set Milestone to 1.12 and Base Branch to release-1.12
> Help editing and submitting pull requests: https://deploy-preview-9510--kubernetes-io-master-staging.netlify.com/docs/contribute/start/#submit-a-pull-request.
> Help choosing which branch to use, see
>
> For 1.13 Features: set Milestone to 1.13 and Base Branch to dev-1.13
>
> Help editing and submitting pull requests:
> https://kubernetes.io/docs/contribute/start/#improve-existing-content.
>
> Help choosing which branch to use:
> https://kubernetes.io/docs/contribute/start#choose-which-git-branch-to-use.
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
+5
View File
@@ -32,3 +32,8 @@ public/
# User-specific editorconfig files
.editorconfig
# Netlify Functions build output
package-lock.json
functions/
node_modules/
+2 -1
View File
@@ -9,7 +9,8 @@ These are just guidelines, not rules. Use your best judgment, and feel free to p
### Code of Conduct
Kubernetes follows the [Cloud Native Computing Foundation (CNCF) Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to Sarah Novotny [sarahnovotny@google.com](mailto:sarahnovotny@google.com) and/or Dan Kohn [dan@linuxfoundation.org](mailto:dan@linuxfoundation.org).
Kubernetes follows the [Cloud Native Computing Foundation (CNCF) Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to the
[Kubernetes Code of Conduct Committee](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct) <conduct@kubernetes.io>.
### Documentation and Site Decisions
+4 -3
View File
@@ -20,10 +20,11 @@ ARG HUGO_VERSION
RUN mkdir -p /usr/local/src && \
cd /usr/local/src && \
curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \
#curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \
curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \
mv hugo /usr/local/bin/hugo && \
curl -L https://bin.equinox.io/c/dhgbqpS8Bvy/minify-stable-linux-amd64.tgz | tar -xz && \
mv minify /usr/local/bin && \
#curl -L https://bin.equinox.io/c/dhgbqpS8Bvy/minify-stable-linux-amd64.tgz | tar -xz && \
#mv minify /usr/local/bin && \
addgroup -Sg 1000 hugo && \
adduser -Sg hugo -u 1000 -h /src hugo
+12 -1
View File
@@ -1,7 +1,9 @@
DOCKER = docker
HUGO_VERSION = 0.47.1
HUGO_VERSION = 0.49
DOCKER_IMAGE = kubernetes-hugo
DOCKER_RUN = $(DOCKER) run --rm --interactive --tty --volume $(PWD):/src
NODE_BIN = node_modules/.bin
NETLIFY_FUNC = $(NODE_BIN)/netlify-lambda
.PHONY: all build sass build-preview help serve
@@ -16,6 +18,9 @@ build: ## Build site with production settings and put deliverables in ./public
build-preview: ## Build site with drafts and future posts enabled
hugo -D -F
functions-build:
$(NETLIFY_FUNC) build functions-src
check-headers-file:
scripts/check-headers-file.sh
@@ -24,6 +29,12 @@ production-build: build check-headers-file ## Build the production site and ensu
non-production-build: ## Build the non-production site, which adds noindex headers to prevent indexing
hugo --enableGitInfo
sass-build:
scripts/sass.sh build
sass-develop:
scripts/sass.sh develop
serve: ## Boot the development server.
hugo server --ignoreCache --disableFastRender
+2 -15
View File
@@ -1,23 +1,10 @@
# Reviewers can /lgtm /approve but not sufficient for auto-merge without an
# approver
reviewers:
- Rajakavitha1
- stewart-yu
- xiangpengzhao
- zhangxiaoyu-zidif
- sig-docs-en-reviews
# Approvers have all the ability of reviewers but their /approve makes
# auto-merge happen if a /lgtm exists, or vice versa, or they can do both
# No need for approvers to also be listed as reviewers
approvers:
- bradamant3
- bradtopol
- chenopis
- kbarnard10
- mistyhacks
- ryanmcginnis
- steveperry-53
- tengqm
- tfogo
- zacharysarah
- zparnold
- sig-docs-en-owners
+53 -3
View File
@@ -97,21 +97,71 @@ aliases:
- apelisse
- grodrigues3
- spxtr
sig-docs: #Team: documentation; GH: sig-docs-pr-reviews
sig-docs: #Team: documentation; GH: sig-docs-maintainers
- bradamant3
- bradtopol
- chenopis
- jaredbhatti
- kbarnard10
- mistyhacks
- rajakavitha1
- ryanmcginnis
- steveperry-53
- stewart-yu
- tengqm
- tfogo
- xiangpengzhao
- zacharysarah
- zhangxiaoyu-zidif
- zparnold
sig-docs-en-owners: #Team: Documentation; GH: sig-docs-en-owners
- bradamant3
- bradtopol
- chenopis
- jaredbhatti
- kbarnard10
- mistyhacks
- ryanmcginnis
- steveperry-53
- stewart-yu
- tengqm
- tfogo
- zacharysarah
- zparnold
sig-docs-en-reviews: #Team: Documentation; GH: sig-docs-pr-reviews
- jimangel
- rajakavitha1
- stewart-yu
- xiangpengzhao
- zhangxiaoyu
sig-docs-ja-owners: #Team: Japanese docs localization; GH: sig-docs-ja-owners
- cstoku
- nasa9084
- tnir
sig-docs-ja-reviews: #Team: Japanese docs PR reviews; GH:sig-docs-ja-reviews
- cstoku
- makocchi-git
- MasayaAoyama
- nasa9084
- tnir
sig-docs-ko-owners: #Team Korean docs localization; GH: sig-docs-ko-owners
- ClaudiaJKang
- gochist
sig-docs-ko-reviews: #Team Korean docs reviews; GH: sig-docs-ko-reviews
- ClaudiaJKang
- gochist
- ianychoi
sig-docs-zh-owners: #Team Chinese docs localization; GH: sig-docs-zh-owners
- dchen1107
- haibinxie
- hanjiayao
- lichuqiang
- tengqm
- xiangpengzhao
- zhangxiaoyu-zidif
sig-docs-zh-reviews: #Team Chinese docs reviews; GH: sig-docs-zh-reviews
- idealhack
- tengqm
- xiangpengzhao
- zhangxiaoyu-zidif
sig-federation: #Team: Federation; e.g. Federated Clusters
- csbell
sig-gcp: #Google Cloud Platform; GH: sig-gcp-pr-reviews
+22 -20
View File
@@ -15,11 +15,29 @@ For more information about contributing to the Kubernetes documentation, see:
* [Using Page Templates](http://kubernetes.io/docs/contribute/style/page-templates/)
* [Documentation Style Guide](http://kubernetes.io/docs/contribute/style/style-guide/)
## Running the site locally using Docker
The recommended way to run the Kubernetes website locally is to run a specialized [Docker](https://docker.com) image that includes the [Hugo](https://gohugo.io) static site generator.
> If you'd prefer to run the website locally without Docker, see [Running the site locally using Hugo](#running-the-site-locally-using-hugo) below.
If you have Docker [up and running](https://www.docker.com/get-started), build the `kubernetes-hugo` Docker image locally:
```bash
make docker-image
```
Once the image has been built, you can run the site locally:
```bash
make docker-serve
```
Open up your browser to http://localhost:1313 to view the site. As you make changes to the source files, Hugo updates the site and forces a browser refresh.
## Running the site locally using Hugo
The Kubernetes documentation is built using the [Hugo](https://gohugo.io) static site generator. See the [official Hugo documentation](https://gohugo.io/getting-started/installing/) for Hugo installation instructions.
> Building and running the site requires the Hugo version specified by the `HUGO_VERSION` environment variable in the [`netlify.toml`](netlify.toml#L9) file.
See the [official Hugo documentation](https://gohugo.io/getting-started/installing/) for Hugo installation instructions. Make sure to install the Hugo version specified by the `HUGO_VERSION` environment variable in the [`netlify.toml`](netlify.toml#L9) file.
To run the site locally when you have Hugo installed:
@@ -27,23 +45,7 @@ To run the site locally when you have Hugo installed:
make serve
```
This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the site. As you make changes to the source files, Hugo updates immediately and forces a browser refresh.
## Building the site using Docker
You can build the Kubernetes docs using [Docker](https://docker.com). To get started, make sure that you have Docker running and build the image locally:
```bash
make docker-image
```
Once the `kubernetes-hugo` image has been built locally, you can run the site locally:
```bash
make docker-serve
```
Open up your browser to http://localhost:1313 to view the site.
This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the site. As you make changes to the source files, Hugo updates the site and forces a browser refresh.
## Thank you!
+1 -1
View File
@@ -11,5 +11,5 @@
# INSTRUCTIONS AT https://kubernetes.io/security/
chenopis
jaredbhatti
bradamant3
zacharysarah
+18 -12
View File
@@ -7,7 +7,7 @@ enableRobotsTXT = true
disableKinds = ["taxonomy", "taxonomyTerm"]
ignoreFiles = [ "^OWNERS$", "README.md", "^node_modules$", "content/en/docs/doc-contributor-tools" ]
ignoreFiles = [ "^OWNERS$", "README[-]+[a-z]*\\.md", "^node_modules$", "content/en/docs/doc-contributor-tools" ]
contentDir = "content/en"
@@ -22,7 +22,7 @@ pygmentsStyle = "emacs"
# Enable Git variables like commit, lastmod
enableGitInfo = true
# This is currently used for testing.
# Norwegian ("no") is sometimes but not currently used for testing.
disableLanguages = ["no"]
[blackfriday]
@@ -131,23 +131,29 @@ description = "Production-Grade Container Orchestration"
languageName ="English"
# Weight used for sorting.
weight = 1
[languages.cn]
[languages.zh]
title = "Kubernetes"
description = "Production-Grade Container Orchestration"
languageName = "Chinese"
languageName = "中文 Chinese"
weight = 2
contentDir = "content/cn"
contentDir = "content/zh"
[languages.ko]
title = "Kubernetes"
description = "Production-Grade Container Orchestration"
languageName = "한국어 Korean"
weight = 3
contentDir = "content/ko"
[languages.no]
title = "Kubernetes"
description = "Production-Grade Container Orchestration"
languageName ="Norsk"
weight = 3
weight = 4
contentDir = "content/no"
[languages.no.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.ko]
title = "Kubernetes"
description = "Production-Grade Container Orchestration"
languageName = "Korean"
weight = 4
contentDir = "content/ko"
@@ -1,6 +0,0 @@
You need to either have a dynamic PersistentVolume provisioner with a default
[StorageClass](/docs/concepts/storage/storage-classes/),
or [statically provision PersistentVolumes](/docs/user-guide/persistent-volumes/#provisioning)
yourself to satisfy the [PersistentVolumeClaims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims)
used here.
@@ -1,8 +0,0 @@
This guide assumes that you have a running Kubernetes Cluster
Federation installation. If not, then head over to the
[federation admin guide](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) to learn how to
bring up a cluster federation (or have your cluster administrator do
this for you).
Other tutorials, such as Kelsey Hightower's
[Federated Kubernetes Tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation),
might also help you create a Federated Kubernetes cluster.
@@ -1,2 +0,0 @@
The topics in the [Federation API](/docs/federation/api-reference/) section of the Kubernetes docs
are being moved to the [Reference](/docs/reference/) section. The content in this topic has moved to:
@@ -1,7 +0,0 @@
**Note:** `Federation V1`, the current Kubernetes federation API which reuses the Kubernetes API
resources 'as is', is currently considered alpha for many of its features, and there is no clear
path to evolve the API to GA. However, there is a `Federation V2` effort in progress to implement
a dedicated federation API apart from the Kubernetes API. The details can be found at
[sig-multicluster community page](https://github.com/kubernetes/community/tree/master/sig-multicluster).
{: .note}
-3
View File
@@ -1,3 +0,0 @@
---
headless: true
---
@@ -1,3 +0,0 @@
The topics in the [User Guide](/docs/user-guide/) section of the Kubernetes docs
are being moved to the [Tasks](/docs/tasks/), [Tutorials](/docs/tutorials/), and
[Concepts](/docs/concepts) sections. The content in this topic has moved to:
@@ -1,12 +0,0 @@
<table style="background-color:#eeeeee">
<tr>
<td>
<p><b>NOTICE</b></p>
<p>As of March 14, 2017, the Kubernetes SIG-Docs-Maintainers group have begun migration of the User Guide content as announced previously to the <a href="https://git.k8s.io/community/sig-docs">SIG Docs community</a> through the <a href="https://groups.google.com/forum/#!forum/kubernetes-sig-docs">kubernetes-sig-docs</a> group and <a href="https://kubernetes.slack.com/messages/sig-docs/">kubernetes.slack.com #sig-docs</a> channel.</p>
<p>The user guides within this section are being refactored into topics within Tutorials, Tasks, and Concepts. Anything that has been moved will have a notice placed in its previous location as well as a link to its new location. The reorganization implements a new table of contents and should improve the documentation's findability and readability for a wider range of audiences.</p>
<p>For any questions, please contact: <a href="mailto:kubernetes-sig-docs@googlegroups.com">kubernetes-sig-docs@googlegroups.com</a></p>
</td>
</tr>
</table>
+11
View File
@@ -0,0 +1,11 @@
# This is the directory for English source content.
# Teams and members are visible at https://github.com/orgs/kubernetes/teams.
reviewers:
- sig-docs-en-reviews
approvers:
- sig-docs-en-owners
labels:
- language/en
@@ -22,7 +22,7 @@ We can consider containers as two parts (as Kubernetes does). The first part is
The interesting part of HyperContainer is not only that it is secure enough for multi-tenant environments (such as a public cloud), but also how well it fits into the Kubernetes philosophy.
One of the most important concepts in Kubernetes is Pods. The design of Pods is a lesson learned ([Borg paper section 8.1](http://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/43438.pdf)) from real world workloads, where in many cases people want an atomic scheduling unit composed of multiple containers (please check this [example](https://github.com/kubernetes/kubernetes/tree/master/examples/javaweb-tomcat-sidecar) for further information). In the context of Linux containers, a Pod wraps and encapsulates several containers into a logical group. But in HyperContainer, the hypervisor serves as a natural boundary, and Pods are introduced as first-class objects:
One of the most important concepts in Kubernetes is Pods. The design of Pods is a lesson learned ([Borg paper section 8.1](http://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/43438.pdf)) from real world workloads, where in many cases people want an atomic scheduling unit composed of multiple containers (please check this [example](https://github.com/kubernetes/examples/tree/master/staging/javaweb-tomcat-sidecar) for further information). In the context of Linux containers, a Pod wraps and encapsulates several containers into a logical group. But in HyperContainer, the hypervisor serves as a natural boundary, and Pods are introduced as first-class objects:
@@ -13,7 +13,7 @@ Of course, this is not true at all. At Google, everything runs in a container, i
If youve followed my previous posts, you know how to create a [MEAN Stack app with Docker](http://blog.sandeepdinesh.com/2015/07/running-mean-web-application-in-docker.html), then [migrate it to Kubernetes](https://medium.com/google-cloud/running-a-mean-stack-on-google-cloud-platform-with-kubernetes-149ca81c2b5d) to provide easier management and reliability, and [create a MongoDB replica set](https://medium.com/google-cloud/mongodb-replica-sets-with-kubernetes-d96606bd9474) to provide redundancy and high availability.
While the replica set in my previous blog post worked, there were some annoying steps that you needed to follow. You had to manually create a disk, a ReplicationController, and a service for each replica. Scaling the set up and down meant managing all of these resources manually, which is an opportunity for error, and would put your stateful application at risk In the previous example, we created a Makefile to ease the management of of these resources, but it would have been great if Kubernetes could just take care of all of this for us.
While the replica set in my previous blog post worked, there were some annoying steps that you needed to follow. You had to manually create a disk, a ReplicationController, and a service for each replica. Scaling the set up and down meant managing all of these resources manually, which is an opportunity for error, and would put your stateful application at risk In the previous example, we created a Makefile to ease the management of these resources, but it would have been great if Kubernetes could just take care of all of this for us.
With StatefulSets, these headaches finally go away. You can create and manage your MongoDB replica set natively in Kubernetes, without the need for scripts and Makefiles. Lets take a look how.
@@ -205,7 +205,7 @@ This environment variable is a hint to the container initialization logic as to
The tests below assume that the psql client has been installed on the test system. If if not, the psql client has been previously installed, it can be installed as follows:
The tests below assume that the psql client has been installed on the test system. If not, the psql client has been previously installed, it can be installed as follows:
@@ -122,7 +122,7 @@ TIM PEPPER: A test escape, another way to think of it as you shipped a bug becau
TIM PEPPER: It's common for us to focus on "I've created this feature and I'm testing the positive cases". And this also comes to thinking about things like secure by default and having a really robust system. A harder piece of engineering often is to think about the failure cases and really actively manage those well.
JOSH BERKUS: I had a conversation with a contributor recently where it became apparent that that contributor had never worked on a support team, because their conception of a badly behaved user was, like, a hacker, right? An attacker who comes from outside.
JOSH BERKUS: I had a conversation with a contributor recently where it became apparent that contributor had never worked on a support team, because their conception of a badly behaved user was, like, a hacker, right? An attacker who comes from outside.
And I'm like, no, no, no. You're stable of badly behaved users is your own staff. You know, they will do bad things, not necessarily intending to do bad things, but because they're trying to take a shortcut. And that is actually your primary concern in terms of preventing breaking the system.
@@ -158,7 +158,7 @@ But then you start also getting interactions. Maybe a bug was introduced, and ot
And maybe because I'm following Josh into this role from a bug triage position and in his mentions earlier of just the communications and tracking involved with that versus triage, I do have a bit of a concern that at times, email and Slack are relatively quiet. Some of the SIG meeting notes are a bit sparse or YouTube videos slow to upload. So the general artifacts around choice making I think is an area where we need a little more rigor. So I'm hoping to see some of that.
And that can be just as subtle as commenting on issues like, hey, this commit doesn't say what it's doing. And for that reason on the release team, we can't assess its risk versus value. So could you give a little more information here? Things like that that give more information both to the release team and the development community as well, because this is open source. And to collaborate, you really do need to communicate in depth.
And that can be just as subtle as commenting on issues like, hey, this commit doesn't say what it's doing. And for that reason on the release team, we can't assess its risk versus value. So could you give a little more information here? Things like that give more information both to the release team and the development community as well, because this is open source. And to collaborate, you really do need to communicate in depth.
<b>CRAIG BOX: Speaking of cultural changes, professional baker to Kubernetes' release lead sounds like quite a journey.</b>
@@ -234,7 +234,7 @@ JOSH BERKUS: And so that made a big difference. And the second thing that was pr
JOSH BERKUS: We had a lot of problems with flaky tests. We have a lot of old tests that are not all that well maintained, and they're testing very complicated things like upgrading a cluster that has 40 nodes. And as a result, these tests have high failure rates that have very little to do with any change in the code.
And so one of the things that happened, and the reason we had a one-day delay in the release is, you know, we're a week out from release, and just by random luck of the draw, a bunch of these tests all at once got a run of failures. And it turned out that that run of failures didn't actually mean anything, having anything to do with Kubernetes. But there was no way for us to tell that without a lot of research, and we were not going to have enough time for that research without delaying the release.
And so one of the things that happened, and the reason we had a one-day delay in the release is, you know, we're a week out from release, and just by random luck of the draw, a bunch of these tests all at once got a run of failures. And it turned out that run of failures didn't actually mean anything, having anything to do with Kubernetes. But there was no way for us to tell that without a lot of research, and we were not going to have enough time for that research without delaying the release.
So one of the things we're looking to address in the 1.12 cycle is to actually move some of those flaky tests out. Either fix them or move them out of the release blocking category.
@@ -258,7 +258,7 @@ And then the second thing, like I said, is that we didn't have sort of major, un
You know, number one was having the scalability tests start failing for unrelated reasons for a long period, which then masked the fact that they were actually failing for real reasons when we actually got them working again. And as a result, ending up debugging a major and super complicated scalability issue within days of what was supposed to be the original release date. So that was monkey wrench number one for the 1.10 cycle.
Monkey wrench number two for the 1.10 cycle was we got a security hole that needed to be patched. And so again, a week out from what was supposed to be the original release date, we were releasing a security update, and that security update required patching the release branch. And it turns out that that patch against the release branch broke a bunch of incoming features. And we didn't get anything of that magnitude in the 1.11 release, and I'm thankful for that.
Monkey wrench number two for the 1.10 cycle was we got a security hole that needed to be patched. And so again, a week out from what was supposed to be the original release date, we were releasing a security update, and that security update required patching the release branch. And it turns out that patch against the release branch broke a bunch of incoming features. And we didn't get anything of that magnitude in the 1.11 release, and I'm thankful for that.
TIM PEPPER: Also, I would maybe argue in a way that a portion of that wasn't just luck. The extent to which this community has a good team, not just the release team but beyond, some of this goes to active work that folks all across the project, but especially in the contributor experience SIG are doing to cultivate a positive and inclusive culture here. And you really see that. When problems crop up, you're seeing people jump on and really try to constructively tackle them. And it's really fun to be a part of that.
@@ -99,7 +99,7 @@ A [CRD finalizer](https://kubernetes.io/docs/tasks/access-kubernetes-API/extend-
The Kubernetes core APIs have the ability to support multiple versions for a single object type and perform conversions between those versions. This gives the Kubernetes core APIs a path for advancing the `v1alpha1` version of an object to a `v1beta1` version and so forth.
Prior to Kubernetes 1.11, CRDs did not not have support for multiple versions. This meant when we wanted to progress a CRD from `kubevirt.io/v1alpha1` to `kubevirt.io/v1beta1`, the only path available to was to backup our CRD objects, delete the registered CRD from Kubernetes, register a new CRD with the updated version, convert the backed up CRD objects to the new version, and finally post the migrated CRD objects back to the cluster.
Prior to Kubernetes 1.11, CRDs did not have support for multiple versions. This meant when we wanted to progress a CRD from `kubevirt.io/v1alpha1` to `kubevirt.io/v1beta1`, the only path available to was to backup our CRD objects, delete the registered CRD from Kubernetes, register a new CRD with the updated version, convert the backed up CRD objects to the new version, and finally post the migrated CRD objects back to the cluster.
That strategy was not exactly a viable option for us.
@@ -119,7 +119,7 @@ Lets scroll a little further down the page, well see a live list of all tr
<center><img src="/images/blog/2018-09-18-2018-linkerd-2.0/4-web-top.png" width="700"></center>
There are two calls that are not at 100%: the first is vote-bots call the “/api/vote” endpoint. The second is the “VotePoop” call from the web service to the voting service. Very interesting! Since /api/vote is an incoming call, and “/VotePoop” is an outgoing call, this is a good clue that that the failure of the vote services VotePoop endpoint is whats causing the problem!
There are two calls that are not at 100%: the first is vote-bots call the “/api/vote” endpoint. The second is the “VotePoop” call from the web service to the voting service. Very interesting! Since /api/vote is an incoming call, and “/VotePoop” is an outgoing call, this is a good clue that the failure of the vote services VotePoop endpoint is whats causing the problem!
Finally, if we click on the “tap” icon for that row in the far right column, well be taken to live list of requests that match this endpoint. This allows us to confirm that the requests are failing (they all have [gRPC status code 2](https://godoc.org/google.golang.org/grpc/codes#Code), indicating an error).
@@ -0,0 +1,115 @@
---
layout: blog
title: 'Kubernetes 1.12: Kubelet TLS Bootstrap and Azure Virtual Machine Scale Sets (VMSS) Move to General Availability'
date: 2018-09-27
---
**Author**: The 1.12 [Release Team](https://github.com/kubernetes/sig-release/blob/master/releases/release-1.12/release_team.md)
Were pleased to announce the delivery of Kubernetes 1.12, our third release of 2018!
Todays release continues to focus on internal improvements and graduating features to stable in Kubernetes. This newest version graduates key features such as security and Azure. Notable additions in this release include two highly-anticipated features graduating to general availability: Kubelet TLS Bootstrap and Support for Azure Virtual Machine Scale Sets (VMSS).
These new features mean increased security, availability, resiliency, and ease of use to get production applications to market faster. The release also signifies the increasing maturation and sophistication of Kubernetes on the developer side.
Lets dive into the key features of this release:
## Introducing General Availability of Kubelet TLS Bootstrap
Were excited to announce General Availability (GA) of [Kubelet TLS Bootstrap](https://github.com/kubernetes/features/issues/43). In Kubernetes 1.4, we introduced an API for requesting certificates from a cluster-level Certificate Authority (CA). The original intent of this API is to enable provisioning of TLS client certificates for kubelets. This feature allows for a kubelet to bootstrap itself into a TLS-secured cluster. Most importantly, it automates the provision and distribution of signed certificates.
Before, when a kubelet ran for the first time, it had to be given client credentials in an out-of-band process during cluster startup. The burden was on the operator to provision these credentials. Because this task was so onerous to manually execute and complex to automate, many operators deployed clusters with a single credential and single identity for all kubelets. These setups prevented deployment of node lockdown features like the Node authorizer and the NodeRestriction admission controller.
To alleviate this, [SIG Auth](https://github.com/kubernetes/community/tree/master/sig-auth) introduced a way for kubelet to generate a private key and a CSR for submission to a cluster-level certificate signing process. The v1 (GA) designation indicates production hardening and readiness, and comes with the guarantee of long-term backwards compatibility.
Alongside this, [Kubelet server certificate bootstrap and rotation](https://github.com/kubernetes/features/issues/267) is moving to beta. Currently, when a kubelet first starts, it generates a self-signed certificate/key pair that is used for accepting incoming TLS connections. This feature introduces a process for generating a key locally and then issuing a Certificate Signing Request to the cluster API server to get an associated certificate signed by the clusters root certificate authority. Also, as certificates approach expiration, the same mechanism will be used to request an updated certificate.
## Support for Azure Virtual Machine Scale Sets (VMSS) and Cluster-Autoscaler is Now Stable
Azure Virtual Machine Scale Sets (VMSS) allow you to create and manage a homogenous VM pool that can automatically increase or decrease based on demand or a set schedule. This enables you to easily manage, scale, and load balance multiple VMs to provide high availability and application resiliency, ideal for large-scale applications that can run as Kubernetes workloads.
With this new stable feature, Kubernetes supports the [scaling of containerized applications with Azure VMSS](https://github.com/kubernetes/features/issues/514), including the ability to [integrate it with cluster-autoscaler](https://github.com/kubernetes/features/issues/513) to automatically adjust the size of the Kubernetes clusters based on the same conditions.
## Additional Notable Feature Updates
[`RuntimeClass`](https://github.com/kubernetes/features/issues/585) is a new cluster-scoped resource that surfaces container runtime properties to the control plane being released as an alpha feature.
[Snapshot / restore functionality for Kubernetes and CSI](https://github.com/kubernetes/features/issues/177) is being introduced as an alpha feature. This provides standardized APIs design (CRDs) and adds PV snapshot/restore support for CSI volume drivers.
[Topology aware dynamic provisioning](https://github.com/kubernetes/features/issues/561) is now in beta, meaning storage resources can now understand where they live. This also includes beta support to [AWS EBS](https://github.com/kubernetes/features/issues/567) and [GCE PD](https://github.com/kubernetes/features/issues/558).
[Configurable pod process namespace sharing](https://github.com/kubernetes/features/issues/495) is moving to beta, meaning users can configure containers within a pod to share a common PID namespace by setting an option in the PodSpec.
[Taint node by condition](https://github.com/kubernetes/features/issues/382) is now in beta, meaning users have the ability to represent node conditions that block scheduling by using taints.
[Arbitrary / Custom Metrics](https://github.com/kubernetes/features/issues/117) in the Horizontal Pod Autoscaler is moving to a second beta to test some additional feature enhancements. This reworked Horizontal Pod Autoscaler functionality includes support for custom metrics and status conditions.
Improvements that will allow the [Horizontal Pod Autoscaler to reach proper size faster](https://github.com/kubernetes/features/issues/591) are moving to beta.
[Vertical Scaling of Pods](https://github.com/kubernetes/features/issues/21) is now in beta, which makes it possible to vary the resource limits on a pod over its lifetime. In particular, this is valuable for pets (i.e., pods that are very costly to destroy and re-create).
[Encryption at rest via KMS](https://github.com/kubernetes/features/issues/460) is now in beta. This adds multiple encryption providers, including Google Cloud KMS, Azure Key Vault, AWS KMS, and Hashicorp Vault, that will encrypt data as it is stored to etcd.
## Availability
Kubernetes 1.12 is available for [download on GitHub](https://github.com/kubernetes/kubernetes/releases/tag/v1.12.0). To get started with Kubernetes, check out these [interactive tutorials](https://kubernetes.io/docs/tutorials/). You can also install 1.12 using [Kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/).
## 5 Day Features Blog Series
If youre interested in exploring these features more in depth, check back next week for our 5 Days of Kubernetes series where well highlight detailed walkthroughs of the following features:
* Day 1 - Kubelet TLS Bootstrap
* Day 2 - Support for Azure Virtual Machine Scale Sets (VMSS) and Cluster-Autoscaler
* Day 3 - Snapshots Functionality
* Day 4 - RuntimeClass
* Day 5 - Topology Resources
## Release team
This release is made possible through the effort of hundreds of individuals who contributed both technical and non-technical content. Special thanks to the [release team](https://github.com/kubernetes/sig-release/blob/master/releases/release-1.12/release_team.md) led by Tim Pepper, Orchestration & Containers Lead, at VMware Open Source Technology Center. The 36 individuals on the release team coordinate many aspects of the release, from documentation to testing, validation, and feature completeness.
As the Kubernetes community has grown, our release process represents an amazing demonstration of collaboration in open source software development. Kubernetes continues to gain new users at a rapid clip. This growth creates a positive feedback cycle where more contributors commit code creating a more vibrant ecosystem. Kubernetes has over 22,000 individual contributors to date and an active community of more than 45,000 people.
## Project Velocity
The CNCF has continued refining DevStats, an ambitious project to visualize the myriad contributions that go into the project. [K8s DevStats](https://devstats.k8s.io) illustrates the breakdown of contributions from major company contributors, as well as an impressive set of preconfigured reports on everything from individual contributors to pull request lifecycle times. On average, 259 different companies and over 1,400 individuals contribute to Kubernetes each month. [Check out DevStats](https://k8s.devstats.cncf.io/d/11/companies-contributing-in-repository-groups?orgId=1&var-period=m&var-repogroup_name=All) to learn more about the overall velocity of the Kubernetes project and community.
## User Highlights
Established, global organizations are using [Kubernetes in production](https://kubernetes.io/case-studies/) at massive scale. Recently published user stories from the community include:
* **Ygrene**, a PACE (Property Assessed Clean Energy) financing company, is using cloud native to [bring security and scalability to the finance industry](https://kubernetes.io/case-studies/ygrene/), cutting deployment times down to five minutes with Kubernetes.
* **Sling TV**, a live TV streaming service, uses Kubernetes to [enable their hybrid cloud strategy](https://kubernetes.io/case-studies/slingtv/) and deliver a high-quality service for their customers.
* **ING**, a Dutch multinational banking and financial services corporation, moved to Kubernetes with the intent to eventually be able to go from [idea to production within 48 hours](https://kubernetes.io/case-studies/ing/).
* **Pinterest**, a web and mobile application company that is running on 1,000 microservices and hundreds of thousands of data jobs, moved to Kubernetes to [build on-demand scaling and simply the deployment process](https://kubernetes.io/case-studies/pinterest/).
* **Pearson**, a global education company serving 75 million learners, is using Kubernetes to [transform the way that educational content is delivered online](https://kubernetes.io/case-studies/pearson/) and has saved 15-20% in developer productivity.
Is Kubernetes helping your team? [Share your story](https://docs.google.com/a/google.com/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform) with the community.
## Ecosystem Updates
* CNCF recently released the findings of their [bi-annual CNCF survey](https://www.cncf.io/blog/2018/08/29/cncf-survey-use-of-cloud-native-technologies-in-production-has-grown-over-200-percent/), finding that the use of cloud native technologies in production has grown over 200% within the last six months.
* CNCF expanded its certification offerings to include a Certified Kubernetes Application Developer exam. The CKAD exam certifies an individual's ability to design, build, configure, and expose cloud native applications for Kubernetes. More information can be found [here](https://www.cncf.io/blog/2018/03/16/cncf-announces-ckad-exam/).
* CNCF added a new partner category, Kubernetes Training Partners (KTP). KTPs are a tier of vetted training providers who have deep experience in cloud native technology training. View partners and learn more [here](https://www.cncf.io/certification/training/).
* CNCF also offers [online training](https://www.cncf.io/certification/training/) that teaches the skills needed to create and configure a real-world Kubernetes cluster.
* Kubernetes documentation now features [user journeys](https://k8s.io/docs/home/): specific pathways for learning based on who readers are and what readers want to do. Learning Kubernetes is easier than ever for beginners, and more experienced users can find task journeys specific to cluster admins and application developers.
## KubeCon
The worlds largest Kubernetes gathering, KubeCon + CloudNativeCon is coming to [Shanghai](https://events.linuxfoundation.cn/events/kubecon-cloudnativecon-china-2018/) from November 13-15, 2018 and [Seattle](https://events.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2018/) from December 10-13, 2018. This conference will feature technical sessions, case studies, developer deep dives, salons and more! [Register today](https://www.cncf.io/community/kubecon-cloudnativecon-events/)!
## Webinar
Join members of the Kubernetes 1.12 release team on November 6th at 10am PDT to learn about the major features in this release. Register [here](https://zoom.us/webinar/register/WN_DYMejau3TMaTbk91oC3YkA).
## Get Involved
The simplest way to get involved with Kubernetes is by joining one of the many [Special Interest Groups](https://github.com/kubernetes/community/blob/master/sig-list.md) (SIGs) that align with your interests. Have something youd like to broadcast to the Kubernetes community? Share your voice at our weekly [community meeting](https://github.com/kubernetes/community/blob/master/communication.md#weekly-meeting), and through the channels below.
Thank you for your continued feedback and support.
* Post questions (or answer questions) on [Stack Overflow](http://stackoverflow.com/questions/tagged/kubernetes)
* Join the community portal for advocates on [K8sPort](http://k8sport.org/)
* Follow us on Twitter [@Kubernetesio](https://twitter.com/kubernetesio) for latest updates
* Chat with the community on [Slack](http://slack.k8s.io/)
* Share your Kubernetes [story](https://docs.google.com/a/linuxfoundation.org/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform)
@@ -0,0 +1,97 @@
---
layout: blog
title: 'Health checking gRPC servers on Kubernetes'
date: 2018-10-01
---
**Author**: [Ahmet Alp Balkan](https://twitter.com/ahmetb) (Google)
[gRPC](https://grpc.io) is on its way to becoming the lingua franca for
communication between cloud-native microservices. If you are deploying gRPC
applications to Kubernetes today, you may be wondering about the best way to
configure health checks. In this article, we will talk about
[grpc-health-probe](https://github.com/grpc-ecosystem/grpc-health-probe/), a
Kubernetes-native way to health check gRPC apps.
If you're unfamiliar, Kubernetes [health
checks](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
(liveness and readiness probes) is what's keeping your applications available
while you're sleeping. They detect unresponsive pods, mark them unhealthy, and
cause these pods to be restarted or rescheduled.
Kubernetes [does not
support](https://github.com/kubernetes/kubernetes/issues/21493) gRPC health
checks natively. This leaves the gRPC developers with the following three
approaches when they deploy to Kubernetes:
[![options for health checking grpc on kubernetes today](/images/blog/2019-09-30-health-checking-grpc/options.png)](/images/blog/2019-09-30-health-checking-grpc/options.png)
1. **httpGet probe:** Cannot be natively used with gRPC. You need to refactor
your app to serve both gRPC and HTTP/1.1 protocols (on different port
numbers).
2. **tcpSocket probe:** Opening a socket to gRPC server is not meaningful,
since it cannot read the response body.
3. **exec probe:** This invokes a program in a container's ecosystem
periodically. In the case of gRPC, this means you implement a health RPC
yourself, then write and ship a client tool with your container.
Can we do better? Absolutely.
## Introducing “grpc-health-probe”
To standardize the "exec probe" approach mentioned above, we need:
- a **standard** health check "protocol" that can be implemented in any gRPC
server easily.
- a **standard** health check "tool" that can query the health protocol easily.
Thankfully, gRPC has a [standard health checking
protocol](https://github.com/grpc/grpc/blob/v1.15.0/doc/health-checking.md). It
can be used easily from any language. Generated code and the utilities for
setting the health status are shipped in nearly all language implementations of
gRPC.
If you
[implement](https://github.com/grpc/grpc/blob/v1.15.0/src/proto/grpc/health/v1/health.proto)
this health check protocol in your gRPC apps, you can then use a standard/common
tool to invoke this `Check()` method to determine server status.
The next thing you need is the "standard tool", and it's the
[**grpc-health-probe**](https://github.com/grpc-ecosystem/grpc-health-probe/).
<a href='/images/blog/2019-09-30-health-checking-grpc/grpc_health_probe.png'>
<img width="768" title='grpc-health-probe on kubernetes'
src='/images/blog/2019-09-30-health-checking-grpc/grpc_health_probe.png'/>
</a>
With this tool, you can use the same health check configuration in all your gRPC
applications. This approach requires you to:
1. Find the gRPC "health" module in your favorite language and start using it
(example [Go library](https://godoc.org/github.com/grpc/grpc-go/health)).
2. Ship the
[grpc_health_probe](https://github.com/grpc-ecosystem/grpc-health-probe/)
binary in your container.
3. [Configure](https://github.com/grpc-ecosystem/grpc-health-probe/tree/1329d682b4232c102600b5e7886df8ffdcaf9e26#example-grpc-health-checking-on-kubernetes)
Kubernetes "exec" probe to invoke the "grpc_health_probe" tool in the
container.
In this case, executing "grpc_health_probe" will call your gRPC server over
`localhost`, since they are in the same pod.
## What's next
**grpc-health-probe** project is still in its early days and it needs your
feedback. It supports a variety of features like communicating with TLS servers
and configurable connection/RPC timeouts.
If you are running a gRPC server on Kubernetes today, try using the gRPC Health
Protocol and try the grpc-health-probe in your deployments, and [give
feedback](https://github.com/grpc-ecosystem/grpc-health-probe/).
## Further reading
- Protocol: [GRPC Health Checking Protocol](https://github.com/grpc/grpc/blob/v1.15.0/doc/health-checking.md) ([health.proto](https://github.com/grpc/grpc/blob/v1.15.0/src/proto/grpc/health/v1/health.proto))
- Documentation: [Kubernetes liveness and readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
- Article: [Advanced Kubernetes Health Check Patterns](https://ahmet.im/blog/advanced-kubernetes-health-checks/)
@@ -0,0 +1,496 @@
---
layout: blog
title: 'Building a Network Bootable Server Farm for Kubernetes with LTSP'
date: 2018-10-02
---
**Author**: Andrei Kvapil (WEDOS)
![k8s+ltsp](/images/blog/2018-10-01-network-bootable-farm-with-ltsp/k8s+ltsp.svg)
In this post, I'm going to introduce you to a cool technology for Kubernetes, LTSP. It is useful for large baremetal Kubernetes deployments.
You don't need to think about installing an OS and binaries on each node anymore. Why? You can do that automatically through Dockerfile!
You can buy and put 100 new servers into a production environment and get them working immediately - it's really amazing!
Intrigued? Let me walk you through how it works.
# Summary
First, we need to understand how exactly it works.
In short, for all nodes we have prepared the image with the OS, Docker, Kubelet and everything else that you need there. This image with the kernel is building automatically by CI using Dockerfile. End nodes are booting the kernel and OS from this image via the network.
Nodes are using overlays as the root filesystem and after reboot any changes will be lost (like in Docker containers). You have a config-file where you can describe mounts and some initial commands which should be executed during node boot (Example: set root user ssh-key and kubeadm join commands)
## Image Preparation Process
We will use LTSP project because it's gives us everything we need to organize the network booting environment. Basically, LTSP is a pack of shell-scripts which makes our life much easier.
LTSP provides a initramfs module, a few helper-scripts, and the configuration system which prepare the system during the early state of boot, before the main init process call.
**This is what the image preparation procedure looks like:**
- You're deploying the basesystem in the chroot environment.
- Make any needed changes there, install software.
- Run the `ltsp-build-image` command
After that, you will get the squashed image from the chroot with all the software inside. Each node will download this image during the boot and use it as the rootfs. For the update node, you can just reboot it. The new squashed image will be downloaded and mounted into the rootfs.
## Server Components
**The server part of LTSP includes two components in our case:**
- **TFTP-server** - TFTP is the initial protocol, it is used the download the kernel, initramfs and main config - lts.conf.
- **NBD-server** - NBD protocol is used to distribute the squashed rootfs image to the clients. It is the fastest way, but if you want, it can be replaced by the NFS or AoE protocol.
You should also have:
- **DHCP-server** - it will distribute the IP-settings and a few specific options to the clients to make it possible for them to boot from our LTSP-server.
## Node Booting Process
**This is how the node is booting up**
- The first time, the node will ask DHCP for IP-settings and `next-server`, `filename` options.
- Next, the node will apply settings and download bootloader (pxelinux or grub)
- Bootloader will download and read config with the kernel and initramfs image.
- Then bootloader will download the kernel and initramfs and execute it with specific cmdline options.
- During the boot, initramfs modules will handle options from cmdline and do some actions like connect NBD-device, prepare overlay rootfs, etc.
- Afterwards it will call the ltsp-init system instead of the normal init.
- ltsp-init scripts will prepare the system on the earlier stage, before the main init will be called. Basically it applies the setting from lts.conf (main config): write fstab and rc.local entries etc.
- Call the main init (systemd) which is booting the configured system as usual, mounts shares from fstab, start targets and services, executes commands from rc.local file.
- In the end you have a fully configured and booted system ready for further operations.
# Preparing the Server
As I said before, I'm preparing the LTSP-server with the squashed image automatically using Dockerfile. This method is quite good because you have all steps described in your git repository.
You have versioning, branches, CI and everything that you used to use for preparing your usual Docker projects.
Otherwise, you can deploy the LTSP server manually by executing all steps by hand. This is a good practice for learning and understanding the basic principles.
Just repeat all the steps listed here by hand, just to try to install LTSP without Dockerfile.
## Used Patches List
LTSP still has some issues which authors dont want to apply, yet. However LTSP is easy customizable so I prepared a few patches for myself and will share them here.
Ill create a fork if the community will warmly accept my solution.
* [feature-grub.diff](https://github.com/kvaps/ltsp/compare/feature-grub.diff)
LTSP does not support EFI by default, so I've prepared a patch which adds GRUB2 with EFI support.
* [feature_preinit.diff](https://github.com/kvaps/ltsp/compare/feature_preinit.diff)
This patch adds a PREINIT option to lts.conf, which allows you to run custom commands before the main init call. It may be useful to modify the systemd units and configure the network. It's remarkable that all environment variables from the boot environment are saved and you can use them in your scripts.
* [feature_initramfs_params_from_lts_conf.diff](https://github.com/kvaps/ltsp/compare/feature_initramfs_params_from_lts_conf.diff)
Solves a problem with NBD_TO_RAM option, after this patch you can specify it on lts.conf inside chroot. (not in tftp directory)
* [nbd-server-wrapper.sh](https://gist.githubusercontent.com/kvaps/1a6a7d8b73bf7444f0f99b22379c9e4e/raw/eb0d60c638ef72b7e28438b7f4d2beda89c41f75/nbd-server-wrapper.sh)
This is not a patch but a special wrapper script which allows you to run NBD-server in the foreground. It is useful if you want to run it inside a Docker container.
## Dockerfile Stages
We will use [stage building](https://docs.docker.com/develop/develop-images/multistage-build/) in our Dockerfile to leave only the needed parts in our Docker image. The unused parts will be removed from the final image.
```
ltsp-base
(install basic LTSP server software)
|
|---basesystem
| (prepare chroot with main software and kernel)
| |
| |---builder
| | (build additional software from sources, if needed)
| |
| '---ltsp-image
| (install additional software, docker, kubelet and build squashed image)
|
'---final-stage
(copy squashed image, kernel and initramfs into first stage)
```
### Stage 1: ltsp-base
Let's start writing our Dockerfile. This is the first part:
```Dockerfile
FROM ubuntu:16.04 as ltsp-base
ADD nbd-server-wrapper.sh /bin/
ADD /patches/feature-grub.diff /patches/feature-grub.diff
RUN apt-get -y update \
&& apt-get -y install \
ltsp-server \
tftpd-hpa \
nbd-server \
grub-common \
grub-pc-bin \
grub-efi-amd64-bin \
curl \
patch \
&& sed -i 's|in_target mount|in_target_nofail mount|' \
/usr/share/debootstrap/functions \
# Add EFI support and Grub bootloader (#1745251)
&& patch -p2 -d /usr/sbin < /patches/feature-grub.diff \
&& rm -rf /var/lib/apt/lists \
&& apt-get clean
```
At this stage our Docker image has already been installed:
* NBD-server
* TFTP-server
* LTSP-scripts with grub bootloader support (for EFI)
### Stage 2: basesystem
In this stage we will prepare a chroot environment with basesystem, and install basic software with the kernel.
We will use the classic **debootstrap** instead of **ltsp-build-client** to prepare the base image, because **ltsp-build-client** will install GUI and few other things which we don't need for the server deployment.
```Dockerfile
FROM ltsp-base as basesystem
ARG DEBIAN_FRONTEND=noninteractive
# Prepare base system
RUN debootstrap --arch amd64 xenial /opt/ltsp/amd64
# Install updates
RUN echo "\
deb http://archive.ubuntu.com/ubuntu xenial main restricted universe multiverse\n\
deb http://archive.ubuntu.com/ubuntu xenial-updates main restricted universe multiverse\n\
deb http://archive.ubuntu.com/ubuntu xenial-security main restricted universe multiverse" \
> /opt/ltsp/amd64/etc/apt/sources.list \
&& ltsp-chroot apt-get -y update \
&& ltsp-chroot apt-get -y upgrade
# Installing LTSP-packages
RUN ltsp-chroot apt-get -y install ltsp-client-core
# Apply initramfs patches
# 1: Read params from /etc/lts.conf during the boot (#1680490)
# 2: Add support for PREINIT variables in lts.conf
ADD /patches /patches
RUN patch -p4 -d /opt/ltsp/amd64/usr/share < /patches/feature_initramfs_params_from_lts_conf.diff \
&& patch -p3 -d /opt/ltsp/amd64/usr/share < /patches/feature_preinit.diff
# Write new local client config for boot NBD image to ram:
RUN echo "[Default]\nLTSP_NBD_TO_RAM = true" \
> /opt/ltsp/amd64/etc/lts.conf
# Install packages
RUN echo 'APT::Install-Recommends "0";\nAPT::Install-Suggests "0";' \
>> /opt/ltsp/amd64/etc/apt/apt.conf.d/01norecommend \
&& ltsp-chroot apt-get -y install \
software-properties-common \
apt-transport-https \
ca-certificates \
ssh \
bridge-utils \
pv \
jq \
vlan \
bash-completion \
screen \
vim \
mc \
lm-sensors \
htop \
jnettop \
rsync \
curl \
wget \
tcpdump \
arping \
apparmor-utils \
nfs-common \
telnet \
sysstat \
ipvsadm \
ipset \
make
# Install kernel
RUN ltsp-chroot apt-get -y install linux-generic-hwe-16.04
```
Note that you may encounter problems with some packages, such as `lvm2`.
They have not fully optimized for installing in an unprivileged chroot.
Their postinstall scripts try to call some privileged commands which can fail with errors and block the package installation.
Solution:
* Some of them can be installed before the kernel without any problems (like `lvm2`)
* But for some of them you will need to use [this workaround](https://askubuntu.com/a/482936/327437) to install without the postinstall script.
### Stage 3: builder
Now we can build all the necessary software and kernel modules. It's really cool that you can do that automatically in this stage.
You can skip this stage if you have nothing to do here.
Here is example for install latest MLNX_EN driver:
```Dockerfile
FROM basesystem as builder
# Set cpuinfo (for building from sources)
RUN cp /proc/cpuinfo /opt/ltsp/amd64/proc/cpuinfo
# Compile Mellanox driver
RUN ltsp-chroot sh -cx \
' VERSION=4.3-1.0.1.0-ubuntu16.04-x86_64 \
&& curl -L http://www.mellanox.com/downloads/ofed/MLNX_EN-${VERSION%%-ubuntu*}/mlnx-en-${VERSION}.tgz \
| tar xzf - \
&& export \
DRIVER_DIR="$(ls -1 | grep "MLNX_OFED_LINUX-\|mlnx-en-")" \
KERNEL="$(ls -1t /lib/modules/ | head -n1)" \
&& cd "$DRIVER_DIR" \
&& ./*install --kernel "$KERNEL" --without-dkms --add-kernel-support \
&& cd - \
&& rm -rf "$DRIVER_DIR" /tmp/mlnx-en* /tmp/ofed*'
# Save kernel modules
RUN ltsp-chroot sh -c \
' export KERNEL="$(ls -1t /usr/src/ | grep -m1 "^linux-headers" | sed "s/^linux-headers-//g")" \
&& tar cpzf /modules.tar.gz /lib/modules/${KERNEL}/updates'
```
### Stage 4: ltsp-image
In this stage we will install what we built in the previous step:
```Dockerfile
FROM basesystem as ltsp-image
# Retrieve kernel modules
COPY --from=builder /opt/ltsp/amd64/modules.tar.gz /opt/ltsp/amd64/modules.tar.gz
# Install kernel modules
RUN ltsp-chroot sh -c \
' export KERNEL="$(ls -1t /usr/src/ | grep -m1 "^linux-headers" | sed "s/^linux-headers-//g")" \
&& tar xpzf /modules.tar.gz \
&& depmod -a "${KERNEL}" \
&& rm -f /modules.tar.gz'
```
Then do some additional changes to finalize our ltsp-image:
```Dockerfile
# Install docker
RUN ltsp-chroot sh -c \
' curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \
&& echo "deb https://download.docker.com/linux/ubuntu xenial stable" \
> /etc/apt/sources.list.d/docker.list \
&& apt-get -y update \
&& apt-get -y install \
docker-ce=$(apt-cache madison docker-ce | grep 18.06 | head -1 | awk "{print $ 3}")'
# Configure docker options
RUN DOCKER_OPTS="$(echo \
--storage-driver=overlay2 \
--iptables=false \
--ip-masq=false \
--log-driver=json-file \
--log-opt=max-size=10m \
--log-opt=max-file=5 \
)" \
&& sed "/^ExecStart=/ s|$| $DOCKER_OPTS|g" \
/opt/ltsp/amd64/lib/systemd/system/docker.service \
> /opt/ltsp/amd64/etc/systemd/system/docker.service
# Install kubeadm, kubelet and kubectl
RUN ltsp-chroot sh -c \
' curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - \
&& echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" \
> /etc/apt/sources.list.d/kubernetes.list \
&& apt-get -y update \
&& apt-get -y install kubelet kubeadm kubectl cri-tools'
# Disable automatic updates
RUN rm -f /opt/ltsp/amd64/etc/apt/apt.conf.d/20auto-upgrades
# Disable apparmor profiles
RUN ltsp-chroot find /etc/apparmor.d \
-maxdepth 1 \
-type f \
-name "sbin.*" \
-o -name "usr.*" \
-exec ln -sf "{}" /etc/apparmor.d/disable/ \;
# Write kernel cmdline options
RUN KERNEL_OPTIONS="$(echo \
init=/sbin/init-ltsp \
forcepae \
console=tty1 \
console=ttyS0,9600n8 \
nvme_core.default_ps_max_latency_us=0 \
)" \
&& sed -i "/^CMDLINE_LINUX_DEFAULT=/ s|=.*|=\"${KERNEL_OPTIONS}\"|" \
"/opt/ltsp/amd64/etc/ltsp/update-kernels.conf"
```
Then we will make the squashed image from our chroot:
```Dockerfile
# Cleanup caches
RUN rm -rf /opt/ltsp/amd64/var/lib/apt/lists \
&& ltsp-chroot apt-get clean
# Build squashed image
RUN ltsp-update-image
```
### Stage 5: Final Stage
In the final stage we will save only our squashed image and kernels with initramfs.
```Dockerfile
FROM ltsp-base
COPY --from=ltsp-image /opt/ltsp/images /opt/ltsp/images
COPY --from=ltsp-image /etc/nbd-server/conf.d /etc/nbd-server/conf.d
COPY --from=ltsp-image /var/lib/tftpboot /var/lib/tftpboot
```
Ok, now we have docker image which includes:
- TFTP-server
- NBD-server
- configured bootloader
- kernel with initramfs
- squashed rootfs image
# Usage
OK, now when our docker-image with LTSP-server, kernel, initramfs and squashed rootfs fully prepared we can run the deployment with it.
We can do that as usual, but one more thing is networking.
Unfortunately, we can't use the standard Kubernetes service abstraction for our deployment, because during the boot, our nodes are not part of Kubernetes cluster and they requires ExternalIP, but Kubernetes always enables NAT for ExternalIPs, and there is no way to disable this behavior.
For now I have two ways for avoid this: use `hostNetwork: true` or use [pipework](https://github.com/dreamcat4/docker-images/blob/master/pipework/3.%20Examples.md#kubernetes). The second option will also provide you redundancy because, in case of failure, the IP will be moved with the Pod to another node. Unfortunately, pipework is not native and a less secure method.
If you have some better option for that please let me know.
Here is example for deployment with hostNetwork:
```yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ltsp-server
labels:
app: ltsp-server
spec:
selector:
matchLabels:
name: ltsp-server
replicas: 1
template:
metadata:
labels:
name: ltsp-server
spec:
hostNetwork: true
containers:
- name: tftpd
image: registry.example.org/example/ltsp:latest
command: [ "/usr/sbin/in.tftpd", "-L", "-u", "tftp", "-a", ":69", "-s", "/var/lib/tftpboot" ]
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "cd /var/lib/tftpboot/ltsp/amd64; ln -sf config/lts.conf ." ]
volumeMounts:
- name: config
mountPath: "/var/lib/tftpboot/ltsp/amd64/config"
- name: nbd-server
image: registry.example.org/example/ltsp:latest
command: [ "/bin/nbd-server-wrapper.sh" ]
volumes:
- name: config
configMap:
name: ltsp-config
```
As you can see it also requires configmap with **lts.conf** file.
Here is example part from mine:
```
apiVersion: v1
kind: ConfigMap
metadata:
name: ltsp-config
data:
lts.conf: |
[default]
KEEP_SYSTEM_SERVICES = "ssh ureadahead dbus-org.freedesktop.login1 systemd-logind polkitd cgmanager ufw rpcbind nfs-kernel-server"
PREINIT_00_TIME = "ln -sf /usr/share/zoneinfo/Europe/Prague /etc/localtime"
PREINIT_01_FIX_HOSTNAME = "sed -i '/^127.0.0.2/d' /etc/hosts"
PREINIT_02_DOCKER_OPTIONS = "sed -i 's|^ExecStart=.*|ExecStart=/usr/bin/dockerd -H fd:// --storage-driver overlay2 --iptables=false --ip-masq=false --log-driver=json-file --log-opt=max-size=10m --log-opt=max-file=5|' /etc/systemd/system/docker.service"
FSTAB_01_SSH = "/dev/data/ssh /etc/ssh ext4 nofail,noatime,nodiratime 0 0"
FSTAB_02_JOURNALD = "/dev/data/journal /var/log/journal ext4 nofail,noatime,nodiratime 0 0"
FSTAB_03_DOCKER = "/dev/data/docker /var/lib/docker ext4 nofail,noatime,nodiratime 0 0"
# Each command will stop script execution when fail
RCFILE_01_SSH_SERVER = "cp /rofs/etc/ssh/*_config /etc/ssh; ssh-keygen -A"
RCFILE_02_SSH_CLIENT = "mkdir -p /root/.ssh/; echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBSLYRaORL2znr1V4a3rjDn3HDHn2CsvUNK1nv8+CctoICtJOPXl6zQycI9KXNhANfJpc6iQG1ZPZUR74IiNhNIKvOpnNRPyLZ5opm01MVIDIZgi9g0DUks1g5gLV5LKzED8xYKMBmAfXMxh/nsP9KEvxGvTJB3OD+/bBxpliTl5xY3Eu41+VmZqVOz3Yl98+X8cZTgqx2dmsHUk7VKN9OZuCjIZL9MtJCZyOSRbjuo4HFEssotR1mvANyz+BUXkjqv2pEa0I2vGQPk1VDul5TpzGaN3nOfu83URZLJgCrX+8whS1fzMepUYrbEuIWq95esjn0gR6G4J7qlxyguAb9 admin@kubernetes' >> /root/.ssh/authorized_keys"
RCFILE_03_KERNEL_DEBUG = "sysctl -w kernel.unknown_nmi_panic=1 kernel.softlockup_panic=1; modprobe netconsole netconsole=@/vmbr0,@10.9.0.15/"
RCFILE_04_SYSCTL = "sysctl -w fs.file-max=20000000 fs.nr_open=20000000 net.ipv4.neigh.default.gc_thresh1=80000 net.ipv4.neigh.default.gc_thresh2=90000 net.ipv4.neigh.default.gc_thresh3=100000"
RCFILE_05_FORWARD = "echo 1 > /proc/sys/net/ipv4/ip_forward"
RCFILE_06_MODULES = "modprobe br_netfilter"
RCFILE_07_JOIN_K8S = "kubeadm join --token 2a4576.504356e45fa3d365 10.9.0.20:6443 --discovery-token-ca-cert-hash sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
```
* **KEEP_SYSTEM_SERVICES** - during the boot, LTSP automatically removes some services, this variable is needed to prevent this behavior.
* **PREINIT_*** - commands listed here will be executed before systemd runs (this function was added by the [feature_preinit.diff](#used-patches-list) patch)
* **FSTAB_*** - entries written here will be added to the `/etc/fstab` file.
As you can see, I use the `nofail` option, that means that if a partition doesn't exist, it will continue to boot without error.
If you have fully diskless nodes you can remove the FSTAB settings or configure the remote filesystem there.
* **RCFILE_*** - those commands will be written to `rc.local` file, which will be called by systemd during the boot.
Here I load the kernel modules and add some sysctl tunes, then call the `kubeadm join` command, which adds my node to the Kubernetes cluster.
You can get more details on all the variables used from [lts.conf manpage](http://manpages.ubuntu.com/manpages/xenial/man5/lts.conf.5.html).
Now you can configure your DHCP. Basically you should set the `next-server` and `filename` options.
I use ISC-DHCP server, and here is an example `dhcpd.conf`:
```
shared-network ltsp-netowrk {
subnet 10.9.0.0 netmask 255.255.0.0 {
authoritative;
default-lease-time -1;
max-lease-time -1;
option domain-name "example.org";
option domain-name-servers 10.9.0.1;
option routers 10.9.0.1;
next-server ltsp-1; # write LTSP-server hostname here
if option architecture = 00:07 {
filename "/ltsp/amd64/grub/x86_64-efi/core.efi";
} else {
filename "/ltsp/amd64/grub/i386-pc/core.0";
}
range 10.9.200.0 10.9.250.254;
}
```
You can start from this, but what about me, I have multiple LTSP-servers and I configure leases statically for each node via the Ansible playbook.
Try to run your first node. If everything was right, you will have a running system there.
The node also will be added to your Kubernetes cluster.
Now you can try to make your own changes.
If you need something more, note that LTSP can be easily changed to meet your needs.
Feel free to look into the source code and you can find many answers there.
**UPD:** Many people asking me: Why not simple use CoreOS and Ignition?
I can answer. The main feature here is image preparation process not configuration.
In case with LTSP you have classic Ubuntu system, and everything that can be installed on Ubuntu it can also be written here in the Dockerfile.
In case CoreOS you have no so many freedom and you cant easily add custom kernel modules and packages at the build stage of the boot image.
@@ -0,0 +1,191 @@
---
layout: blog
title: 'KubeDirector: The easy way to run complex stateful applications on Kubernetes'
date: 2018-10-03
---
**Author**: Thomas Phelan (BlueData)
KubeDirector is an open source project designed to make it easy to run complex stateful scale-out application clusters on Kubernetes. KubeDirector is built using the custom resource definition (CRD) framework and leverages the native Kubernetes API extensions and design philosophy. This enables transparent integration with Kubernetes user/resource management as well as existing clients and tools.
We recently [introduced the KubeDirector project](https://medium.com/@thomas_phelan/operation-stateful-introducing-bluek8s-and-kubernetes-director-aa204952f619/), as part of a broader open source Kubernetes initiative we call BlueK8s. Im happy to announce that the pre-alpha
code for [KubeDirector](https://github.com/bluek8s/kubedirector/) is now available. And in this blog post, Ill show how it works.
KubeDirector provides the following capabilities:
* The ability to run non-cloud native stateful applications on Kubernetes without modifying the code. In other words, its not necessary to decompose these existing applications to fit a microservices design pattern.
* Native support for preserving application-specific configuration and state.
* An application-agnostic deployment pattern, minimizing the time to onboard new stateful applications to Kubernetes.
KubeDirector enables data scientists familiar with data-intensive distributed applications such as Hadoop, Spark, Cassandra, TensorFlow, Caffe2, etc. to run these applications on Kubernetes -- with a minimal learning curve and no need to write GO code. The applications controlled by KubeDirector are defined by some basic metadata and an associated package of configuration artifacts. The application metadata is referred to as a KubeDirectorApp resource.
To understand the components of KubeDirector, clone the repository on [GitHub](https://github.com/bluek8s/kubedirector/) using a command similar to:
```
git clone http://<userid>@github.com/bluek8s/kubedirector.
```
The KubeDirectorApp definition for the Spark 2.2.1 application is located
in the file `kubedirector/deploy/example_catalog/cr-app-spark221e2.json`.
```
~> cat kubedirector/deploy/example_catalog/cr-app-spark221e2.json
{
"apiVersion": "kubedirector.bluedata.io/v1alpha1",
"kind": "KubeDirectorApp",
"metadata": {
"name" : "spark221e2"
},
"spec" : {
"systemctlMounts": true,
"config": {
"node_services": [
{
"service_ids": [
"ssh",
"spark",
"spark_master",
"spark_worker"
],
```
The configuration of an application cluster is referred to as a KubeDirectorCluster resource. The
KubeDirectorCluster definition for a sample Spark 2.2.1 cluster is located in the file
`kubedirector/deploy/example_clusters/cr-cluster-spark221.e1.yaml`.
```
~> cat kubedirector/deploy/example_clusters/cr-cluster-spark221.e1.yaml
apiVersion: "kubedirector.bluedata.io/v1alpha1"
kind: "KubeDirectorCluster"
metadata:
name: "spark221e2"
spec:
app: spark221e2
roles:
- name: controller
replicas: 1
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "4Gi"
cpu: "2"
- name: worker
replicas: 2
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "4Gi"
cpu: "2"
- name: jupyter
```
## Running Spark on Kubernetes with KubeDirector
With KubeDirector, its easy to run Spark clusters on Kubernetes.
First, verify that Kubernetes (version 1.9 or later) is running, using the command `kubectl version`
```
~> kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T18:02:47Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T17:53:03Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
```
Deploy the KubeDirector service and the example KubeDirectorApp resource definitions with the commands:
```
cd kubedirector
make deploy
```
These will start the KubeDirector pod:
```
~> kubectl get pods
NAME READY STATUS RESTARTS AGE
kubedirector-58cf59869-qd9hb 1/1 Running 0 1m
```
List the installed KubeDirector applications with `kubectl get KubeDirectorApp`
```
~> kubectl get KubeDirectorApp
NAME AGE
cassandra311 30m
spark211up 30m
spark221e2 30m
```
Now you can launch a Spark 2.2.1 cluster using the example KubeDirectorCluster file and the
`kubectl create -f deploy/example_clusters/cr-cluster-spark211up.yaml` command.
Verify that the Spark cluster has been started:
```
~> kubectl get pods
NAME READY STATUS RESTARTS AGE
kubedirector-58cf59869-djdwl 1/1 Running 0 19m
spark221e2-controller-zbg4d-0 1/1 Running 0 23m
spark221e2-jupyter-2km7q-0 1/1 Running 0 23m
spark221e2-worker-4gzbz-0 1/1 Running 0 23m
spark221e2-worker-4gzbz-1 1/1 Running 0 23m
```
The running services now include the Spark services:
```
~> kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubedirector ClusterIP 10.98.234.194 <none> 60000/TCP 1d
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
svc-spark221e2-5tg48 ClusterIP None <none> 8888/TCP 21s
svc-spark221e2-controller-tq8d6-0 NodePort 10.104.181.123 <none> 22:30534/TCP,8080:31533/TCP,7077:32506/TCP,8081:32099/TCP 20s
svc-spark221e2-jupyter-6989v-0 NodePort 10.105.227.249 <none> 22:30632/TCP,8888:30355/TCP 20s
svc-spark221e2-worker-d9892-0 NodePort 10.107.131.165 <none> 22:30358/TCP,8081:32144/TCP 20s
svc-spark221e2-worker-d9892-1 NodePort 10.110.88.221 <none> 22:30294/TCP,8081:31436/TCP 20s
```
Pointing the browser at port 31533 connects to the Spark Master UI:
![kubedirector](/images/blog/2018-10-03-kubedirector/kubedirector.png)
Thats all there is to it!
In fact, in the example above we also deployed a Jupyter notebook along with the Spark cluster.
To start another application (e.g. Cassandra), just specify another KubeDirectorApp file:
```
kubectl create -f deploy/example_clusters/cr-cluster-cassandra311.yaml
```
See the running Cassandra cluster:
```
~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cassandra311-seed-v24r6-0 1/1 Running 0 1m
cassandra311-seed-v24r6-1 1/1 Running 0 1m
cassandra311-worker-rqrhl-0 1/1 Running 0 1m
cassandra311-worker-rqrhl-1 1/1 Running 0 1m
kubedirector-58cf59869-djdwl 1/1 Running 0 1d
spark221e2-controller-tq8d6-0 1/1 Running 0 22m
spark221e2-jupyter-6989v-0 1/1 Running 0 22m
spark221e2-worker-d9892-0 1/1 Running 0 22m
spark221e2-worker-d9892-1 1/1 Running 0 22m
```
Now you have a Spark cluster (with a Jupyter notebook) and a Cassandra cluster running on Kubernetes.
Use `kubectl get service` to see the set of services.
```
~> kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubedirector ClusterIP 10.98.234.194 <none> 60000/TCP 1d
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
svc-cassandra311-seed-v24r6-0 NodePort 10.96.94.204 <none> 22:31131/TCP,9042:30739/TCP 3m
svc-cassandra311-seed-v24r6-1 NodePort 10.106.144.52 <none> 22:30373/TCP,9042:32662/TCP 3m
svc-cassandra311-vhh29 ClusterIP None <none> 8888/TCP 3m
svc-cassandra311-worker-rqrhl-0 NodePort 10.109.61.194 <none> 22:31832/TCP,9042:31962/TCP 3m
svc-cassandra311-worker-rqrhl-1 NodePort 10.97.147.131 <none> 22:31454/TCP,9042:31170/TCP 3m
svc-spark221e2-5tg48 ClusterIP None <none> 8888/TCP 24m
svc-spark221e2-controller-tq8d6-0 NodePort 10.104.181.123 <none> 22:30534/TCP,8080:31533/TCP,7077:32506/TCP,8081:32099/TCP 24m
svc-spark221e2-jupyter-6989v-0 NodePort 10.105.227.249 <none> 22:30632/TCP,8888:30355/TCP 24m
svc-spark221e2-worker-d9892-0 NodePort 10.107.131.165 <none> 22:30358/TCP,8081:32144/TCP 24m
svc-spark221e2-worker-d9892-1 NodePort 10.110.88.221 <none> 22:30294/TCP,8081:31436/TCP 24m
```
## Get Involved
KubeDirector is a fully open source, Apache v2 licensed, project the first of multiple open source projects within a broader initiative we call BlueK8s.
The pre-alpha code for KubeDirector has just been released and we would love for you to join the growing community of developers, contributors, and adopters.
Follow [@BlueK8s](https://twitter.com/BlueK8s/) on Twitter and get involved through these channels:
* KubeDirector [chat room on Slack](https://join.slack.com/t/bluek8s/shared_invite/enQtNDUwMzkwODY5OTM4LTRhYmRmZmE4YzY3OGUzMjA1NDg0MDVhNDQ2MGNkYjRhM2RlMDNjMTI1NDQyMjAzZGVlMDFkNThkNGFjZGZjMGY/)
* KubeDirector [GitHub repo](https://github.com/bluek8s/kubedirector/)
@@ -0,0 +1,43 @@
---
layout: blog
title: 'Introducing the Non-Code Contributors Guide'
date: 2018-10-04
---
**Author**: [Noah Abrahams](https://twitter.com/noah_abrahams) (InfoSiftr), [Jonas Rosland](https://twitter.com/jonasrosland) (VMware), [Ihor Dvoretskyi](https://twitter.com/idvoretskyi) (CNCF)
It was May 2018 in Copenhagen, and the Kubernetes community was enjoying the contributor summit at KubeCon/CloudNativeCon, complete with the first run of the New Contributor Workshop. As a time of tremendous collaboration between contributors, the topics covered ranged from signing the CLA to deep technical conversations. Along with the vast exchange of information and ideas, however, came continued scrutiny of the topics at hand to ensure that the community was being as inclusive and accommodating as possible. Over that spring week, some of the pieces under the microscope included the many themes being covered, and how they were being presented, but also the overarching characteristics of the people contributing and the skill sets involved. From the discussions and analysis that followed grew the idea that the community was not benefiting as much as it could from the many people who wanted to contribute, but whose strengths were in areas other than writing code.
**This all led to an effort called the [Non-Code Contributors Guide](https://github.com/kubernetes/community/blob/master/contributors/guide/non-code-contributions.md).**
Now, its important to note that Kubernetes is rare, if not unique, in the open source world, in that it was defined very early on as both a project and a community. While the project itself is focused on the codebase, it is the community of people driving it forward that makes the project successful. The community works together with an explicit set of [community values](https://github.com/kubernetes/steering/blob/master/values.md), guiding the day-to-day behavior of contributors whether on GitHub, Slack, Discourse, or sitting together over tea or coffee.
By having a community that values people first, and explicitly values a diversity of people, the Kubernetes project is building a product to serve people with diverse needs. The different backgrounds of the contributors bring different approaches to the problem solving, with different methods of collaboration, and all those different viewpoints ultimately create a better project.
The Non-Code Contributors Guide aims to make it easy for anyone to contribute to the Kubernetes project in a way that makes sense for them. This can be in many forms, technical and non-technical, based on the person's knowledge of the project and their available time. Most individuals are not developers, and most of the worlds developers are not paid to fully work on open source projects. Based on this we have started an ever-growing list of possible ways to contribute to the Kubernetes project in a Non-Code way!
## Get Involved
Some of the ways that you can contribute to the Kubernetes community without writing a single line of code include:
- Community education, answering questions on [Discuss](https://discuss.kubernetes.io/), [StackOverflow](https://stackoverflow.com/questions/tagged/kubernetes), and [Slack](http://slack.k8s.io/)
- Outward facing community work such as [hosting meetups](https://www.meetup.com/pro/cncf/) and events
- Writing [project documentation](https://github.com/kubernetes/community/tree/master/sig-docs)
- Writing operational manuals, helping users understand how to run Kubernetes
- Helping deliver Kubernetes, as a part of the [release team](https://github.com/kubernetes/sig-release/blob/master/release-team/README.md)
- Project, program, and [product management](https://github.com/kubernetes/community/blob/master/sig-pm/README.md)
- And many more!
The guide to get started with Kubernetes project contribution is [documented on Github](https://github.com/kubernetes/community/tree/master/contributors/guide), and as the Non-Code Contributors Guide is a part of that Kubernetes Contributors Guide, it can be found [here](https://github.com/kubernetes/community/blob/master/contributors/guide/non-code-contributions.md). As stated earlier, this list is not exhaustive and will continue to be a work in progress.
To date, the typical Non-Code contributions fall into the following categories:
- Roles that are based on skill sets other than “software developer”
- Non-Code contributions in primarily code-based roles
- “Post-Code” roles, that are not code-based, but require knowledge of either the code base or management of the code base
If you, dear reader, have any additional ideas for a Non-Code way to contribute, whether or not it fits in an existing category, the team will always appreciate if you could help us expand the list.
If a contribution of the Non-Code nature appeals to you, please read the Non-Code Contributions document, and then check the [Contributor Role Board](https://discuss.kubernetes.io/c/contributors/role-board) to see if there are any open positions where your expertise could be best used! If there are no listed open positions that match your skill set, drop on by the [#sig-contribex](https://kubernetes.slack.com/messages/sig-contribex) channel on Slack, and well point you in the right direction.
We hope to see you contributing to the Kubernetes community soon!
@@ -0,0 +1,338 @@
---
layout: blog
title: 'Support for Azure VMSS, Cluster-Autoscaler and User Assigned Identity'
date: 2018-10-08
---
**Author**: [Krishnakumar R (KK)](https://twitter.com/kkwriting) (Microsoft), [Pengfei Ni](https://twitter.com/feisky) (Microsoft)
## Introduction
With Kubernetes v1.12, Azure virtual machine scale sets (VMSS) and cluster-autoscaler have reached their General Availability (GA) and User Assigned Identity is available as a preview feature.
_Azure VMSS allow you to create and manage identical, load balanced VMs that automatically increase or decrease based on demand or a set schedule. This enables you to easily manage and scale multiple VMs to provide high availability and application resiliency, ideal for large-scale applications like container workloads [[1]](https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview)._
Cluster autoscaler allows you to adjust the size of the Kubernetes clusters based on the load conditions automatically.
Another exciting feature which v1.12 brings to the table is the ability to use User Assigned Identities with Kubernetes clusters [[12]](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview).
In this article, we will do a brief overview of VMSS, cluster autoscaler and user assigned identity features on Azure.
## VMSS
Azures Virtual Machine Scale sets (VMSS) feature offers users an ability to automatically create VMs from a single central configuration, provide load balancing via L4 and L7 load balancing, provide a path to use availability zones for high availability, provides large-scale VM instances et. al.
VMSS consists of a group of virtual machines, which are identical and can be managed and configured at a group level. More details of this feature in Azure itself can be found at the following link [[1]](https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview).
With Kubernetes v1.12 customers can create k8s cluster out of VMSS instances and utilize VMSS features.
## Cluster components on Azure
Generally, standalone Kubernetes cluster in Azure consists of the following parts
* Compute - the VM itself and its properties.
* Networking - this includes the IPs and load balancers.
* Storage - the disks which are associated with the VMs.
## Compute
Compute in cloud k8s cluster consists of the VMs. These VMs are created by provisioning tools such as acs-engine or AKS (in case of managed service). Eventually, they run various system daemons such as kubelet, kube-api server etc. either as a process (in some versions) or as a docker container.
![](/images/blog/2018-10-08-support-for-azure-vmss/sample-azure-cluster.png)
## Networking
In Azure Kubernetes cluster various networking components are brought together to provide features required for users. Typically they consist of the network interfaces, network security groups, public IP resource, VNET (virtual networks), load balancers etc.
## Storage
Kubernetes clusters are built on top of disks created in Azure. In a typical configuration, we have managed disks which are used to hold the regular OS images and a separate disk is used for etcd.
## Cloud provider components
![](/images/blog/2018-10-08-support-for-azure-vmss/cloud-provider-components.png)
Kubernetes cloud provider interface provides interactions with clouds for managing cloud-specific resources, e.g. public IPs and routes. A good overview of these components is given in [[2]](https://kubernetes.io/docs/concepts/architecture/cloud-controller/). In case of Azure Kubernetes cluster, the Kubernetes interactions go through the Azure cloud provider layer and contact the various services running in the cloud.
The cloud provider implementation of K8s can be largely divided into the following component interfaces which we need to implement:
1. Load Balancer
1. Instances
1. Zones
1. Routes
In addition to the above interfaces, the storage services from the cloud provider is linked via the volume plugin layer.
## Azure cloud provider implementation and VMSS
In the Azure cloud provider, for every type of cluster we implement, there is a VMType option which we specify. In case of VMSS, the VM type is “vmss”. The provisioning software (acs-engine, in future AKS etc.) would setup these values in /etc/kubernetes/azure.json file. Based on this type, various implementations would get instantiated [[3]](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/azure/azure_vmss.go)
The load balancer interface provides access to the underlying cloud provider load balancer service. The information about the load balancers and the control operations on them are required for Kubernetes to handle the services which gets hosted on the Kubernetes cluster. For VMSS support the changes ensure that the VMSS instances are part of the load balancer pool as required.
The instances interfaces help the cloud controller to get various details about a node from the cloud provider layer. For example, the details of a node like the IP address, the instance id etc, is obtained by the controller by means of the instances interfaces which the cloud provider layer registers with it. In case of VMSS support, we talk to VMSS service to gather information regarding the instances.
The zones interfaces help the cloud controller to get zone information for each node. Scheduler could spread pods to different availability zones with such information. It is also required for supporting topology aware dynamic provisioning features, e.g. AzureDisk. Each VMSS instances will be labeled with its current zone and region.
The routes interfaces help the cloud controller to setup advanced routes for Pod network. For example, a route with prefix nodes podCIDR and next hop nodes internal IP will be set for each node. In case of VMSS support, the next hops are VMSS virtual machines internal IP address.
The Azure volume plugin interfaces have been modified for VMSS to work properly. For example, the attach/detach to the AzureDisk have been modified to perform these operations at VMSS instance level.
## Setting up a VMSS cluster on Azure
The following link [[4]](https://github.com/Azure/acs-engine/blob/master/docs/kubernetes/deploy.md) provides an example of acs-engine to create a Kubernetes cluster.
```
acs-engine deploy --subscription-id <subscription id> \
--dns-prefix <dns> --location <location> \
--api-model examples/kubernetes.json
```
API model file provides various configurations which acs-engine uses to create a cluster. The API model here [[5]](https://github.com/Azure/acs-engine/blob/master/examples/kubernetes-vmss/kubernetes.json) gives a good starting configuration to setup the VMSS cluster.
Once a VMSS cluster is created, here are some of the steps you can run to understand more about the cluster setup. Here is the output of kubectl get nodes from a cluster created using the above command:
```
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-agentpool1-92998111-vmss000000 Ready agent 1h v1.12.0-rc.2
k8s-agentpool1-92998111-vmss000001 Ready agent 1h v1.12.0-rc.2
k8s-master-92998111-0 Ready master 1h v1.12.0-rc.2
```
This cluster consists of two worker nodes and one master. Now how do we check which node is which in Azure parlance? In VMSS listing, we can see a single VMSS:
```
$ az vmss list -o table -g k8sblogkk1
Name ResourceGroup Location Zones Capacity Overprovision UpgradePolicy
---------------------------- --------------- ---------- ------- ---------- --------------- ---------------
k8s-agentpool1-92998111-vmss k8sblogkk1 westus2 2 False Manual
```
The nodes which we see as agents (in the kubectl get nodes command) are part of this vmss. We can use the following command to list the instances which are part of the VM scale set:
```
$ az vmss list-instances -g k8sblogkk1 -n k8s-agentpool1-92998111-vmss -o table
InstanceId LatestModelApplied Location Name ProvisioningState ResourceGroup VmId
------------ -------------------- ---------- ------------------------------ ------------------- --------------- ------------------------------------
0 True westus2 k8s-agentpool1-92998111-vmss_0 Succeeded K8SBLOGKK1 21c57d6c-9c8f-4a62-970f-63ed0fcba53f
1 True westus2 k8s-agentpool1-92998111-vmss_1 Succeeded K8SBLOGKK1 840743b9-0076-4a2e-920e-5ba9da296665
```
The node name does not match the name in the vm scale set, but if we run the following command to list the providerID we can find the matching node which resembles the instance name:
```
$ kubectl describe nodes k8s-agentpool1-92998111-vmss000000| grep ProviderID
ProviderID: azure:///subscriptions/<subscription id>/resourceGroups/k8sblogkk1/providers/Microsoft.Compute/virtualMachineScaleSets/k8s-agentpool1-92998111-vmss/virtualMachines/0
```
## Current Status and Future
Currently the following is supported:
1. VMSS master nodes and worker nodes
1. VMSS on worker nodes and Availability set on master nodes combination.
1. Per vm disk attach
1. Azure Disk & Azure File support
1. Availability zones (Alpha)
In future there will be support for the following:
1. AKS with VMSS support
1. Per VM instance public IP
## Cluster Autoscaler
A Kubernetes cluster consists of nodes. These nodes can be virtual machines, bare metal servers or could be even virtual node (virtual kubelet). To avoid getting lost in permutations and combinations of Kubernetes ecosystem ;-), let's consider that the cluster we are discussing consists of virtual machines, which are hosted in a cloud (eg: Azure, Google or AWS). What this effectively means is that you have access to virtual machines which run Kubernetes agents and a master node which runs k8s services like API server. A detailed version of k8s architecture can be found here [[11]](https://kubernetes.io/docs/concepts/architecture/).
The number of nodes which are required on a cluster depends on the workload on the cluster. When the load goes up there is a need to increase the nodes and when it subsides, there is a need to reduce the nodes and clean up the resources which are no longer in use. One way this can be taken care of is to manually scale up the nodes which are part of the Kubernetes cluster and manually scale down when the demand reduces. But shouldnt this be done automatically ? Answer to this question is the Cluster Autoscaler (CA).
The cluster autoscaler itself runs as a pod within the kubernetes cluster. The following figure illustrates the high level view of the setup with respect to the k8s cluster:
![](/images/blog/2018-10-08-support-for-azure-vmss/cluster-autoscaler.png)
Since Cluster Autoscaler is a pod within the k8s cluster, it can use the in-cluster config and the Kubernetes go client [[10]](https://github.com/kubernetes/client-go) to contact the API server.
## Internals
The API server is the central service which manages the state of the k8s cluster utilizing a backing store (an etcd database), runs on the management node or runs within the cloud (in case of managed service such as AKS). For any component within the Kubernetes cluster to figure out the state of the cluster, like for example the nodes registered in the cluster, contacting the API server is the way to go.
In order to simplify our discussion lets divide the CA functionality into 3 parts as given below:
![](/images/blog/2018-10-08-support-for-azure-vmss/ca-functionality.png)
The main portion of the CA is a control loop which keeps running at every scan interval. This loop is responsible for updating the autoscaler metrics and health probes. Before this loop is entered auto scaler performs various operations such as claiming the leader state after performing a Kubernetes leader election. The main loop initializes static autoscaler component. This component initializes the underlying cloud provider based on the parameters passed onto the CA.
Various operations performed by the CA to manage the state of the cluster is passed onto the cloud provider component. Some examples like - increase target size, decrease target size etc, results in the cloud provider component talking to the cloud services internally and performing operations such as adding a node or deleting a node. These operations are performed on group of nodes in the cluster. The static autoscaler also keeps tab on the state of the system by querying the API server - operations such as list pods and list nodes are used to get hold of such information.
The decision to make a scale up is based on pods which remain unscheduled and a variety of checks and balances. The nodes which are free to be scaled down are deleted from the cluster and deleted from the cloud itself. The cluster autoscaler applies checks and balances before scaling up and scaling down - for example the nodes which have been recently added are given special consideration. During the deletion the nodes are drained to ensure that no disruption happens to the running pods.
## Setting up CA on Azure:
Cluster Autoscaler is available as an add-on with acs-engine. The following link [[15]](https://github.com/Azure/acs-engine/tree/master/examples/addons/cluster-autoscaler) has an example configuration file used to deploy autoscaler with acs-engine. The following link [[8]](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/azure/README.md) provides details on manual step by step way to do the same.
In acs-engine case we use the the regular command line to deploy:
```
acs-engine deploy --subscription-id <subscription id> \
--dns-prefix <dns> --location <location> \
--api-model examples/kubernetes.json
```
The main difference are the following lines in the config file at [[15]](https://github.com/Azure/acs-engine/tree/master/examples/addons/cluster-autoscaler) makes sure that CA is deployed as an addon:
```
"addons": [
{
"name": "cluster-autoscaler",
"enabled": true,
"config": {
"minNodes": "1",
"maxNodes": "5"
}
}
]
```
The config section in the json above can be used to provide the configuration to the cluster autoscaler pod, eg: min and max nodes as above.
Once the setup completes we can see that the cluster-autoscaler pod is deployed in the system namespace:
```
$kubectl get pods -n kube-system | grep autoscaler
cluster-autoscaler-7bdc74d54c-qvbjs 1/1 Running 1 6m
```
Here is the output from the CA configmap and events from a sample cluster:
```
$kubectl -n kube-system describe configmap cluster-autoscaler-status
Name: cluster-autoscaler-status
Namespace: kube-system
Labels: <none>
Annotations: cluster-autoscaler.kubernetes.io/last-updated=2018-10-02 01:21:17.850010508 +0000 UTC
Data
====
status:
----
Cluster-autoscaler status at 2018-10-02 01:21:17.850010508 +0000 UTC:
Cluster-wide:
Health: Healthy (ready=3 unready=0 notStarted=0 longNotStarted=0 registered=3 longUnregistered=0)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleUp: NoActivity (ready=3 registered=3)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:39:50.493307405 +0000 UTC m=+674.133759650
NodeGroups:
Name: k8s-agentpool1-92998111-vmss
Health: Healthy (ready=2 unready=0 notStarted=0 longNotStarted=0 registered=2 longUnregistered=0 cloudProviderTarget=2 (minSize=1, maxSize=5))
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleUp: NoActivity (ready=2 cloudProviderTarget=2)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:28:49.944222739 +0000 UTC m=+13.584675084
ScaleDown: NoCandidates (candidates=0)
LastProbeTime: 2018-10-02 01:21:17.772229859 +0000 UTC m=+3161.412682204
LastTransitionTime: 2018-10-02 00:39:50.493307405 +0000 UTC m=+674.133759650
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScaleDownEmpty 42m cluster-autoscaler Scale-down: removing empty node k8s-agentpool1-92998111-vmss000002
```
As can be seen the events, the cluster autoscaler scaled down and deleted a node as there was no load on this cluster. The rest of the configmap in this case indicates that there are no further actions which the autoscaler is taking at this moment.
## Current status and future:
Cluster Autoscaler currently supports four VM types: standard (VMAS), VMSS, ACS and AKS. In the future, Cluster Autoscaler will be integrated within AKS product, so that users can enable it by one-click.
## User Assigned Identity
Inorder for the Kubernetes cluster components to securely talk to the cloud services, it needs to authenticate with the cloud provider. In Azure Kubernetes clusters, up until now this was done using two ways - Service Principals or Managed Identities. In case of service principal the credentials are stored within the cluster and there are password rotation and other challenges which user needs to incur to accommodate this model. Managed service identities takes out this burden from the user and manages the service instances directly [[12]](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview).
There are two kinds of managed identities possible - one is system assigned and another is user assigned. In case of system assigned identity each vm in the Kubernetes cluster is assigned a managed identity during creation. This identity is used by various Kubernetes components needing access to Azure resources. Examples to these operations are getting/updating load balancer configuration, getting/updating vm information etc. With the system assigned managed identity, user has no control over the identity which is assigned to the underlying vm. The system automatically assigns it and this reduces the flexibility for the user.
With v1.12 we bring user assigned managed identity support for Kubernetes. With this support user does not have to manage any passwords but at the same time has the flexibility to manage the identity which is used by the cluster. For example if the user needs to allow access to a cluster for a specific storage account or a Azure key vault, the user assigned identity can be created in advance and key vault access provided.
## Internals
To understand the internals, we will focus on a cluster created using acs-engine. This can be configured in other ways, but the basic interactions are of the same pattern.
The acs-engine sets up the cluster with the required configuration. The /etc/kubernetes/azure.json file provides a way for the cluster components (eg: kube-apiserver) to gather configuration on how to access the cloud resources. In a user managed identity cluster there is a value filled with the key as `UserAssignedIdentityID`. This value is filled with the client id of the user assigned identity created by acs-engine or provided by the user, however the case may be. The code which does the authentication for Kubernetes on azure can be found here [[14]](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/azure/auth/azure_auth.go). This code uses Azure adal packages to get authenticated to access various resources in the cloud. In case of user assigned identity the following API call is made to get new token:
```
adal.NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint,
env.ServiceManagementEndpoint,
config.UserAssignedIdentityID)
```
This calls hits either the instance metadata service or the vm extension [[12]](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) to gather the token which is then used to access various resources.
## Setting up a cluster with user assigned identity
With the upstream support for user assigned identity in v1.12, it is now supported in the acs-engine to create a cluster with the user assigned identity. The json config files present here [[13]](https://github.com/Azure/acs-engine/tree/master/examples/kubernetes-msi-userassigned) can be used to create a cluster with user assigned identity. The same step used to create a vmss cluster can be used to create a cluster which has user assigned identity assigned.
```
acs-engine deploy --subscription-id <subscription id> \
--dns-prefix <dns> --location <location> \
--api-model examples/kubernetes-msi-userassigned/kube-vmss.json
```
The main config values here are the following:
```
"useManagedIdentity": true
"userAssignedID": "acsenginetestid"
```
The first one `useManagedIdentity` indicates to acs-engine that we are going to use the managed identity extension. This sets up the necessary packages and extensions required for the managed identities to work. The next one `userAssignedID` provides the information on the user identity which is to be used with the cluster.
## Current status and future
Currently we support the user assigned identity creation with the cluster using deploy of the acs-engine. In future this will become part of AKS.
## Get involved
For azure specific discussions - please checkout the Azure SIG page at [[6]](https://github.com/kubernetes/community/tree/master/sig-azure) and come and join the [#sig-azure](https://kubernetes.slack.com/messages/sig-azure) slack channel for more.
For CA, please checkout the Autoscaler project here [[7]](http://www.github.com/kubernetes/autoscaler) and join the [#sig-autoscaling](https://kubernetes.slack.com/messages/sig-autoscaling) Slack for more discussions.
For the acs-engine (the unmanaged variety) on Azure docs can be found here: [[9]](https://github.com/Azure/acs-engine). More details about the managed service from Azure Kubernetes Service (AKS) here [[5]](https://docs.microsoft.com/en-us/azure/aks/).
## References
1) https://docs.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview
2) https://kubernetes.io/docs/concepts/architecture/cloud-controller/
3) https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/azure/azure_vmss.go
4) https://github.com/Azure/acs-engine/blob/master/docs/kubernetes/deploy.md
5) https://docs.microsoft.com/en-us/azure/aks/
6) https://github.com/kubernetes/community/tree/master/sig-azure
7) https://github.com/kubernetes/autoscaler
8) https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/azure/README.md
9) https://github.com/Azure/acs-engine
10) https://github.com/kubernetes/client-go
11) https://kubernetes.io/docs/concepts/architecture/
12) https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
13) https://github.com/Azure/acs-engine/tree/master/examples/kubernetes-msi-userassigned
14) https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/azure/auth/azure_auth.go
15) https://github.com/Azure/acs-engine/tree/master/examples/addons/cluster-autoscaler
@@ -0,0 +1,292 @@
---
layout: blog
title: 'Introducing Volume Snapshot Alpha for Kubernetes'
date: 2018-10-09
---
**Author**: Jing Xu (Google) Xing Yang (Huawei), Saad Ali (Google)
Kubernetes v1.12 introduces alpha support for volume snapshotting. This feature allows creating/deleting volume snapshots, and the ability to create new volumes from a snapshot natively using the Kubernetes API.
## What is a Snapshot?
Many storage systems (like Google Cloud Persistent Disks, Amazon Elastic Block Storage, and many on-premise storage systems) provide the ability to create a "snapshot" of a persistent volume. A snapshot represents a point-in-time copy of a volume. A snapshot can be used either to provision a new volume (pre-populated with the snapshot data) or to restore the existing volume to a previous state (represented by the snapshot).
## Why add Snapshots to Kubernetes?
The Kubernetes volume plugin system already provides a powerful abstraction that automates the provisioning, attaching, and mounting of block and file storage.
Underpinning all these features is the Kubernetes goal of workload portability: Kubernetes aims to create an abstraction layer between distributed systems applications and underlying clusters so that applications can be agnostic to the specifics of the cluster they run on and application deployment requires no “cluster specific” knowledge.
The [Kubernetes Storage SIG](https://github.com/kubernetes/community/tree/master/sig-storage) identified snapshot operations as critical functionality for many stateful workloads. For example, a database administrator may want to snapshot a database volume before starting a database operation.
By providing a standard way to trigger snapshot operations in the Kubernetes API, Kubernetes users can now handle use cases like this without having to go around the Kubernetes API (and manually executing storage system specific operations).
Instead, Kubernetes users are now empowered to incorporate snapshot operations in a cluster agnostic way into their tooling and policy with the comfort of knowing that it will work against arbitrary Kubernetes clusters regardless of the underlying storage.
Additionally these Kubernetes snapshot primitives act as basic building blocks that unlock the ability to develop advanced, enterprise grade, storage administration features for Kubernetes: such as data protection, data replication, and data migration.
## Which volume plugins support Kubernetes Snapshots?
Kubernetes supports three types of volume plugins: in-tree, Flex, and CSI. See [Kubernetes Volume Plugin FAQ](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md) for details.
Snapshots are only supported for CSI drivers (not for in-tree or Flex). To use the Kubernetes snapshots feature, ensure that a CSI Driver that implements snapshots is deployed on your cluster.
As of the publishing of this blog, the following CSI drivers support snapshots:
* [GCE Persistent Disk CSI Driver](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver)
* [OpenSDS CSI Driver](https://github.com/opensds/nbp/tree/master/csi/server)
* [Ceph RBD CSI Driver](https://github.com/ceph/ceph-csi/tree/master/pkg/rbd)
* [Portworx CSI Driver](https://github.com/libopenstorage/openstorage/tree/master/csi)
Snapshot support for other [drivers](https://kubernetes-csi.github.io/docs/Drivers.html) is pending, and should be available soon. Read the “[Container Storage Interface (CSI) for Kubernetes Goes Beta](https://kubernetes.io/blog/2018/04/10/container-storage-interface-beta/)” blog post to learn more about CSI and how to deploy CSI drivers.
## Kubernetes Snapshots API
Similar to the API for managing Kubernetes Persistent Volumes, Kubernetes Volume Snapshots introduce three new API objects for managing snapshots:
* `VolumeSnapshot`
* Created by a Kubernetes user to request creation of a snapshot for a specified volume. It contains information about the snapshot operation such as the timestamp when the snapshot was taken and whether the snapshot is ready to use.
* Similar to the `PersistentVolumeClaim` object, the creation and deletion of this object represents a user desire to create or delete a cluster resource (a snapshot).
* `VolumeSnapshotContent`
* Created by the CSI volume driver once a snapshot has been successfully created. It contains information about the snapshot including snapshot ID.
* Similar to the `PersistentVolume` object, this object represents a provisioned resource on the cluster (a snapshot).
* Like `PersistentVolumeClaim` and `PersistentVolume` objects, once a snapshot is created, the `VolumeSnapshotContent` object binds to the VolumeSnapshot for which it was created (with a one-to-one mapping).
* `VolumeSnapshotClass`
* Created by cluster administrators to describe how snapshots should be created. including the driver information, the secrets to access the snapshot, etc.
It is important to note that unlike the core Kubernetes Persistent Volume objects, these Snapshot objects are defined as [CustomResourceDefinitions (CRDs)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions). The Kubernetes project is moving away from having resource types pre-defined in the API server, and is moving towards a model where the API server is independent of the API objects. This allows the API server to be reused for projects other than Kubernetes, and consumers (like Kubernetes) can simply install the resource types they require as CRDs.
[CSI Drivers](https://kubernetes-csi.github.io/docs/Drivers.html) that support snapshots will automatically install the required CRDs. Kubernetes end users only need to verify that a CSI driver that supports snapshots is deployed on their Kubernetes cluster.
In addition to these new objects, a new, DataSource field has been added to the `PersistentVolumeClaim` object:
```
type PersistentVolumeClaimSpec struct {
AccessModes []PersistentVolumeAccessMode
Selector *metav1.LabelSelector
Resources ResourceRequirements
VolumeName string
StorageClassName *string
VolumeMode *PersistentVolumeMode
DataSource *TypedLocalObjectReference
}
```
This new alpha field enables a new volume to be created and automatically pre-populated with data from an existing snapshot.
## Kubernetes Snapshots Requirements
Before using Kubernetes Volume Snapshotting, you must:
* Ensure a CSI driver implementing snapshots is deployed and running on your Kubernetes cluster.
* Enable the Kubernetes Volume Snapshotting feature via new Kubernetes feature gate (disabled by default for alpha):
* Set the following flag on the API server binary: `--feature-gates=VolumeSnapshotDataSource=true`
Before creating a snapshot, you also need to specify CSI driver information for snapshots by creating a `VolumeSnapshotClass` object and setting the `snapshotter` field to point to your CSI driver. In the example of `VolumeSnapshotClass` below, the CSI driver is `com.example.csi-driver`. You need at least one `VolumeSnapshotClass` object per snapshot provisioner. You can also set a default `VolumeSnapshotClass` for each individual CSI driver by putting an annotation `snapshot.storage.kubernetes.io/is-default-class: "true"` in the class definition.
```
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name: default-snapclass
annotations:
snapshot.storage.kubernetes.io/is-default-class: "true"
snapshotter: com.example.csi-driver
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
snapshotter: com.example.csi-driver
parameters:
fakeSnapshotOption: foo
csiSnapshotterSecretName: csi-secret
csiSnapshotterSecretNamespace: csi-namespace
```
You must set any required opaque parameters based on the documentation for your CSI driver. As the example above shows, the parameter `fakeSnapshotOption: foo` and any referenced secret(s) will be passed to CSI driver during snapshot creation and deletion. The [default CSI external-snapshotter](https://github.com/kubernetes-csi/external-snapshotter) reserves the parameter keys `csiSnapshotterSecretName` and `csiSnapshotterSecretNamespace`. If specified, it fetches the secret and passes it to the CSI driver when creating and deleting a snapshot.
And finally, before creating a snapshot, you must provision a volume using your CSI driver and populate it with some data that you want to snapshot (see the [CSI blog post](https://kubernetes.io/blog/2018/04/10/container-storage-interface-beta/) on how to create and use CSI volumes).
## Creating a new Snapshot with Kubernetes
Once a `VolumeSnapshotClass` object is defined and you have a volume you want to snapshot, you may create a new snapshot by creating a `VolumeSnapshot` object.
The source of the snapshot specifies the volume to create a snapshot from. It has two parameters:
* `kind` - must be `PersistentVolumeClaim`
* `name` - the PVC API object name
The namespace of the volume to snapshot is assumed to be the same as the namespace of the `VolumeSnapshot` object.
```
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: new-snapshot-demo
namespace: demo-namespace
spec:
snapshotClassName: csi-snapclass
source:
name: mypvc
kind: PersistentVolumeClaim
```
In the `VolumeSnapshot` spec, user can specify the `VolumeSnapshotClass` which has the information about which CSI driver should be used for creating the snapshot . When the `VolumeSnapshot` object is created, the parameter `fakeSnapshotOption: foo` and any referenced secret(s) from the `VolumeSnapshotClass` are passed to the CSI plugin `com.example.csi-driver` via a `CreateSnapshot` call.
In response, the CSI driver triggers a snapshot of the volume and then automatically creates a `VolumeSnapshotContent` object to represent the new snapshot, and binds the new `VolumeSnapshotContent` object to the `VolumeSnapshot`, making it ready to use. If the CSI driver fails to create the snapshot and returns error, the snapshot controller reports the error in the status of `VolumeSnapshot` object and does not retry (this is different from other controllers in Kubernetes, and is to prevent snapshots from being taken at an unexpected time).
If a snapshot class is not specified, the external snapshotter will try to find and set a default snapshot class for the snapshot. The `CSI driver` specified by `snapshotter` in the default snapshot class must match the `CSI driver` specified by the `provisioner` in the storage class of the PVC.
Please note that the alpha release of Kubernetes Snapshot does not provide any consistency guarantees. You have to prepare your application (pause application, freeze filesystem etc.) before taking the snapshot for data consistency.
You can verify that the `VolumeSnapshot` object is created and bound with `VolumeSnapshotContent` by running `kubectl describe volumesnapshot`:
* `Ready` should be set to true under `Status` to indicate this volume snapshot is ready for use.
* `Creation Time` field indicates when the snapshot is actually created (cut).
* `Restore Size` field indicates the minimum volume size when restoring a volume from the snapshot.
* `Snapshot Content Name` field in the `spec` points to the `VolumeSnapshotContent` object created for this snapshot.
## Importing an existing snapshot with Kubernetes
You can always import an existing snapshot to Kubernetes by manually creating a `VolumeSnapshotContent` object to represent the existing snapshot. Because `VolumeSnapshotContent` is a non-namespace API object, only a system admin may have the permission to create it. Once a `VolumeSnapshotContent` object is created, the user can create a `VolumeSnapshot` object pointing to the `VolumeSnapshotContent` object. The external-snapshotter controller will mark snapshot as ready after verifying the snapshot exists and the binding between `VolumeSnapshot` and `VolumeSnapshotContent` objects is correct. Once bound, the snapshot is ready to use in Kubernetes.
A `VolumeSnapshotContent` object should be created with the following fields to represent a pre-provisioned snapshot:
* `csiVolumeSnapshotSource` - Snapshot identifying information.
* `snapshotHandle` - name/identifier of the snapshot. This field is required.
* `driver` - CSI driver used to handle this volume. This field is required. It must match the snapshotter name in the snapshot controller.
* `creationTime` and `restoreSize` - these fields are not required for pre-provisioned volumes. The external-snapshotter controller will automatically update them after creation.
* `volumeSnapshotRef` - Pointer to the `VolumeSnapshot` object this object should bind to.
* `name` and `namespace` - It specifies the name and namespace of the `VolumeSnapshot` object which the content is bound to.
* `UID` - these fields are not required for pre-provisioned volumes.The external-snapshotter controller will update the field automatically after binding. If user specifies UID field, he/she must make sure that it matches with the binding snapshots UID. If the specified UID does not match the binding snapshots UID, the content is considered an orphan object and the controller will delete it and its associated snapshot.
* `snapshotClassName` - This field is optional. The external-snapshotter controller will update the field automatically after binding.
```
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshotContent
metadata:
name: static-snapshot-content
spec:
csiVolumeSnapshotSource:
driver: com.example.csi-driver
snapshotHandle: snapshotcontent-example-id
volumeSnapshotRef:
kind: VolumeSnapshot
name: static-snapshot-demo
namespace: demo-namespace
```
A `VolumeSnapshot` object should be created to allow a user to use the snapshot:
* `snapshotClassName` - name of the volume snapshot class. This field is optional. If set, the snapshotter field in the snapshot class must match the snapshotter name of the snapshot controller. If not set, the snapshot controller will try to find a default snapshot class.
* `snapshotContentName` - name of the volume snapshot content. This field is required for pre-provisioned volumes.
```
apiVersion: snapshot.storage.k8s.io/v1alpha1
kind: VolumeSnapshot
metadata:
name: static-snapshot-demo
namespace: demo-namespace
spec:
snapshotClassName: csi-snapclass
snapshotContentName: static-snapshot-content
```
Once these objects are created, the snapshot controller will bind them together, and set the field Ready (under `Status`) to True to indicate the snapshot is ready to use.
## Provision a new volume from a snapshot with Kubernetes
To provision a new volume pre-populated with data from a snapshot object, use the new dataSource field in the `PersistentVolumeClaim`. It has three parameters:
* name - name of the `VolumeSnapshot` object representing the snapshot to use as source
* kind - must be `VolumeSnapshot`
* apiGroup - must be `snapshot.storage.k8s.io`
The namespace of the source `VolumeSnapshot` object is assumed to be the same as the namespace of the `PersistentVolumeClaim` object.
```
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-restore
Namespace: demo-namespace
spec:
storageClassName: csi-storageclass
dataSource:
name: new-snapshot-demo
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
```
When the `PersistentVolumeClaim` object is created, it will trigger provisioning of a new volume that is pre-populated with data from the specified snapshot.
## As a storage vendor, how do I add support for snapshots to my CSI driver?
To implement the snapshot feature, a CSI driver MUST add support for additional controller capabilities `CREATE_DELETE_SNAPSHOT` and `LIST_SNAPSHOTS`, and implement additional controller RPCs: `CreateSnapshot`, `DeleteSnapshot`, and `ListSnapshots`. For details, see [the CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md).
Although Kubernetes is as [minimally prescriptive](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md#third-party-csi-volume-drivers) on the packaging and deployment of a CSI Volume Driver as possible, it provides a [suggested mechanism](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md#recommended-mechanism-for-deploying-csi-drivers-on-kubernetes) for deploying an arbitrary containerized CSI driver on Kubernetes to simplify deployment of containerized CSI compatible volume drivers.
As part of this recommended deployment process, the Kubernetes team provides a number of sidecar (helper) containers, including a new [external-snapshotter](https://github.com/kubernetes-csi/external-snapshotter) sidecar container.
The external-snapshotter watches the Kubernetes API server for `VolumeSnapshot` and `VolumeSnapshotContent` objects and triggers CreateSnapshot and DeleteSnapshot operations against a CSI endpoint. The CSI [external-provisioner](https://github.com/kubernetes-csi/external-provisioner) sidecar container has also been updated to support restoring volume from snapshot using the new `dataSource` PVC field.
In order to support snapshot feature, it is recommended that storage vendors deploy the external-snapshotter sidecar containers in addition to the external provisioner the external attacher, along with their CSI driver in a statefulset as shown in the following diagram.
![](/images/blog/2018-10-09-volume-snapshot-alpha/snapshot.png)
In this [example deployment yaml](https://github.com/kubernetes-csi/external-snapshotter/blob/e011fe31df548813d2eb6dacb278c0ca58533b34/deploy/kubernetes/setup-csi-snapshotter.yaml) file, two sidecar containers, the external provisioner and the external snapshotter, and CSI drivers are deployed together with the hostpath CSI plugin in the statefulset pod. Hostpath CSI plugin is a sample plugin, not for production.
## What are the limitations of alpha?
The alpha implementation of snapshots for Kubernetes has the following limitations:
* Does not support reverting an existing volume to an earlier state represented by a snapshot (alpha only supports provisioning a new volume from a snapshot).
* Does not support “in-place restore” of an existing PersistentVolumeClaim from a snapshot: i.e. provisioning a new volume from a snapshot, but updating an existing PersistentVolumeClaim to point to the new volume and effectively making the PVC appear to revert to an earlier state (alpha only supports using a new volume provisioned from a snapshot via a new PV/PVC).
* No snapshot consistency guarantees beyond any guarantees provided by storage system (e.g. crash consistency).
## Whats next?
Depending on feedback and adoption, the Kubernetes team plans to push the CSI Snapshot implementation to beta in either 1.13 or 1.14.
## How can I learn more?
Check out additional documentation on the snapshot feature here: http://k8s.io/docs/concepts/storage/volume-snapshots and https://kubernetes-csi.github.io/docs/
## How do I get involved?
This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together.
In addition to the contributors who have been working on the Snapshot feature:
* Xing Yang ([xing-yang](https://github.com/xing-yang))
* Jing Xu ([jingxu97](https://github.com/jingxu97))
* Huamin Chen ([rootfs](https://github.com/rootfs))
* Tomas Smetana ([tsmetana](https://github.com/tsmetana))
* Shiwei Xu ([wackxu](https://github.com/wackxu))
We offer a huge thank you to all the contributors in Kubernetes Storage SIG and CSI community who helped review the design and implementation of the project, including but not limited to the following:
* Saad Ali ([saadali](https://github.com/saadali))
* Tim Hockin ([thockin](https://github.com/thockin))
* Jan Šafránek ([jsafrane](https://github.com/jsafrane))
* Luis Pabon ([lpabon](https://github.com/lpabon))
* Jordan Liggitt ([liggitt](https://github.com/liggitt))
* David Zhu ([davidz627](https://github.com/davidz627))
* Garth Bushell ([garthy](https://github.com/garthy))
* Ardalan Kangarlou ([kangarlou](https://github.com/kangarlou))
* Seungcheol Ko ([sngchlko](https://github.com/sngchlko))
* Michelle Au ([msau42](https://github.com/msau42))
* Humble Devassy Chirammal ([humblec](https://github.com/humblec))
* Vladimir Vivien ([vladimirvivien](https://github.com/vladimirvivien))
* John Griffith ([j-griffith](https://github.com/j-griffith))
* Bradley Childs ([childsb](https://github.com/childsb))
* Ben Swartzlander ([bswartz](https://github.com/bswartz))
If youre interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system, join the [Kubernetes Storage Special Interest Group](https://github.com/kubernetes/community/tree/master/sig-storage) (SIG). Were rapidly growing and always welcome new contributors.
@@ -0,0 +1,47 @@
---
layout: blog
title: 'Kubernetes v1.12: Introducing RuntimeClass'
date: 2018-10-10
---
**Author**: Tim Allclair (Google)
Kubernetes originally launched with support for Docker containers running native applications on a Linux host. Starting with [rkt](https://kubernetes.io/blog/2016/07/rktnetes-brings-rkt-container-engine-to-kubernetes/) in Kubernetes 1.3 more runtimes were coming, which lead to the development of the [Container Runtime Interface](https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/) (CRI). Since then, the set of alternative runtimes has only expanded: projects like [Kata Containers](https://katacontainers.io/) and [gVisor](https://github.com/google/gvisor) were announced for stronger workload isolation, and Kubernetes' Windows support has been [steadily progressing](https://kubernetes.io/blog/2018/01/kubernetes-v19-beta-windows-support/).
With runtimes targeting so many different use cases, a clear need for mixed runtimes in a cluster arose. But all these different ways of running containers have brought a new set of problems to deal with:
- How do users know which runtimes are available, and select the runtime for their workloads?
- How do we ensure pods are scheduled to the nodes that support the desired runtime?
- Which runtimes support which features, and how can we surface incompatibilities to the user?
- How do we account for the varying resource overheads of the runtimes?
**RuntimeClass** aims to solve these issues.
## RuntimeClass in Kubernetes 1.12
RuntimeClass was recently introduced as an alpha feature in Kubernetes 1.12. The initial implementation focuses on providing a runtime selection API, and paves the way to address the other open problems.
The RuntimeClass resource represents a container runtime supported in a Kubernetes cluster. The cluster provisioner sets up, configures, and defines the concrete runtimes backing the RuntimeClass. In its current form, a RuntimeClassSpec holds a single field, the **RuntimeHandler**. The RuntimeHandler is interpreted by the CRI implementation running on a node, and mapped to the actual runtime configuration. Meanwhile the PodSpec has been expanded with a new field, **RuntimeClassName**, which names the RuntimeClass that should be used to run the pod.
Why is RuntimeClass a pod level concept? The Kubernetes resource model expects certain resources to be shareable between containers in the pod. If the pod is made up of different containers with potentially different resource models, supporting the necessary level of resource sharing becomes very challenging. For example, it is extremely difficult to support a loopback (localhost) interface across a VM boundary, but this is a common model for communication between two containers in a pod.
## What's next?
The RuntimeClass resource is an important foundation for surfacing runtime properties to the control plane. For example, to implement scheduler support for clusters with heterogeneous nodes supporting different runtimes, we might add [NodeAffinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) terms to the RuntimeClass definition. Another area to address is managing the variable resource requirements to run pods of different runtimes. The [Pod Overhead proposal](https://docs.google.com/document/d/1EJKT4gyl58-kzt2bnwkv08MIUZ6lkDpXcxkHqCvvAp4/preview) was an early take on this that aligns nicely with the RuntimeClass design, and may be pursued further.
Many other RuntimeClass extensions have also been proposed, and will be revisited as the feature continues to develop and mature. A few more extensions that are being considered include:
- Surfacing optional features supported by runtimes, and better visibility into errors caused by incompatible features.
- Automatic runtime or feature discovery, to support scheduling decisions without manual configuration.
- Standardized or conformant RuntimeClass names that define a set of properties that should be supported across clusters with RuntimeClasses of the same name.
- Dynamic registration of additional runtimes, so users can install new runtimes on existing clusters with no downtime.
- "Fitting" a RuntimeClass to a pod's requirements. For instance, specifying runtime properties and letting the system match an appropriate RuntimeClass, rather than explicitly assigning a RuntimeClass by name.
RuntimeClass will be under active development at least through 2019, and were excited to see the feature take shape, starting with the RuntimeClass alpha in Kubernetes 1.12.
## Learn More
- Take it for a spin! As an alpha feature, there are some additional setup steps to use RuntimeClass. Refer to the [RuntimeClass documentation](https://kubernetes.io/docs/concepts/containers/runtime-class/#runtime-class) for how to get it running.
- Check out the [RuntimeClass Kubernetes Enhancement Proposal](https://github.com/kubernetes/community/blob/master/keps/sig-node/0014-runtime-class.md) for more nitty-gritty design details.
- The [Sandbox Isolation Level Decision](https://docs.google.com/document/d/1fe7lQUjYKR0cijRmSbH_y0_l3CYPkwtQa5ViywuNo8Q/preview) documents the thought process that initially went into making RuntimeClass a pod-level choice.
- Join the discussions and help shape the future of RuntimeClass with the [SIG-Node community](https://github.com/kubernetes/community/tree/master/sig-node)
@@ -0,0 +1,158 @@
---
layout: blog
title: 'Topology-Aware Volume Provisioning in Kubernetes'
date: 2018-10-11
---
**Author**: Michelle Au (Google)
The multi-zone cluster experience with persistent volumes is improving in Kubernetes 1.12 with the topology-aware dynamic provisioning beta feature. This feature allows Kubernetes to make intelligent decisions when dynamically provisioning volumes by getting scheduler input on the best place to provision a volume for a pod. In multi-zone clusters, this means that volumes will get provisioned in an appropriate zone that can run your pod, allowing you to easily deploy and scale your stateful workloads across failure domains to provide high availability and fault tolerance.
## Previous challenges
Before this feature, running stateful workloads with zonal persistent disks (such as AWS ElasticBlockStore, Azure Disk, GCE PersistentDisk) in multi-zone clusters had many challenges. Dynamic provisioning was handled independently from pod scheduling, which meant that as soon as you created a PersistentVolumeClaim (PVC), a volume would get provisioned. This meant that the provisioner had no knowledge of what pods were using the volume, and any pod constraints it had that could impact scheduling.
This resulted in unschedulable pods because volumes were provisioned in zones that:
* did not have enough CPU or memory resources to run the pod
* conflicted with node selectors, pod affinity or anti-affinity policies
* could not run the pod due to taints
Another common issue was that a non-StatefulSet pod using multiple persistent volumes could have each volume provisioned in a different zone, again resulting in an unschedulable pod.
Suboptimal workarounds included overprovisioning of nodes, or manual creation of volumes in the correct zones, making it difficult to dynamically deploy and scale stateful workloads.
The topology-aware dynamic provisioning feature addresses all of the above issues.
## Supported Volume Types
In 1.12, the following drivers support topology-aware dynamic provisioning:
* AWS EBS
* Azure Disk
* GCE PD (including Regional PD)
* CSI (alpha) - currently only the GCE PD CSI driver has implemented topology support
## Design Principles
While the initial set of supported plugins are all zonal-based, we designed this feature to adhere to the Kubernetes principle of portability across environments. Topology specification is generalized and uses a similar label-based specification like in Pod nodeSelectors and nodeAffinity. This mechanism allows you to define your own topology boundaries, such as racks in on-premise clusters, without requiring modifications to the scheduler to understand these custom topologies.
In addition, the topology information is abstracted away from the pod specification, so a pod does not need knowledge of the underlying storage systems topology characteristics. This means that you can use the same pod specification across multiple clusters, environments, and storage systems.
## Getting Started
To enable this feature, all you need to do is to create a StorageClass with `volumeBindingMode` set to `WaitForFirstConsumer`:
```
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: topology-aware-standard
provisioner: kubernetes.io/gce-pd
volumeBindingMode: WaitForFirstConsumer
parameters:
type: pd-standard
```
This new setting instructs the volume provisioner to not create a volume immediately, and instead, wait for a pod using an associated PVC to run through scheduling. Note that previous StorageClass `zone` and `zones` parameters do not need to be specified anymore, as pod policies now drive the decision of which zone to provision a volume in.
Next, create a pod and PVC with this StorageClass. This sequence is the same as before, but with a different StorageClass specified in the PVC. The following is a hypothetical example, demonstrating the capabilities of the new feature by specifying many pod constraints and scheduling policies:
* multiple PVCs in a pod
* nodeAffinity across a subset of zones
* pod anti-affinity on zones
```
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
- us-central1-a
- us-central1-f
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: failure-domain.beta.kubernetes.io/zone
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
- name: logs
mountPath: /logs
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: topology-aware-standard
resources:
requests:
storage: 10Gi
- metadata:
name: logs
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: topology-aware-standard
resources:
requests:
storage: 1Gi
```
Afterwards, you can see that the volumes were provisioned in zones according to the policies set by the pod:
```
$ kubectl get pv -o=jsonpath='{range .items[*]}{.spec.claimRef.name}{"\t"}{.metadata.labels.failure\-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}'
www-web-0 us-central1-f
logs-web-0 us-central1-f
www-web-1 us-central1-a
logs-web-1 us-central1-a
```
## How can I learn more?
Official documentation on the topology-aware dynamic provisioning feature is available here:
https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode
Documentation for CSI drivers is available at https://kubernetes-csi.github.io/docs/
## Whats next?
We are actively working on improving this feature to support:
* more volume types, including dynamic provisioning for local volumes
* dynamic volume attachable count and capacity limits per node
## How do I get involved?
If you have feedback for this feature or are interested in getting involved with the design and development, join the [Kubernetes Storage Special-Interest-Group](https://github.com/kubernetes/community/tree/master/sig-storage) (SIG). Were rapidly growing and always welcome new contributors.
Special thanks to all the contributors that helped bring this feature to beta, including Cheng Xing ([verult](https://github.com/verult)), Chuqiang Li ([lichuqiang](https://github.com/lichuqiang)), David Zhu ([davidz627](https://github.com/davidz627)), Deep Debroy ([ddebroy](https://github.com/ddebroy)), Jan Šafránek ([jsafrane](https://github.com/jsafrane)), Jordan Liggitt ([liggitt](https://github.com/liggitt)), Michelle Au ([msau42](https://github.com/msau42)), Pengfei Ni ([feiskyer](https://github.com/feiskyer)), Saad Ali ([saad-ali](https://github.com/saad-ali)), Tim Hockin ([thockin](https://github.com/thockin)), and Yecheng Fu ([cofyc](https://github.com/cofyc)).
@@ -0,0 +1,33 @@
---
layout: blog
title: '2018 Steering Committee Election Results'
date: 2018-10-15
---
**Authors**: Jorge Castro (Heptio), Ihor Dvoretskyi (CNCF), Paris Pittman (Google)
## Results
The [Kubernetes Steering Committee Election](https://kubernetes.io/blog/2018/09/06/2018-steering-committee-election-cycle-kicks-off/) is now complete and the following candidates came ahead to secure two year terms that start immediately:
* Aaron Crickenberger, Google, [@spiffxp](https://github.com/spiffxp)
* Davanum Srinivas, Huawei, [@dims](https://github.com/dims)
* Tim St. Clair, Heptio, [@timothysc](https://github.com/timothysc)
## Big Thanks!
* Steering Committee Member Emeritus [Quinton Hoole](https://github.com/quinton-hoole) for his service to the community over the past year. We look forward to
* The candidates that came forward to run for election. May we always have a strong set of people who want to push community forward like yours in every election.
* All 307 voters who cast a ballot.
* And last but not least...Cornell University for hosting [CIVS](https://civs.cs.cornell.edu/)!
## Get Involved with the Steering Committee
You can follow along to Steering Committee [backlog items](https://git.k8s.io/steering/backlog.md) and weigh in by filing an issue or creating a PR against their [repo](https://github.com/kubernetes/steering). They meet bi-weekly on [Wednesdays at 8pm UTC](https://github.com/kubernetes/steering) and regularly attend Meet Our Contributors.
Steering Committee Meetings:
* [YouTube Playlist](https://www.youtube.com/playlist?list=PL69nYSiGNLP1yP1B_nd9-drjoxp0Q14qM)
Meet Our Contributors Steering AMAs:
* [Oct 3 2018](https://youtu.be/x6Jm8p0K-IQ)
* [Sept 5 2018](https://youtu.be/UbxWV12Or58)
@@ -0,0 +1,63 @@
---
layout: "Blog"
title: "Kubernetes 2018 North American Contributor Summit"
date: 2018-10-16
---
**Authors:**
[Bob Killen][bob] (University of Michigan)
[Sahdev Zala][sahdev] (IBM),
[Ihor Dvoretskyi][ihor] (CNCF)
The 2018 North American Kubernetes Contributor Summit to be hosted right before
[KubeCon + CloudNativeCon][kubecon] Seattle is shaping up to be the largest yet.
It is an event that brings together new and current contributors alike to
connect and share face-to-face; and serves as an opportunity for existing
contributors to help shape the future of community development. For new
community members, it offers a welcoming space to learn, explore and put the
contributor workflow to practice.
Unlike previous Contributor Summits, the event now spans two-days with a more
relaxed hallway track and general Contributor get-together to be hosted from
5-8pm on Sunday December 9th at the [Garage Lounge and Gaming Hall][garage], just
a short walk away from the Convention Center. There, contributors can enjoy
billiards, bowling, trivia and more; accompanied by a variety of food and drink.
Things pick up the following day, Monday the 10th with three separate tracks:
### New Contributor Workshop:
A half day workshop aimed at getting new and first time contributors onboarded
and comfortable with working within the Kubernetes Community. Staying for the
duration is required; this is not a workshop you can drop into.
### Current Contributor Track:
Reserved for those that are actively engaged with the development of the
project; the Current Contributor Track includes Talks, Workshops, Birds of a
Feather, Unconferences, Steering Committee Sessions, and more! Keep an eye on
the [schedule in GitHub][schedule] as content is frequently being updated.
### Docs Sprint:
SIG-Docs will have a curated list of issues and challenges to be tackled closer
to the event date.
## To Register:
To register for the Contributor Summit, see the [Registration section of the
Event Details in GitHub][register]. Please note that registrations are being
reviewed. If you select the “Current Contributor Track” and are not an active
contributor, you will be asked to attend the New Contributor Workshop, or asked
to be put on a waitlist. With thousands of contributors and only 300 spots, we
need to make sure the right folks are in the room.
If you have any questions or concerns, please dont hesitate to reach out to
the Contributor Summit Events Team at community@kubernetes.io.
Look forward to seeing everyone there!
[bob]: https://twitter.com/mrbobbytables
[sahdev]: https://twitter.com/sp_zala
[ihor]: https://twitter.com/idvoretskyi
[kubecon]: https://events.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2018/
[garage]: https://www.garagebilliards.com/
[schedule]: https://git.k8s.io/community/events/2018/12-contributor-summit#agenda
[register]: https://git.k8s.io/community/events/2018/12-contributor-summit#registration
+1 -1
View File
@@ -7,7 +7,7 @@ css: /css/style_ancestry.css
---
<div class="banner1">
<h1> CASE STUDY:<img src="https://c.mfcreative.com/i/logo/ancestry-on-dark.svg" width="22%" style="margin-bottom:-12px;margin-left:3px;"><br> <div class="subhead">Digging Into the Past With New Technology</div></h1>
<h1> CASE STUDY:<img src="/images/ancestry_logo.png" width="22%" style="margin-bottom:-12px;margin-left:3px;"><br> <div class="subhead">Digging Into the Past With New Technology</div></h1>
</div>
@@ -89,7 +89,7 @@ css: /css/style_case_studies.css
</div>
<div class="fullcol">
And on the opex side, Gasser says, the savings are high. "We run dozens of services, we have scores of pods, many daemon sets, and since were data-driven, we take advantage of EBS-backed volume claims for all of our stateful services. If we had to do all of this without Kubernetes, on underlying cloud services, I could easily see our costs triple, quadruple what they are now for the amount of pure AWS expense. That doesnt account for personnel to deploy and maintain all the additional infrastructure."<br><br>
And on the opex side, Gasser says, the savings are high. "We run dozens of services, we have scores of pods, many daemon sets, and since were data-driven, we take advantage of EBS-backed volume claims for all of our stateful services. If we had to do all of this without Kubernetes, on underlying cloud services, I could easily see our costs triple, quadruple what they are now for the amount of pure AWS expense. That doesnt account for personnel to deploy and maintain all the additional infrastructure."<br><br>
The team is confident that the benefits will continue to multiply—without a steep learning curve for the engineers being exposed to the new technology. "As we onboard additional tenants in this ecosystem, I think the need for folks to understand Kubernetes may not necessarily go up. In fact, I think it goes down, and thats good," says Gasser. "Because that really demonstrates the scalability of the technology. You start to reap the benefits, and they can concentrate on all the features they need to build for great decisioning in the business— fraud decisions, credit decisions—and not have to worry about, Is my AWS server broken? Is my pod not running?"
</div>
+1 -1
View File
@@ -21,7 +21,7 @@ css: /css/style_peardeck.css
<div class="cols">
<div class="col1">
<h2>Challenge</h2>
The three-year-old startup provides a web app for teachers to interact with their students in the classroom. The JavaScript app was built on Googles web app development platform <a href="https://firebase.google.com/">Firebase</a>, using <a href="https://www.heroku.com/">Heroku</a>. As the user base steadily grew, so did the development team. "We outgrew Heroku when we started wanting to have multiple services, and the deploying story got pretty horrendous. We were frustrated that we couldnt have the developers quickly stage a version," says CEO Riley Eynon-Lynch. "Tracing and monitoring became basically impossible." On top of that, many of Pear Decks customers are behind government firewalls and connect through Firebase, not Pear Decks servers, making troubleshooting even more difficult.
The three-year-old startup provides a web app for teachers to interact with their students in the classroom. The JavaScript app was built on Googles web app development platform <a href="https://firebase.google.com/">Firebase</a>, using <a href="https://www.heroku.com/">Heroku</a>. As the user base steadily grew, so did the development team. "We outgrew Heroku when we started wanting to have multiple services, and the deploying story got pretty horrendous. We were frustrated that we couldnt have the developers quickly stage a version," says CEO Riley Eynon-Lynch. "Tracing and monitoring became basically impossible." On top of that, many of Pear Decks customers are behind government firewalls and connect through Firebase, not Pear Decks servers, making troubleshooting even more difficult.
</div>
<div class="col2">
+1 -1
View File
@@ -41,7 +41,7 @@ css: /css/style_wink.css
<div class="banner2">
<div class="banner2text">
"Its not proprietary, its totally open, its really portable. You can run all the workloads across different cloud providers. You can easily run a hybrid AWS or even bring in your own data center. Thats the benefit of having everything unified on one open source Kubernetes-Docker-CoreOS Container Linux stack. There are massive security benefits if you only have one Linux distro/machine image to validate. The benefits are enormous because you save money, and you save time.”<br><br><span style="font-size:15px;letter-spacing:0.08em">- KIT KLEIN, HEAD OF ENGINEERING, WINK</span>
"Its not proprietary, its totally open, its really portable. You can run all the workloads across different cloud providers. You can easily run a hybrid AWS or even bring in your own data center. Thats the benefit of having everything unified on one open source Kubernetes-Docker-CoreOS Container Linux stack. There are massive security benefits if you only have one Linux distro/machine image to validate. The benefits are enormous because you save money, and you save time.”<br><br><span style="font-size:15px;letter-spacing:0.08em">- KIT KLEIN, HEAD OF ENGINEERING, WINK</span>
</div>
</div>
+2 -2
View File
@@ -44,8 +44,8 @@ cid: community
enforces a <a href="code-of-conduct/">Code of Conduct</a> in all
interactions. If you notice a violation of the Code of Conduct at
an event or meeting, in Slack, or in another communication
mechanism, reach out to the
<a href="mailto:steering-private@kubernetes.io">steering committee</a>.
mechanism, reach out to the <a href="https://github.com/kubernetes/community/tree/master/committee-code-of-conduct">Kubernetes Code of Conduct Committee</a>
<a href="mailto:conduct@kubernetes.io">conduct@kubernetes.io</a>.
Your anonymity will be protected.</p>
</p>
</div>
+3 -3
View File
@@ -16,9 +16,9 @@ If you notice that this is out of date, please
<a href="https://github.com/kubernetes/website/issues/new">file an issue</a>.
If you notice a violation of the Code of Conduct at an event or meeting, in
Slack, or in another communication mechanism, reach out to the
<a href="mailto:steering-private@kubernetes.io">steering committee</a>. Your
anonymity will be protected.
Slack, or in another communication mechanism, reach out to
the [Kubernetes Code of Conduct Committee](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct) <conduct@kubernetes.io>.
Your anonymity will be protected.
<div class="cncf_coc_container">
{{< include "/static/cncf-code-of-conduct.md" >}}
@@ -34,7 +34,8 @@ Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a CNCF project maintainer, Sarah Novotny <sarahnovotny@google.com>, and/or Dan Kohn <dan@linuxfoundation.org>.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting
the [Kubernetes Code of Conduct Committee](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct) <conduct@kubernetes.io>.
This Code of Conduct is adapted from the Contributor Covenant
(http://contributor-covenant.org), version 1.2.0, available at
-12
View File
@@ -1,12 +0,0 @@
---
title: "Community"
weight: 80
menu:
main:
title: "Community"
weight: 30
post: >
<p>If you need help, you can connect with other Kubernetes users and the Kubernetes authors, attend community events, and watch video presentations from around the web.</p>
---
This section of the Kubernetes documentation surfaces key topics imported from the [kubernetes/community](https://github.com/kubernetes/community) repo. It is the starting point for becoming a contributor -- improving docs, improving code, giving talks etc.
-80
View File
@@ -1,80 +0,0 @@
---
title: Kubernetes Developer Guide
---
The developer guide is for anyone wanting to either write code which directly accesses the
Kubernetes API, or to contribute directly to the Kubernetes project.
It assumes some familiarity with concepts in the [User Guide](http://kubernetes.io/docs/user-guide/) and the [Cluster Admin
Guide](http://kubernetes.io/docs/admin/).
## The process of developing and contributing code to the Kubernetes project
* **Contributor Guide**
([Please start here](https://github.com/kubernetes/community/tree/master/contributors/guide/README.md)) to learn about how to contribute to Kubernetes
* **GitHub Issues** ([issues-triage.md](https://github.com/kubernetes/community/blob/master/contributors/guide/issue-triage.md)): How incoming issues are triaged.
* **Pull Request Process** ([/contributors/guide/pull-requests.md](https://github.com/kubernetes/community/tree/master/contributors/guide/pull-requests.md)): When and why pull requests are closed.
* **Getting Recent Builds** ([getting-builds.md](https://github.com/kubernetes/community/tree/master/contributors/devel/getting-builds.md)): How to get recent builds including the latest builds that pass CI.
* **Automated Tools** ([automation.md](https://github.com/kubernetes/community/tree/master/contributors/devel/automation.md)): Descriptions of the automation that is running on our github repository.
## Setting up your dev environment, coding, and debugging
* **Development Guide** ([development.md](https://github.com/kubernetes/community/tree/master/contributors/devel/development.md)): Setting up your development environment.
* **Testing** ([testing.md](https://github.com/kubernetes/community/tree/master/contributors/devel/testing.md)): How to run unit, integration, and end-to-end tests in your development sandbox.
* **Hunting flaky tests** ([flaky-tests.md](https://github.com/kubernetes/community/tree/master/contributors/devel/flaky-tests.md)): We have a goal of 99.9% flake free tests.
Here's how to run your tests many times.
* **Logging Conventions** ([logging.md](https://github.com/kubernetes/community/tree/master/contributors/devel/logging.md)): Glog levels.
* **Profiling Kubernetes** ([profiling.md](https://github.com/kubernetes/community/tree/master/contributors/devel/profiling.md)): How to plug in go pprof profiler to Kubernetes.
* **Instrumenting Kubernetes with a new metric**
([instrumentation.md](https://github.com/kubernetes/community/tree/master/contributors/devel/instrumentation.md)): How to add a new metrics to the
Kubernetes code base.
* **Coding Conventions** ([coding-conventions.md](https://github.com/kubernetes/community/tree/master/contributors/devel/../guide/coding-conventions.md)):
Coding style advice for contributors.
* **Document Conventions** ([how-to-doc.md](https://github.com/kubernetes/community/tree/master/contributors/devel/how-to-doc.md))
Document style advice for contributors.
* **Running a cluster locally** ([running-locally.md](https://github.com/kubernetes/community/tree/master/contributors/devel/running-locally.md)):
A fast and lightweight local cluster deployment for development.
## Developing against the Kubernetes API
* The [REST API documentation](http://kubernetes.io/docs/reference/) explains the REST
API exposed by apiserver.
* **Annotations** ([Annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)): are for attaching arbitrary non-identifying metadata to objects.
Programs that automate Kubernetes objects may use annotations to store small amounts of their state.
* **API Conventions** ([api-conventions.md](https://github.com/kubernetes/community/tree/master/contributors/devel/api-conventions.md)):
Defining the verbs and resources used in the Kubernetes API.
* **API Client Libraries** ([client-libraries](/docs/reference/using-api/client-libraries/)):
A list of existing client libraries, both supported and user-contributed.
## Writing plugins
* **Authentication** ([Authentication](http://kubernetes.io/docs/reference/access-authn-authz/authentication/)):
The current and planned states of authentication tokens.
* **Authorization Plugins** ([Authorization](http://kubernetes.io/docs/reference/access-authn-authz/authorization/)):
Authorization applies to all HTTP requests on the main apiserver port.
This doc explains the available authorization implementations.
* **Admission Control Plugins** ([admission_control](https://github.com/kubernetes/community/tree/master/contributors/design-proposals/api-machinery/admission_control.md))
## Building releases
See the [kubernetes/release](https://github.com/kubernetes/release) repository for details on creating releases and related tools and helper scripts.
-248
View File
@@ -1,248 +0,0 @@
---
title: Kubernetes Contributor Guide
owner: sig-contributor-experience
notitle: true
---
# Kubernetes Contributor Guide
## Disclaimer
Hello! This is the starting point for our brand new contributor guide, currently underway as per [issue#6102](https://github.com/kubernetes/website/issues/6102) and is in need of help.
Please be patient, or fix a section below that needs improvement, and submit a pull request! Feel free to browse the [open issues](https://github.com/kubernetes/community/issues?q=is%3Aissue+is%3Aopen+label%3Aarea%2Fcontributor-guide) and file new ones, all feedback welcome!
# Welcome
Welcome to Kubernetes! This document is the single source of truth for how to contribute to the code base. Please leave comments / suggestions if you find something is missing or incorrect.
- [Before you get started](#before-you-get-started)
- [Sign the CLA](#sign-the-cla)
- [Code of Conduct](#code-of-conduct)
- [Setting up your development
environment](#setting-up-your-development-environment)
- [Community Expectations and Roles](#community-expectations-and-roles)
- [Thanks](#thanks)
- [Your First Contribution](#your-first-contribution)
- [Find something to work on](#find-something-to-work-on)
- [Find a good first topic](#find-a-good-first-topic)
- [Learn about SIGs](#learn-about-sigs)
- [File an Issue](#file-an-issue)
- [Contributing](#contributing)
- [Communication](#communication)
- [GitHub workflow](#github-workflow)
- [Open a Pull Request](#open-a-pull-request)
- [Code Review](#code-review)
- [Testing](#testing)
- [Security](#security)
- [Documentation](#documentation)
- [Issues Management or Triage](#issues-management-or-triage)
- [Community](#community)
- [Communication](#communication-1)
- [Events](#events)
- [Meetups](#meetups)
- [Mentorship](#mentorship)
# Before you get started
## Sign the CLA
Before you can contribute, you will need to sign the [Contributor License Agreement](https://github.com/kubernetes/community/tree/master/CLA.md).
## Code of Conduct
Please make sure to read and observe our [Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
## Setting up your development environment
If you havent set up your environment, please find resources [here](https://github.com/kubernetes/community/tree/master/contributors/devel).
## Community Expectations and Roles
Kubernetes is a community project. Consequently, it is wholly dependent on its community to provide a productive, friendly and collaborative environment.
- Read and review the [Community Expectations](https://github.com/kubernetes/community/tree/master/contributors/guide/community-expectations.md) for an understand of code and review expectations.
- See [Community Membership](https://github.com/kubernetes/community/tree/master/community-membership.md) for a list the various responsibilities of contributor roles. You are encouraged to move up this contributor ladder as you gain experience.
# Your First Contribution
Have you ever wanted to contribute to the coolest cloud technology? We will help you understand the organization of the Kubernetes project and direct you to the best places to get started. You'll be able to pick up issues, write code to fix them, and get your work reviewed and merged.
Please be aware that due to the large number of issues our triage team deals with, we cannot offer technical support in GitHub issues. If you have questions about the development process, feel free to jump into our [Slack Channel](http://slack.k8s.io/) or join our [mailing list](https://groups.google.com/forum/#!forum/kubernetes-dev). You can also ask questions on [ServerFault](https://serverfault.com/questions/tagged/kubernetes) or [Stack Overflow](https://stackoverflow.com/questions/tagged/kubernetes). The Kubernetes team scans Stack Overflow on a regular basis and will try to ensure your questions don't go unanswered.
## Find something to work on
Help is always welcome! For example, documentation (like the text you are reading now) can always use improvement. There's always code that can be clarified and variables or functions that can be renamed or commented. There's always a need for more test coverage.
You get the idea - if you ever see something you think should be fixed, you should own it. Here is how you get started.
### Find a good first topic
There are multiple repositories within the Kubernetes community and a full list of repositories can be found [here](https://github.com/kubernetes/).
Each repository in the Kubernetes organization has beginner-friendly issues that provide a good first issue. For example, [kubernetes/kubernetes](https://git.k8s.io/kubernetes) has [help wanted issues](https://go.k8s.io/help-wanted) that should not need deep knowledge of the system.
Another good strategy is to find a documentation improvement, such as a missing/broken link, which will give you exposure to the code submission/review process without the added complication of technical depth. Please see [Contributing](#contributing) below for the workflow.
### Learn about SIGs
#### Sig structure
You may have noticed that some repositories in the Kubernetes Organization are owned by Special Interest Groups, or SIGs. We organize the Kubernetes community into SIGs in order to improve our workflow and more easily manage what is a very large community project. The developers within each SIG have autonomy and ownership over that SIG's part of Kubernetes.
Some SIGs also have their own `CONTRIBUTING.md` files, which may contain extra information or guidelines in addition to these general ones. These are located in the SIG-specific community directories. For example: the contributor's guide for SIG CLI is located in the *kubernetes/community* repo, as [`/sig-cli/CONTRIBUTING.md`](https://github.com/kubernetes/community/tree/master/sig-cli/CONTRIBUTING.md).
Like everything else in Kubernetes, a SIG is an open, community, effort. Anybody is welcome to jump into a SIG and begin fixing issues, critiquing design proposals and reviewing code. SIGs have regular [video meetings](https://kubernetes.io/community/) which everyone is welcome to. Each SIG has a kubernetes slack channel that you can join as well.
There is an entire SIG ([sig-contributor-experience](https://github.com/kubernetes/community/tree/master/sig-contributor-experience/README.md)) devoted to improving your experience as a contributor.
Contributing to Kubernetes should be easy. If you find a rough edge, let us know! Better yet, help us fix it by joining the SIG; just
show up to one of the [bi-weekly meetings](https://docs.google.com/document/d/1qf-02B7EOrItQgwXFxgqZ5qjW0mtfu5qkYIF1Hl4ZLI/edit).
#### Find a SIG that is related to your contribution
Finding the appropriate SIG for your contribution and adding a SIG label will help you ask questions in the correct place and give your contribution higher visibility and a faster community response.
For Pull Requests, the automatically assigned reviewer will add a SIG label if you haven't done so. See [Open A Pull Request](#open-a-pull-request) below.
For Issues, we are still working on a more automated workflow. Since SIGs do not directly map onto Kubernetes subrepositories, it may be difficult to find which SIG your contribution belongs in. Here is the [list of SIGs](https://github.com/kubernetes/community/tree/master/sig-list.md). Determine which is most likely related to your contribution.
*Example:* if you are filing a cni issue, you should choose the [Network SIG](http://git.k8s.io/community/sig-network). Add the SIG label in a comment like so:
```
/sig network
```
Follow the link in the SIG name column to reach each SIGs README. Most SIGs will have a set of GitHub Teams with tags that can be mentioned in a comment on issues and pull requests for higher visibility. If you are not sure about the correct SIG for an issue, you can try SIG-contributor-experience [here](https://github.com/kubernetes/community/tree/master/sig-contributor-experience#github-teams), or [ask in Slack](http://slack.k8s.io/).
### File an Issue
Not ready to contribute code, but see something that needs work? While the community encourages everyone to contribute code, it is also appreciated when someone reports an issue (aka problem). Issues should be filed under the appropriate Kubernetes subrepository.
Check the [issue triage guide](https://github.com/kubernetes/community/tree/master/contributors/guide/./issue-triage.md) for more information.
*Example:* a documentation issue should be opened to [kubernetes/website](https://github.com/kubernetes/website/issues).
Make sure to adhere to the prompted submission guidelines while opening an issue.
# Contributing
Kubernetes is open source, but many of the people working on it do so as their day job. In order to avoid forcing people to be "at work" effectively 24/7, we want to establish some semi-formal protocols around development. Hopefully, these rules make things go more smoothly. If you find that this is not the case, please complain loudly.
As a potential contributor, your changes and ideas are welcome at any hour of the day or night, weekdays, weekends, and holidays. Please do not ever hesitate to ask a question or send a pull request.
Our community guiding principles on how to create great code as a big group are found [here](https://github.com/kubernetes/community/tree/master/contributors/devel/collab.md).
Beginner focused information can be found below in [Open a Pull Request](#open-a-pull-request) and [Code Review](#code-review).
For quick reference on contributor resources, we have a handy [contributor cheatsheet](https://github.com/kubernetes/community/tree/master/contributors/guide/./contributor-cheatsheet.md)
### Communication
It is best to contact your [SIG](#learn-about-sigs) for issues related to the SIG's topic. Your SIG will be able to help you much more quickly than a general question would.
For general questions and troubleshooting, use the [kubernetes standard lines of communication](https://github.com/kubernetes/community/tree/master/communication.md) and work through the [kubernetes troubleshooting guide](https://kubernetes.io/docs/tasks/debug-application-cluster/troubleshooting/).
## GitHub workflow
To check out code to work on, please refer to [this guide](https://github.com/kubernetes/community/tree/master/contributors/guide/./github-workflow.md).
## Open a Pull Request
Pull requests are often called simply "PR". Kubernetes generally follows the standard [github pull request](https://help.github.com/articles/about-pull-requests/) process, but there is a layer of additional kubernetes specific (and sometimes SIG specific) differences:
- [Kubernetes-specific github workflow](https://github.com/kubernetes/community/tree/master/contributors/guide/pull-requests.md#the-testing-and-merge-workflow).
The first difference you'll see is that a bot will begin applying structured labels to your PR.
The bot may also make some helpful suggestions for commands to run in your PR to facilitate review. These `/command` options can be entered in comments to trigger auto-labeling and notifications. The command reference is [here](https://go.k8s.io/bot-commands).
Common new contributor PR issues are:
* not having correctly signed the CLA ahead of your first PR (see [Sign the CLA](#sign-the-cla) section)
* finding the right SIG or reviewer(s) for the PR (see [Code Review](#code-review) section) and following any SIG specific contributing guidelines
* dealing with test cases which fail on your PR, unrelated to the changes you introduce (see [Test Flakes](http://velodrome.k8s.io/dashboard/db/bigquery-metrics?orgId=1))
* Not following [scalability good practices](https://github.com/kubernetes/community/tree/master/contributors/guide/scalability-good-practices.md)
## Code Review
For a brief description of the importance of code review, please read [On Code Review](https://github.com/kubernetes/community/tree/master/contributors/guide/community-expectations.md#code-review). There are two aspects of code review: giving and receiving.
To make it easier for your PR to receive reviews, consider the reviewers will need you to:
* follow the project [coding conventions](https://github.com/kubernetes/community/tree/master/contributors/guide/coding-conventions.md)
* write [good commit messages](https://chris.beams.io/posts/git-commit/)
* break large changes into a logical series of smaller patches which individually make easily understandable changes, and in aggregate solve a broader issue
* label PRs with appropriate SIGs and reviewers: to do this read the messages the bot sends you to guide you through the PR process
Reviewers, the people giving the review, are highly encouraged to revisit the [Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md) and must go above and beyond to promote a collaborative, respectful Kubernetes community. When reviewing PRs from others [The Gentle Art of Patch Review](http://sage.thesharps.us/2014/09/01/the-gentle-art-of-patch-review/) suggests an iterative series of focuses which is designed to lead new contributors to positive collaboration without inundating them initially with nuances:
* Is the idea behind the contribution sound?
* Is the contribution architected correctly?
* Is the contribution polished?
## Testing
Testing is the responsibility of all contributors and is in part owned by all sigs, but is also coordinated by [sig-testing](https://github.com/kubernetes/community/tree/master/sig-testing).
The main testing overview document is [here](https://github.com/kubernetes/community/tree/master/contributors/devel/testing.md).
There are three types of test in kubernetes. The location of the test code varies with type, as does the specifics of the environment needed to successfully run the test:
* Unit: These confirm that a particular function behaves as intended. Golang includes a native ability for unit testing via the [testing](https://golang.org/pkg/testing/) package. Unit test source code can be found adjacent to the corresponding source code within a given package. For example: functions defined in [kubernetes/cmd/kubeadm/app/util/version.go](https://git.k8s.io/kubernetes/cmd/kubeadm/app/util/version.go) will have unit tests in [kubernetes/cmd/kubeadm/app/util/version_test.go](https://git.k8s.io/kubernetes/cmd/kubeadm/app/util/version_test.go). These are easily run locally by any developer on any OS.
* Integration: These tests cover interactions of package components or interactions between kubernetes components and some other non-kubernetes system resource (eg: etcd). An example would be testing whether a piece of code can correctly store data to or retrieve data from etcd. Integration tests are stored in [kubernetes/test/integration/](https://git.k8s.io/kubernetes/test/integration). Running these can require the developer set up additional functionality on their development system.
* End-to-end ("e2e"): These are broad tests of overall kubernetes system behavior and coherence. These are more complicated as they require a functional kubernetes cluster built from the sources to be tested. A separate document [here](https://github.com/kubernetes/community/tree/master/contributors/devel/e2e-tests.md) details e2e testing and test cases themselves can be found in [kubernetes/test/e2e/](https://git.k8s.io/kubernetes/test/e2e).
Continuous integration will run these tests either as pre-submits on PRs, post-submits against master/release branches, or both. The results appear on [testgrid](https://testgrid.k8s.io).
sig-testing is responsible for that official infrastructure and CI. The associated automation is tracked in the [test-infra repo](https://git.k8s.io/test-infra). If you're looking to run e2e tests on your own infrastructure, [kubetest](https://git.k8s.io/test-infra/kubetest) is the mechanism.
## Security
* Please help write this section.
## Documentation
- [Contributing to Documentation](https://kubernetes.io/editdocs/)
## Issues Management or Triage
Have you ever noticed the total number of [open issues](https://issues.k8s.io)? This number at any given time is typically high. Helping to manage or triage these open issues can be a great contribution to the Kubernetes project. This is also a great opportunity to learn about the various areas of the project. Refer to the [Kubernetes Issue Triage Guidelines](https://github.com/kubernetes/community/tree/master/contributors/devel/issues.md) for more information.
# Community
If you haven't noticed by now, we have a large, lively, and friendly open-source community. We depend on new people becoming members and regular code contributors, so we would like you to come join us. To find out more about our community structure, different levels of membership and code contributors, please [explore here](https://github.com/kubernetes/community/tree/master/community-membership.md).
## Communication
- [General Information](https://github.com/kubernetes/community/tree/master/communication)
## Events
Kubernetes is the main focus of CloudNativeCon/KubeCon, held twice per year in EMEA and in North America. Information about these and other community events is available on the CNCF [events](https://www.cncf.io/events/) pages.
### Meetups
We follow the general [Cloud Native Computing Foundation guidelines](https://github.com/cncf/meetups) for Meetups. You may also contact Paris Pittman via direct message on Kubernetes Slack (@paris) or by email (parispittman@google.com)
## Mentorship
Please learn about our mentoring initiatives [here](http://git.k8s.io/community/mentoring/README.md).
# Advanced Topics
This section includes things that need to be documented, but typical contributors do not need to interact with regularly.
- [OWNERS files](https://github.com/kubernetes/community/tree/master/contributors/guide/owners.md) - The Kubernetes organizations are managed with OWNERS files, which outline which parts of the code are owned by what groups.
EMEA and in North America. Information about these and other community events is available on the CNCF [events](https://www.cncf.io/events/) pages.
### Meetups
_Improvements needed_
* include link to meetups
* information on CNCF support for founding a Meetup
### KubeCon
_Improvements needed_
* write friendly blurb about KubeCon, and include links
## Mentorship
_Improvements needed_
* Link and mini description for Kubernetes Pilots should go here.
-419
View File
@@ -1,419 +0,0 @@
---
title: Kubernetes Enhancement Proposal Process
---
---
kep-number: 1
title: Kubernetes Enhancement Proposal Process
authors:
- "@calebamiles"
- "@jbeda"
owning-sig: sig-architecture
participating-sigs:
- kubernetes-wide
reviewers:
- name: "@timothysc"
approvers:
- name: "@bgrant0607"
editor:
name: "@jbeda"
creation-date: 2017-08-22
status: implementable
---
# Kubernetes Enhancement Proposal Process
## Table of Contents
* [Kubernetes Enhancement Proposal Process](#kubernetes-enhancement-proposal-process)
* [Metadata](#metadata)
* [Table of Contents](#table-of-contents)
* [Summary](#summary)
* [Motivation](#motivation)
* [Reference-level explanation](#reference-level-explanation)
* [What type of work should be tracked by a KEP](#what-type-of-work-should-be-tracked-by-a-kep)
* [KEP Template](#kep-template)
* [KEP Metadata](#kep-metadata)
* [KEP Workflow](#kep-workflow)
* [Git and GitHub Implementation](#git-and-github-implementation)
* [KEP Editor Role](#kep-editor-role)
* [Important Metrics](#important-metrics)
* [Prior Art](#prior-art)
* [Graduation Criteria](#graduation-criteria)
* [Drawbacks](#drawbacks)
* [Alternatives](#alternatives)
* [Unresolved Questions](#unresolved-questions)
* [Mentors](#mentors)
## Summary
A standardized development process for Kubernetes is proposed in order to
- provide a common structure for proposing changes to Kubernetes
- ensure that the motivation for a change is clear
- allow for the enumeration stability milestones and stability graduation
criteria
- persist project information in a Version Control System (VCS) for future
Kubernauts
- support the creation of _high value user facing_ information such as:
- an overall project development roadmap
- motivation for impactful user facing changes
- reserve GitHub issues for tracking work in flight rather than creating "umbrella"
issues
- ensure community participants are successfully able to drive changes to
completion across one or more releases while stakeholders are adequately
represented throughout the process
This process is supported by a unit of work called a Kubernetes Enhancement Proposal or KEP.
A KEP attempts to combine aspects of a
- feature, and effort tracking document
- a product requirements document
- design document
into one file which is created incrementally in collaboration with one or more
Special Interest Groups (SIGs).
## Motivation
For cross project SIGs such as SIG PM and SIG Release an abstraction beyond a
single GitHub Issue or Pull request seems to be required in order to understand
and communicate upcoming changes to Kubernetes. In a blog post describing the
[road to Go 2][], Russ Cox explains
> that it is difficult but essential to describe the significance of a problem
> in a way that someone working in a different environment can understand
as a project it is vital to be able to track the chain of custody for a proposed
enhancement from conception through implementation.
Without a standardized mechanism for describing important enhancements our
talented technical writers and product managers struggle to weave a coherent
narrative explaining why a particular release is important. Additionally for
critical infrastructure such as Kubernetes adopters need a forward looking road
map in order to plan their adoption strategy.
The purpose of the KEP process is to reduce the amount of "tribal knowledge" in
our community. By moving decisions from a smattering of mailing lists, video
calls and hallway conversations into a well tracked artifact this process aims
to enhance communication and discoverability.
A KEP is broken into sections which can be merged into source control
incrementally in order to support an iterative development process. An important
goal of the KEP process is ensuring that the process for submitting the content
contained in [design proposals][] is both clear and efficient. The KEP process
is intended to create high quality uniform design and implementation documents
for SIGs to deliberate.
[road to Go 2]: https://blog.golang.org/toward-go2
[design proposals]: /contributors/design-proposals
## Reference-level explanation
### What type of work should be tracked by a KEP
The definition of what constitutes an "enhancement" is a foundational concern
for the Kubernetes project. Roughly any Kubernetes user or operator facing
enhancement should follow the KEP process: if an enhancement would be described
in either written or verbal communication to anyone besides the KEP author or
developer then consider creating a KEP.
Similarly, any technical effort (refactoring, major architectural change) that
will impact a large section of the development community should also be
communicated widely. The KEP process is suited for this even if it will have
zero impact on the typical user or operator.
As the local bodies of governance, SIGs should have broad latitude in describing
what constitutes an enhancement which should be tracked through the KEP process.
SIGs may find that helpful to enumerate what _does not_ require a KEP rather
than what does. SIGs also have the freedom to customize the KEP template
according to their SIG specific concerns. For example the KEP template used to
track API changes will likely have different subsections than the template for
proposing governance changes. However, as changes start impacting other SIGs or
the larger developer community outside of a SIG, the KEP process should be used
to coordinate and communicate.
Enhancements that have major impacts on multiple SIGs should use the KEP process.
A single SIG will own the KEP but it is expected that the set of approvers will span the impacted SIGs.
The KEP process is the way that SIGs can negotiate and communicate changes that cross boundaries.
KEPs will also be used to drive large changes that will cut across all parts of the project.
These KEPs will be owned by SIG-architecture and should be seen as a way to communicate the most fundamental aspects of what Kubernetes is.
### KEP Template
The template for a KEP is precisely defined [here](https://github.com/kubernetes/community/tree/master/keps/0000-kep-template.md)
### KEP Metadata
There is a place in each KEP for a YAML document that has standard metadata.
This will be used to support tooling around filtering and display. It is also
critical to clearly communicate the status of a KEP.
Metadata items:
* **kep-number** Required
* Each proposal has a number. This is to make all references to proposals as
clear as possible. This is especially important as we create a network
cross references between proposals.
* Before having the `Approved` status, the number for the KEP will be in the
form of `draft-YYYYMMDD`. The `YYYYMMDD` is replaced with the current date
when first creating the KEP. The goal is to enable fast parallel merges of
pre-acceptance KEPs.
* On acceptance a sequential dense number will be assigned. This will be done
by the editor and will be done in such a way as to minimize the chances of
conflicts. The final number for a KEP will have no prefix.
* **title** Required
* The title of the KEP in plain language. The title will also be used in the
KEP filename. See the template for instructions and details.
* **status** Required
* The current state of the KEP.
* Must be one of `provisional`, `implementable`, `implemented`, `deferred`, `rejected`, `withdrawn`, or `replaced`.
* **authors** Required
* A list of authors for the KEP.
This is simply the github ID.
In the future we may enhance this to include other types of identification.
* **owning-sig** Required
* The SIG that is most closely associated with this KEP. If there is code or
other artifacts that will result from this KEP, then it is expected that
this SIG will take responsibility for the bulk of those artifacts.
* Sigs are listed as `sig-abc-def` where the name matches up with the
directory in the `kubernetes/community` repo.
* **participating-sigs** Optional
* A list of SIGs that are involved or impacted by this KEP.
* A special value of `kubernetes-wide` will indicate that this KEP has impact
across the entire project.
* **reviewers** Required
* Reviewer(s) chosen after triage according to proposal process
* If not yet chosen replace with `TBD`
* Same name/contact scheme as `authors`
* Reviewers should be a distinct set from authors.
* **approvers** Required
* Approver(s) chosen after triage according to proposal process
* Approver(s) are drawn from the impacted SIGs.
It is up to the individual SIGs to determine how they pick approvers for KEPs impacting them.
The approvers are speaking for the SIG in the process of approving this KEP.
The SIGs in question can modify this list as necessary.
* The approvers are the individuals that make the call to move this KEP to the `approved` state.
* Approvers should be a distinct set from authors.
* If not yet chosen replace with `TBD`
* Same name/contact scheme as `authors`
* **editor** Required
* Someone to keep things moving forward.
* If not yet chosen replace with `TBD`
* Same name/contact scheme as `authors`
* **creation-date** Required
* The date that the KEP was first submitted in a PR.
* In the form `yyyy-mm-dd`
* While this info will also be in source control, it is helpful to have the set of KEP files stand on their own.
* **last-updated** Optional
* The date that the KEP was last changed significantly.
* In the form `yyyy-mm-dd`
* **see-also** Optional
* A list of other KEPs that are relevant to this KEP.
* In the form `KEP-123`
* **replaces** Optional
* A list of KEPs that this KEP replaces. Those KEPs should list this KEP in
their `superseded-by`.
* In the form `KEP-123`
* **superseded-by**
* A list of KEPs that supersede this KEP. Use of this should be paired with
this KEP moving into the `Replaced` status.
* In the form `KEP-123`
### KEP Workflow
A KEP has the following states
- `provisional`: The KEP has been proposed and is actively being defined.
This is the starting state while the KEP is being fleshed out and actively defined and discussed.
The owning SIG has accepted that this is work that needs to be done.
- `implementable`: The approvers have approved this KEP for implementation.
- `implemented`: The KEP has been implemented and is no longer actively changed.
- `deferred`: The KEP is proposed but not actively being worked on.
- `rejected`: The approvers and authors have decided that this KEP is not moving forward.
The KEP is kept around as a historical document.
- `withdrawn`: The KEP has been withdrawn by the authors.
- `replaced`: The KEP has been replaced by a new KEP.
The `superseded-by` metadata value should point to the new KEP.
### Git and GitHub Implementation
KEPs are checked into the community repo under the `/kep` directory.
In the future, as needed we can add SIG specific subdirectories.
KEPs in SIG specific subdirectories have limited impact outside of the SIG and can leverage SIG specific OWNERS files.
New KEPs can be checked in with a file name in the form of `draft-YYYYMMDD-my-title.md`.
As significant work is done on the KEP the authors can assign a KEP number.
This is done by taking the next number in the NEXT_KEP_NUMBER file, incrementing that number, and renaming the KEP.
No other changes should be put in that PR so that it can be approved quickly and minimize merge conflicts.
The KEP number can also be done as part of the initial submission if the PR is likely to be uncontested and merged quickly.
### KEP Editor Role
Taking a cue from the [Python PEP process][], we define the role of a KEP editor.
The job of an KEP editor is likely very similar to the [PEP editor responsibilities][] and will hopefully provide another opportunity for people who do not write code daily to contribute to Kubernetes.
In keeping with the PEP editors which
> Read the PEP to check if it is ready: sound and complete. The ideas must make
> technical sense, even if they don't seem likely to be accepted.
> The title should accurately describe the content.
> Edit the PEP for language (spelling, grammar, sentence structure, etc.), markup
> (for reST PEPs), code style (examples should match PEP 8 & 7).
KEP editors should generally not pass judgement on a KEP beyond editorial corrections.
KEP editors can also help inform authors about the process and otherwise help things move smoothly.
[Python PEP process]: https://www.python.org/dev/peps/pep-0001/
[PEP editor responsibilities]: https://www.python.org/dev/peps/pep-0001/#pep-editor-responsibilities-workflow
### Important Metrics
It is proposed that the primary metrics which would signal the success or
failure of the KEP process are
- how many "enhancements" are tracked with a KEP
- distribution of time a KEP spends in each state
- KEP rejection rate
- PRs referencing a KEP merged per week
- number of issued open which reference a KEP
- number of contributors who authored a KEP
- number of contributors who authored a KEP for the first time
- number of orphaned KEPs
- number of retired KEPs
- number of superseded KEPs
### Prior Art
The KEP process as proposed was essentially stolen from the [Rust RFC process][] which
itself seems to be very similar to the [Python PEP process][]
[Rust RFC process]: https://github.com/rust-lang/rfcs
## Drawbacks
Any additional process has the potential to engender resentment within the
community. There is also a risk that the KEP process as designed will not
sufficiently address the scaling challenges we face today. PR review bandwidth is
already at a premium and we may find that the KEP process introduces an unreasonable
bottleneck on our development velocity.
It certainly can be argued that the lack of a dedicated issue/defect tracker
beyond GitHub issues contributes to our challenges in managing a project as large
as Kubernetes, however, given that other large organizations, including GitHub
itself, make effective use of GitHub issues perhaps the argument is overblown.
The centrality of Git and GitHub within the KEP process also may place too high
a barrier to potential contributors, however, given that both Git and GitHub are
required to contribute code changes to Kubernetes today perhaps it would be reasonable
to invest in providing support to those unfamiliar with this tooling.
Expanding the proposal template beyond the single sentence description currently
required in the [features issue template][] may be a heavy burden for non native
English speakers and here the role of the KEP editor combined with kindness and
empathy will be crucial to making the process successful.
[features issue template]: https://git.k8s.io/features/ISSUE_TEMPLATE.md
## Alternatives
This KEP process is related to
- the generation of a [architectural roadmap][]
- the fact that the [what constitutes a feature][] is still undefined
- [issue management][]
- the difference between an [accepted design and a proposal][]
- [the organization of design proposals][]
this proposal attempts to place these concerns within a general framework.
[architectural roadmap]: https://github.com/kubernetes/community/issues/952
[what constitutes a feature]: https://github.com/kubernetes/community/issues/531
[issue management]: https://github.com/kubernetes/community/issues/580
[accepted design and a proposal]: https://github.com/kubernetes/community/issues/914
[the organization of design proposals]: https://github.com/kubernetes/community/issues/918
### Github issues vs. KEPs
The use of GitHub issues when proposing changes does not provide SIGs good
facilities for signaling approval or rejection of a proposed change to Kubernetes
since anyone can open a GitHub issue at any time. Additionally managing a proposed
change across multiple releases is somewhat cumbersome as labels and milestones
need to be updated for every release that a change spans. These long lived GitHub
issues lead to an ever increasing number of issues open against
`kubernetes/features` which itself has become a management problem.
In addition to the challenge of managing issues over time, searching for text
within an issue can be challenging. The flat hierarchy of issues can also make
navigation and categorization tricky. While not all community members might
not be comfortable using Git directly, it is imperative that as a community we
work to educate people on a standard set of tools so they can take their
experience to other projects they may decide to work on in the future. While
git is a fantastic version control system (VCS), it is not a project management
tool nor a cogent way of managing an architectural catalog or backlog; this
proposal is limited to motivating the creation of a standardized definition of
work in order to facilitate project management. This primitive for describing
a unit of work may also allow contributors to create their own personalized
view of the state of the project while relying on Git and GitHub for consistency
and durable storage.
## Unresolved Questions
- How reviewers and approvers are assigned to a KEP
- Example schedule, deadline, and time frame for each stage of a KEP
- Communication/notification mechanisms
- Review meetings and escalation procedure
roadmap][]
- the fact that the [what constitutes a feature][] is still undefined
- [issue management][]
- the difference between an [accepted design and a proposal][]
- [the organization of design proposals][]
this proposal attempts to place these concerns within a general framework.
[architectural roadmap]: https://github.com/kubernetes/community/issues/952
[what constitutes a feature]: https://github.com/kubernetes/community/issues/531
[issue management]: https://github.com/kubernetes/community/issues/580
[accepted design and a proposal]: https://github.com/kubernetes/community/issues/914
[the organization of design proposals]: https://github.com/kubernetes/community/issues/918
### Github issues vs. KEPs
The use of GitHub issues when proposing changes does not provide SIGs good
facilities for signaling approval or rejection of a proposed change to Kubernetes
since anyone can open a GitHub issue at any time. Additionally managing a proposed
change across multiple releases is somewhat cumbersome as labels and milestones
need to be updated for every release that a change spans. These long lived GitHub
issues lead to an ever increasing number of issues open against
`kubernetes/features` which itself has become a management problem.
In addition to the challenge of managing issues over time, searching for text
within an issue can be challenging. The flat hierarchy of issues can also make
navigation and categorization tricky. While not all community members might
not be comfortable using Git directly, it is imperative that as a community we
work to educate people on a standard set of tools so they can take their
experience to other projects they may decide to work on in the future. While
git is a fantastic version control system (VCS), it is not a project management
tool nor a cogent way of managing an architectural catalog or backlog; this
proposal is limited to motivating the creation of a standardized definition of
work in order to facilitate project management. This primitive for describing
a unit of work may also allow contributors to create their own personalized
view of the state of the project while relying on Git and GitHub for consistency
and durable storage.
## Unresolved Questions
- How reviewers and approvers are assigned to a KEP
- Approval decision process for a KEP
- Example schedule, deadline, and time frame for each stage of a KEP
- Communication/notification mechanisms
- Review meetings and escalation procedure
- Decision on where development should occur
## Mentors
- caleb miles
- github: [calebamiles](https://github.com/calebamiles/)
- slack: [calebamiles](https://coreos.slack.com/team/caleb.miles)
- email: [caleb.miles@coreos.com](mailto:caleb.miles@coreos.com)
- pronoun: "he"
-49
View File
@@ -1,49 +0,0 @@
---
title: Kubernetes Mentoring Initiatives
notitle: true
---
# Kubernetes Mentoring Initiatives
This folder will be used for all mentoring initiatives for Kubernetes.
---
## Kubernetes Pilots
We understand that everyone has different learning styles and we want to support as many of those as possible. Mentoring is vital to the growth of an individual and organization of every kind. For Kubernetes, the larger the project becomes, it's necessary to keep a continuous pipeline of quality contributors.
*What's a Pilot?*
A pilot is a Kubernetes mentor helping new and current members navigate the seas of our repos.
## Current mentoring activities:
All are currently in an incubation phase. Please reach out to Paris Pittman (parispittman@google.com or Paris on Kubernetes slack channel) for more information on how to get involved.
Mentors On Demand
* [Meet Our Contributors](https://github.com/kubernetes/community/tree/master/mentoring/meet-our-contributors.md)
Long Term Contributor Ladder Growth
* [Group Mentoring Cohorts](https://github.com/kubernetes/community/tree/master/mentoring/group-mentoring.md)
Students
* [Outreachy](https://github.com/kubernetes/community/tree/master/sig-cli/outreachy.md)
* [Google Summer of Code](https://github.com/kubernetes/community/tree/master/mentoring/google-summer-of-code.md)
#### Inspiration and Thanks
This is not an out of the box program but was largely inspired by the following:
* [Ada Developer Academy](https://adadevelopersacademy.org/)
* [Apache Mentoring Programme](https://community.apache.org/mentoringprogramme.html)
* [exercism.io](https://github.com/OperationCode/exercism-io-mentoring)
* [Google Summer of Code](https://developers.google.com/open-source/gsoc/)
* [Outreachy](https://www.outreachy.org/)
* [OpenStack Mentoring](https://wiki.openstack.org/wiki/Mentoring)
Thanks to:
* the many contributors who reviewed and participated in brainstorming,
* founding mentees for their willingness to try this out,
* founding Pilots (@chrislovecnm, @luxas, @kow3ns)
We welcome PRs, suggestions, and help!
try this out,
* founding Pilots (@chrislovecnm, @luxas, @kow3ns)
We welcome PRs, suggestions, and help!
@@ -63,7 +63,7 @@ Resource creation isn't the only operation that `kubectl` can perform in bulk. I
```shell
$ kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment "my-nginx" deleted
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
```
@@ -117,9 +117,9 @@ Instead, specify the `--recursive` or `-R` flag with the `--filename,-f` flag as
```shell
$ kubectl create -f project/k8s/development --recursive
configmap "my-config" created
deployment "my-deployment" created
persistentvolumeclaim "my-pvc" created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
```
The `--recursive` flag works with any operation that accepts the `--filename,-f` flag such as: `kubectl {create,get,delete,describe,rollout} etc.`
@@ -128,11 +128,11 @@ The `--recursive` flag also works when multiple `-f` arguments are provided:
```shell
$ kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive
namespace "development" created
namespace "staging" created
configmap "my-config" created
deployment "my-deployment" created
persistentvolumeclaim "my-pvc" created
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
```
If you're interested in learning more about `kubectl`, go ahead and read [kubectl Overview](/docs/reference/kubectl/overview/).
@@ -201,6 +201,10 @@ sysctl net.ipv4.ip_forward=1
The result of all this is that all `Pods` can reach each other and can egress
traffic to the internet.
### Jaguar
[Jaguar](https://gitlab.com/sdnlab/jaguar) is an open source solution for Kubernetes's network based on OpenDaylight. Jaguar provides overlay network using vxlan and Jaguar CNIPlugin provides one IP address per pod.
### Knitter
[Knitter](https://github.com/ZTE/Knitter/) is a network solution which supports multiple networking in Kubernetes. It provides the ability of tenant management and network management. Knitter includes a set of end-to-end NFV container networking solutions besides multiple network planes, such as keeping IP address for applications, IP address migration, etc.
@@ -273,6 +277,11 @@ Weave Net runs as a [CNI plug-in](https://www.weave.works/docs/net/latest/cni-pl
or stand-alone. In either version, it doesn't require any configuration or extra code
to run, and in both cases, the network provides one IP address per pod - as is standard for Kubernetes.
### Jaguar
[Jaguar](https://gitlab.com/sdnlab/jaguar) is an open source solution for Kubernetes's network based on OpenDaylight.
Jaguar provides overlay network using vxlan and Jaguar CNIPlugin provides one IP address per pod.
{{% /capture %}}
{{% capture whatsnext %}}
@@ -366,7 +366,9 @@ spec:
### How Pods with ephemeral-storage requests are scheduled
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. (For more information, see ["Node Allocatable"](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node.
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.
### How Pods with ephemeral-storage limits run
@@ -202,7 +202,7 @@ spec:
In Kubernetes 1.9 and later, when Pod priority is enabled, scheduler orders
pending Pods by their priority and a pending Pod is placed ahead of other
pending Pods with lower priority in the scheduling queue. As a result, the
higher priority Pod may by scheduled sooner that Pods with lower priority if its
higher priority Pod may be scheduled sooner than Pods with lower priority if its
scheduling requirements are met. If such Pod cannot be scheduled, scheduler will
continue and tries to schedule other lower priority Pods.
@@ -1,3 +1,4 @@
<<<<<<< HEAD
---
reviewers:
- tallclair
@@ -120,3 +121,128 @@ If no `runtimeClassName` is specified, the default RuntimeHandler will be used,
to the behavior when the RuntimeClass feature is disabled.
{{% /capture %}}
||||||| merged common ancestors
=======
---
reviewers:
- tallclair
- dchen1107
title: Runtime Class
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.12" state="alpha" >}}
This page describes the RuntimeClass resource and runtime selection mechanism.
{{% /capture %}}
{{< toc >}}
{{% capture body %}}
## Runtime Class
RuntimeClass is an alpha feature for selecting the container runtime configuration to use to run a
pod's containers.
### Set Up
As an early alpha feature, there are some additional setup steps that must be taken in order to use
the RuntimeClass feature:
1. Enable the RuntimeClass feature gate (on apiservers & kubelets, requires version 1.12+)
2. Install the RuntimeClass CRD
3. Configure the CRI implementation on nodes (runtime dependent)
4. Create the corresponding RuntimeClass resources
#### 1. Enable the RuntimeClass feature gate
See [Feature Gates](/docs/reference/command-line-tools-reference/feature-gates/) for an explanation
of enabling feature gates. The `RuntimeClass` feature gate must be enabled on apiservers _and_
kubelets.
#### 2. Install the RuntimeClass CRD
The RuntimeClass [CustomResourceDefinition][] (CRD) can be found in the addons directory of the
Kubernetes git repo: [kubernetes/cluster/addons/runtimeclass/runtimeclass_crd.yaml][runtimeclass_crd]
Install the CRD with `kubectl apply -f runtimeclass_crd.yaml`.
[CustomResourceDefinition]: /docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
[runtimeclass_crd]: https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/runtimeclass/runtimeclass_crd.yaml
#### 3. Configure the CRI implementation on nodes
The configurations to select between with RuntimeClass are CRI implementation dependent. See the
corresponding documentation for your CRI implementation for how to configure. As this is an alpha
feature, not all CRIs support multiple RuntimeClasses yet.
{{< note >}}
**Note:** RuntimeClass currently assumes a homogeneous node configuration across the cluster
(which means that all nodes are configured the same way with respect to container runtimes). Any heterogeneity (varying configurations) must be
managed independently of RuntimeClass through scheduling features (see [Assigning Pods to
Nodes](/docs/concepts/configuration/assign-pod-node/)).
{{< /note >}}
The configurations have a corresponding `RuntimeHandler` name, referenced by the RuntimeClass. The
RuntimeHandler must be a valid DNS 1123 subdomain (alpha-numeric + `-` and `.` characters).
#### 4. Create the corresponding RuntimeClass resources
The configurations setup in step 3 should each have an associated `RuntimeHandler` name, which
identifies the configuration. For each RuntimeHandler (and optionally the empty `""` handler),
create a corresponding RuntimeClass object.
The RuntimeClass resource currently only has 2 significant fields: the RuntimeClass name
(`metadata.name`) and the RuntimeHandler (`spec.runtimeHandler`). The object definition looks like this:
```yaml
apiVersion: node.k8s.io/v1alpha1 # RuntimeClass is defined in the node.k8s.io API group
kind: RuntimeClass
metadata:
name: myclass # The name the RuntimeClass will be referenced by
# RuntimeClass is a non-namespaced resource
spec:
runtimeHandler: myconfiguration # The name of the corresponding CRI configuration
```
{{< note >}}
**Note:** It is recommended that RuntimeClass write operations (create/update/patch/delete) be
restricted to the cluster administrator. This is typically the default. See [Authorization
Overview](https://kubernetes.io/docs/reference/access-authn-authz/authorization/) for more details.
{{< /note >}}
### Usage
Once RuntimeClasses are configured for the cluster, using them is very simple. Specify a
`runtimeClassName` in the Pod spec. For example:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
runtimeClassName: myclass
# ...
```
This will instruct the Kubelet to use the named RuntimeClass to run this pod. If the named
RuntimeClass does not exist, or the CRI cannot run the corresponding handler, the pod will enter the
`Failed` terminal [phase](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase). Look for a
corresponding [event](/docs/tasks/debug-application-cluster/debug-application-introspection/) for an
error message.
If no `runtimeClassName` is specified, the default RuntimeHandler will be used, which is equivalent
to the behavior when the RuntimeClass feature is disabled.
{{% /capture %}}
>>>>>>> master
@@ -84,8 +84,8 @@ For example:
#### Support traffic shaping
The CNI networking plugin also supports pod ingress and egress traffic shaping. You can use the officical [bandwidth](https://github.com/containernetworking/plugins/tree/master/plugins/meta/bandwidth)
plugin offered by the CNI plugin team or use your own plugin with bandwidth contol functionality.
The CNI networking plugin also supports pod ingress and egress traffic shaping. You can use the official [bandwidth](https://github.com/containernetworking/plugins/tree/master/plugins/meta/bandwidth)
plugin offered by the CNI plugin team or use your own plugin with bandwidth control functionality.
If you want to enable traffic shaping support, you must add a `bandwidth` plugin to your CNI configuration file
(default `/etc/cni/net.d`).
@@ -132,7 +132,7 @@ Adding an API does not directly let you affect the behavior of existing APIs (e.
### API Access Extensions
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then subject to various types of Admission Control. See [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/)] for more on this flow.
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then subject to various types of Admission Control. See [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/) for more on this flow.
Each of these steps offers extension points.
@@ -207,7 +207,7 @@ the nodes chosen for a pod.
* [Device Plugins](/docs/concepts/cluster-administration/device-plugins/)
* Learn about [kubectl plugins](/docs/tasks/extend-kubectl/kubectl-plugins/)
* See examples of Automation
* [List of Operators](https://github.com/coreos/awesome-kubernetes-extensions)
* [List of Operators](https://github.com/operator-framework/awesome-operators)
{{% /capture %}}
@@ -481,7 +481,7 @@ spec:
### Users and groups
**RunAsUser** - Controls the what user ID containers run as.
**RunAsUser** - Controls which user ID the containers are run with.
- *MustRunAs* - Requires at least one `range` to be specified. Uses the
minimum value of the first range as the default. Validates against all ranges.
@@ -491,7 +491,7 @@ image. No default provided. Setting `allowPrivilegeEscalation=false` is strongly
recommended with this strategy.
- *RunAsAny* - No default provided. Allows any `runAsUser` to be specified.
**RunAsGroup** - Controls the what primary group ID containers run as.
**RunAsGroup** - Controls which primary group ID the containers are run with.
- *MustRunAs* - Requires at least one `range` to be specified. Uses the
minimum value of the first range as the default. Validates against all ranges.
@@ -613,4 +613,4 @@ default cannot be changed.
Controlled via annotations on the PodSecurityPolicy. Refer to the [Sysctl documentation](
/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy-annotations).
{{% /capture %}}
{{% /capture %}}
@@ -568,7 +568,7 @@ For example:
values: ["cluster-services"]
```
See [LimitedResources](https://github.com/kubernetes/kubernetes/pull/36765) and [Quota supoport for priority class design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/pod-priority-resourcequota.md) for more information.
See [LimitedResources](https://github.com/kubernetes/kubernetes/pull/36765) and [Quota support for priority class design doc](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/pod-priority-resourcequota.md) for more information.
## Example
@@ -580,4 +580,4 @@ See a [detailed example for how to use resource quota](/docs/tasks/administer-cl
See [ResourceQuota design doc](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md) for more information.
{{% /capture %}}
{{% /capture %}}
@@ -65,7 +65,7 @@ You can create a Service for your 2 nginx replicas with `kubectl expose`:
```shell
$ kubectl expose deployment/my-nginx
service "my-nginx" exposed
service/my-nginx exposed
```
This is equivalent to `kubectl create -f` the following yaml:
@@ -213,7 +213,7 @@ You can acquire all these from the [nginx https example](https://github.com/kube
```shell
$ make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json
$ kubectl create -f /tmp/secret.json
secret "nginxsecret" created
secret/nginxsecret created
$ kubectl get secrets
NAME TYPE DATA AGE
default-token-il9rc kubernetes.io/service-account-token 1 1d
@@ -48,7 +48,7 @@ It can be configured to give services externally-reachable URLs, load balance tr
Before you start using the Ingress resource, there are a few things you should understand. The Ingress is a beta resource, not available in any Kubernetes release prior to 1.1. You need an Ingress controller to satisfy an Ingress, simply creating the resource will have no effect.
GCE/Google Kubernetes Engine deploys an ingress controller on the master. You can deploy any number of custom ingress controllers in a pod. You must annotate each ingress with the appropriate class, as indicated [here](https://git.k8s.io/ingress#running-multiple-ingress-controllers) and [here](https://git.k8s.io/ingress-gce/BETA_LIMITATIONS.md#disabling-glbc).
GCE/Google Kubernetes Engine deploys an ingress controller on the master. You can deploy any number of custom ingress controllers in a pod. You must annotate each ingress with the appropriate class, as indicated [here](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) and [here](https://git.k8s.io/ingress-gce/examples/PREREQUISITES.md#ingress-class).
Make sure you review the [beta limitations](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations) of this controller. In environments other than GCE/Google Kubernetes Engine, you need to [deploy a controller](https://git.k8s.io/ingress-nginx/README.md) as a pod.
@@ -173,8 +173,6 @@ By default, the choice of backend is round robin.
![Services overview diagram for userspace proxy](/images/docs/services-userspace-overview.svg)
Note that in the above diagram, `clusterIP` is shown as `ServiceIP`.
### Proxy-mode: iptables
In this mode, kube-proxy watches the Kubernetes master for the addition and
@@ -192,8 +190,6 @@ having working [readiness probes](/docs/tasks/configure-pod-container/configure-
![Services overview diagram for iptables proxy](/images/docs/services-iptables-overview.svg)
Note that in the above diagram, `clusterIP` is shown as `ServiceIP`.
### Proxy-mode: ipvs
{{< feature-state for_k8s_version="v1.9" state="beta" >}}
@@ -66,9 +66,9 @@ In this example:
* The Pods are labeled `app: nginx`using the `labels` field.
* The Pod template's specification, or `.template.spec` field, indicates that
the Pods run one container, `nginx`, which runs the `nginx`
[Docker Hub](https://hub.docker.com/) image at version 1.7.9.
[Docker Hub](https://hub.docker.com/) image at version 1.15.4.
* Create one container and name it `nginx` using the `name` field.
* Run the `nginx` image at version `1.7.9`.
* Run the `nginx` image at version `1.15.4`.
* Open port `80` so that the container can send and accept traffic.
To create this Deployment, run the following command:
@@ -78,9 +78,7 @@ kubectl create -f https://k8s.io/examples/controllers/nginx-deployment.yaml
```
{{< note >}}
**Note:** You can append `--record` to this command to record the current command in the annotations of
the created or updated resource. This is useful for future review, such as investigating which
commands were executed in each Deployment revision.
**Note:** You may specify the `--record` flag to write the command executed in the resource annotation `kubernetes.io/change-cause`. It is useful for future instrospection, for example to see the commands executed in each Deployment revision.
{{< /note >}}
Next, run `kubectl get deployments`. The output is similar to the following:
@@ -173,15 +171,15 @@ Suppose that you now want to update the nginx Pods to use the `nginx:1.9.1` imag
instead of the `nginx:1.7.9` image.
```shell
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.extensions/nginx-deployment image updated
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record
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`:
```shell
$ kubectl edit deployment/nginx-deployment
deployment.extensions/nginx-deployment edited
deployment.apps/nginx-deployment edited
```
To see the rollout status, run:
@@ -189,7 +187,7 @@ To see the rollout status, run:
```shell
$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment.extensions/nginx-deployment successfully rolled out
deployment.apps/nginx-deployment successfully rolled out
```
After the rollout succeeds, you may want to `get` the Deployment:
@@ -340,7 +338,7 @@ Suppose that you made a typo while updating the Deployment, by putting the image
```shell
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
deployment.extensions/nginx-deployment image updated
deployment.apps/nginx-deployment image updated
```
The rollout will be stuck.
@@ -420,13 +418,15 @@ First, check the revisions of this deployment:
$ kubectl rollout history deployment/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 kubectl create -f https://k8s.io/examples/controllers/nginx-deployment.yaml --record
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91
1 kubectl create --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record=true
3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91 --record=true
```
`CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You could specify the`CHANGE-CAUSE` message by:
Because you recorded the command while creating this Deployment using `--record`, you can easily see
the changes you made in each revision.
* Annotating the Deployment with `kubectl annotate deploy nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"`
* Append the `--record` flag to save the `kubectl` command that is making changes to the resource.
* Manually editing the manifest of the resource.
To further see the details of each revision, run:
@@ -435,7 +435,7 @@ $ kubectl rollout history deployment/nginx-deployment --revision=2
deployments "nginx-deployment" revision 2
Labels: app=nginx
pod-template-hash=1159050644
Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record=true
Containers:
nginx:
Image: nginx:1.9.1
@@ -453,14 +453,14 @@ Now you've decided to undo the current rollout and rollback to the previous revi
```shell
$ kubectl rollout undo deployment/nginx-deployment
deployment.extensions/nginx-deployment
deployment.apps/nginx-deployment
```
Alternatively, you can rollback to a specific revision by specify that in `--to-revision`:
```shell
$ kubectl rollout undo deployment/nginx-deployment --to-revision=2
deployment.extensions/nginx-deployment
deployment.apps/nginx-deployment
```
For more details about rollout related commands, read [`kubectl rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout).
@@ -469,36 +469,52 @@ The Deployment is now rolled back to a previous stable revision. As you can see,
for rolling back to revision 2 is generated from Deployment controller.
```shell
$ kubectl get deployment
$ kubectl get deployment nginx-deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 3 3 3 30m
$ kubectl describe deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700
Labels: app=nginx
Selector: app=nginx
Replicas: 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created)
$ kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=4
kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-c4747d96c (3/3 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
30m 30m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2
2m 2m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-3066724191 to 0
2m 2m 1 {deployment-controller } Normal DeploymentRollback Rolled back deployment "nginx-deployment" to revision 2
29m 2m 2 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 12m deployment-controller Scaled up replica set nginx-deployment-75675f5897 to 3
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 1
Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 2
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 2
Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 1
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 3
Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 0
Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-595696685f to 1
Normal DeploymentRollback 15s deployment-controller Rolled back deployment "nginx-deployment" to revision 2
Normal ScalingReplicaSet 15s deployment-controller Scaled down replica set nginx-deployment-595696685f to 0
```
## Scaling a Deployment
@@ -516,7 +532,7 @@ Pods you want to run based on the CPU utilization of your existing Pods.
```shell
$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
deployment.extensions/nginx-deployment scaled
deployment.apps/nginx-deployment scaled
```
### Proportional scaling
@@ -538,7 +554,7 @@ You update to a new image which happens to be unresolvable from inside the clust
```shell
$ kubectl set image deploy/nginx-deployment nginx=nginx:sometag
deployment.extensions/nginx-deployment image updated
deployment.apps/nginx-deployment image updated
```
The image update starts a new rollout with ReplicaSet nginx-deployment-1989198191, but it's blocked due to the
@@ -592,14 +608,14 @@ Pause by running the following command:
```shell
$ kubectl rollout pause deployment/nginx-deployment
deployment.extensions/nginx-deployment paused
deployment.apps/nginx-deployment paused
```
Then update the image of the Deployment:
```shell
$ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1
deployment.extensions/nginx-deployment image updated
deployment.apps/nginx-deployment image updated
```
Notice that no new rollout started:
@@ -619,7 +635,7 @@ You can make as many updates as you wish, for example, update the resources that
```shell
$ kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
deployment.extensions/nginx-deployment resource requirements updated
deployment.apps/nginx-deployment resource requirements updated
```
The initial state of the Deployment prior to pausing it will continue its function, but new updates to
@@ -629,7 +645,7 @@ Eventually, resume the Deployment and observe a new ReplicaSet coming up with al
```shell
$ kubectl rollout resume deploy/nginx-deployment
deployment.extensions/nginx-deployment resumed
deployment.apps/nginx-deployment resumed
$ kubectl get rs -w
NAME DESIRED CURRENT READY AGE
nginx-2142116321 2 2 2 2m
@@ -688,7 +704,7 @@ successfully, `kubectl rollout status` returns a zero exit code.
```shell
$ kubectl rollout status deploy/nginx-deployment
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment.extensions/nginx-deployment successfully rolled out
deployment.apps/nginx-deployment successfully rolled out
$ echo $?
0
```
@@ -715,7 +731,7 @@ lack of progress for a Deployment after 10 minutes:
```shell
$ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
deployment.extensions/nginx-deployment patched
deployment.apps/nginx-deployment patched
```
Once the deadline has been exceeded, the Deployment controller adds a DeploymentCondition with the following
attributes to the Deployment's `.status.conditions`:
@@ -81,7 +81,7 @@ the following things are true:
Once the "deletion in progress" state is set, the garbage
collector deletes the object's dependents. Once the garbage collector has deleted all
"blocking" dependents (objects with `ownerReference.blockOwnerDeletion=true`), it delete
"blocking" dependents (objects with `ownerReference.blockOwnerDeletion=true`), it deletes
the owner object.
Note that in the "foregroundDeletion", only dependents with
@@ -134,8 +134,8 @@ There are three main types of jobs:
- the job is complete when there is one successful pod for each value in the range 1 to `.spec.completions`.
- **not implemented yet:** Each pod passed a different index in the range 1 to `.spec.completions`.
1. Parallel Jobs with a *work queue*:
 - do not specify `.spec.completions`, default to `.spec.parallelism`.
 - the pods must coordinate with themselves or an external service to determine what each should work on.
- do not specify `.spec.completions`, default to `.spec.parallelism`.
- the pods must coordinate with themselves or an external service to determine what each should work on.
- each pod is independently capable of determining whether or not all its peers are done, thus the entire Job is done.
- when _any_ pod terminates with success, no new pods are created.
- once at least one pod has terminated with success and all pods are terminated, then the job is completed with success.
@@ -207,10 +207,7 @@ back-off count is reset if no new failed Pods appear before the Job's next
status check.
{{< note >}}
**Note:** Due to a known issue [#54870](https://github.com/kubernetes/kubernetes/issues/54870),
when the `.spec.template.spec.restartPolicy` field is set to "`OnFailure`", the
back-off limit may be ineffective. As a short-term workaround, set the restart
policy for the embedded template to "`Never`".
**Note:** Issue [#54870](https://github.com/kubernetes/kubernetes/issues/54870) still exists for versions of Kubernetes prior to version 1.12
{{< /note >}}
## Job Termination and Cleanup
@@ -281,7 +278,6 @@ apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-ttl
spec:
spec:
ttlSecondsAfterFinished: 100
template:
@@ -458,4 +454,4 @@ object, but complete control over what pods are created and how work is assigned
Support for creating Jobs at specified times/dates (i.e. cron) is available in Kubernetes [1.4](https://github.com/kubernetes/kubernetes/pull/11980). More information is available in the [cron job documents](/docs/concepts/workloads/controllers/cron-jobs/)
{{% /capture %}}
{{% /capture %}}
@@ -32,7 +32,6 @@ following.
* Stable, unique network identifiers.
* Stable, persistent storage.
* Ordered, graceful deployment and scaling.
* Ordered, graceful deletion and termination.
* Ordered, automated rolling updates.
In the above, stable is synonymous with persistence across Pod (re)scheduling.
@@ -48,6 +47,7 @@ provides a set of stateless replicas. Controllers such as
* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin.
* Deleting and/or scaling a StatefulSet down will *not* delete the volumes associated with the StatefulSet. This is done to ensure data safety, which is generally more valuable than an automatic purge of all related StatefulSet resources.
* StatefulSets currently require a [Headless Service](/docs/concepts/services-networking/service/#headless-services) to be responsible for the network identity of the Pods. You are responsible for creating this Service.
* StatefulSets do not provide any guarantees on the termination of pods when a StatefulSet is deleted. To achieve ordered and graceful termination of the pods in the StatefulSet, it is possible to scale the StatefulSet down to 0 prior to deletion.
## Components
The example below demonstrates the components of a StatefulSet.
@@ -24,7 +24,8 @@ for how to run the containers. A pod's contents are always co-located and
co-scheduled, and run in a shared context. A pod models an
application-specific "logical host" - it contains one or more application
containers which are relatively tightly coupled &mdash; in a pre-container
world, they would have executed on the same physical or virtual machine.
world, being executed on the same physical or virtual machine would mean being
executed on the same logical host.
While Kubernetes supports more container runtimes than just Docker, Docker is
the most commonly known runtime, and it helps to describe pods in Docker terms.
+5 -1
View File
@@ -13,7 +13,11 @@ we're happy to have your help! Anyone can contribute, whether you're new to the
project or you've been around a long time, and whether you self-identify as a
developer, an end user, or someone who just can't stand seeing typos.
Looking for the [style guide](/docs/contribute/style/style-guide/)?
For more ways to get involved in the Kubernetes community or to learn about us,
also visit the [Kubernetes community site](/community/).
Looking for the [style guide](/docs/contribute/style/style-guide/) or the
[Kubernetes Community site](/community/)?
{{% /capture %}}
{{% capture body %}}
+1 -1
View File
@@ -490,7 +490,7 @@ Slack channel or the
If you aren't ready to create a pull request but you want to see what your
changes look like, you can use the `hugo` command to stage the changes locally.
1. Install Hugo version `0.40.3` or later.
1. Install Hugo version {{< hugoVersion >}} or later.
2. In a terminal, go to the root directory of your clone of the Kubernetes
docs, and enter this command:
+124 -59
View File
@@ -4,17 +4,19 @@ content_template: templates/concept
approvers:
- chenopis
- zacharysarah
- zparnold
---
{{% capture overview %}}
The Kubernetes documentation is currently available in [multiple languages](#supported-languages) and we encourage you to add new localizations ([l10n](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/))!
Documentation for Kubernetes is available in multiple languages:
Currently available languages:
- English
- Chinese
- Japanese
- Korean
{{< language-repos-list >}}
In order for localizations to be accepted, however, they must fulfill some requirements related to workflow (*how* to localize) and output (*what* to localize).
We encourage you to add new [localizations](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/)!
{{% /capture %}}
@@ -22,42 +24,51 @@ In order for localizations to be accepted, however, they must fulfill some requi
{{% capture body %}}
## Workflow
The Kubernetes documentation for all languages is built from the [kubernetes/website](https://github.com/kubernetes/website) repository on GitHub. Most day-to-work work on translations, however, happens in separate translation repositories. Changes to those repositories are then [periodically](#upstream-contributions) synced to the main kubernetes/website repository via [pull request](../create-pull-request).
Work on the Chinese translation, for example, happens in the [kubernetes/kubernetes-docs-zh](https://github.com/kubernetes/kubernetes-docs-zh) repository.
{{< note >}}
**Note**: For an example localization-related [pull request](../create-pull-request), see [this pull request](https://github.com/kubernetes/website/pull/8636) to the [Kubernetes website repo](https://github.com/kubernetes/website) adding Korean localization to the Kubernetes docs.
{{< /note >}}
## Source Files
Localizations must use English files from the most recent major release as sources. To find the most recent release's documentation source files:
1. Navigate to the Kubernetes website repository at https://github.com/kubernetes/website.
2. Select the `release-1.X` branch for the most recent version, which is currently **{{< latest-version >}}**, making the most recent release branch [`{{< release-branch >}}`](https://github.com/kubernetes/website/tree/{{< release-branch >}}).
## Getting started
In order to add a new localization of the Kubernetes documentation, you'll need to make a few modifications to the site's [configuration](#configuration) and [directory structure](#new-directory), and then you can get to work [translating documents](#translating-documents)!
Localizations must meet some requirements for workflow (*how* to localize) and output (*what* to localize).
To get started, clone the website repo and `cd` into it:
To add a new localization of the Kubernetes documentation, you'll need to update the website by modifying the [site configuration](#modify-the-site-configuration) and [directory structure](#add-a-new-localization-directory). Then you can start [translating documents](#translating-documents)!
Let Kubernetes SIG Docs know you're interested in creating a localization! Join the [SIG Docs Slack channel](https://kubernetes.slack.com/messages/C1J0BPD2M/). We're happy to help you get started and answer any questions you have.
All localization teams must be self-sustaining with their own resources. We're happy to host your work, but we can't translate it for you.
### Fork and clone the repo
First, [create your own fork](https://help.github.com/articles/fork-a-repo/) of the [kubernetes/website](https://github.com/kubernetes/website).
Then, clone the website repo and `cd` into it:
```shell
git clone https://github.com/kubernetes/website
cd website
git checkout {{< release-branch >}}
```
## Configuration
{{< note >}}
Contributors to `k/website` must [create a fork](https://kubernetes.io/docs/contribute/start/#improve-existing-content) from which to open pull requests. For localizations, we ask additionally that:
We'll walk you through the configuration process using the German language (language code `de`) as an example.
1. Team approvers open development branches directly from https://github.com/kubernetes/website.
2. Localization contributors work from forks, with branches based on the current development branch.
There's currently no translation for German, but you're welcome to create one using the instructions here.
This is because localization projects are collaborative efforts on long-running branches, similar to the development branches for the Kubernetes release cycle. For information about localization pull requests, see ["branching strategy"](#branching-strategy).
{{< /note >}}
The Kubernetes website's configuration is in the [`config.toml`](https://github.com/kubernetes/website/tree/master/config.toml) file. You need to add a configuration block for the new language to that file, under the existing `[languages]` block. The German block, for example, looks like this:
### Find your two-letter language code
Consult the [ISO 639-1 standard](https://www.loc.gov/standards/iso639-2/php/code_list.php) for your localization's two-letter country code. For example, the two-letter code for German is `de`.
{{< note >}}
These instructions use the [ISO 639-1](https://www.loc.gov/standards/iso639-2/php/code_list.php) language code for German (`de`) as an example.
There's currently no Kubernetes localization for German, but you're welcome to create one!
{{< /note >}}
### Modify the site configuration
The Kubernetes website uses Hugo as its web framework. The website's Hugo configuration resides in the [`config.toml`](https://github.com/kubernetes/website/tree/master/config.toml) file. To support a new localization, you'll need to modify `config.toml`.
Add a configuration block for the new language to `config.toml`, under the existing `[languages]` block. The German block, for example, looks like:
```toml
[languages.de]
@@ -68,74 +79,128 @@ contentDir = "content/de"
weight = 3
```
When assigning a `weight` parameter, see which of the current languages has the highest weight and add 1 to that value.
When assigning a `weight` parameter for your block, find the language block with the highest weight and add 1 to that value.
Now add a language-specific subdirectory to the [`content`](https://github.com/kubernetes/website/tree/master/content) folder. The two-letter code for German is `de`, so add a `content/de` directory:
For more information about Hugo's multilingual support, see "[Multilingual Mode](https://gohugo.io/content-management/multilingual/)".
### Add a new localization directory
Add a language-specific subdirectory to the [`content`](https://github.com/kubernetes/website/tree/master/content) folder in the repository. For example, the two-letter code for German is `de`:
```shell
mkdir content/de
```
### Add a localized README
To guide other localization contributors, add a new [`README-**.md`](https://help.github.com/articles/about-readmes/) to the top level of k/website, where `**` is the two-letter language code. For example, a German README file would be `README-de.md`.
Provide guidance to localization contributors in the localized `README-**.md` file. Include the same information contained in `README.md` as well as:
- A point of contact for the localization project
- Any information specific to the localization
After you create the localized README, add a link to the file from the main English file, [`README.md`] and include contact information in English. You can provide a GitHub ID, email address, [Slack channel](https://slack.com/), or other method of contact.
## Translating documents
We understand that localizing *all* of the Kubernetes documentation would be an enormous task. We're okay with localizations smarting small and expanding over time.
Localizing *all* of the Kubernetes documentation is an enormous task. It's okay to start small and expand over time.
As an initial requirement, all localizations must include the following documentation at a minimum:
At a minimum, all localizations must include:
Description | URLs
-----|-----
Home | [All heading and subheading URLs](https://kubernetes.io/docs/home/)
Setup | [All heading and subheading URLs](https://kubernetes.io/docs/setup/)
Tutorials | [Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/), [Hello Minikube](https://kubernetes.io/docs/tutorials/stateless-application/hello-minikube/)
Site strings | [All site strings in a new localized TOML file](https://github.com/kubernetes/website/tree/master/i18n)
Translated documents should have the same URL endpoint as the English docs (substituting the subdirectory of the `content` folder). To translate the [Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) doc into German, for example, create the proper subfolder under the `content/de` folder and copy the English doc:
Translated documents must reside in their own `content/**/` subdirectory, but otherwise follow the same URL path as the English source. For example, to prepare the [Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) tutorial for translation into German, create a subfolder under the `content/de/` folder and copy the English source:
```shell
mkdir -p content/de/docs/tutorials
cp content/en/docs/tutorials/kubernetes-basics.md content/de/docs/tutorials/kubernetes-basics.md
```
For an example of a localization-related [pull request](../create-pull-request), [this pull request](https://github.com/kubernetes/website/pull/10471) to the [Kubernetes website repo](https://github.com/kubernetes/website) added Korean localization to the Kubernetes docs.
### Source Files
Localizations must use English files from the most recent release as their source. The most recent version is **{{< latest-version >}}**.
To find source files for the most recent release:
1. Navigate to the Kubernetes website repository at https://github.com/kubernetes/website.
2. Select the `release-1.X` branch for the most recent version.
The latest version is **{{< latest-version >}}**, so the most recent release branch is [`{{< release-branch >}}`](https://github.com/kubernetes/website/tree/{{< release-branch >}}).
### Site strings in i18n/
Localizations must include the contents of [`i18n/en.toml`](https://github.com/kubernetes/website/blob/master/i18n/en.toml) in a new language-specific file. Using German as an example: `i18n/de.toml`.
Add a new localization file to `i18n/`. For example, with German (`de`):
```shell
cp i18n/en.toml i18n/de.toml
```
Then translate the value of each string:
```TOML
[docs_label_i_am]
other = "ICH BIN..."
```
Localizing site strings lets you customize site-wide text and features: for example, the legal copyright text in the footer on each page.
## Project logistics
### Contact with project chairs
### Contact the SIG Docs chairs
When starting a new localization effort, you should get in touch with one of the chairs of the Kubernetes [SIG Docs](https://github.com/kubernetes/community/tree/master/sig-docs) organization. The current chairs are listed [here](https://github.com/kubernetes/community/tree/master/sig-docs#chairs).
### Project information
Teams working on localization efforts must provide a single point of contact, including the name and contact information of a person who can respond to or redirect questions or concerns, listed in the translation repository's main [`README`](https://help.github.com/articles/about-readmes/). You can provide an email address, email list, [Slack channel](https://slack.com/), or some other method of contact.
Contact one of the chairs of the Kubernetes [SIG Docs](https://github.com/kubernetes/community/tree/master/sig-docs#chairs) chairs when you start a new localization.
### Maintainers
Each localization repository must select its own maintainers. Maintainers can be from a single organization or multiple organizations.
Each localization repository must provide its own maintainers. Maintainers can be from a single organization or multiple organizations. Whenever possible, localization pull requests should be approved by a reviewer from a different organization than the translator.
In addition, all l10n work must be self-sustaining with the team's own resources.
A localization must provide a minimum of two maintainers. (It's not possible to review and approve one's own work.)
Wherever possible, every localized page must be approved by a reviewer from a different company than the translator.
### Branching strategy
### GitHub project
Because localization projects are highly collaborative efforts, we encourage teams to work from a shared development branch.
Each Kubernetes localization repository must track its overall progress with a [GitHub project](https://help.github.com/articles/creating-a-project-board/).
To collaborate on a development branch:
Projects must include at least these columns:
1. A team member opens a development branch, usually by opening a new pull request against a source branch on https://github.com/kubernetes/website.
- To Do
- In Progress
- Done
We recommend the following branch naming scheme:
{{< note >}}
**Note**: For an example GitHub project, see the [Chinese localization project](https://github.com/kubernetes/kubernetes-docs-zh/projects/1).
{{< /note >}}
`dev-<source version>-<language code>.<team milestone>`
### Repository structure
For example, an approver on a German localization team opens the development branch `dev-1.12-de.1` directly against the k/website repository, based on the source branch for Kubernetes v1.12.
Each l10n repository must have branches for the different Kubernetes documentation release versions, matching the branches in the main [kubernetes/website](https://github.com/kubernetes/website) documentation repository. For example, the kubernetes/website `release-1.10` branch (https://github.com/kubernetes/website/tree/release-1.10) has a corresponding branch in the kubernetes/kubernetes-docs-zh repository (https://github.com/kubernetes/kubernetes-docs-zh/tree/release-1.10). These version branches keep track of the differences in the documentation between Kubernetes versions.
2. Individual contributors open feature branches based on the development branch.
For example, a German contributor opens a pull request with changes to `kubernetes:dev-1.12-de.1` from `username:local-branch-name`.
3. Approvers review and merge feature branches into the development branch.
4. Periodically, an approver merges the development branch to its source branch.
Repeat steps 1-4 as needed until the localization is complete. For example, subsequent German development branches would be: `dev-1.12-de.2`, `dev-1.12-de.3`, etc.
Teams must merge localized content into the same release branch from which the content was sourced. For example, a development branch sourced from {{< release-branch >}} must be based on {{< release-branch >}}.
An approver must maintain a development branch by keeping it current with its source branch and resolving merge conflicts. The longer a development branch stays open, the more maintenance it typically requires. Consider periodically merging development branches and opening new ones, rather than maintaining one extremely long-running development branch.
While only approvers can merge pull requests, anyone can open a pull request for a new development branch. No special permissions are required.
For more information about working from forks or directly from the repository, see ["fork and clone the repo"](#fork-and-clone-the-repo).
### Upstream contributions
Upstream contributions are welcome and encouraged!
For the sake of efficiency, limit upstream contributions to a single pull request per week, containing a single [squashed commit](https://github.com/todotxt/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit).
SIG Docs welcomes upstream contributions and corrections to the English source! Open a [pull request](https://kubernetes.io/docs/contribute/start/#improve-existing-content) (from a fork) with any updates.
{{% /capture %}}
@@ -143,7 +208,7 @@ For the sake of efficiency, limit upstream contributions to a single pull reques
Once a l10n meets requirements for workflow and minimum output, SIG docs will:
- Work with the localization team to implement language selection on the website.
- Publicize availability through [Cloud Native Computing Foundation](https://www.cncf.io/) (CNCF) channels.
- Enable language selection on the website
- Publicize the localization's availability through [Cloud Native Computing Foundation](https://www.cncf.io/) (CNCF) channels, including the [Kubernetes blog](https://kubernetes.io/blog/).
{{% /capture %}}
+2 -2
View File
@@ -114,7 +114,7 @@ in mind:
For instance, "Fix the security docs" is not an actionable issue, but "Add
details to the 'Restricting network access' topic" might be.
- If the issue relates to another issue or pull request, you can refer to it
either by its full URL or by the the issue or pull request number prefixed
either by its full URL or by the issue or pull request number prefixed
with a `#` character. For instance, `Introduced by #987654`.
- Be respectful and avoid venting. For instance, "The docs about X suck" is not
helpful or actionable feedback. The
@@ -179,7 +179,7 @@ to base your work on. Use these guidelines to make the decision:
- Use `master` for fixing problems in content that is already published, or
making improvements to content that already exists.
- Use a release branch (such as `release-1.12`) to document upcoming features
- Use a release branch (such as `dev-{{< release-branch >}}` for the {{< release-branch >}} release) to document upcoming features
or changes for an upcoming release that is not yet published.
- Use a feature branch that has been agreed upon by SIG Docs to collaborate on
big improvements or changes to the existing documentation, including content
@@ -56,11 +56,11 @@ leads to an awkward construction.
Use angle brackets for placeholders. Tell the reader what a placeholder
represents.
1. Display information about a pod:
1. Display information about a Pod:
kubectl describe pod <pod-name>
where `<pod-name>` is the name of one of your pods.
where `<pod-name>` is the name of one of your Pods.
### Use bold for user interface elements
@@ -138,7 +138,7 @@ For field values of type string or integer, use normal style without quotation m
### Separate commands from output
Verify that the pod is running on your chosen node:
Verify that the Pod is running on your chosen node:
kubectl get pods --output=wide
@@ -149,7 +149,7 @@ The output is similar to this:
### Versioning Kubernetes examples
Code examples and configuration examples that include version information should be consistent with the accompanying text.
Code examples and configuration examples that include version information should be consistent with the accompanying text.
If the information is version specific, the Kubernetes version needs to be defined in the `prerequisites` section of the [Task template](/docs/contribute/style/page-templates/#task-template) or the [Tutorial template] (/docs/contribute/style/page-templates/#tutorial-template). Once the page is saved, the `prerequisites` section is shown as **Before you begin**.
@@ -194,7 +194,7 @@ Hugo [Shortcodes](https://gohugo.io/content-management/shortcodes) help create d
1. Surround the text with an opening and closing shortcode.
2. Use the following syntax to apply a style:
```
{{</* note */>}}
**Note:** The prefix you use is the same text you use in the tag.
@@ -213,7 +213,7 @@ The output is:
Use {{</* note */>}} to highlight a tip or a piece of information that may be helpful to know.
For example:
```
{{</* note */>}}
**Note:** You can _still_ use Markdown inside these callouts.
@@ -387,7 +387,7 @@ whether they're part of the "we" you're describing.
<tr><th>Do</th><th>Don't</th></tr>
<tr><td>Version 1.4 includes ...</td><td>In version 1.4, we have added ...</td></tr>
<tr><td>Kubernetes provides a new feature for ...</td><td>We provide a new feature ...</td></tr>
<tr><td>This page teaches you how to use pods.</td><td>In this page, we are going to learn about pods.</td></tr>
<tr><td>This page teaches you how to use Pods.</td><td>In this page, we are going to learn about Pods.</td></tr>
</table>
### Avoid jargon and idioms
@@ -41,7 +41,7 @@ juju deploy etcd new-etcd
The above code snippet will deploy a single unit of etcd, as 'new-etcd'
```
juju run-action etcd/0 restore target=/mnt/etcd-backups
juju run-action new-etcd/0 restore target=/mnt/etcd-backups
```
Once the restore action has completed, evaluate the cluster health. If the unit
@@ -18,7 +18,8 @@ sudo snap install conjure-up --classic
sudo usermod -a -G lxd $(whoami)
```
Note: If conjure-up asks you to "Setup an ipv6 subnet" with LXD, answer NO. ipv6 with Juju/LXD is currently unsupported.
Note: If conjure-up asks you to "Setup an IPv6 subnet" with LXD, answer NO. IPv6 with Juju/LXD is currently unsupported.
If you already have a bridge configured, e.g. `lxdbr0`, [disable IPv6 on the bridge](https://docs.conjure-up.io/stable/en/troubleshoot#common-problems), otherwise you won't be able to choose it.
{{% /capture %}}
{{% capture steps %}}
+2 -1
View File
@@ -20,6 +20,7 @@ This section of the Kubernetes documentation contains references.
* [Kubernetes API Overview](/docs/reference/using-api/api-overview/) - Overview of the API for Kubernetes.
* Kubernetes API Versions
* [1.12](/docs/reference/generated/kubernetes-api/v1.12/)
* [1.11](/docs/reference/generated/kubernetes-api/v1.11/)
* [1.10](https://v1-10.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/)
* [1.9](https://v1-9.docs.kubernetes.io/docs/api-reference/v1.9/)
@@ -39,7 +40,7 @@ client libraries:
* [kubectl](/docs/user-guide/kubectl-overview) - Main CLI tool for running commands and managing Kubernetes clusters.
* [JSONPath](/docs/user-guide/jsonpath/) - Syntax guide for using [JSONPath expressions](http://goessner.net/articles/JsonPath/) with kubectl.
* [kubeadm](/docs/admin/kubeadm/) - CLI tool to easily provision a secure Kubernetes cluster.
* [kubeadm](/docs/admin/kubeadm/) - CLI tool to easily provision a secure Kubernetes cluster.
* [kubefed](/docs/admin/kubefed/) - CLI tool to help you administrate your federated clusters.
## Config Reference
@@ -16,12 +16,12 @@ Attribute-based access control (ABAC) defines an access control paradigm whereby
{{% capture body %}}
## Policy File Format
For mode `ABAC`, also specify `--authorization-policy-file=SOME_FILENAME`.
To enable `ABAC` mode, specify `--authorization-policy-file=SOME_FILENAME` and `--authorization-mode=ABAC` on startup.
The file format is [one JSON object per line](http://jsonlines.org/). There
should be no enclosing list or map, just one map per line.
Each line is a "policy object". A policy object is a map with the following
Each line is a "policy object", where each such object is a map with the following
properties:
- Versioning properties:
@@ -104,12 +104,12 @@ up the verbosity:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
```
2. Kubelet can read any pods:
2. The Kubelet can read any pods:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}
```
3. Kubelet can read and write events:
3. The Kubelet can read and write events:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
@@ -130,22 +130,20 @@ up the verbosity:
## A quick note on service accounts
A service account automatically generates a user. The user's name is generated
according to the naming convention:
Every service account has a corresponding ABAC username, and that service account's user name is generated according to the naming convention:
```shell
system:serviceaccount:<namespace>:<serviceaccountname>
```
Creating a new namespace also causes a new service account to be created, of
this form:
Creating a new namespace leads to the creation of a new service account in the following format:
```shell
system:serviceaccount:<namespace>:default
```
For example, if you wanted to grant the default service account in the
kube-system full privilege to the API, you would add this line to your policy
file:
For example, if you wanted to grant the default service account (in the `kube-system` namespace) full
privilege to the API using ABAC, you would add this line to your policy file:
```json
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
@@ -62,7 +62,7 @@ For example, the following command line enables the `NamespaceLifecycle` and the
admission control plugins:
```shell
kube-apiserver --enable-admission-plugins=NamespaceLifecyle,LimitRanger ...
kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger ...
```
{{< note >}}
@@ -408,6 +408,10 @@ file format. Within the file, `clusters` refers to the remote service and
`users` refers to the API server webhook. An example would be:
```yaml
# Kubernetes API version
apiVersion: v1
# kind of the API object
kind: Config
# clusters refers to the remote service.
clusters:
- name: name-of-remote-authn-service
@@ -29,6 +29,10 @@ file format. Within the file "users" refers to the API Server webhook and
A configuration example which uses HTTPS client auth:
```yaml
# Kubernetes API version
apiVersion: v1
# kind of the API object
kind: Config
# clusters refers to the remote service.
clusters:
- name: name-of-remote-authz-service
@@ -1,3 +1,8 @@
---
title: federation-apiserver
notitle: true
---
## federation-apiserver
@@ -145,4 +150,4 @@ VolumeScheduling=true|false (ALPHA - default=false)
--watch-cache-sizes strings List of watch cache sizes for every resource (pods, nodes, etc.), comma separated. The individual override format: resource[.group]#size, where resource is lowercase plural (no version), group is optional, and size is a number. It takes effect when watch-cache is enabled. Some resources (replicationcontrollers, endpoints, nodes, pods, services, apiservices.apiregistration.k8s.io) have system defaults set by heuristics, others default to default-watch-cache-size
```
###### Auto generated by spf13/cobra on 24-Sep-2018
###### Auto generated by spf13/cobra on 24-Sep-2018
@@ -1,3 +1,8 @@
---
title: federation-controller-manager
notitle: true
---
## federation-controller-manager
@@ -51,4 +56,4 @@ federation-controller-manager [flags]
--zone-name string Zone name, like example.com.
```
###### Auto generated by spf13/cobra on 24-Sep-2018
###### Auto generated by spf13/cobra on 24-Sep-2018
@@ -132,7 +132,7 @@ kubelet [flags]
<td colspan="2">--bootstrap-checkpoint-path string</td>
</tr>
<tr>
<td></td><td style="line-height: 130%; word-wrap: break-word;"><Warning: Alpha feature> Path to to the directory where the checkpoints are stored</td>
<td></td><td style="line-height: 130%; word-wrap: break-word;"><Warning: Alpha feature> Path to the directory where the checkpoints are stored</td>
</tr>
<tr>
@@ -1451,7 +1451,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<div class="sect2">
<h3 id="_v1beta1_httpingressrulevalue">v1beta1.HTTPIngressRuleValue</h3>
<div class="paragraph">
<p>HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: <a href="http://&lt;host&gt;/&lt;path&gt;?&lt;searchpart&gt;">http://&lt;host&gt;/&lt;path&gt;?&lt;searchpart&gt;</a> &#8594; backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last <em>/</em> and before the first <em>?</em> or <em>#</em>.</p>
<p>HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: <a href="http://&lt;host&gt;/&lt;path&gt;?&lt;searchpart&gt;">http://&lt;host&gt;/&lt;path&gt;?&lt;searchpart&gt;</a> &#8594; backend where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last <em>/</em> and before the first <em>?</em> or <em>#</em>.</p>
</div>
<table class="tableblock frame-all grid-all" style="width:100%; ">
<colgroup>
@@ -2350,7 +2350,7 @@ When an object is created, the system will populate this list with the current s
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">loadBalancerIP</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Only applies to Service Type: LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
@@ -4,15 +4,14 @@ id: container-env-variables
date: 2018-04-12
full_link: /docs/concepts/containers/container-environment-variables.md
short_description: >
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 Pod.
aka:
tags:
- 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 Pod.
<!--more-->
Container environment variables provide information that is required by the running containerized applications along with information about important resources to the [Containers] {{< glossary_tooltip text="Containers" term_id="container" >}}. For example, file system, information about the container itself and other cluster resources such as service endpoints, etc.
<!--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.
@@ -1,3 +1,4 @@
<<<<<<< HEAD
---
title: Quantity
id: quantity
@@ -28,3 +29,37 @@ intentionally lowercase), `M` (mega), `G` (giga), `T` (terra), `P` (peta),
The accepted binary (power-of-2) units are `Ki` (kibi), `Mi` (mebi), `Gi` (gibi),
`Ti` (tebi), `Pi` (pebi), `Ei` (exbi).
||||||| merged common ancestors
=======
---
title: Quantity
id: quantity
date: 2018-08-07
full_link:
short_description: >
A whole-number representation of small or large numbers using SI suffixes.
aka:
tags:
- core-object
---
A whole-number representation of small or large numbers using SI suffixes.
<!--more-->
Quantities are representations of small or large numbers using a compact,
whole-number notation with SI suffixes. Fractional numbers are represented
using milli units, while large numbers can be represented using kilo,
mega, or giga units.
For instance, the number `1.5` is represented as `1500m`, while the number `1000`
can be represented as `1k`, and `1000000` as `1M`. You can also specify
binary-notation suffixes; the number 2048 can be written as `2Ki`.
The accepted decimal (power-of-10) units are `m` (milli), `k` (kilo,
intentionally lowercase), `M` (mega), `G` (giga), `T` (terra), `P` (peta),
`E` (exa).
The accepted binary (power-of-2) units are `Ki` (kibi), `Mi` (mebi), `Gi` (gibi),
`Ti` (tebi), `Pi` (pebi), `Ei` (exbi).
>>>>>>> master
@@ -23,7 +23,7 @@ Join the [kubernetes-announce](https://groups.google.com/forum/#!forum/kubernete
Were extremely grateful for security researchers and users that report vulnerabilities to the Kubernetes Open Source Community. All reports are thoroughly investigated by a set of community volunteers.
To make a report, please email the private [kubernetes-security@googlegroups.com](mailto:kubernetes-security@googlegroups.com) list with the security details and the details expected for [all Kubernetes bug reports](https://git.k8s.io/kubernetes/.github/ISSUE_TEMPLATE.md).
To make a report, please email the private [security@kubernetes.io](mailto:security@kubernetes.io) list with the security details and the details expected for [all Kubernetes bug reports](https://git.k8s.io/kubernetes/.github/ISSUE_TEMPLATE.md).
You may encrypt your email to this list using the GPG keys of the [Product Security Team members](https://git.k8s.io/sig-release/security-release-process-documentation/security-release-process.md#product-security-team-pst). Encryption using GPG is NOT required to make a disclosure.
@@ -321,4 +321,6 @@ Verbosity | Description
* Also [kubectl Usage Conventions](/docs/reference/kubectl/conventions/) to understand how to use it in reusable scripts.
* See more community [kubectl cheatsheets](https://github.com/dennyzhang/cheatsheet-kubernetes-A4).
{{% /capture %}}
+42 -43
View File
@@ -9,7 +9,7 @@ kubectl controls the Kubernetes cluster manager
### Synopsis
kubectl controls the Kubernetes cluster manager.
kubectl controls the Kubernetes cluster manager.
Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/
@@ -249,45 +249,44 @@ kubectl [flags]
### SEE ALSO
* [kubectl alpha](kubectl_alpha.md) - Commands for features in alpha
* [kubectl annotate](kubectl_annotate.md) - Update the annotations on a resource
* [kubectl api-resources](kubectl_api-resources.md) - Print the supported API resources on the server
* [kubectl api-versions](kubectl_api-versions.md) - Print the supported API versions on the server, in the form of "group/version"
* [kubectl apply](kubectl_apply.md) - Apply a configuration to a resource by filename or stdin
* [kubectl attach](kubectl_attach.md) - Attach to a running container
* [kubectl auth](kubectl_auth.md) - Inspect authorization
* [kubectl autoscale](kubectl_autoscale.md) - Auto-scale a Deployment, ReplicaSet, or ReplicationController
* [kubectl certificate](kubectl_certificate.md) - Modify certificate resources.
* [kubectl cluster-info](kubectl_cluster-info.md) - Display cluster info
* [kubectl completion](kubectl_completion.md) - Output shell completion code for the specified shell (bash or zsh)
* [kubectl config](kubectl_config.md) - Modify kubeconfig files
* [kubectl convert](kubectl_convert.md) - Convert config files between different API versions
* [kubectl cordon](kubectl_cordon.md) - Mark node as unschedulable
* [kubectl cp](kubectl_cp.md) - Copy files and directories to and from containers.
* [kubectl create](kubectl_create.md) - Create a resource from a file or from stdin.
* [kubectl delete](kubectl_delete.md) - Delete resources by filenames, stdin, resources and names, or by resources and label selector
* [kubectl describe](kubectl_describe.md) - Show details of a specific resource or group of resources
* [kubectl drain](kubectl_drain.md) - Drain node in preparation for maintenance
* [kubectl edit](kubectl_edit.md) - Edit a resource on the server
* [kubectl exec](kubectl_exec.md) - Execute a command in a container
* [kubectl explain](kubectl_explain.md) - Documentation of resources
* [kubectl expose](kubectl_expose.md) - Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service
* [kubectl get](kubectl_get.md) - Display one or many resources
* [kubectl label](kubectl_label.md) - Update the labels on a resource
* [kubectl logs](kubectl_logs.md) - Print the logs for a container in a pod
* [kubectl options](kubectl_options.md) - Print the list of flags inherited by all commands
* [kubectl patch](kubectl_patch.md) - Update field(s) of a resource using strategic merge patch
* [kubectl plugin](kubectl_plugin.md) - Provides utilities for interacting with plugins.
* [kubectl port-forward](kubectl_port-forward.md) - Forward one or more local ports to a pod
* [kubectl proxy](kubectl_proxy.md) - Run a proxy to the Kubernetes API server
* [kubectl replace](kubectl_replace.md) - Replace a resource by filename or stdin
* [kubectl rollout](kubectl_rollout.md) - Manage the rollout of a resource
* [kubectl run](kubectl_run.md) - Run a particular image on the cluster
* [kubectl scale](kubectl_scale.md) - Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job
* [kubectl set](kubectl_set.md) - Set specific features on objects
* [kubectl taint](kubectl_taint.md) - Update the taints on one or more nodes
* [kubectl top](kubectl_top.md) - Display Resource (CPU/Memory/Storage) usage.
* [kubectl uncordon](kubectl_uncordon.md) - Mark node as schedulable
* [kubectl version](kubectl_version.md) - Print the client and server version information
* [kubectl wait](kubectl_wait.md) - Experimental: Wait for a specific condition on one or many resources.
* [kubectl alpha](/docs/reference/generated/kubectl/kubectl-commands#alpha) - Commands for features in alpha
* [kubectl annotate](/docs/reference/generated/kubectl/kubectl-commands#annotate) - Update the annotations on a resource
* [kubectl api-resources](/docs/reference/generated/kubectl/kubectl-commands#api-resources) - Print the supported API resources on the server
* [kubectl api-versions](/docs/reference/generated/kubectl/kubectl-commands#api-versions) - Print the supported API versions on the server, in the form of "group/version"
* [kubectl apply](/docs/reference/generated/kubectl/kubectl-commands#apply) - Apply a configuration to a resource by filename or stdin
* [kubectl attach](/docs/reference/generated/kubectl/kubectl-commands#attach) - Attach to a running container
* [kubectl auth](/docs/reference/generated/kubectl/kubectl-commands#auth) - Inspect authorization
* [kubectl autoscale](/docs/reference/generated/kubectl/kubectl-commands#autoscale) - Auto-scale a Deployment, ReplicaSet, or ReplicationController
* [kubectl certificate](/docs/reference/generated/kubectl/kubectl-commands#certificate) - Modify certificate resources.
* [kubectl cluster-info](/docs/reference/generated/kubectl/kubectl-commands#cluster-info) - Display cluster info
* [kubectl completion](/docs/reference/generated/kubectl/kubectl-commands#completion) - Output shell completion code for the specified shell (bash or zsh)
* [kubectl config](/docs/reference/generated/kubectl/kubectl-commands#config) - Modify kubeconfig files
* [kubectl convert](/docs/reference/generated/kubectl/kubectl-commands#convert) - Convert config files between different API versions
* [kubectl cordon](/docs/reference/generated/kubectl/kubectl-commands#cordon) - Mark node as unschedulable
* [kubectl cp](/docs/reference/generated/kubectl/kubectl-commands#cp) - Copy files and directories to and from containers.
* [kubectl create](/docs/reference/generated/kubectl/kubectl-commands#create) - Create a resource from a file or from stdin.
* [kubectl delete](/docs/reference/generated/kubectl/kubectl-commands#delete) - Delete resources by filenames, stdin, resources and names, or by resources and label selector
* [kubectl describe](/docs/reference/generated/kubectl/kubectl-commands#describe) - Show details of a specific resource or group of resources
* [kubectl drain](/docs/reference/generated/kubectl/kubectl-commands#drain) - Drain node in preparation for maintenance
* [kubectl edit](/docs/reference/generated/kubectl/kubectl-commands#edit) - Edit a resource on the server
* [kubectl exec](/docs/reference/generated/kubectl/kubectl-commands#exec) - Execute a command in a container
* [kubectl explain](/docs/reference/generated/kubectl/kubectl-commands#explain) - Documentation of resources
* [kubectl expose](/docs/reference/generated/kubectl/kubectl-commands#expose) - Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service
* [kubectl get](/docs/reference/generated/kubectl/kubectl-commands#get) - Display one or many resources
* [kubectl label](/docs/reference/generated/kubectl/kubectl-commands#label) - Update the labels on a resource
* [kubectl logs](/docs/reference/generated/kubectl/kubectl-commands#logs) - Print the logs for a container in a pod
* [kubectl options](/docs/reference/generated/kubectl/kubectl-commands#options) - Print the list of flags inherited by all commands
* [kubectl patch](/docs/reference/generated/kubectl/kubectl-commands#patch) - Update field(s) of a resource using strategic merge patch
* [kubectl plugin](/docs/reference/generated/kubectl/kubectl-commands#plugin) - Provides utilities for interacting with plugins.
* [kubectl port-forward](/docs/reference/generated/kubectl/kubectl-commands#port-forward) - Forward one or more local ports to a pod
* [kubectl proxy](/docs/reference/generated/kubectl/kubectl-commands#proxy) - Run a proxy to the Kubernetes API server
* [kubectl replace](/docs/reference/generated/kubectl/kubectl-commands#replace) - Replace a resource by filename or stdin
* [kubectl rollout](/docs/reference/generated/kubectl/kubectl-commands#rollout) - Manage the rollout of a resource
* [kubectl run](/docs/reference/generated/kubectl/kubectl-commands#run) - Run a particular image on the cluster
* [kubectl scale](/docs/reference/generated/kubectl/kubectl-commands#scale) - Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job
* [kubectl set](/docs/reference/generated/kubectl/kubectl-commands#set) - Set specific features on objects
* [kubectl taint](/docs/reference/generated/kubectl/kubectl-commands#taint) - Update the taints on one or more nodes
* [kubectl top](/docs/reference/generated/kubectl/kubectl-commands#top) - Display Resource (CPU/Memory/Storage) usage.
* [kubectl uncordon](/docs/reference/generated/kubectl/kubectl-commands#uncordon) - Mark node as schedulable
* [kubectl version](/docs/reference/generated/kubectl/kubectl-commands#version) - Print the client and server version information
* [kubectl wait](/docs/reference/generated/kubectl/kubectl-commands#wait) - Experimental: Wait for a specific condition on one or many resources.
@@ -1,5 +1,5 @@
---
title: v1.11
title: v1.12
---
[Kubernetes API v1.11](/docs/reference/generated/kubernetes-api/v1.11/)
[Kubernetes API v1.12](/docs/reference/generated/kubernetes-api/v1.12/)
@@ -16,7 +16,7 @@ provide a file - a subset of the standard kubeconfig file. This file
can be a local file or downloaded via an HTTPS URL. The forms are
kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443,
kubeadm join --discovery-file path/to/file.conf, or kubeadm join
--discovery-file https://url/file.conf. Only one form can be used. If
--discovery-file `https://url/file.conf`. Only one form can be used. If
the discovery information is loaded from a URL, HTTPS must be used.
Also, in that case the host installed CA bundle is used to verify
the connection.
@@ -86,7 +86,7 @@ In any case the user can skip specific preflight checks (or eventually all prefl
- [error] if not Kernel 3.10+ or 4+ with specific KernelSpec
- [error] if required cgroups subsystem aren't in set up
- if using docker:
- [warning/error] if Docker service does not exists, if it is disabled, if it is not active.
- [warning/error] if Docker service does not exist, if it is disabled, if it is not active.
- [error] if Docker endpoint does not exist or does not work
- [warning] if docker version >17.03
- If using other cri engine:
@@ -106,8 +106,8 @@ It is **recommended** that you migrate your old `v1alpha2` configuration to `v1a
the [kubeadm config migrate](/docs/reference/setup-tools/kubeadm/kubeadm-config/) command,
because `v1alpha2` will be removed in Kubernetes 1.13.
For more details on each field in the configuration you can navigate to our
[API reference pages.] (https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm)
For more details on each field in the `v1alpha3` configuration you can navigate to our
[API reference pages.] (https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3)
### Adding kube-proxy parameters {#kube-proxy}
@@ -226,7 +226,7 @@ Other CRI-based runtimes include:
- [frakti](https://github.com/kubernetes/frakti)
- [rkt](https://github.com/kubernetes-incubator/rktlet)
Refer to the [CRI installation instructions](/docs/setup/cri.md) for more information.
Refer to the [CRI installation instructions](/docs/setup/cri) for more information.
After you have successfully installed `kubeadm` and `kubelet`, execute
these two additional steps:
@@ -411,4 +411,4 @@ provisioned). For details, see the [kubeadm join](/docs/reference/setup-tools/ku
* [kubeadm join](/docs/reference/setup-tools/kubeadm/kubeadm-join/) to bootstrap a Kubernetes worker node and join it to the cluster
* [kubeadm upgrade](/docs/reference/setup-tools/kubeadm/kubeadm-upgrade/) to upgrade a Kubernetes cluster to a newer version
* [kubeadm reset](/docs/reference/setup-tools/kubeadm/kubeadm-reset/) to revert any changes made to this host by `kubeadm init` or `kubeadm join`
{{% /capture %}}
{{% /capture %}}
@@ -19,14 +19,10 @@ cluster if necessary.
Every upgrade process might be a bit different, so we've documented each minor upgrade process individually.
For more version-specific upgrade guidance, see the following resources:
* [1.7.x to 1.7.y upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-8/)
* [1.7 to 1.8 upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-8/)
* [1.8.x to 1.8.y upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-8/)
* [1.8.x to 1.9.x upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-9/)
* [1.9.x to 1.9.y upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-9/)
* [1.9.x to 1.9.y HA cluster upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-ha/)
* [1.10 to 1.11 upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-11/)
* [1.11 to 1.12 upgrades](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-12/)
_For older versions, please refer to older documentation sets on the Kubernetes website._
In Kubernetes v1.11.0 and later, you can use `kubeadm upgrade diff` to see the changes that would be
applied to static pod manifests.
@@ -50,4 +46,4 @@ applied to static pod manifests.
{{% capture whatsnext %}}
* [kubeadm config](/docs/reference/setup-tools/kubeadm/kubeadm-config/) if you initialized your cluster using kubeadm v1.7.x or lower, to configure your cluster for `kubeadm upgrade`
{{% /capture %}}
{{% /capture %}}
@@ -164,7 +164,7 @@ For example:
1. List all of the pods on a cluster in the Table format.
GET /api/v1/pods
Accept: application/json;as=Table;v=meta.k8s.io;g=v1beta1
Accept: application/json;as=Table;g=meta.k8s.io;v=v1beta1
---
200 OK
Content-Type: application/json
@@ -205,7 +205,7 @@ For API resource types that do not have a custom Table definition on the server,
Table responses are available beginning in version 1.10 of the kube-apiserver. As such, not all API resource types will support a Table response, specifically when using a client against older clusters. Clients that must work against all resource types, or can potentially deal with older clusters, should specify multiple content types in their `Accept` header to support fallback to non-Tabular JSON:
```
Accept: application/json;as=Table;v=meta.k8s.io;g=v1beta1, application/json
Accept: application/json;as=Table;g=meta.k8s.io;v=v1beta1, application/json
```
+1 -1
View File
@@ -75,7 +75,7 @@ You should pick a on-prem turnkey cloud solution if you:
* Want to deploy clusters on your private cloud network
* Have a dedicated SRE team
* Have the the resources to host and monitor your clusters
* Have the resources to host and monitor your clusters
Pick an [on-prem turnkey cloud solution](/docs/setup/pick-right-solution/#on-premises-turnkey-cloud-solutions).
@@ -30,7 +30,7 @@ scope.
You can install _kubeadm_ very easily on operating systems that support
installing deb or rpm packages. The responsible SIG for kubeadm,
[SIG Cluster Lifecycle](https://github.com/kubernetes/community/tree/master/sig-cluster-lifecycle), provides these packages pre-built for you,
but you may also on other OSes.
but you may also build them from source for other OSes.
### kubeadm Maturity
@@ -317,14 +317,10 @@ Set `/proc/sys/net/bridge/bridge-nf-call-iptables` to `1` by running `sysctl net
to pass bridged IPv4 traffic to iptables' chains. This is a requirement for some CNI plugins to work, for more information
please see [here](https://kubernetes.io/docs/concepts/cluster-administration/network-plugins/#network-plugin-requirements).
```shell
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
```
Note that `flannel` works on `amd64`, `arm`, `arm64` and `ppc64le`, but until `flannel v0.11.0` is released
you need to use the following manifest that supports all the architectures:
Note that `flannel` works on `amd64`, `arm`, `arm64` and `ppc64le`.
```shell
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/c5d10c8/Documentation/kube-flannel.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
```
For more information about `flannel`, see [the CoreOS flannel repository on GitHub
@@ -306,6 +306,7 @@ done
```sh
kubeadm alpha phase kubeconfig all --config kubeadm-config.yaml
kubeadm alpha phase controlplane all --config kubeadm-config.yaml
kubeadm alpha phase kubelet config annotate-cri --config kubeadm-config.yaml
kubeadm alpha phase mark-master --config kubeadm-config.yaml
```
@@ -393,6 +394,7 @@ done
```sh
kubeadm alpha phase kubeconfig all --config kubeadm-config.yaml
kubeadm alpha phase controlplane all --config kubeadm-config.yaml
kubeadm alpha phase kubelet config annotate-cri --config kubeadm-config.yaml
kubeadm alpha phase mark-master --config kubeadm-config.yaml
```
@@ -23,11 +23,11 @@ see the [Using kubeadm to Create a Cluster](/docs/setup/independent/create-clust
- HypriotOS v1.0.1+
- Container Linux (tested with 1800.6.0)
* 2 GB or more of RAM per machine (any less will leave little room for your apps)
* 2 CPUs or more
* 2 CPUs or more
* Full network connectivity between all machines in the cluster (public or private network is fine)
* Unique hostname, MAC address, and product_uuid for every node. See [here](#verify-the-mac-address-and-product-uuid-are-unique-for-every-node) for more details.
* Certain ports are open on your machines. See [here](#check-required-ports) for more details.
* Swap disabled. You **MUST** disable swap in order for the kubelet to work properly.
* Swap disabled. You **MUST** disable swap in order for the kubelet to work properly.
{{% /capture %}}
@@ -87,12 +87,12 @@ The container runtime used by default is Docker, which is enabled through the bu
Other CRI-based runtimes include:
- [cri-containerd](https://github.com/containerd/cri-containerd)
- [containerd](https://github.com/containerd/cri) (CRI plugin built into containerd)
- [cri-o](https://github.com/kubernetes-incubator/cri-o)
- [frakti](https://github.com/kubernetes/frakti)
- [rkt](https://github.com/kubernetes-incubator/rktlet)
Refer to the [CRI installation instructions](/docs/setup/cri.md) for more information.
Refer to the [CRI installation instructions](/docs/setup/cri) for more information.
## Installing kubeadm, kubelet and kubectl
@@ -105,10 +105,10 @@ You will install these packages on all of your machines:
* `kubectl`: the command line util to talk to your cluster.
kubeadm **will not** install or manage `kubelet` or `kubectl` for you, so you will
need to ensure they match the version of the Kubernetes control panel you want
kubeadm **will not** install or manage `kubelet` or `kubectl` for you, so you will
need to ensure they match the version of the Kubernetes control panel you want
kubeadm to install for you. If you do not, there is a risk of a version skew occurring that
can lead to unexpected, buggy behaviour. However, _one_ minor version skew between the
can lead to unexpected, buggy behaviour. However, _one_ minor version skew between the
kubelet and the control plane is supported, but the kubelet version may never exceed the API
server version. For example, kubelets running 1.7.0 should be fully compatible with a 1.8.0 API server,
but not vice versa.
@@ -119,7 +119,7 @@ This is because kubeadm and Kubernetes require
[special attention to upgrade](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-11/).
{{</ warning >}}
For more information on version skews, please read our
For more information on version skews, please read our
[version skew policy](/docs/setup/independent/create-cluster-kubeadm/#version-skew-policy).
{{< tabs name="k8s_install" >}}
@@ -128,7 +128,7 @@ For more information on version skews, please read our
apt-get update && apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
@@ -147,18 +147,24 @@ repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
EOF
# Set SELinux in permissive mode (effectively disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable kubelet && systemctl start kubelet
```
**Note:**
- Disabling SELinux by running `setenforce 0` is required to allow containers to access the host filesystem, which is required by pod networks for example.
- 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.
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
@@ -244,8 +250,4 @@ If you are running into difficulties with kubeadm, please consult our [troublesh
* [Using kubeadm to Create a Cluster](/docs/setup/independent/create-cluster-kubeadm/)
{{% /capture %}}
{{% /capture %}}
+32 -16
View File
@@ -64,11 +64,34 @@ NAME READY STATUS RESTARTS AGE
hello-minikube-3383150820-vctvh 1/1 Running 0 13s
# We can see that the pod is now Running and we will now be able to curl it:
$ curl $(minikube service hello-minikube --url)
CLIENT VALUES:
client_address=192.168.99.1
command=GET
real path=/
...
Hostname: hello-minikube-7c77b68cff-8wdzq
Pod Information:
-no pod information available-
Server values:
server_version=nginx: 1.13.3 - lua: 10008
Request Information:
client_address=172.17.0.1
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://192.168.99.100:8080/
Request Headers:
accept=*/*
host=192.168.99.100:30674
user-agent=curl/7.47.0
Request Body:
-no body in request-
$ kubectl delete services hello-minikube
service "hello-minikube" deleted
$ kubectl delete deployment hello-minikube
@@ -195,13 +218,6 @@ To switch back to this context later, run this command: `kubectl config use-cont
#### Specifying the Kubernetes version
Minikube supports running multiple different versions of Kubernetes. You can
access a list of all available versions via
```
minikube get-k8s-versions
```
You can specify the specific version of Kubernetes for Minikube to use by
adding the `--kubernetes-version` string to the `minikube start` command. For
example, to run version `v1.7.3`, you would run the following:
@@ -223,12 +239,12 @@ configuration struct and `value` is the value to set.
Valid keys can be found by examining the documentation for the Kubernetes `componentconfigs` for each component.
Here is the documentation for each supported configuration:
* [kubelet](https://godoc.org/k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig#KubeletConfiguration)
* [kubelet](https://godoc.org/k8s.io/kubernetes/pkg/kubelet/apis/config#KubeletConfiguration)
* [apiserver](https://godoc.org/k8s.io/kubernetes/cmd/kube-apiserver/app/options#ServerRunOptions)
* [proxy](https://godoc.org/k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig#KubeProxyConfiguration)
* [controller-manager](https://godoc.org/k8s.io/kubernetes/pkg/apis/componentconfig#KubeControllerManagerConfiguration)
* [proxy](https://godoc.org/k8s.io/kubernetes/pkg/proxy/apis/config#KubeProxyConfiguration)
* [controller-manager](https://godoc.org/k8s.io/kubernetes/pkg/controller/apis/config#KubeControllerManagerConfiguration)
* [etcd](https://godoc.org/github.com/coreos/etcd/etcdserver#ServerConfig)
* [scheduler](https://godoc.org/k8s.io/kubernetes/pkg/apis/componentconfig#KubeSchedulerConfiguration)
* [scheduler](https://godoc.org/k8s.io/kubernetes/pkg/scheduler/apis/config#KubeSchedulerConfiguration)
#### Examples
+14 -14
View File
@@ -126,10 +126,10 @@ and `failure-domain.beta.kubernetes.io/zone` for the zone:
NAME STATUS ROLES AGE VERSION LABELS
kubernetes-master Ready,SchedulingDisabled <none> 6m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-87j9 Ready <none> 6m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready <none> 6m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready <none> 6m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
kubernetes-master Ready,SchedulingDisabled <none> 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-87j9 Ready <none> 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready <none> 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready <none> 6m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
```
### Add more nodes in a second zone
@@ -161,13 +161,13 @@ in us-central1-b:
> kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
kubernetes-master Ready,SchedulingDisabled <none> 16m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-281d Ready <none> 2m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-87j9 Ready <none> 16m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready <none> 16m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready <none> 17m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
kubernetes-minion-pp2f Ready <none> 2m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f
kubernetes-minion-wf8i Ready <none> 2m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i
kubernetes-master Ready,SchedulingDisabled <none> 16m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-281d Ready <none> 2m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-87j9 Ready <none> 16m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready <none> 16m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready <none> 17m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
kubernetes-minion-pp2f Ready <none> 2m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f
kubernetes-minion-wf8i Ready <none> 2m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i
```
### Volume affinity
@@ -288,9 +288,9 @@ Node: kubernetes-minion-olsh/10.240.0.11
> kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels
NAME STATUS ROLES AGE VERSION LABELS
kubernetes-minion-9vlv Ready <none> 34m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-281d Ready <none> 20m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-olsh Ready <none> 3m v1.11.1 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh
kubernetes-minion-9vlv Ready <none> 34m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-281d Ready <none> 20m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-olsh Ready <none> 3m v1.12.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh
```
@@ -0,0 +1,95 @@
---
title: Installing Kubernetes with Digital Rebar Provision (DRP) via KRIB
krib-version: 2.4
author: Rob Hirschfeld (zehicle)
---
## Overview
This guide helps to install a Kubernetes cluster hosted on bare metal with [Digital Rebar Provision](https://github.com/digitalrebar/provision) using only its Content packages and *kubeadm*.
Digital Rebar Provision (DRP) is an integrated Golang DHCP, bare metal provisioning (PXE/iPXE) and workflow automation platform. While [DRP can be used to invoke](https://provision.readthedocs.io/en/tip/doc/integrations/ansible.html) [kubespray](../kubespray), it also offers a self-contained Kubernetes installation known as [KRIB (Kubernetes Rebar Integrated Bootstrap)](https://github.com/digitalrebar/provision-content/tree/master/krib).
{{< note >}}
**Note:** KRIB is not a _stand-alone_ installer: Digital Rebar templates drive a standard *[kubeadm](/docs/admin/kubeadm/)* configuration that manages the Kubernetes installation with the [Digital Rebar cluster pattern](https://provision.readthedocs.io/en/tip/doc/arch/cluster.html#rs-cluster-pattern) to elect leaders _without external supervision_.
{{< /note >}}
KRIB features:
* zero-touch, self-configuring cluster without pre-configuration or inventory
* very fast, no-ssh required automation
* bare metal, on-premises focused platform
* highly available cluster options (including splitting etcd from the controllers)
* dynamic generation of a TLS infrastructure
* composable attributes and automatic detection of hardware by profile
* options for persistent, immutable and image-based deployments
* support for Ubuntu 18.04, CentOS/RHEL 7 and others
## Creating a cluster
Review [Digital Rebar documentation](https://https://provision.readthedocs.io/en/tip/README.html) for details about installing the platform.
The Digital Rebar Provision Golang binary should be installed on a Linux-like system with 16 GB of RAM or larger (Packet.net Tiny and Rasberry Pi are also acceptable).
### (1/5) Discover servers
Following the [Digital Rebar installation](https://provision.readthedocs.io/en/tip/doc/quickstart.html), allow one or more servers to boot through the _Sledgehammer_ discovery process to register with the API. This will automatically install the Digital Rebar runner and to allow for next steps.
### (2/5) Install KRIB Content and Certificate Plugin
Upload the KRIB Content bundle (or build from [source](https://github.com/digitalrebar/provision-content/tree/master/krib)) and the Cert Plugin for your DRP platform (e.g.: [amd64 Linux v2.4.0](https://s3-us-west-2.amazonaws.com/rebar-catalog/certs/v2.4.0-0-02301d35f9f664d6c81d904c92a9c81d3fd41d2c/amd64/linux/certs)). Both are freely available via the [RackN UX](https://portal.rackn.io).
### (3/5) Start your cluster deployment
{{< note >}}
**Note:** KRIB documentation is dynamically generated from the source and will be more up to date than this guide.
{{< /note >}}
Following the [KRIB documentation](https://provision.readthedocs.io/en/tip/doc/content-packages/krib.html), create a Profile for your cluster and assign your target servers into the cluster Profile. The Profile must set `krib\cluster-name` and `etcd\cluster-name` Params to be the name of the Profile. Cluster configuration choices can be made by adding additional Params to the Profile; however, safe defaults are provided for all Params.
Once all target servers are assigned to the cluster Profile, start a KRIB installation Workflow by assigning one of the included Workflows to all cluster servers. For example, selecting `krib-live-cluster` will perform an immutable deployment into the Sledgehammer discovery operating system. You may use one of the pre-created read-only Workflows or choose to build your own custom variation.
For basic installs, no further action is required. Advanced users may choose to assign the controllers, etcd servers or other configuration values in the relevant Params.
### (4/5) Monitor your cluster deployment
Digital Rebar Provision provides detailed logging and live updates during the installation process. Workflow events are available via a websocket connection or monitoring the Jobs list.
During the installation, KRIB writes cluster configuration data back into the cluster Profile.
### (5/5) Access your cluster
The cluster is available for access via *kubectl* once the `krib/cluster-admin-conf` Param has been set. This Param contains the `kubeconfig` information necessary to access the cluster.
For example, if you named the cluster Profile `krib` then the following commands would allow you to connect to the installed cluster from your local terminal.
::
drpcli profiles get krib params krib/cluster-admin-conf > admin.conf
export KUBECONFIG=admin.conf
kubectl get nodes
The installation continues after the `krib/cluster-admin-conf` is set to install the Kubernetes UI and Helm. You may interact with the cluster as soon as the `admin.conf` file is available.
## Cluster operations
KRIB provides additional Workflows to manage your cluster. Please see the [KRIB documentation](https://provision.readthedocs.io/en/tip/doc/content-packages/krib.html) for an updated list of advanced cluster operations.
### Scale your cluster
You can add servers into your cluster by adding the cluster Profile to the server and running the appropriate Workflow.
### Cleanup your cluster (for developers)
You can reset your cluster and wipe out all configuration and TLS certificates using the the `krib-reset-cluster` Workflow on any of the servers in the cluster.
{{< caution >}}
**Caution:** When running the reset Workflow, be sure not to accidentally target your production cluster!
{{< /caution >}}
## Feedback
* Slack Channel: [#community](https://rackn.slack.com/messages/community/)
* [GitHub Issues](https://github.com/digital/provision/issues)
@@ -34,6 +34,8 @@ a Kubernetes cluster from scratch.
* [Minikube](/docs/setup/minikube/) is the recommended method for creating a local, single-node Kubernetes cluster for development and testing. Setup is completely automated and doesn't require a cloud provider account.
* [microk8s](https://microk8s.io/) provides a single command installation of the latest Kubernetes release on a local machine for development and testing. Setup is quick, fast (~30 sec) and supports many plugins including Istio with a single command.
* [IBM Cloud Private-CE (Community Edition)](https://github.com/IBM/deploy-ibm-cloud-private) can use VirtualBox on your machine to deploy Kubernetes to one or more VMs for development and test scenarios. Scales to full multi-node cluster.
* [IBM Cloud Private-CE (Community Edition) on Linux Containers](https://github.com/HSBawa/icp-ce-on-linux-containers) is a Terraform/Packer/BASH based Infrastructure as Code (IaC) scripts to create a seven node (1 Boot, 1 Master, 1 Management, 1 Proxy and 3 Workers) LXD cluster on Linux Host.
@@ -95,6 +97,7 @@ few commands. These solutions are actively developed and have active community s
* [Madcore.Ai](https://madcore.ai/)
* [Oracle Container Engine for K8s](https://docs.us-phoenix-1.oraclecloud.com/Content/ContEng/Concepts/contengprerequisites.htm)
* [Pivotal Container Service](https://pivotal.io/platform/pivotal-container-service)
* [Giant Swarm](https://giantswarm.io)
* [Rancher 2.0](https://rancher.com/docs/rancher/v2.x/en/)
* [Stackpoint.io](/docs/setup/turnkey/stackpoint/)
* [Tectonic by CoreOS](https://coreos.com/tectonic)
@@ -105,11 +108,13 @@ few commands.
* [Agile Stacks](https://www.agilestacks.com/products/kubernetes)
* [APPUiO](https://appuio.ch)
* [GKE On-Prem | Google Cloud](https://cloud.google.com/gke-on-prem/)
* [IBM Cloud Private](https://www.ibm.com/cloud-computing/products/ibm-cloud-private/)
* [Kontena Pharos](https://kontena.io/pharos/)
* [Kubermatic](https://www.loodse.com)
* [Kublr](https://kublr.com/)
* [Pivotal Container Service](https://pivotal.io/platform/pivotal-container-service)
* [Giant Swarm](https://giantswarm.io)
* [Rancher 2.0](https://rancher.com/docs/rancher/v2.x/en/)
* [SUSE CaaS Platform](https://www.suse.com/products/caas-platform)
* [SUSE Cloud Application Platform](https://www.suse.com/products/cloud-application-platform/)
@@ -157,6 +162,7 @@ These solutions are combinations of cloud providers and operating systems not co
### Bare Metal
* [CoreOS](/docs/setup/custom-cloud/coreos/)
* [Digital Rebar](/docs/setup/on-premises-metal/krib/)
* [Fedora (Single Node)](/docs/getting-started-guides/fedora/fedora_manual_config/)
* [Fedora (Multi Node)](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/)
* [Kubernetes on Ubuntu](/docs/getting-started-guides/ubuntu/)
@@ -218,6 +224,7 @@ any | [Gardener Cluster-Operator](https://kubernetes.io/blog/20
Alibaba Cloud Container Service For Kubernetes | ROS | CentOS | flannel/Terway | [docs](https://www.aliyun.com/product/containerservice) | Commercial
Agile Stacks | Terraform | CoreOS | multi-support | [docs](https://www.agilestacks.com/products/kubernetes) | Commercial
IBM Cloud Kubernetes Service | | Ubuntu | calico | [docs](https://console.bluemix.net/docs/containers/container_index.html) | Commercial
Digital Rebar | kubeadm | any | metal | [docs](/docs/setup/on-premises-metal/krib/) | Community ([@digitalrebar](https://github.com/digitalrebar))
{{< note >}}

Some files were not shown because too many files have changed in this diff Show More