diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 401f52479c..235973f654 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,10 +1,11 @@
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-> For 1.8 Features: set Milestone to `1.8` and Base Branch to `release-1.8`
+> For 1.9 Features: set Milestone to `1.9` and Base Branch to `release-1.9`
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
->
> NOTE: Please check the “Allow edits from maintainers” box (see image below) to
> [allow reviewers to fix problems](https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/) on your patch and speed up the review process.
>
> Please delete this note before submitting the pull request.
+>
+> NOTE: After opening the PR, please *un-check and re-check* the "Allow edits from maintainers" box. This is a temporary workaround to address a known issue with GitHub.

diff --git a/.travis.yml b/.travis.yml
index f7f8311130..9e19abba15 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,15 +6,15 @@ go:
install:
- export PATH=$GOPATH/bin:$PATH
- mkdir -p $HOME/gopath/src/k8s.io
-- mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/kubernetes.github.io
+- mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/website
# (1) Fetch dependencies for us to run the tests in test/examples_test.go
-- go get -t -v k8s.io/kubernetes.github.io/test
+- go get -t -v k8s.io/website/test
# Simplified deduplication of dependencies.
- cp -L -R $GOPATH/src/k8s.io/kubernetes/vendor/ $GOPATH/src/
- rm -r $GOPATH/src/k8s.io/kubernetes/vendor/
script:
-- go test -v k8s.io/kubernetes.github.io/test
+- go test -v k8s.io/website/test
- ./verify-docs-format.sh
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ed6b348338..13c07eb905 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,7 +9,7 @@ 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 Sarah Novotny [sarahnovotny@google.com](mailto:sarahnovotny@google.com) and/or Dan Kohn [dan@linuxfoundation.org](mailto:dan@linuxfoundation.org).
### Documentation and Site Decisions
@@ -17,7 +17,7 @@ The [Kubernetes SIG Docs Discussion Group](https://groups.google.com/forum/#!for
### Style Guides and Templates
-Before submitting a pull request to create new content, please review the [Kubernetes.io style guide](http://kubernetes.io/docs/home/contribute/style-guide/) and follow the [instructions for using page templates](http://kubernetes.io/docs/home/contribute/page-templates/).
+Before submitting a pull request to create new content, please review the [Kubernetes.io style guide](http://kubernetes.io/docs/home/contribute/style-guide/) and follow the [instructions for using page templates](http://kubernetes.io/docs/home/contribute/page-templates/).
## Contributing to Documentation
@@ -26,10 +26,10 @@ Before submitting a pull request to create new content, please review the [Kuber
Kubernetes.io uses github issues to track documentation issues and requests. If you see a documentation issue, submit an issue using the following steps:
-1. Check the [kubernetes.io issues list](https://github.com/kubernetes/kubernetes.github.io/issues) as you might find out the issue is a duplicate.
-2. Use the [included template for every new issue](https://github.com/kubernetes/kubernetes.github.io/issues/new). When you create a bug report, include as many details as possible and include suggested fixes to the issue.
+1. Check the [kubernetes.io issues list](https://github.com/kubernetes/website/issues) as you might find out the issue is a duplicate.
+2. Use the [included template for every new issue](https://github.com/kubernetes/website/issues/new). When you create a bug report, include as many details as possible and include suggested fixes to the issue.
-Note that code issues should be filed against the main kubernetes repository, while documentation issues should go in the kubernetes.io repository.
+Note that code issues should be filed against the main kubernetes repository, while documentation issues should go in the kubernetes.io repository.
### Submitting Documentation Pull Requests
diff --git a/Gemfile b/Gemfile
index 3828560a73..409583e72a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,4 +1,53 @@
source "https://rubygems.org"
-gem "github-pages", group: :jekyll_plugins
+# gem "github-pages", group: :jekyll_plugins
+
+gem "jekyll", "3.6.0"
+
+group :github_pages_compatible do
+ gem "json", "~> 1.7", ">= 1.7.7"
+ gem "coffee-script", "~> 2.4"
+ gem "coffee-script-source", "~> 1.12"
+ gem "ethon", "~> 0.10"
+ gem "execjs", "~> 2.7"
+ gem "minima", "~> 2.0"
+ gem "terminal-table", "~> 1.4"
+ gem "unicode-display_width", "~> 1.1"
+end
+
+group :jekyll_plugins do
+ gem "jekyll-feed", "~> 0.6"
+ gem "jekyll-sitemap"
+ gem "jekyll-gist"
+ gem "jekyll-paginate", "1.1.0"
+ gem "jekyll-seo-tag"
+ gem "jekyll-avatar", "~> 0.4"
+ gem "jekyll-coffeescript", "~> 1.0"
+ gem "jekyll-default-layout", "~> 0.1"
+ gem "jekyll-github-metadata", "~> 2.2"
+ gem "jekyll-optional-front-matter", "~> 0.1"
+ gem "jekyll-readme-index", "0.0.3"
+ gem "jekyll-redirect-from", "~> 0.11"
+ gem "jekyll-relative-links", "~> 0.2"
+ gem "jekyll-swiss", "~> 0.4"
+ gem "jekyll-theme-architect", "0.0.3"
+ gem "jekyll-theme-cayman", "0.0.3"
+ gem "jekyll-theme-dinky", "0.0.3"
+ gem "jekyll-theme-hacker", "0.0.3"
+ gem "jekyll-theme-leap-day", "0.0.3"
+ gem "jekyll-theme-merlot", "0.0.3"
+ gem "jekyll-theme-midnight", "0.0.3"
+ gem "jekyll-theme-minimal", "0.0.3"
+ gem "jekyll-theme-modernist", "0.0.3"
+ gem "jekyll-theme-primer", "~> 0.1"
+ gem "jekyll-theme-slate", "0.0.3"
+ gem "jekyll-theme-tactile", "0.0.3"
+ gem "jekyll-theme-time-machine", "0.0.3"
+ gem "jekyll-titles-from-headings", "~> 0.1"
+end
+
gem "jekyll-include-cache", "~> 0.1"
+
+gem "kramdown", "~> 1.11"
+gem "rouge", "~> 2.0"
+gem "pry"
diff --git a/Gemfile.lock b/Gemfile.lock
index 09d52b8d72..577f4e69b2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,123 +1,61 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (4.2.7)
- i18n (~> 0.7)
- json (~> 1.7, >= 1.7.7)
- minitest (~> 5.1)
- thread_safe (~> 0.3, >= 0.3.4)
- tzinfo (~> 1.1)
- addressable (2.5.0)
- public_suffix (~> 2.0, >= 2.0.2)
+ addressable (2.5.2)
+ public_suffix (>= 2.0.2, < 4.0)
+ coderay (1.1.2)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
colorator (1.1.0)
- ethon (0.10.1)
+ ethon (0.11.0)
ffi (>= 1.3.0)
execjs (2.7.0)
- faraday (0.10.0)
+ faraday (0.13.1)
multipart-post (>= 1.2, < 3)
- ffi (1.9.14)
+ ffi (1.9.18)
forwardable-extended (2.6.0)
- gemoji (2.1.0)
- github-pages (112)
- activesupport (= 4.2.7)
- github-pages-health-check (= 1.3.0)
- jekyll (= 3.3.1)
- jekyll-avatar (= 0.4.2)
- jekyll-coffeescript (= 1.0.1)
- jekyll-default-layout (= 0.1.4)
- jekyll-feed (= 0.8.0)
- jekyll-gist (= 1.4.0)
- jekyll-github-metadata (= 2.2.0)
- jekyll-mentions (= 1.2.0)
- jekyll-optional-front-matter (= 0.1.2)
- jekyll-paginate (= 1.1.0)
- jekyll-readme-index (= 0.0.3)
- jekyll-redirect-from (= 0.11.0)
- jekyll-relative-links (= 0.2.1)
- jekyll-sass-converter (= 1.3.0)
- jekyll-seo-tag (= 2.1.0)
- jekyll-sitemap (= 0.12.0)
- jekyll-swiss (= 0.4.0)
- jekyll-theme-architect (= 0.0.3)
- jekyll-theme-cayman (= 0.0.3)
- jekyll-theme-dinky (= 0.0.3)
- jekyll-theme-hacker (= 0.0.3)
- jekyll-theme-leap-day (= 0.0.3)
- jekyll-theme-merlot (= 0.0.3)
- jekyll-theme-midnight (= 0.0.3)
- jekyll-theme-minimal (= 0.0.3)
- jekyll-theme-modernist (= 0.0.3)
- jekyll-theme-primer (= 0.1.5)
- jekyll-theme-slate (= 0.0.3)
- jekyll-theme-tactile (= 0.0.3)
- jekyll-theme-time-machine (= 0.0.3)
- jekyll-titles-from-headings (= 0.1.3)
- jemoji (= 0.7.0)
- kramdown (= 1.11.1)
- liquid (= 3.0.6)
- listen (= 3.0.6)
- mercenary (~> 0.3)
- minima (= 2.0.0)
- rouge (= 1.11.1)
- terminal-table (~> 1.4)
- github-pages-health-check (1.3.0)
- addressable (~> 2.3)
- net-dns (~> 0.8)
- octokit (~> 4.0)
- public_suffix (~> 2.0)
- typhoeus (~> 0.7)
- html-pipeline (2.4.2)
- activesupport (>= 2)
- nokogiri (>= 1.4)
- i18n (0.7.0)
- jekyll (3.3.1)
+ jekyll (3.6.0)
addressable (~> 2.4)
colorator (~> 1.0)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 1.1)
- kramdown (~> 1.3)
- liquid (~> 3.0)
+ kramdown (~> 1.14)
+ liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
- rouge (~> 1.7)
+ rouge (>= 1.7, < 3)
safe_yaml (~> 1.0)
- jekyll-avatar (0.4.2)
+ jekyll-avatar (0.5.0)
jekyll (~> 3.0)
jekyll-coffeescript (1.0.1)
coffee-script (~> 2.2)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
- jekyll-feed (0.8.0)
+ jekyll-feed (0.9.2)
jekyll (~> 3.3)
- jekyll-gist (1.4.0)
+ jekyll-gist (1.4.1)
octokit (~> 4.2)
- jekyll-github-metadata (2.2.0)
+ jekyll-github-metadata (2.9.3)
jekyll (~> 3.1)
octokit (~> 4.0, != 4.4.0)
jekyll-include-cache (0.1.0)
jekyll (~> 3.3)
- jekyll-mentions (1.2.0)
- activesupport (~> 4.0)
- html-pipeline (~> 2.3)
- jekyll (~> 3.0)
- jekyll-optional-front-matter (0.1.2)
+ jekyll-optional-front-matter (0.3.0)
jekyll (~> 3.0)
jekyll-paginate (1.1.0)
jekyll-readme-index (0.0.3)
jekyll (~> 3.0)
- jekyll-redirect-from (0.11.0)
- jekyll (>= 2.0)
- jekyll-relative-links (0.2.1)
+ jekyll-redirect-from (0.12.1)
jekyll (~> 3.3)
- jekyll-sass-converter (1.3.0)
- sass (~> 3.2)
- jekyll-seo-tag (2.1.0)
+ jekyll-relative-links (0.5.1)
jekyll (~> 3.3)
- jekyll-sitemap (0.12.0)
+ jekyll-sass-converter (1.5.0)
+ sass (~> 3.4)
+ jekyll-seo-tag (2.3.0)
+ jekyll (~> 3.3)
+ jekyll-sitemap (1.1.1)
jekyll (~> 3.3)
jekyll-swiss (0.4.0)
jekyll-theme-architect (0.0.3)
@@ -138,66 +76,101 @@ GEM
jekyll (~> 3.3)
jekyll-theme-modernist (0.0.3)
jekyll (~> 3.3)
- jekyll-theme-primer (0.1.5)
- jekyll (~> 3.3)
+ jekyll-theme-primer (0.5.2)
+ jekyll (~> 3.5)
+ jekyll-github-metadata (~> 2.9)
+ jekyll-seo-tag (~> 2.2)
jekyll-theme-slate (0.0.3)
jekyll (~> 3.3)
jekyll-theme-tactile (0.0.3)
jekyll (~> 3.3)
jekyll-theme-time-machine (0.0.3)
jekyll (~> 3.3)
- jekyll-titles-from-headings (0.1.3)
+ jekyll-titles-from-headings (0.5.0)
jekyll (~> 3.3)
jekyll-watch (1.5.0)
listen (~> 3.0, < 3.1)
- jemoji (0.7.0)
- activesupport (~> 4.0)
- gemoji (~> 2.0)
- html-pipeline (~> 2.2)
- jekyll (>= 3.0)
json (1.8.6)
- kramdown (1.11.1)
- liquid (3.0.6)
- listen (3.0.6)
- rb-fsevent (>= 0.9.3)
- rb-inotify (>= 0.9.7)
+ kramdown (1.15.0)
+ liquid (4.0.0)
+ listen (3.0.8)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
mercenary (0.3.6)
- mini_portile2 (2.1.0)
- minima (2.0.0)
- minitest (5.10.1)
+ method_source (0.9.0)
+ minima (2.1.1)
+ jekyll (~> 3.3)
multipart-post (2.0.0)
- net-dns (0.8.0)
- nokogiri (1.6.8.1)
- mini_portile2 (~> 2.1.0)
- octokit (4.6.2)
+ octokit (4.7.0)
sawyer (~> 0.8.0, >= 0.5.3)
- pathutil (0.14.0)
+ pathutil (0.16.0)
forwardable-extended (~> 2.6)
- public_suffix (2.0.4)
- rb-fsevent (0.9.8)
- rb-inotify (0.9.7)
- ffi (>= 0.5.0)
- rouge (1.11.1)
+ pry (0.11.2)
+ coderay (~> 1.1.0)
+ method_source (~> 0.9.0)
+ public_suffix (3.0.0)
+ rb-fsevent (0.10.2)
+ rb-inotify (0.9.10)
+ ffi (>= 0.5.0, < 2)
+ rouge (2.2.1)
safe_yaml (1.0.4)
- sass (3.4.23)
+ sass (3.5.3)
+ sass-listen (~> 4.0.0)
+ sass-listen (4.0.0)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.8.1)
addressable (>= 2.3.5, < 2.6)
faraday (~> 0.8, < 1.0)
- terminal-table (1.7.3)
- unicode-display_width (~> 1.1.1)
- thread_safe (0.3.5)
- typhoeus (0.8.0)
- ethon (>= 0.8.0)
- tzinfo (1.2.2)
- thread_safe (~> 0.1)
- unicode-display_width (1.1.2)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ unicode-display_width (1.3.0)
PLATFORMS
ruby
DEPENDENCIES
- github-pages
+ coffee-script (~> 2.4)
+ coffee-script-source (~> 1.12)
+ ethon (~> 0.10)
+ execjs (~> 2.7)
+ jekyll (= 3.6.0)
+ jekyll-avatar (~> 0.4)
+ jekyll-coffeescript (~> 1.0)
+ jekyll-default-layout (~> 0.1)
+ jekyll-feed (~> 0.6)
+ jekyll-gist
+ jekyll-github-metadata (~> 2.2)
jekyll-include-cache (~> 0.1)
+ jekyll-optional-front-matter (~> 0.1)
+ jekyll-paginate (= 1.1.0)
+ jekyll-readme-index (= 0.0.3)
+ jekyll-redirect-from (~> 0.11)
+ jekyll-relative-links (~> 0.2)
+ jekyll-seo-tag
+ jekyll-sitemap
+ jekyll-swiss (~> 0.4)
+ jekyll-theme-architect (= 0.0.3)
+ jekyll-theme-cayman (= 0.0.3)
+ jekyll-theme-dinky (= 0.0.3)
+ jekyll-theme-hacker (= 0.0.3)
+ jekyll-theme-leap-day (= 0.0.3)
+ jekyll-theme-merlot (= 0.0.3)
+ jekyll-theme-midnight (= 0.0.3)
+ jekyll-theme-minimal (= 0.0.3)
+ jekyll-theme-modernist (= 0.0.3)
+ jekyll-theme-primer (~> 0.1)
+ jekyll-theme-slate (= 0.0.3)
+ jekyll-theme-tactile (= 0.0.3)
+ jekyll-theme-time-machine (= 0.0.3)
+ jekyll-titles-from-headings (~> 0.1)
+ json (~> 1.7, >= 1.7.7)
+ kramdown (~> 1.11)
+ minima (~> 2.0)
+ pry
+ rouge (~> 2.0)
+ terminal-table (~> 1.4)
+ unicode-display_width (~> 1.1)
BUNDLED WITH
- 1.15.2
+ 1.15.4
diff --git a/OWNERS b/OWNERS
index 64804981da..1e01984e33 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,6 @@
reviewers:
+- a-mccarthy
+- abiogenesis-now
- bradamant3
-- chenopis
- steveperry-53
- zacharysarah
diff --git a/README.md b/README.md
index 280a4ceb40..9eb11944de 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ Welcome! We are very pleased you want to contribute to the Kubernetes documentat
You can click the **Fork** button in the upper-right area of the screen to create a copy of this repository in your GitHub account called a *fork*. Make any changes you want in your fork, and when you are ready to send those changes to us, go to your fork and create a new pull request to let us know about it.
+Once your pull request is created, a Kubernetes reviewer will take responsibility for providing clear, actionable feedback. As the owner of the pull request, **it is your responsibility to modify your pull request to address the feedback that has been provided to you by the Kubernetes reviewer.** Also note that you may end up having more than one Kubernetes reviewer provide you feedback or you may end up getting feedback from a Kubernetes reviewer that is different than the one originally assigned to provide you feedback. Furthermore, in some cases, one of your reviewers might ask for a technical review from a [Kubernetes tech reviewer](https://github.com/kubernetes/website/wiki/Tech-reviewers) when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances.
+
For more information about contributing to the Kubernetes documentation, see:
* [Contributing to the Kubernetes Documentation](http://kubernetes.io/editdocs/)
diff --git a/_config.yml b/_config.yml
index f13463f283..7891f3f36f 100644
--- a/_config.yml
+++ b/_config.yml
@@ -32,7 +32,7 @@ defaults:
version: "v1.7"
githubbranch: "v1.7.6"
docsbranch: "release-1.7"
- url: https://kubernetes-io-v1-7.netlify.com/docs/home/
+ url: https://v1-7.docs.kubernetes.io/docs/home/
- fullversion: "v1.6.8"
version: "v1.6"
githubbranch: "v1.6.8"
@@ -60,7 +60,7 @@ defaults:
permalink: pretty
-gems:
+plugins:
- jekyll-feed
- jekyll-sitemap
- jekyll-seo-tag
diff --git a/_data/canonical-tags.yml b/_data/canonical-tags.yml
deleted file mode 100644
index d5c4bcfdec..0000000000
--- a/_data/canonical-tags.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-- Fundamental
-- API Object
-- Metadata
-- Configuration
-- Security
-- Networking
-- Storage
-- Operation
-- Workload
-- Component
-- API
-- Extension
diff --git a/_data/canonical-tags/architecture.yaml b/_data/canonical-tags/architecture.yaml
new file mode 100644
index 0000000000..369aa36cc0
--- /dev/null
+++ b/_data/canonical-tags/architecture.yaml
@@ -0,0 +1,3 @@
+id: architecture
+name: Architecture
+description: The inner components of Kubernetes.
diff --git a/_data/canonical-tags/community.yaml b/_data/canonical-tags/community.yaml
new file mode 100644
index 0000000000..34a60b5df2
--- /dev/null
+++ b/_data/canonical-tags/community.yaml
@@ -0,0 +1,3 @@
+id: community
+name: Community
+description: Related to Kubernetes open-source development.
diff --git a/_data/canonical-tags/core-object.yaml b/_data/canonical-tags/core-object.yaml
new file mode 100644
index 0000000000..c816013899
--- /dev/null
+++ b/_data/canonical-tags/core-object.yaml
@@ -0,0 +1,3 @@
+id: core-object
+name: Core Object
+description: A resource type that Kubernetes supports by default.
diff --git a/_data/canonical-tags/extension.yaml b/_data/canonical-tags/extension.yaml
new file mode 100644
index 0000000000..6aacd8dac9
--- /dev/null
+++ b/_data/canonical-tags/extension.yaml
@@ -0,0 +1,3 @@
+id: extension
+name: Extension
+description: Supported customizations of Kubernetes.
diff --git a/_data/canonical-tags/fundamental.yaml b/_data/canonical-tags/fundamental.yaml
new file mode 100644
index 0000000000..f9dc8f2398
--- /dev/null
+++ b/_data/canonical-tags/fundamental.yaml
@@ -0,0 +1,3 @@
+id: fundamental
+name: Fundamental
+description: Relevant for a first-time user of Kubernetes.
diff --git a/_data/canonical-tags/networking.yaml b/_data/canonical-tags/networking.yaml
new file mode 100644
index 0000000000..481c02c50a
--- /dev/null
+++ b/_data/canonical-tags/networking.yaml
@@ -0,0 +1,3 @@
+id: networking
+name: Networking
+description: How Kubernetes components talk to each other (and to programs outside the cluster).
diff --git a/_data/canonical-tags/operation.yaml b/_data/canonical-tags/operation.yaml
new file mode 100644
index 0000000000..140be06e0c
--- /dev/null
+++ b/_data/canonical-tags/operation.yaml
@@ -0,0 +1,3 @@
+id: operation
+name: Operation
+description: Starting and maintaining Kubernetes.
diff --git a/_data/canonical-tags/security.yaml b/_data/canonical-tags/security.yaml
new file mode 100644
index 0000000000..4bb7191a6f
--- /dev/null
+++ b/_data/canonical-tags/security.yaml
@@ -0,0 +1,3 @@
+id: security
+name: Security
+description: Keeping Kubernetes applications safe and secure.
diff --git a/_data/canonical-tags/storage.yaml b/_data/canonical-tags/storage.yaml
new file mode 100644
index 0000000000..e98d797b6e
--- /dev/null
+++ b/_data/canonical-tags/storage.yaml
@@ -0,0 +1,3 @@
+id: storage
+name: Storage
+description: How Kubernetes applications handle persistent data.
diff --git a/_data/canonical-tags/tool.yaml b/_data/canonical-tags/tool.yaml
new file mode 100644
index 0000000000..943d1ba4b0
--- /dev/null
+++ b/_data/canonical-tags/tool.yaml
@@ -0,0 +1,3 @@
+id: tool
+name: Tool
+description: Software that makes Kubernetes easier or better to use.
diff --git a/_data/canonical-tags/user-type.yaml b/_data/canonical-tags/user-type.yaml
new file mode 100644
index 0000000000..8f38725720
--- /dev/null
+++ b/_data/canonical-tags/user-type.yaml
@@ -0,0 +1,3 @@
+id: user-type
+name: User Type
+description: Represents a common type of Kubernetes user.
diff --git a/_data/canonical-tags/workload.yaml b/_data/canonical-tags/workload.yaml
new file mode 100644
index 0000000000..4b18a36443
--- /dev/null
+++ b/_data/canonical-tags/workload.yaml
@@ -0,0 +1,3 @@
+id: workload
+name: Workload
+description: Applications running on Kubernetes.
diff --git a/_data/concepts.yml b/_data/concepts.yml
index 964080693d..0a0fc14143 100644
--- a/_data/concepts.yml
+++ b/_data/concepts.yml
@@ -20,11 +20,21 @@ toc:
section:
- docs/concepts/architecture/nodes.md
- docs/concepts/architecture/master-node-communication.md
+ - docs/concepts/architecture/cloud-controller.md
-- title: Extending the Kubernetes API
+- title: Extending Kubernetes
section:
- - docs/concepts/api-extension/custom-resources.md
- - docs/concepts/api-extension/apiserver-aggregation.md
+ - docs/concepts/overview/extending.md
+ - title: Extending the Kubernetes API
+ section:
+ - docs/concepts/api-extension/apiserver-aggregation.md
+ - docs/concepts/api-extension/custom-resources.md
+ - title: Compute, Storage, and Networking Extensions
+ section:
+ - docs/concepts/cluster-administration/network-plugins.md
+ - docs/concepts/cluster-administration/device-plugins.md
+ - docs/concepts/cluster-administration/sysctl-cluster.md
+ - docs/concepts/service-catalog/index.md
- title: Containers
section:
@@ -40,6 +50,7 @@ toc:
- docs/concepts/workloads/pods/pod.md
- docs/concepts/workloads/pods/pod-lifecycle.md
- docs/concepts/workloads/pods/init-containers.md
+ - docs/concepts/workloads/pods/podpreset.md
- docs/concepts/workloads/pods/disruptions.md
- title: Controllers
section:
@@ -75,12 +86,13 @@ toc:
section:
- docs/concepts/storage/volumes.md
- docs/concepts/storage/persistent-volumes.md
- - title: Dynamic Provisioning
- path: http://blog.kubernetes.io/2016/10/dynamic-provisioning-and-storage-in-kubernetes.html
+ - docs/concepts/storage/storage-classes.md
+ - docs/concepts/storage/dynamic-provisioning.md
- title: Cluster Administration
section:
- docs/concepts/cluster-administration/cluster-administration-overview.md
+ - docs/concepts/cluster-administration/certificates.md
- docs/concepts/cluster-administration/cloud-providers.md
- docs/concepts/cluster-administration/manage-deployment.md
- docs/concepts/cluster-administration/networking.md
diff --git a/_data/docs-home.yml b/_data/docs-home.yml
index 7771dbbf33..ee3b471e3d 100644
--- a/_data/docs-home.yml
+++ b/_data/docs-home.yml
@@ -3,8 +3,6 @@ abstract: "Documentation for using and learning about Kubernetes."
toc:
- docs/home/index.md
-- docs/home/index.md
-
- title: Release Notes
path: https://git.k8s.io/kubernetes/CHANGELOG.md
- title: Release Roadmap
@@ -21,3 +19,4 @@ toc:
- docs/home/contribute/page-templates.md
- docs/home/contribute/review-issues.md
- docs/home/contribute/style-guide.md
+ - docs/home/contribute/includes.md
diff --git a/_data/glossary/_example.yml b/_data/glossary/_example.yml
index d939c91f3c..78ef717df2 100644
--- a/_data/glossary/_example.yml
+++ b/_data/glossary/_example.yml
@@ -1,17 +1,27 @@
id: _example
name: Example K8s Term
-formerly:
+full-link: kubernetes.io/docs/link-to-long-dedicated-docs-page
+aka:
- Slang K8s Term
- Misnomer
- Formerly Known as Prince
related:
-- Less Fancy K8s Term
-- Tangential Term
-- Commonly Used With
+- id-of-less-fancy-k8s-term
+- id-of-tangential-term
+- id-of-commonly-used-with-term
tags:
- Some Tag
-short-description: |
- Required. One or two lines that provide a minimum definition. Do not repeat the term. Write about the plural of the term. Prefer fragments. Model after tooltips. End with a period.
-long-description: |
- Optional. Longer additional text to appear after (in conjunction with) short description. Provide where the short description is not sufficient as the intro paragraph to a topic. Write complete but concise sentences.
+short-description: >
+ Required.
+ Markdown allowed (e.g. for cross-linking).
+ One or two lines that provide a minimum definition.
+ Do not repeat the term.
+ Prefer fragments.
+ End with a period.
+long-description: >
+ Optional.
+ Markdown allowed.
+ Longer additional text to appear after (in conjunction with) short description.
+ Provide where the short description is not sufficient as the intro paragraph to a topic.
+ Write complete but concise sentences.
**See /_includes/templates/glossary/README.md for the official style guide.**
diff --git a/_data/glossary/application-architect.yaml b/_data/glossary/application-architect.yaml
new file mode 100644
index 0000000000..387d4443ea
--- /dev/null
+++ b/_data/glossary/application-architect.yaml
@@ -0,0 +1,11 @@
+id: application-architect
+name: Application Architect
+related:
+ - application-developer
+tags:
+ - user-type
+short-description: >
+ A person responsible for the high-level design of an application.
+long-description: >
+ An architect ensures that an app's implementation allows it to interact with its surrounding components in a scalable, maintainable way.
+ Surrounding components include databases, logging infrastructure, and other microservices.
diff --git a/_data/glossary/application-developer.yaml b/_data/glossary/application-developer.yaml
new file mode 100644
index 0000000000..696e53ef6d
--- /dev/null
+++ b/_data/glossary/application-developer.yaml
@@ -0,0 +1,11 @@
+id: application-developer
+name: Application Developer
+related:
+ - application-architect
+tags:
+ - user-type
+short-description: >
+ A person who writes an application that runs in a Kubernetes cluster.
+long-description: >
+ An application developer focuses on one part of an application.
+ The scale of their focus may vary significantly in size.
diff --git a/_data/glossary/approver.yaml b/_data/glossary/approver.yaml
new file mode 100644
index 0000000000..f521314566
--- /dev/null
+++ b/_data/glossary/approver.yaml
@@ -0,0 +1,10 @@
+id: approver
+name: Approver
+tags:
+- community
+short-description: >
+ A person who can review and approve Kubernetes code contributions.
+long-description: >
+ While code review is focused on code quality and correctness, approval is focused on the holistic acceptance of a contribution.
+ Holistic acceptance includes backwards/forwards compatibility, adhering to API and flag conventions, subtle performance and correctness issues, interactions with other parts of the system, and others.
+ Approver status is scoped to a part of the codebase.
diff --git a/_data/glossary/cla.yaml b/_data/glossary/cla.yaml
new file mode 100644
index 0000000000..159cb575d9
--- /dev/null
+++ b/_data/glossary/cla.yaml
@@ -0,0 +1,9 @@
+id: cla
+name: CLA (Contributor License Agreement)
+full-link: https://github.com/kubernetes/community/blob/master/CLA.md
+tags:
+- community
+short-description: >
+ Terms under which a {% glossary_tooltip text="contributor" term_id="contributor" %} grants a license to an open source project for their contributions.
+long-description: >
+ CLAs help resolve legal disputes involving contributed material and intellectual property (IP).
diff --git a/_data/glossary/cluster-architect.yaml b/_data/glossary/cluster-architect.yaml
new file mode 100644
index 0000000000..14b60a0e18
--- /dev/null
+++ b/_data/glossary/cluster-architect.yaml
@@ -0,0 +1,11 @@
+id: cluster-architect
+name: Cluster Architect
+related:
+ - cluster
+ - cluster-operator
+tags:
+ - user-type
+short-description: >
+ A person who designs infrastructure that involves one or more Kubernetes clusters.
+long-description: >
+ Cluster architects are concerned with best practices for distributed systems, for example: high availability and security.
diff --git a/_data/glossary/cluster-operator.yaml b/_data/glossary/cluster-operator.yaml
new file mode 100644
index 0000000000..82eaa42a60
--- /dev/null
+++ b/_data/glossary/cluster-operator.yaml
@@ -0,0 +1,15 @@
+id: cluster-operator
+name: Cluster Operator
+aka:
+ - Cluster Administrator
+related:
+ - cluster
+ - cluster-architect
+tags:
+ - user-type
+short-description: >
+ A person who configures, controls, and monitors clusters.
+long-description: |
+ Their primary responsibility is keeping a cluster up and running, which may involve periodic maintenance activities or upgrades.
+
+ **NOTE:** Cluster operators are different from the [Operator pattern](https://coreos.com/operators) that extends the Kubernetes API.
diff --git a/_data/glossary/cluster.yaml b/_data/glossary/cluster.yaml
new file mode 100644
index 0000000000..a86c1ab696
--- /dev/null
+++ b/_data/glossary/cluster.yaml
@@ -0,0 +1,9 @@
+id: cluster
+name: Cluster
+tags:
+- fundamental
+- operation
+short-description: >
+ A set of machines, called nodes, that run containerized applications managed by Kubernetes.
+long-description: >
+ A cluster has several worker nodes and at least one master node.
diff --git a/_data/glossary/code-contributor.yaml b/_data/glossary/code-contributor.yaml
new file mode 100644
index 0000000000..9fa8fbe82c
--- /dev/null
+++ b/_data/glossary/code-contributor.yaml
@@ -0,0 +1,11 @@
+id: code-contributor
+name: Code Contributor
+aka:
+ - Community Developer
+tags:
+- community
+- user-type
+short-description: >
+ A person who develops and contributes code to the Kubernetes open source codebase.
+long-description: >
+ They are also an active {% glossary_tooltip text="community member" term_id="member" %} who participates in one or more {% glossary_tooltip text="Special Interest Groups (SIGs)" term_id="sig" %}.
diff --git a/_data/glossary/container.yaml b/_data/glossary/container.yaml
new file mode 100644
index 0000000000..b9682d4b23
--- /dev/null
+++ b/_data/glossary/container.yaml
@@ -0,0 +1,10 @@
+id: container
+name: Container
+full-link: /docs/concepts/overview/what-is-kubernetes/#why-containers
+tags:
+- fundamental
+- workload
+short-description: >
+ A lightweight and portable executable image that contains software and all of its dependencies.
+long-description: >
+ Containers decouple applications from underlying host infrastructure to make deployment easier in different cloud or OS environments, and for easier scaling.
diff --git a/_data/glossary/contributor.yaml b/_data/glossary/contributor.yaml
new file mode 100644
index 0000000000..af005aac50
--- /dev/null
+++ b/_data/glossary/contributor.yaml
@@ -0,0 +1,8 @@
+id: contributor
+name: Contributor
+tags:
+- community
+short-description: >
+ Someone who donates code, documentation, or their time to help the Kubernetes project or community.
+long-description: >
+ Contributions include pull requests (PRs), issues, feedback, {% glossary_tooltip text="special interest groups (SIG)" term_id="sig" %} participation, or organizing community events.
diff --git a/_data/glossary/cronjob.yaml b/_data/glossary/cronjob.yaml
new file mode 100644
index 0000000000..5116cf424a
--- /dev/null
+++ b/_data/glossary/cronjob.yaml
@@ -0,0 +1,10 @@
+id: cronjob
+name: CronJob
+full-link: /docs/concepts/workloads/controllers/cron-jobs/
+tags:
+- core-object
+- workload
+short-description: >
+ Manages a [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/) that runs on a periodic schedule.
+long-description: >
+ Similar to a line in a *crontab* file, a Cronjob object specifies a schedule using the [Cron](https://en.wikipedia.org/wiki/Cron) format.
diff --git a/_data/glossary/deployment.yaml b/_data/glossary/deployment.yaml
new file mode 100644
index 0000000000..4a8d04211a
--- /dev/null
+++ b/_data/glossary/deployment.yaml
@@ -0,0 +1,11 @@
+id: deployment
+name: Deployment
+full-link: /docs/concepts/workloads/controllers/deployment/
+tags:
+- fundamental
+- core-object
+- workload
+short-description: >
+ An API object that manages a replicated application.
+long-description: >
+ Each replica is represented by a {% glossary_tooltip term_id="pod" %}, and the Pods are distributed among the nodes of a cluster.
diff --git a/_data/glossary/developer.yaml b/_data/glossary/developer.yaml
new file mode 100644
index 0000000000..38534826ab
--- /dev/null
+++ b/_data/glossary/developer.yaml
@@ -0,0 +1,11 @@
+id: developer
+name: Developer (disambiguation)
+aka:
+ - Kubernetes Developer
+tags:
+- community
+- user-type
+short-description: >
+ May refer to: {% glossary_tooltip text="Application Developer" term_id="application-developer" %}, {% glossary_tooltip text="Code Contributor" term_id="code-contributor" %}, or {% glossary_tooltip text="Platform Developer" term_id="platform-developer" %}.
+long-description: >
+ This overloaded term may have different meanings depending on the context
diff --git a/_data/glossary/downstream.yaml b/_data/glossary/downstream.yaml
new file mode 100644
index 0000000000..dab6d75628
--- /dev/null
+++ b/_data/glossary/downstream.yaml
@@ -0,0 +1,11 @@
+id: downstream
+name: Downstream (disambiguation)
+related:
+- upstream
+tags:
+- community
+short-description: >
+ May refer to: code in the Kubernetes ecosystem that depends upon the core Kubernetes codebase or a forked repo.
+long-description: |
+ * In the **Kubernetes Community**: Conversations often use *downstream* to mean the ecosystem, code, or third-party tools that rely on the core Kubernetes codebase. For example, a new feature in Kubernetes may be adopted by applications *downstream* to improve their functionality.
+ * In **GitHub** or **git**: The convention is to refer to a forked repo as *downstream*, whereas the source repo is considered *upstream*.
diff --git a/_data/glossary/helm-chart.yaml b/_data/glossary/helm-chart.yaml
new file mode 100644
index 0000000000..49d916d1af
--- /dev/null
+++ b/_data/glossary/helm-chart.yaml
@@ -0,0 +1,10 @@
+id: helm-chart
+name: Helm Chart
+full-link: https://github.com/kubernetes/helm/blob/master/docs/charts.md
+tags:
+- tool
+short-description: >
+ A package of pre-configured Kubernetes resources that can be managed with the Helm tool.
+long-description: |
+ Charts provide a reproducible way of creating and sharing Kubernetes applications.
+ A single chart can be used to deploy something simple, like a memcached Pod, or something complex, like a full web app stack with HTTP servers, databases, caches, and so on.
diff --git a/_data/glossary/ingress.yaml b/_data/glossary/ingress.yaml
new file mode 100644
index 0000000000..f06031ee2e
--- /dev/null
+++ b/_data/glossary/ingress.yaml
@@ -0,0 +1,13 @@
+id: ingress
+name: Ingress
+full-link: /docs/concepts/services-networking/ingress/
+aka:
+ - Ingress controller
+tags:
+- networking
+- architecture
+- extension
+short-description: >
+ An API object that manages external access to the services in a cluster, typically HTTP.
+long-description: >
+ Ingress can provide load balancing, SSL termination and name-based virtual hosting.
diff --git a/_data/glossary/istio.yaml b/_data/glossary/istio.yaml
new file mode 100644
index 0000000000..c05bad8e72
--- /dev/null
+++ b/_data/glossary/istio.yaml
@@ -0,0 +1,13 @@
+id: istio
+name: Istio
+full-link: https://istio.io/docs/concepts/what-is-istio/overview.html
+tags:
+- networking
+- architecture
+- extension
+short-description: >
+ An open platform (not Kubernetes-specific) that provides a uniform way to integrate microservices, manage traffic flow, enforce policies, and aggregate telemetry data.
+long-description: >
+ Adding Istio does not require changing application code.
+ It is a layer of infrastructure between a service and the network, which when combined with service deployments, is commonly referred to as a service mesh.
+ Istio's control plane abstracts away the underlying cluster management platform, which may be Kubernetes, Mesosphere, etc.
diff --git a/_data/glossary/kops.yaml b/_data/glossary/kops.yaml
new file mode 100644
index 0000000000..67a40892d1
--- /dev/null
+++ b/_data/glossary/kops.yaml
@@ -0,0 +1,19 @@
+id: kops
+name: Kops
+full-link: /docs/getting-started-guides/kops/
+tags:
+- tool
+- operation
+short-description: >
+ A CLI tool that helps you create, destroy, upgrade and maintain production-grade, highly available, Kubernetes clusters. *NOTE: Officially supports AWS only, with GCE and VMware vSphere in alpha*.
+long-description: |
+ `kops` provisions your cluster with:
+
+ * Fully automated installation
+ * DNS-based cluster identification
+ * Self-healing: everything runs in Auto-Scaling Groups
+ * Limited OS support (Debian preferred, Ubuntu 16.04 supported, early support for CentOS & RHEL)
+ * High availability (HA) support
+ * The ability to directly provision, or generate terraform manifests
+
+ You can also build your own cluster using {% glossary_tooltip term_id="kubeadm" %} as a building block. `kops` builds on the kubeadm work.
diff --git a/_data/glossary/kubeadm.yaml b/_data/glossary/kubeadm.yaml
new file mode 100644
index 0000000000..e70b046f19
--- /dev/null
+++ b/_data/glossary/kubeadm.yaml
@@ -0,0 +1,10 @@
+id: kubeadm
+name: Kubeadm
+full-link: /docs/admin/kubeadm/
+tags:
+- tool
+- operation
+short-description: >
+ A tool for quickly installing Kubernetes and setting up a secure cluster.
+long-description: >
+ You can use kubeadm to install both the control plane and the worker node components.
diff --git a/_data/glossary/kubectl.yaml b/_data/glossary/kubectl.yaml
new file mode 100644
index 0000000000..825749811c
--- /dev/null
+++ b/_data/glossary/kubectl.yaml
@@ -0,0 +1,10 @@
+id: kubectl
+name: Kubectl
+full-link: /docs/user-guide/kubectl-overview/
+tags:
+- tool
+- fundamental
+short-description: >
+ A command line tool for communicating with a {% glossary_tooltip text="Kubernetes API" term_id="kubernetes-api" %} server.
+long-description: >
+ You can use kubectl to create, inspect, update, and delete Kubernetes objects.
diff --git a/_data/glossary/kubernetes-api.yaml b/_data/glossary/kubernetes-api.yaml
new file mode 100644
index 0000000000..773da6e516
--- /dev/null
+++ b/_data/glossary/kubernetes-api.yaml
@@ -0,0 +1,13 @@
+id: kubernetes-api
+name: Kubernetes API
+full-link: /docs/concepts/overview/kubernetes-api/
+tags:
+- fundamental
+- architecture
+short-description: >
+ The application that serves Kubernetes functionality through a RESTful interface and stores the state of the cluster.
+long-description: >
+ Kubernetes resources and "records of intent" are all stored as API objects, and modified via RESTful calls to the API.
+ The API allows configuration to be managed in a declarative way.
+ Users can interact with the Kubernetes API directly, or via tools like `kubectl`.
+ The core Kubernetes API is flexible and can also be extended to support custom resources.
diff --git a/_data/glossary/maintainer.yaml b/_data/glossary/maintainer.yaml
new file mode 100644
index 0000000000..dc97b11544
--- /dev/null
+++ b/_data/glossary/maintainer.yaml
@@ -0,0 +1,8 @@
+id: maintainer
+name: Maintainer
+tags:
+- community
+short-description: >
+ A highly experienced {% glossary_tooltip text="contributor" term_id="contributor" %}, active in multiple areas of Kubernetes, who has cross-area ownership and write access to a project's GitHub repository.
+long-description: >
+ Maintainers work holistically across the project to maintain its health and success and have made substantial contributions, both through code development and broader organizational efforts.
diff --git a/_data/glossary/managed-service.yaml b/_data/glossary/managed-service.yaml
new file mode 100644
index 0000000000..409831141f
--- /dev/null
+++ b/_data/glossary/managed-service.yaml
@@ -0,0 +1,9 @@
+id: managed-service
+name: Managed Service
+tags:
+- extension
+short-description: >
+ A software offering maintained by a third-party provider.
+long-description: >
+ Some examples of Managed Services are AWS EC2, Azure SQL Database, and GCP Pub/Sub, but they can be any software offering that can be used by an application.
+ [Service Catalog](/docs/concepts/service-catalog/) provides a way to list, provision, and bind with Managed Services offered by {% glossary_tooltip text="Service Brokers" term_id="service-broker" %}.
\ No newline at end of file
diff --git a/_data/glossary/member.yaml b/_data/glossary/member.yaml
new file mode 100644
index 0000000000..e78ec6bcce
--- /dev/null
+++ b/_data/glossary/member.yaml
@@ -0,0 +1,10 @@
+id: member
+name: Member
+tags:
+- community
+short-description: >
+ A continuously active {% glossary_tooltip text="contributor" term_id="contributor" %} in the K8s community.
+long-description: >
+ Members can have issues and PRs assigned to them and participate in {% glossary_tooltip text="special interest groups (SIGs)" term_id="sig" %} through GitHub teams.
+ Pre-submit tests are automatically run for members' PRs.
+ A member is expected to remain an active contributor to the community.
diff --git a/_data/glossary/minikube.yaml b/_data/glossary/minikube.yaml
new file mode 100644
index 0000000000..3f9c01ef51
--- /dev/null
+++ b/_data/glossary/minikube.yaml
@@ -0,0 +1,10 @@
+id: minikube
+name: Minikube
+full-link: /docs/getting-started-guides/minikube/
+tags:
+- fundamental
+- tool
+short-description: >
+ A tool for running Kubernetes locally.
+long-description: >
+ Minikube runs a single-node cluster inside a VM on your computer.
diff --git a/_data/glossary/platform-developer.yaml b/_data/glossary/platform-developer.yaml
new file mode 100644
index 0000000000..8d0c556d06
--- /dev/null
+++ b/_data/glossary/platform-developer.yaml
@@ -0,0 +1,11 @@
+id: platform-developer
+name: Platform Developer
+aka:
+ - Kubernetes Developer
+ - Extension Developer
+tags:
+ - user-type
+short-description: >
+ A person who customizes the Kubernetes platform to fit the needs of their project.
+long-description: >
+ A platform developer may, for example, use [Custom Resources](/docs/concepts/api-extension/custom-resources/) or [Extend the Kubernetes API with the aggregation layer](/docs/concepts/api-extension/apiserver-aggregation/) to add functionality to their instance of Kubernetes, specifically for their application. Some Platform Developers are also {% glossary_tooltip text="contributors" term_id="contributor" %} and develop extensions which are contributed to the Kubernetes community. Others develop closed-source commercial or site-specific extensions.
diff --git a/_data/glossary/pod.yaml b/_data/glossary/pod.yaml
new file mode 100644
index 0000000000..a5d3f567b9
--- /dev/null
+++ b/_data/glossary/pod.yaml
@@ -0,0 +1,17 @@
+id: pod
+name: Pod
+full-link: /docs/concepts/workloads/pods/pod-overview/
+related:
+- container
+- sidecar
+- deployment
+- statefulset
+tags:
+- core-object
+- fundamental
+short-description: >
+ The smallest and simplest Kubernetes object. A Pod represents a set of running {% glossary_tooltip text="containers" term_id="container" %} on your cluster.
+long-description: >
+ A Pod is typically set up to run a single primary container.
+ It can also run optional sidecar containers that add supplementary features like logging.
+ Pods are commonly managed by a {% glossary_tooltip term_id="deployment" %}.
diff --git a/_data/glossary/rbac.yaml b/_data/glossary/rbac.yaml
new file mode 100644
index 0000000000..e1fde1de8d
--- /dev/null
+++ b/_data/glossary/rbac.yaml
@@ -0,0 +1,10 @@
+id: rbac
+name: RBAC (Role-Based Access Control)
+full-link: /docs/admin/authorization/rbac/
+tags:
+- security
+- fundamental
+short-description: >
+ Manages authorization decisions, allowing admins to dynamically configure access policies through the {% glossary_tooltip text="Kubernetes API" term_id="kubernetes-api" %}.
+long-description: >
+ RBAC utilizes *roles*, which contain permission rules, and *role bindings*, which grant the permissions defined in a role to a set of users.
diff --git a/_data/glossary/reviewer.yaml b/_data/glossary/reviewer.yaml
new file mode 100644
index 0000000000..076b120e02
--- /dev/null
+++ b/_data/glossary/reviewer.yaml
@@ -0,0 +1,8 @@
+id: reviewer
+name: Reviewer
+tags:
+- community
+short-description: >
+ A person who reviews code for quality and correctness on some part of the project.
+long-description: >
+ Reviewers are knowledgeable about both the codebase and software engineering principles. Reviewer status is scoped to a part of the codebase.
diff --git a/_data/glossary/service-broker.yaml b/_data/glossary/service-broker.yaml
new file mode 100644
index 0000000000..9cdc99bbcb
--- /dev/null
+++ b/_data/glossary/service-broker.yaml
@@ -0,0 +1,9 @@
+id: service-broker
+name: Service Broker
+tags:
+- extension
+short-description: >
+ An endpoint for a set of {% glossary_tooltip text="Managed Services" term_id="managed-service" %} offered and maintained by a third-party.
+long-description: >
+ {% glossary_tooltip text="Service Brokers" term_id="service-broker" %} implement the [Open Service Broker API spec](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md) and provide a standard interface for applications to use their Managed Services.
+ [Service Catalog](/docs/concepts/service-catalog/) provides a way to list, provision, and bind with Managed Services offered by Service Brokers.
\ No newline at end of file
diff --git a/_data/glossary/service-catalog.yaml b/_data/glossary/service-catalog.yaml
new file mode 100644
index 0000000000..bcbadd309c
--- /dev/null
+++ b/_data/glossary/service-catalog.yaml
@@ -0,0 +1,8 @@
+id: service-catalog
+name: Service Catalog
+tags:
+- extension
+short-description: >
+ An extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
+long-description: >
+ Service Catalog provides a way to list, provision, and bind with external {% glossary_tooltip text="Managed Services" term_id="managed-service" %} from {% glossary_tooltip text="Service Brokers" term_id="service-broker" %} without needing detailed knowledge about how those services are created or managed.
\ No newline at end of file
diff --git a/_data/glossary/service.yaml b/_data/glossary/service.yaml
new file mode 100644
index 0000000000..03c3469c53
--- /dev/null
+++ b/_data/glossary/service.yaml
@@ -0,0 +1,10 @@
+id: service
+name: Service
+full-link: /docs/concepts/services-networking/service/
+tags:
+- fundamental
+- core-object
+short-description: >
+ An API object that describes how to access applications, such as a set of {% glossary_tooltip text="Pods" term_id="pod" %}, and can describe ports and load-balancers.
+long-description: >
+ The access point can be internal or external to the cluster.
diff --git a/_data/glossary/sig.yaml b/_data/glossary/sig.yaml
new file mode 100644
index 0000000000..8e9ccef98b
--- /dev/null
+++ b/_data/glossary/sig.yaml
@@ -0,0 +1,12 @@
+id: sig
+name: SIG (special interest group)
+full-link: https://github.com/kubernetes/community/blob/master/sig-list.md#master-sig-list
+tags:
+- community
+short-description: >
+ {% glossary_tooltip text="Community members" term_id="member" %} who collectively manage an ongoing piece or aspect of the larger Kubernetes open source project.
+long-description: |
+ Members within a SIG have a shared interest in advancing a specific area, such as architecture, API machinery, or documentation.
+ SIGs must follow the [SIG Governance](https://github.com/kubernetes/community/blob/master/sig-governance.md) guidelines but can have their own contribution policy and channels of communication.
+
+ For more information, see the [kubernetes/community](https://github.com/kubernetes/community) repo and the current list of [SIGs and Working Groups](https://github.com/kubernetes/community/blob/master/sig-list.md).
diff --git a/_data/glossary/statefulset.yml b/_data/glossary/statefulset.yml
index 3f05200012..9b2d6c44fb 100644
--- a/_data/glossary/statefulset.yml
+++ b/_data/glossary/statefulset.yml
@@ -1,18 +1,18 @@
id: statefulset
name: StatefulSet
-formerly:
+full-link: /docs/concepts/workloads/controllers/statefulset/
+aka:
- PetSet
related:
-- Deployment
-- Pod
+- deployment
+- pod
tags:
-- Storage
-- Workload
-- API Object
-short-description: |
- Manage the deployment and scaling of a set of Pods, *and provide guarantees about ordering*. They do so by maintaining a *unique*, sticky identity for each of their Pods.
-
+- core-object
+- workload
+- storage
+short-description: >
+ Manages the deployment and scaling of a set of {% glossary_tooltip text="Pods" term_id="pod" %}, *and provides guarantees about the ordering and uniqueness* of these Pods.
long-description: |
- Like Deployments, StatefulSets manage Pods that are based on an identical container spec. However, although their specs are the same, the Pods in a StatefulSet are not interchangeable. Each Pod has a persistent identifier that it maintains across any rescheduling.
+ Like a {% glossary_tooltip term_id="deployment" %}, a StatefulSet manages Pods that are based on an identical container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.
- StatefulSets also operate according to the Controller pattern. You define your desired state in a StatefulSet *object*, and the StatefulSet *controller* makes any necessary updates to the get there from the current state.
+ A StatefulSet operates under the same pattern as any other Controller. You define your desired state in a StatefulSet *object*, and the StatefulSet *controller* makes any necessary updates to get there from the current state.
diff --git a/_data/glossary/upstream.yaml b/_data/glossary/upstream.yaml
new file mode 100644
index 0000000000..e2c2cac66d
--- /dev/null
+++ b/_data/glossary/upstream.yaml
@@ -0,0 +1,11 @@
+id: upstream
+name: Upstream (disambiguation)
+related:
+- downstream
+tags:
+- community
+short-description: >
+ May refer to: core Kubernetes or the source repo from which a repo was forked.
+long-description: |
+ * In the **Kubernetes Community**: Conversations often use *upstream* to mean the core Kubernetes codebase, which the general ecosystem, other code, or third-party tools relies upon. For example, [community members](#term-member) may suggest that a feature is moved upstream so that it is in the core codebase instead of in a plugin or third-party tool.
+ * In **GitHub** or **git**: The convention is to refer to a source repo as *upstream*, whereas the forked repo is considered *downstream*.
diff --git a/_data/glossary/wg.yaml b/_data/glossary/wg.yaml
new file mode 100644
index 0000000000..8237068cf0
--- /dev/null
+++ b/_data/glossary/wg.yaml
@@ -0,0 +1,11 @@
+id: wg
+name: WG (working group)
+full-link: https://github.com/kubernetes/community/blob/master/sig-list.md#master-working-group-list
+tags:
+- community
+short-description: >
+ Facilitates the discussion and/or implementation of a short-lived, narrow, or decoupled project for a committee, {% glossary_tooltip text="SIG" term_id="sig" %}, or cross-SIG effort.
+long-description: |
+ Working groups are a way of organizing people to accomplish a discrete task, and are relatively easy to create and deprecate when inactive.
+
+ For more information, see the [kubernetes/community](https://github.com/kubernetes/community) repo and the current list of [SIGs and working groups](https://github.com/kubernetes/community/blob/master/sig-list.md).
diff --git a/_data/reference.yml b/_data/reference.yml
index fa403d8e44..ed7e57f37a 100644
--- a/_data/reference.yml
+++ b/_data/reference.yml
@@ -2,6 +2,7 @@ bigheader: "Reference Documentation"
abstract: "Design docs, concept definitions, and references for APIs and CLIs."
toc:
- docs/reference/index.md
+- docs/reference/glossary.md
- title: Using the API
section:
@@ -29,12 +30,6 @@ toc:
section:
- title: v1.8
path: /docs/api-reference/v1.8/
- - title: v1.7
- path: /docs/api-reference/v1.7/
- - title: v1.6
- path: /docs/api-reference/v1.6/
- - title: v1.5
- path: /docs/api-reference/v1.5/
- docs/reference/labels-annotations-taints.md
- title: OpenAPI and Swagger
section:
@@ -54,45 +49,39 @@ toc:
- title: kubectl CLI
section:
- - docs/user-guide/kubectl-overview.md
- - title: v1.8 Commands
- path: /docs/user-guide/kubectl/v1.8/
- - title: v1.7 Commands
- path: /docs/user-guide/kubectl/v1.7/
- - title: v1.6 Commands
- path: /docs/user-guide/kubectl/v1.6/
- - title: v1.5 Commands
- path: /docs/user-guide/kubectl/v1.5/
- - docs/user-guide/docker-cli-to-kubectl.md
- - docs/user-guide/kubectl-conventions.md
- - docs/user-guide/jsonpath.md
- - docs/user-guide/kubectl-cheatsheet.md
+ - docs/reference/kubectl/overview.md
+ - docs/reference/generated/kubectl/kubectl-options.md
+ - title: kubectl Commands
+ path: /docs/reference/generated/kubectl/kubectl-commands.html
+ - docs/reference/kubectl/docker-cli-to-kubectl.md
+ - docs/reference/kubectl/conventions.md
+ - docs/reference/kubectl/jsonpath.md
+ - docs/reference/kubectl/cheatsheet.md
-- title: Cloud Controller Manager
+- title: Setup Tools Reference
section:
- - docs/admin/cloud-controller-manager.md
-
-- title: Setup Tools
- section:
- - docs/admin/kubeadm.md
+ - docs/reference/generated/kubeadm.md
- title: Kubefed
section:
- - docs/admin/kubefed.md
- - docs/admin/kubefed_options.md
- - docs/admin/kubefed_init.md
- - docs/admin/kubefed_join.md
- - docs/admin/kubefed_unjoin.md
- - docs/admin/kubefed_version.md
+ - docs/reference/generated/kubefed.md
+ - docs/reference/generated/kubefed_options.md
+ - docs/reference/generated/kubefed_init.md
+ - docs/reference/generated/kubefed_join.md
+ - docs/reference/generated/kubefed_unjoin.md
+ - docs/reference/generated/kubefed_version.md
-- title: Config Reference
+- title: Command-line Tools Reference
section:
- - docs/admin/kubelet.md
- - docs/admin/kube-apiserver.md
- - docs/admin/kube-controller-manager.md
- - docs/admin/kube-proxy.md
- - docs/admin/kube-scheduler.md
- - docs/admin/federation-apiserver.md
- - docs/admin/federation-controller-manager.md
+ - docs/reference/generated/kubelet.md
+ - docs/admin/kubelet-authentication-authorization.md
+ - docs/reference/generated/kube-apiserver.md
+ - docs/reference/generated/kube-controller-manager.md
+ - docs/reference/generated/kube-proxy.md
+ - docs/reference/generated/kube-scheduler.md
+ - docs/admin/kubelet-tls-bootstrapping.md
+ - docs/reference/generated/cloud-controller-manager.md
+ - docs/reference/generated/federation-apiserver.md
+ - docs/reference/generated/federation-controller-manager.md
- title: Kubernetes Design Docs
section:
@@ -113,5 +102,3 @@ toc:
- title: Kubernetes Issue Tracker on GitHub
path: https://github.com/kubernetes/kubernetes/issues/
- docs/reference/security.md
-
-
diff --git a/_data/setup.yml b/_data/setup.yml
index 86d591f46d..d2907e9433 100644
--- a/_data/setup.yml
+++ b/_data/setup.yml
@@ -12,18 +12,19 @@ toc:
section:
- docs/setup/independent/install-kubeadm.md
- docs/setup/independent/create-cluster-kubeadm.md
+ - docs/setup/independent/troubleshooting-kubeadm.md
- docs/getting-started-guides/scratch.md
- docs/getting-started-guides/alternatives.md
- title: Hosted Solutions
section:
- - title: Running Kubernetes on Google Container Engine
- path: https://cloud.google.com/container-engine/docs/before-you-begin/
+ - title: Running Kubernetes on Google Kubernetes Engine
+ path: https://cloud.google.com/kubernetes-engine/docs/before-you-begin/
- title: Running Kubernetes on Azure Container Service
path: https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough
- - title: Running Kubernetes on IBM Bluemix Container Service
- path: https://console.ng.bluemix.net/docs/containers/container_index.html
+ - title: Running Kubernetes on IBM Cloud Container Service
+ path: https://console.bluemix.net/docs/containers/container_index.html
- title: Turn-key Cloud Solutions
section:
@@ -32,7 +33,7 @@ toc:
- docs/getting-started-guides/azure.md
- docs/getting-started-guides/alibaba-cloud.md
- docs/getting-started-guides/clc.md
- - title: Running Kubernetes on IBM Bluemix
+ - title: Running Kubernetes on IBM Cloud
path: https://github.com/patrocinio/kubernetes-softlayer
- docs/getting-started-guides/stackpoint.md
diff --git a/_data/tasks.yml b/_data/tasks.yml
index 6fcac21d54..15eb64620b 100644
--- a/_data/tasks.yml
+++ b/_data/tasks.yml
@@ -96,10 +96,11 @@ toc:
- docs/tasks/debug-application-cluster/debug-stateful-set.md
- docs/tasks/debug-application-cluster/debug-application-introspection.md
- docs/tasks/debug-application-cluster/audit.md
+ - docs/tasks/debug-application-cluster/local-debugging.md
- title: Use Explorer to Examine the Runtime Environment
path: https://github.com/kubernetes/kubernetes/tree/release-1.5/examples/explorer
-- title: Access and Extend the Kubernetes API
+- title: Extend Kubernetes
section:
- docs/tasks/access-kubernetes-api/http-proxy-access-api.md
- docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md
@@ -107,6 +108,8 @@ toc:
- docs/tasks/access-kubernetes-api/migrate-third-party-resource.md
- docs/tasks/access-kubernetes-api/configure-aggregation-layer.md
- docs/tasks/access-kubernetes-api/setup-extension-api-server.md
+ - docs/tasks/service-catalog/install-service-catalog-using-helm.md
+ - docs/tasks/service-catalog/install-service-catalog-using-sc.md
- title: TLS
section:
@@ -147,6 +150,7 @@ toc:
- docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods.md
- docs/tasks/administer-cluster/declare-network-policy.md
- docs/tasks/administer-cluster/reconfigure-kubelet.md
+ - docs/tasks/administer-cluster/kubelet-config-file.md
- title: Install Network Policy Provider
section:
- docs/tasks/administer-cluster/calico-network-policy.md
diff --git a/_data/tutorials.yml b/_data/tutorials.yml
index 60462663a6..eaf44f93e8 100644
--- a/_data/tutorials.yml
+++ b/_data/tutorials.yml
@@ -36,6 +36,8 @@ toc:
- title: Introduction to Kubernetes (edX)
path: https://www.edx.org/course/introduction-kubernetes-linuxfoundationx-lfs158x#
- docs/tutorials/stateless-application/hello-minikube.md
+- docs/user-guide/walkthrough/index.md
+- docs/user-guide/walkthrough/k8s201.md
- title: Configuration
section:
- docs/tutorials/configuration/configure-redis-using-configmap.md
diff --git a/_includes/code.html b/_includes/code.html
index d59db08ff7..83a702785d 100644
--- a/_includes/code.html
+++ b/_includes/code.html
@@ -1,6 +1,6 @@
{% capture samplecode %}{% include_relative {{include.file}} %}{% endcapture %}
{% if include.k8slink %}{% capture ghlink %}https://raw.githubusercontent.com/kubernetes/kubernetes/blob/{{page.githubbranch}}{{include.k8slink}}{% endcapture %}{% endif %}
-{% if include.ghlink %}{% capture ghlink %}https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/{{page.docsbranch}}{{include.ghlink}}{% endcapture %}{% endif %}
+{% if include.ghlink %}{% capture ghlink %}https://raw.githubusercontent.com/kubernetes/website/{{page.docsbranch}}{{include.ghlink}}{% endcapture %}{% endif %}
{% capture mysample %}
```{{include.language}}
{{ samplecode | raw | strip }}
diff --git a/_includes/default-storage-class-prereqs.md b/_includes/default-storage-class-prereqs.md
index a4747d9032..ef4823318d 100644
--- a/_includes/default-storage-class-prereqs.md
+++ b/_includes/default-storage-class-prereqs.md
@@ -1,5 +1,5 @@
You need to either have a dynamic PersistentVolume provisioner with a default
-[StorageClass](/docs/user-guide/persistent-volumes/#storageclasses),
+[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.
diff --git a/_includes/footer.html b/_includes/footer.html
index 3cb98b0d08..c01c5d5e1b 100644
--- a/_includes/footer.html
+++ b/_includes/footer.html
@@ -25,7 +25,7 @@
- {% if page.url != "/404.html" and page.url != "/docs/search/" %}
+ {% if page.url != "/404.html" and page.url != "/docs/search/"%}
+ {% unless page.no_issue %}
Create an Issue
- Edit this Page
+ {% endunless %}
+ {% unless page.noedit %}
+ Edit this Page
+ {% endunless %}
{% endif %}
diff --git a/_plugins/README.md b/_plugins/README.md
new file mode 100644
index 0000000000..d4a192840e
--- /dev/null
+++ b/_plugins/README.md
@@ -0,0 +1,75 @@
+# Custom Jekyll Plugins
+
+This directory contains `*.rb` files that extend the original Jekyll classes and provide custom formatting for the docs site:
+
+### `glossary_tags.rb`
+
+A full list of glossary terms is available on the [Standardized Glossary](https://kubernetes.io/docs/reference/glossary/?fundamental=true) page. For further information about term schemas, see the [README](../_includes/templates/glossary/README.md) and the provided [`_example.yml`](../_data/glossary/_example.yml).
+
+*NOTE: The "tags" referenced here are Liquid tags like `{% include %}`, **not** the glossary canonical tags that are used to categorize terms.*
+
+#### (1) `glossary_definition` tag
+
+This renders the definition of the glossary term inside a `
`, preserving Markdown formatting where possible. It uses the [`snippet.md` template](../_includes/templates/glossary/snippet.md).
+
+**Usage:**
+
+```
+{% glossary_definition term_id="helm-chart" length="all" %}
+```
+
+**Parameters:**
+
+
+| Name | Default | Description |
+| --- | --- | --- |
+| `term_id` | N/A (Required) | The `id` of the glossary term whose definition will be used. (This `id` is the same as the filename of the term, i.e. `_data/glossary/.yml`.) |
+| `length` | "short" | Specifies which term definition should be used ("short" for the `short-definition`, "long" for `long-description`, "all" when both should be included). |
+
+#### (2) `glossary_tooltip` tag
+
+This renders the glossary term with a tooltip--when the term is moused over by the user, its definition is displayed above.
+
+**Usage:**
+
+```
+{% glossary_tooltip text="Helm Charts" term_id="helm-chart" %}
+```
+
+This renders the following:
+
+
+
+**Parameters:**
+
+
+| Name | Default | Description |
+| --- | --- | --- |
+| `text` | the `name` of the glossary term | The text that the user will hover over to display the glossary definition. **You should include this if using the tooltip inside of a glossary term's YAML short-definition.** |
+| `term_id` | N/A (Required) | The `id` of the associated glossary term. (This `id` is the same as the filename of the term, i.e. `_data/glossary/.yml`.) |
+
+#### (3) `glossary_injector` tag
+
+This takes the definition of the term specified by the `term_id` and uses it to populate the contents of another HTML element specified by `placeholder_id`.
+
+**Usage:**
+
+```
+{% glossary_injector term_id="kubectl" placeholder_id="def-container" length="short" %}
+```
+
+This renders the following:
+
+
+
+*NOTE: Neither the placeholder nor the term's styling/CSS is determined by this Jekyll tag. You will need to specify this yourself in your Markdown/HTML files, i.e. by assigning a custom class.*
+
+**Parameters:**
+
+
+| Name | Default | Description |
+| --- | --- | --- |
+| `text` | the `name` of the glossary term | The text that the user will hover over to display the glossary definition. |
+| `term_id` | N/A (Required) | The `id` of the glossary term whose definition will be used. (This `id` is the same as the filename of the term, i.e. `_data/glossary/.yml`.) |
+| `placeholder_id` | N/A (Required) | The `id` of the HTML element whose contents will be populated with the definition of `term_id` |
+| `length` | "short" | Specifies which term definition should be used ("short" for the `short-definition`, "long" for `long-description`, "all" when both should be included). |
diff --git a/_plugins/glossary_tags.rb b/_plugins/glossary_tags.rb
new file mode 100644
index 0000000000..c59ccf0e9f
--- /dev/null
+++ b/_plugins/glossary_tags.rb
@@ -0,0 +1,122 @@
+# See /_plugins/README.md for full documentation of these custom Jekyll tags
+module Jekyll
+ module GlossaryTags
+ # Base class for tags (not to be instantiated)
+ class Base < Liquid::Tag
+ VALID_PARAM_NAMES = []
+ LENGTH_SHORT = "short"
+ LENGTH_LONG = "long"
+ SNIPPET_TEMPLATE = "templates/glossary/snippet.md"
+
+ def initialize(tag_name, markup, options)
+ super
+ @args = {}
+ @markup.scan(/([\S]+=['"][^=]+["'])+/).each do |arg|
+ key, val = arg.first.split("=")
+ key = key.to_sym
+ next unless val
+ if self.class::VALID_PARAM_NAMES.include?(key)
+ @args[key] = val.gsub("\"", "")
+ end
+ end
+ end
+
+ # "abstract" method
+ def render(context)
+ raise NotImplementedError
+ end
+
+ protected
+
+ def glossary_term_info(context)
+ global_glossary_hash = context.registers[:site].data["glossary"]
+ unless global_glossary_hash.keys.to_set.include?(@args[:term_id])
+ raise StandardError,
+ "#{@args[:term_id]} is not a valid glossary term id. Please " \
+ "see ./_data/glossary/* for the complete list."
+ end
+ global_glossary_hash[@args[:term_id]]
+ end
+
+ def include_snippet(context)
+ @args[:length] ||= LENGTH_SHORT
+ clean_markup = @args.keys.map { |k| "#{k}=\"#{@args[k]}\"" }.join(" ")
+
+ Jekyll::Tags::IncludeTag.parse(
+ "include",
+ "#{SNIPPET_TEMPLATE} #{clean_markup}",
+ nil,
+ @parse_context
+ ).render(context)
+ end
+ end
+
+ # Tag for displaying a glossary term's definition inline
+ class Definition < Base
+ VALID_PARAM_NAMES = [
+ :term_id,
+ :length
+ ].freeze
+
+ def render(context)
+ include_snippet(context)
+ end
+ end
+
+ # Tag to display a tooltip for a specific glossary term
+ class Tooltip < Base
+ VALID_PARAM_NAMES = [
+ :text,
+ :term_id
+ ].freeze
+ GLOSSARY_HOME = "/docs/reference/glossary/?all=true"
+ NESTED_TOOLTIPS = /{% (.*?text="(.*?)".*?) %}/
+ NESTED_MARKDOWN_LINKS = /(\[(.*?)\]\(.*?\))/
+
+ def render(context)
+ term_info = glossary_term_info(context)
+ external_link =
+ term_info["full-link"] ||
+ "#{GLOSSARY_HOME}#term-#{term_info["id"]}"
+ tooltip = term_info["short-description"].
+ gsub(NESTED_TOOLTIPS, '\2').
+ gsub(NESTED_MARKDOWN_LINKS, '\2').
+ strip
+
+ "" \
+ "#{@args[:text] || term_info["name"]}" \
+ "" \
+ "#{tooltip}" \
+ "" \
+ ""
+ end
+ end
+
+ # Tag to inject a glossary term definition into another HTML element
+ class Injector < Base
+ VALID_PARAM_NAMES = [
+ :text,
+ :term_id,
+ :placeholder_id,
+ :length
+ ].freeze
+ RENDERED_DESCRIPTION_BLOCK = /.*
Turning to Containerization to Support Millions of Rideshares
+
+
+
+
+ Company BlaBlaCar Location Paris, France Industry Ridesharing Company
+
+
+
+
+
+
+
+
Challenge
+ The world’s largest long-distance carpooling community, BlaBlaCar, connects 40 million members across 22 countries. The company has been experiencing exponential growth since 2012 and needed its infrastructure to keep up. "When you’re thinking about doubling the number of servers, you start thinking, ‘What should I do to be more efficient?’" says Simon Lallemand, Infrastructure Engineer at BlaBlaCar. "The answer is not to hire more and more people just to deal with the servers and installation." The team knew they had to scale the platform, but wanted to stay on their own bare metal servers.
+
+
+
Solution
+ Opting not to shift to cloud virtualization or use a private cloud on their own servers, the BlaBlaCar team became early adopters of containerization, using the CoreOs runtime rkt, initially deployed using fleet cluster manager. Last year, the company switched to Kubernetes orchestration, and now also uses Prometheus for monitoring.
+
+
+
+
Impact
+ "Before using containers, it would take sometimes a day, sometimes two, just to create a new service," says Lallemand. "With all the tooling that we made around the containers, copying a new service now is a matter of minutes. It’s really a huge gain. We are better at capacity planning in our data center because we have fewer constraints due to this abstraction between the services and the hardware we run on. For the developers, it also means they can focus only on the features that they’re developing, and not on the infrastructure."
+
+
+
+
+
+
+ "When you’re switching to this cloud-native model and running everything in containers, you have to make sure that at any moment you can reboot without any downtime and without losing traffic. [With Kubernetes] our infrastructure is much more resilient and we have better availability than before." - Simon Lallemand, Infrastructure Engineer at BlaBlaCar
+
+
+
+
+
+
For the 40 million users of BlaBlaCar, it’s easy to find strangers headed in the same direction to share rides and costs. You can even choose how much "bla bla" chatter you want from a long-distance ride mate.
+ Behind the scenes, though, the infrastructure was falling woefully behind the rider community’s exponential growth. Founded in 2006, the company hit its current stride around 2012. "Our infrastructure was very traditional," says Infrastructure Engineer Simon Lallemand, who began working at the company in 2014. "In the beginning, it was a bit chaotic because we had to [grow] fast. But then comes the time when you have to design things to make it manageable."
+ By 2015, the company had about 50 bare metal servers. The team was using a MySQL database and PHP, but, Lallemand says, "it was a very static way." They also utilized the configuration management system, Chef, but had little automation in its process. "When you’re thinking about doubling the number of servers, you start thinking, ‘What should I do to be more efficient?’" says Lallemand. "The answer is not to hire more and more people just to deal with the servers and installation."
+ Instead, BlaBlaCar began its cloud-native journey but wasn’t sure which route to take. "We could either decide to go into cloud virtualization or even use a private cloud on our own servers," says Lallemand. "But going into the cloud meant we had to make a lot of changes in our application work, and we were just not ready to make the switch from on premise to the cloud." They wanted to keep the great performance they got on bare metal, so they didn’t want to go to virtualization on premise.
+ The solution: containerization. This was early 2015 and containers were still relatively new. "It was a bold move at the time," says Lallemand. "We decided that the next servers that we would buy in the new data center would all be the same model, so we could outsource the maintenance of the servers. And we decided to go with containers and with CoreOS Container Linux as an abstraction for this hardware. It seemed future-proof to go with containers because we could see what companies were already doing with containers."
+
+
+
+
+
+ "With all the tooling that we made around the containers, copying a new service is a matter of minutes. It’s a huge gain. For the developers, it means they can focus only on the features that they’re developing and not on the infrastructure or the hour they would test their code, or the hour that it would get deployed."
+
+
+
+
+
+ Next, they needed to choose a runtime for the containers, but "there were very few deployments in production at that time," says Lallemand. They experimented with Docker but decided to go with rkt. Lallemand explains that for BlaBlaCar, it was "much simpler to integrate things that are on rkt." At the time, the project was still pre-v1.0, so "we could speak with the developers of rkt and give them feedback. It was an advantage." Plus, he notes, rkt was very stable, even at this early stage.
+ Once those decisions were made that summer, the company came up with a plan for implementation. First, they formed a task force to create a workflow that would be tested by three of the 10 members on Lallemand’s team. But they took care to run regular workshops with all 10 members to make sure everyone was on board. "When you’re focused on your product sometimes you forget if it’s really user friendly, whether other people can manage to create containers too," Lallemand says. "So we did a lot of iterations to find a good workflow."
+ After establishing the workflow, Lallemand says with a smile that "we had this strange idea that we should try the most difficult thing first. Because if it works, it will work for everything." So the first project the team decided to containerize was the database. "Nobody did that at the time, and there were really no existing tools for what we wanted to do, including building container images," he says. So the team created their own tools, such as dgr, which builds container images so that the whole team has a common framework to build on the same images with the same standards. They also revamped the service-discovery tools Nerve and Synapse; their versions, Go-Nerve and Go-Synapse, were written in Go and built to be more efficient and include new features. All of these tools were open-sourced.
+ At the same time, the company was working to migrate its entire platform to containers with a deadline set for Christmas 2015. With all the work being done in parallel, BlaBlaCar was able to get about 80 percent of its production into containers by its deadline with live traffic running on containers during December. (It’s now at 100 percent.) "It’s a really busy time for traffic," says Lallemand. "We knew that by using those new servers with containers, it would help us handle the traffic."
+ In the middle of that peak season for carpooling, everything worked well. "The biggest impact that we had was for the deployment of new services," says Lallemand. "Before using containers, we had to first deploy a new server and create configurations with Chef. It would take sometimes a day, sometimes two, just to create a new service. And with all the tooling that we made around the containers, copying a new service is a matter of minutes. So it’s really a huge gain. For the developers, it means they can focus only on the features that they’re developing and not on the infrastructure or the hour they would test their code, or the hour that it would get deployed."
+
+
+
+
+
+ "We realized that there was a really strong community around it [Kubernetes], which meant we would not have to maintain a lot of tools of our own," says Lallemand. "It was better if we could contribute to some bigger project like Kubernetes."
+
+
+
+
+
+ In order to meet their self-imposed deadline, one of the decisions they made was to not do any "orchestration magic" for containers in the first production alignment. Instead, they used the basic fleet tool from CoreOS to deploy their containers. (They did build a tool called GGN, which they’ve open-sourced, to make it more manageable for their system engineers to use.)
+ Still, the team knew that they’d want more orchestration. "Our tool was doing a pretty good job, but at some point you want to give more autonomy to the developer team," Lallemand says. "We also realized that we don’t want to be the single point of contact for developers when they want to launch new services." By the summer of 2016, they found their answer in Kubernetes, which had just begun supporting rkt implementation.
+ After discussing their needs with their contacts at CoreOS and Google, they were convinced that Kubernetes would work for BlaBlaCar. "We realized that there was a really strong community around it, which meant we would not have to maintain a lot of tools of our own," says Lallemand. "It was better if we could contribute to some bigger project like Kubernetes." They also started using Prometheus, as they were looking for "service-oriented monitoring that could be updated nightly." Production on Kubernetes began in December 2016. "We like to do crazy stuff around Christmas," he adds with a laugh.
+ BlaBlaCar now has about 3,000 pods, with 1200 of them running on Kubernetes. Lallemand leads a "foundations team" of 25 members who take care of the networks, databases and systems for about 100 developers. There have been some challenges getting to this point. "The rkt implementation is still not 100 percent finished," Lallemand points out. "It’s really good, but there are some features still missing. We have questions about how we do things with stateful services, like databases. We know how we will be migrating some of the services; some of the others are a bit more complicated to deal with. But the Kubernetes community is making a lot of progress on that part."
+ The team is particularly happy that they’re now able to plan capacity better in the company’s data center. "We have fewer constraints since we have this abstraction between the services and the hardware we run on," says Lallemand. "If we lose a server because there’s a hardware problem on it, we just move the containers onto another server. It’s much more efficient. We do that by just changing a line in the configuration file. And with Kubernetes, it should be automatic, so we would have nothing to do."
+
+
+
+
+
+ "If we lose a server because there’s a hardware problem on it, we just move the containers onto another server. It’s much more efficient. We do that by just changing a line in the configuration file. With Kubernetes, it should be automatic, so we would have nothing to do."
+
+
+
+
+
+ And these advances ultimately trickle down to BlaBlaCar’s users. "We have improved availability overall on our website," says Lallemand. "When you’re switching to this cloud-native model with running everything in containers, you have to make sure that you can at any moment reboot a server or a data container without any downtime, without losing traffic. So now our infrastructure is much more resilient and we have better availability than before."
+ Within BlaBlaCar’s technology department, the cloud-native journey has created some profound changes. Lallemand thinks that the regular meetings during the conception stage and the training sessions during implementation helped. "After that everybody took part in the migration process," he says. "Then we split the organization into different ‘tribes’—teams that gather developers, product managers, data analysts, all the different jobs, to work on a specific part of the product. Before, they were organized by function. The idea is to give all these tribes access to the infrastructure directly in a self-service way without having to ask. These people are really autonomous. They have responsibility of that part of the product, and they can make decisions faster."
+ This DevOps transformation turned out to be a positive one for the company’s staffers. "The team was very excited about the DevOps transformation because it was new, and we were working to make things more reliable, more future-proof," says Lallemand. "We like doing things that very few people are doing, other than the internet giants."
+ With these changes already making an impact, BlaBlaCar is looking to split up more and more of its application into services. "I don’t say microservices because they’re not so micro," Lallemand says. "If we can split the responsibilities between the development teams, it would be easier to manage and more reliable, because we can easily add and remove services if one fails. You can handle it easily, instead of adding a big monolith that we still have."
+ When Lallemand speaks to other European companies curious about what BlaBlaCar has done with its infrastructure, he tells them to come along for the ride. "I tell them that it’s such a pleasure to deal with the infrastructure that we have today compared to what we had before," he says. "They just need to keep in mind their real motive, whether it’s flexibility in development or reliability or so on, and then go step by step towards reaching those objectives. That’s what we’ve done. It’s important not to do technology for the sake of technology. Do it for a purpose. Our focus was on helping the developers."
+
The path to those stellar results began in late 2014. In order to support GolfNow’s global growth, the team decided that the company needed to have multiple data centers and the ability to quickly and easily re-route traffic as needed. "From there we knew that we needed to go in a direction of breaking things apart, microservices, and containerization," says Sheriff. "At the time we were trying to get away from C#.NET and SQL Server since it didn’t run very well on Linux, where everything container was running smoothly."
- To that end, the team shifted to working with Node.js, the open-source, cross-platform JavaScript runtime environment for developing tools and applications, and MongoDB, the open-source database program. At the time, Docker, the platform for deploying applications in containers, was still new. But once the team began experimenting with it, Sheriff says, "we realized that was the way we wanted to go, especially since that’s the way the industry is heading."
+ To that end, the team shifted to working with Node.js, the open-source, cross-platform JavaScript runtime environment for developing tools and applications, and MongoDB, the open-source database program. At the time, Docker, the platform for deploying applications in containers, was still new. But once the team began experimenting with it, Sheriff says, "we realized that was the way we wanted to go, especially since that’s the way the industry is heading."
@@ -51,22 +51,22 @@ But once it launched, the user base began growing steadily at a rate of 30 perce
On top of that, many of Pear Deck’s customers are behind government firewalls and connect through Firebase, not Pear Deck’s servers, making troubleshooting even more difficult.
-The team began looking around for another solution, and finally decided in early 2016 to start moving the app from Heroku to Docker containers running on Google Container Engine, orchestrated by Kubernetes and monitored with Prometheus.
+The team began looking around for another solution, and finally decided in early 2016 to start moving the app from Heroku to Docker containers running on Google Kubernetes Engine, orchestrated by Kubernetes and monitored with Prometheus.
- "When it became clear that Google Container Engine was going to have a lot of support from Google and be a fully-managed Kubernetes platform, it seemed very obvious to us that was the way to go," says Eynon-Lynch.
+ "When it became clear that Google Kubernetes Engine was going to have a lot of support from Google and be a fully-managed Kubernetes platform, it seemed very obvious to us that was the way to go," says Eynon-Lynch.
- They had considered other options like Google’s App Engine (which they were already using for one service) and Amazon’s Elastic Compute Cloud (EC2), while experimenting with running one small service that wasn’t accessible to the Internet in Kubernetes. "When it became clear that Google Container Engine was going to have a lot of support from Google and be a fully-managed Kubernetes platform, it seemed very obvious to us that was the way to go," says Eynon-Lynch. "We didn’t really consider Terraform and the other competitors because the abstractions offered by Kubernetes just jumped off the page to us."
+ They had considered other options like Google’s App Engine (which they were already using for one service) and Amazon’s Elastic Compute Cloud (EC2), while experimenting with running one small service that wasn’t accessible to the Internet in Kubernetes. "When it became clear that Google Kubernetes Engine was going to have a lot of support from Google and be a fully-managed Kubernetes platform, it seemed very obvious to us that was the way to go," says Eynon-Lynch. "We didn’t really consider Terraform and the other competitors because the abstractions offered by Kubernetes just jumped off the page to us."
Once the team started porting its Heroku apps into Kubernetes, which was "super easy," he says, the impact was immediate. "Before, to make a new version of the app meant going to Heroku and reconfiguring 10 new services, so basically no one was willing to do it, and we never staged things," he says. "Now we can deploy our exact same configuration in lots of different clusters in 30 seconds. We have a full set up that’s always running, and then any of our developers or designers can stage new versions with one command, including their recent changes. We stage all the time now, and everyone stopped talking about how cool it is because it’s become invisible how great it is."
- Along with Kubernetes came Prometheus. "Until pretty recently we didn’t have any kind of visibility into aggregate server metrics or performance," says Eynon-Lynch. The team had tried to use GKE’s Stackdriver monitoring, but had problems making it work, and considered New Relic. When they started looking at Prometheus in the fall of 2016, "the fit between the abstractions in Prometheus and the way we think about how our system works, was so clear and obvious," he says.
+ Along with Kubernetes came Prometheus. "Until pretty recently we didn’t have any kind of visibility into aggregate server metrics or performance," says Eynon-Lynch. The team had tried to use Google Kubernetes Engine’s Stackdriver monitoring, but had problems making it work, and considered New Relic. When they started looking at Prometheus in the fall of 2016, "the fit between the abstractions in Prometheus and the way we think about how our system works, was so clear and obvious," he says.
The integration with Kubernetes made set-up easy. Once Helm installed Prometheus, "We started getting a graph of the health of all our Kubernetes nodes and pods immediately. I think we were pretty hooked at that point," Eynon-Lynch says. "Then we got our own custom instrumentation working in 15 minutes, and had an actively updated count of requests that we could do, rate on and get a sense of how many users are connected at a given point. And then it was another hour before we had alarms automatically showing up in our Slack channel. All that was in one afternoon. And it was an afternoon of gasping with delight, basically!"
diff --git a/cn/_includes/task-tutorial-prereqs.md b/cn/_includes/task-tutorial-prereqs.md
new file mode 100644
index 0000000000..a9cf90d265
--- /dev/null
+++ b/cn/_includes/task-tutorial-prereqs.md
@@ -0,0 +1,4 @@
+You need to have a Kubernetes cluster, and the kubectl command-line tool must
+be configured to communicate with your cluster. If you do not already have a
+cluster, you can create one by using
+[Minikube](/docs/getting-started-guides/minikube).
diff --git a/cn/_includes/templates/task.md b/cn/_includes/templates/task.md
new file mode 100644
index 0000000000..e76cb7b117
--- /dev/null
+++ b/cn/_includes/templates/task.md
@@ -0,0 +1,55 @@
+{% if overview %}
+
+{{ overview }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='overview' purpose='states, in one or two sentences, the purpose of this document' %}
+
+{% endif %}
+
+
+* TOC
+{: toc}
+
+
+{% if prerequisites %}
+
+## Before you begin
+
+{{ prerequisites }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='prerequisites' heading='Before you begin' purpose='lists action prerequisites and knowledge prerequisites' %}
+
+{% endif %}
+
+
+{% if steps %}
+
+{{ steps }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='steps' purpose='lists a sequence of numbered steps that accomplish the task.' %}
+
+{% endif %}
+
+
+{% if discussion %}
+
+{{ discussion }}
+
+{% else %}
+
+{% endif %}
+
+
+{% if whatsnext %}
+
+## What's next
+
+{{ whatsnext }}
+
+{% endif %}
diff --git a/cn/_includes/templates/tutorial.md b/cn/_includes/templates/tutorial.md
new file mode 100644
index 0000000000..b4c1faa0f1
--- /dev/null
+++ b/cn/_includes/templates/tutorial.md
@@ -0,0 +1,68 @@
+{% if overview %}
+
+{{ overview }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='overview' purpose='states, in one or two sentences, the purpose of this document' %}
+
+{% endif %}
+
+
+* TOC
+{: toc}
+
+
+{% if objectives %}
+
+## Objectives
+
+{{ objectives }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='objectives' heading='Objectives' purpose='lists the objectives for this tutorial.' %}
+
+{% endif %}
+
+
+{% if prerequisites %}
+
+## Before you begin
+
+{{ prerequisites }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='prerequisites' heading='Before you begin' purpose='lists action prerequisites and knowledge prerequisites' %}
+
+{% endif %}
+
+
+{% if lessoncontent %}
+
+{{ lessoncontent }}
+
+{% else %}
+
+{% include templates/_errorthrower.md missing_block='lessoncontent' purpose='provides the lesson content for this tutorial.' %}
+
+{% endif %}
+
+
+{% if cleanup %}
+
+## Cleaning up
+
+{{ cleanup }}
+
+{% endif %}
+
+
+{% if whatsnext %}
+
+## What's next
+
+{{ whatsnext }}
+
+{% endif %}
diff --git a/cn/docs/admin/authorization/abac.md b/cn/docs/admin/authorization/abac.md
index 1db4103ed8..bdf17e9c82 100644
--- a/cn/docs/admin/authorization/abac.md
+++ b/cn/docs/admin/authorization/abac.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- erictune
- lavalamp
- deads2k
diff --git a/cn/docs/admin/authorization/index.md b/cn/docs/admin/authorization/index.md
index fdf788fd1c..ff878b6da4 100644
--- a/cn/docs/admin/authorization/index.md
+++ b/cn/docs/admin/authorization/index.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- erictune
- lavalamp
- deads2k
diff --git a/cn/docs/admin/authorization/webhook.md b/cn/docs/admin/authorization/webhook.md
new file mode 100644
index 0000000000..5c4f7a13e4
--- /dev/null
+++ b/cn/docs/admin/authorization/webhook.md
@@ -0,0 +1,142 @@
+---
+approvers:
+- erictune
+- lavalamp
+- deads2k
+- liggitt
+title: Webhook Mode
+---
+
+{% capture overview %}
+WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL 。
+{% endcapture %}
+
+{% capture body %}
+具体来说,当在判断用户权限时,`Webhook` 模式会使 Kubernetes 查询外部的 REST 服务。
+
+## 配置文件格式
+
+`Webhook` 模式需要一个 HTTP 配置文件,通过 `--authorization-webhook-config-file=SOME_FILENAME` 的参数声明。
+
+配置文件的格式使用 [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)。
+在文件中,"users" 代表着 API 服务器的 webhook,而 "cluster" 代表着远程服务。
+
+使用 HTTPS 客户端认证的配置例子:
+
+```yaml
+# clusters 代表远程服务。
+clusters:
+ - name: name-of-remote-authz-service
+ cluster:
+ certificate-authority: /path/to/ca.pem # 对远程服务进行身份认证的CA。
+ server: https://authz.example.com/authorize # 远程服务的查询 URL. 必须使用 'https'。
+
+# users 代表 API 服务器的 webhook 配置.
+users:
+ - name: name-of-api-server
+ user:
+ client-certificate: /path/to/cert.pem # webhook plugin 使用的 cert。
+ client-key: /path/to/key.pem # cert 所对应的 key。
+
+# kubeconfig 文件必须有 context 。 需要提供一个给 API 服务器。
+current-context: webhook
+contexts:
+- context:
+ cluster: name-of-remote-authz-service
+ user: name-of-api-server
+ name: webhook
+```
+
+
+## 请求载荷
+
+在做认证决策时,API 服务器会 POST 一个 JSON 序列化的 api.authorization.v1beta1.SubjectAccessReview 对象来描述这个动作。这个对象包含了描述用户请求的字段,同时也包含了需要被访问资源或者请求特征的具体信息。
+
+需要注意的是 webhook API 对象与其他 Kubernetes API 对象一样都同样都服从 [版本兼容规则](/docs/api/) 。
+实施人员应该了解 beta 对象的更宽松的兼容性承诺,同时确认请求的 "apiVersion" 字段以确保能被正确地反序列化。
+此外,API 服务器还必须启用 `authorization.k8s.io/v1beta1` API 扩展组(`--runtime-config=authorization.k8s.io/v1beta1=true`)。
+
+
+一个请求内容的例子:
+
+```json
+{
+ "apiVersion": "authorization.k8s.io/v1beta1",
+ "kind": "SubjectAccessReview",
+ "spec": {
+ "resourceAttributes": {
+ "namespace": "kittensandponies",
+ "verb": "get",
+ "group": "unicorn.example.org",
+ "resource": "pods"
+ },
+ "user": "jane",
+ "group": [
+ "group1",
+ "group2"
+ ]
+ }
+}
+```
+
+远程服务被预期能填写请求和反馈的 SubjectAccessReviewStatus 字段,无论是允许访问还是拒绝访问。
+反馈内容的 "spec" 字段是被忽略的,也是可以被省略的。当请求是被允许的时候,返回的响应如下例所示:
+
+```json
+{
+ "apiVersion": "authorization.k8s.io/v1beta1",
+ "kind": "SubjectAccessReview",
+ "status": {
+ "allowed": true
+ }
+}
+```
+
+
+如拒绝,远程服务器会返回:
+
+```json
+{
+ "apiVersion": "authorization.k8s.io/v1beta1",
+ "kind": "SubjectAccessReview",
+ "status": {
+ "allowed": false,
+ "reason": "user does not have read access to the namespace"
+ }
+}
+```
+
+
+对于非资源的路径访问是这么发送的:
+
+```json
+{
+ "apiVersion": "authorization.k8s.io/v1beta1",
+ "kind": "SubjectAccessReview",
+ "spec": {
+ "nonResourceAttributes": {
+ "path": "/debug",
+ "verb": "get"
+ },
+ "user": "jane",
+ "group": [
+ "group1",
+ "group2"
+ ]
+ }
+}
+```
+
+
+非资源类的路径包括:`/api`, `/apis`, `/metrics`, `/resetMetrics`,
+`/logs`, `/debug`, `/healthz`, `/swagger-ui/`, `/swaggerapi/`, `/ui`, and
+`/version`。 客户端需要访问 `/api`, `/api/*`, `/apis`, `/apis/*`, 和 `/version` 以便
+能发现服务器上有什么资源和版本。对于其他非资源类的路径访问在没有 REST API 访问限制的情况下拒绝。
+
+
+更多信息可以参考 uthorization.v1beta1 API 对象和
+[webhook.go](https://git.k8s.io/kubernetes/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go).
+
+{% endcapture %}
+
+{% include templates/concept.md %}
diff --git a/cn/docs/admin/bootstrap-tokens.md b/cn/docs/admin/bootstrap-tokens.md
new file mode 100644
index 0000000000..11ce1c53d7
--- /dev/null
+++ b/cn/docs/admin/bootstrap-tokens.md
@@ -0,0 +1,137 @@
+---
+approvers:
+- jbeda
+title: 使用启动引导令牌(Bootstrap Tokens)认证
+---
+
+* TOC
+{:toc}
+
+## 概述
+
+启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群或者在现有集群中添加新节点时使用的。
+它被设计成能够支持 [`kubeadm`](/docs/admin/kubeadm/),但是也可以被用在其他的案例中以便用户在
+不使用 `kubeadm` 的情况下启动集群。它也被设计成可以通过 RBAC 策略,结合 [Kubelet TLS
+Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。
+
+启动引导令牌被定义成一个特定类型的 secrets(`bootstrap.kubernetes.io/token`),并存在于
+`kube-system` 命名空间中。然后这些 secrets 会被 API 服务器上的启动引导的认证器读取。
+控制器管理器中的控制器TokenCleaner能够删除过期的令牌。在节点发现的过程中Kubernetes会使用特殊的ConfigMap对象。
+控制器管理器中的BootstrapSigner控制器也会使用启动引导令牌为这类对象生成签名信息。
+
+目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性变化。
+
+## 令牌格式
+
+启动引导令牌使用 `abcdef.0123456789abcdef` 的形式。
+更加规范地说,它们必须符合正则表达式 `[a-z0-9]{6}\.[a-z0-9]{16}`。
+
+令牌的第一部分是 "Token ID" ,它是公共信息。用于引用某个令牌,并确保不会泄露认证所使用的秘密信息。
+第二部分是 "令牌秘密(Token Secret)",它应该被共享给收信的第三方。
+
+## 启用启动引导令牌
+
+所有与启动引导令牌相关的特性在 Kubernetes v1.6 版本中默认都是禁用的。
+
+你可以在 API 服务器上通过 `--experimental-bootstrap-token-auth` 参数启用启动引导令牌。
+你可以设置控制管理器的 `--controllers` 参数来启用启动引导令牌相关的控制器,例如 `--controllers=*,tokencleaner,bootstrapsigner` 。
+在使用 `kubeadm` 时,这是自动完成的。
+
+HTTPS 调用中的令牌是这样使用的:
+
+```http
+Authorization: Bearer 07401b.f395accd246ae52d
+```
+
+## 启动引导令牌的密文格式
+
+每个合法的令牌背后对应着 `kube-system` 命名空间中的某个 Secret 对象。
+你可以从 [这里](https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md) 找到完整设计文档。
+
+这是 secret 看起来的样子。注意,`base64(string)` 表示应该通过 base64 对值进行编码。
+这里使用的是未解码的版本以便于阅读。
+
+```yaml
+apiVersion: v1
+kind: Secret
+metadata:
+ name: bootstrap-token-07401b
+ namespace: kube-system
+type: bootstrap.kubernetes.io/token
+data:
+ description: base64(The default bootstrap token generated by 'kubeadm init'.)
+ token-id: base64(07401b)
+ token-secret: base64(f395accd246ae52d)
+ expiration: base64(2017-03-10T03:22:11Z)
+ usage-bootstrap-authentication: base64(true)
+ usage-bootstrap-signing: base64(true)
+```
+
+secret 的类型必须是 `bootstrap.kubernetes.io/token` ,而且名字必须是 `bootstrap-token-`。
+`description` 是人类可读的描述,而不应该是机器可读的信息。令牌 ID 和 Secret 是包含在数据字典中的。
+
+`usage-bootstrap-*` 成员表示这个 secret 的用途。启用时,值必须设置为 `true`。
+
+`usage-bootstrap-authentication` 表示令牌可以用于 API 服务器的认证。认证器会以
+`system:bootstrap:` 认证。它被包含在 `system:bootstrappers` 组中。
+命名和组是故意受限制的,以防止用户在启动引导后再使用这些令牌。
+
+`usage-bootstrap-signing` 表示令牌应该被用于 `cluster-info` ConfigMap 的签名,就像下面描述的那样。
+
+`expiration` 数据成员显示了令牌在失效后到现在的时间。这是遵循 RFC3339 进行编码的 UTC 时间。
+TokenCleaner 控制器会删除过期的令牌。
+
+## 使用 `kubeadm` 管理令牌
+
+你可以使用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群(`/etc/kubernetes/admin.conf`)
+自动抓取默认管理员密码。你可以通过参数 `--kubeconfig` 对下面命令指定一个另外的 kubeconfig 文件抓取密码。
+
+* `kubeadm token list` 列举了令牌,同时显示了它们的过期时间和用途。
+* `kubeadm token create` 创建一个新令牌。
+ * `--description` 设置新令牌的描述。
+ * `--ttl duration` 设置令牌从 "现在" 起到过期时间的差值。
+ 默认是 0 ,也就是不过期。
+ * `--usages` 设置令牌被使用的方式。默认是 `signing,authentication`。用途在上面已经描述。
+* `kubeadm token delete |.` 删除令牌。
+ 令牌可以只用 ID 来确认,也可以用整个令牌的值。如果只用 ID 的情况下,密文不匹配的令牌也会被删除。
+
+### ConfigMap签名
+
+除了认证之外,令牌可以用于签名 ConfigMap。这在集群启动过程的早期,在客户端信任 API 服务器之前被使用。
+被签名的 ConfigMap 可以通过共享令牌被认证。
+
+被签名的 ConfigMap 是 `cluster-info`,存在于 `kube-public` 命名空间中。
+典型的工作流中,客户端在未经认证和忽略 TLS 报错的状态下读取这个 ConfigMap。
+通过 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。
+
+ConfigMap 会是这个样子的:
+
+```yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: cluster-info
+ namespace: kube-public
+data:
+ jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
+ kubeconfig: |
+ apiVersion: v1
+ clusters:
+ - cluster:
+ certificate-authority-data:
+ server: https://10.138.0.2:6443
+ name: ""
+ contexts: []
+ current-context: ""
+ kind: Config
+ preferences: {}
+ users: []
+```
+
+ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件。
+这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。
+
+签名是一个 JWS 签名,使用了 "detached" 模式。为了检验签名,用户应该按照 JWS 规则
+(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间
+,用于形成一个完整的 JWS。可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥,
+通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 用户 _必须_ 确保使用了 HS256。
diff --git a/cn/docs/admin/cluster-large.md b/cn/docs/admin/cluster-large.md
new file mode 100644
index 0000000000..9f6b33c94f
--- /dev/null
+++ b/cn/docs/admin/cluster-large.md
@@ -0,0 +1,122 @@
+---
+approvers:
+- davidopp
+- lavalamp
+title: 创建大规模集群
+---
+
+## 支持规格
+
+在 {{page.version}},Kubernetes支持最多5000节点规模的集群。 更具体地说,我们支持满足以下 *所有* 标准的配置:
+
+* 不超过5000节点
+* 总共不超过15000个pod
+* 总共不超过300000个容器
+* 每个节点不超过100个pod
+
+
+
+* TOC
+{:toc}
+
+## 创建
+
+集群是一组运行Kubernetes代理组件的节点(物理或虚拟机),它们被 "master" (集群管理平面)所管理。
+
+一般来说,集群的节点数量通过平台相关的 `config-default.sh` 文件中的 `NUM_NODES` 值来控制,(例如,详见 [GCE's `config-default.sh`](http://releases.k8s.io/{{page.githubbranch}}/cluster/gce/config-default.sh))。
+
+对很多云提供商来说,单纯地修改`NUM_NODES` 为一个非常大的值,可能会导致集群的创建脚本失败。 例如,在GCE中部署时,会因配额不足,导致集群启动失败。
+
+当建立一个大型的Kubernetes集群,以下几个问题必须考虑。
+
+### 配额问题
+
+为了避免出现配额问题,当创建包含大量节点的集群时,考虑:
+
+* 提高相关配额,如CPU,IP等。
+ * 如,在 [GCE](https://cloud.google.com/compute/docs/resource-quotas)中,你可能需要提高以下资源的配额:
+ * CPU
+ * 虚机实例
+ * 磁盘
+ * 使用的IP地址
+ * 防火墙规则
+ * 转发规则
+ * 路由
+ * 对象池
+* 设置创建脚本,使其以较小的规模分批次拉起新的节点,并在其间设置一定的等待时间,因为一些云供应商可能对虚机的创建速率进行了限制。
+
+### Etcd存储
+
+为了提升大规模集群的性能,我们将事件对象存储到独立的etcd实例中。
+
+创建集群时,当前的salt脚本:
+
+* 启动并配置额外的etcd实例
+* 配置api-server,将该etcd实例用于事件对象的存储
+
+### 管理节点和组件的规格
+
+在 GCE/Google Kubernetes Engine 或 AWS平台中, `kube-up` 会根据集群的节点规模合理地设置管理节点的规格。 在其他云平台上,用户需要手动配置。 作为参考,GCE使用的规格为:
+
+* 1-5 节点: n1-standard-1
+* 6-10 节点: n1-standard-2
+* 11-100 节点: n1-standard-4
+* 101-250 节点: n1-standard-8
+* 251-500 节点: n1-standard-16
+* 500节点以上: n1-standard-32
+
+AWS使用的规格为:
+
+* 1-5 节点: m3.medium
+* 6-10 节点: m3.large
+* 11-100 节点: m3.xlarge
+* 101-250 节点: m3.2xlarge
+* 251-500 节点: c4.4xlarge
+* 500节点以上: c4.8xlarge
+
+注意,管理节点的规格只会在集群创建时进行设置,后续集群规模发生变化 (如 手动增删节点或集群自动扩缩容)后不会再调整。
+
+### 插件的资源占用
+
+为防止 [集群插件](https://releases.k8s.io/{{page.githubbranch}}/cluster/addons) 耗尽节点资源引起内存泄漏或其他资源问题, Kubernetes 设置了插件容器资源的上限,来限制其对CPU和内存资源的占用 (参考 PR [#10653](http://pr.k8s.io/10653/files) 和 [#10778](http://pr.k8s.io/10778/files))。
+
+例如:
+
+```yaml
+ containers:
+ - name: fluentd-cloud-logging
+ image: gcr.io/google_containers/fluentd-gcp:1.16
+ resources:
+ limits:
+ cpu: 100m
+ memory: 200Mi
+```
+
+除 Heapster 外,这些限制是静态的,基于4个节点规模的集群上运行的插件所采集的数据 (详见 [#10335](http://issue.k8s.io/10335#issuecomment-117861225))。 而实际大规模集群中插件所消耗的资源要多得多 (详见 [#5880](http://issue.k8s.io/5880#issuecomment-113984085))。 所以如果部署大规模集群时不对这些值进行调整,插件可能会因为资源占用达到上限而不断被杀死。
+
+为了避免集群插件的资源问题,创建多节点的集群时,考虑以下几点:
+
+* 当扩大集群规模时,如果涉及,相应扩大以下插件的内存和CPU限制 (通过一个实例处理整个集群,因此其内存和CPU使用量往往与集群的大小/负载成比例增长):
+ * [InfluxDB 和 Grafana](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-monitoring/influxdb/influxdb-grafana-controller.yaml)
+ * [kubedns, dnsmasq, 和 sidecar](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/kubedns-controller.yaml.in)
+ * [Kibana](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/kibana-controller.yaml)
+* 当扩大集群规模时,如果涉及,相应扩大以下插件副本数 (每个组件有多个副本,因此增加副本将有助于处理增加的负载,但是,由于每个副本的负载也略有增加,也应考虑提高CPU /内存上限):
+ * [elasticsearch](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/es-controller.yaml)
+* 当扩大集群规模时,如果涉及,略微扩大以下插件的内存和CPU限制 (每个节点一个副本, 但是CPU/内存使用随集群的大小/负载增长变化不明显):
+ * [FluentD with ElasticSearch Plugin](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml)
+ * [FluentD with GCP Plugin](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-gcp/fluentd-gcp-ds.yaml)
+
+Heapster的资源限制是基于集群的初始规模动态设置的 (参考 [#16185](http://issue.k8s.io/16185)
+和 [#22940](http://issue.k8s.io/22940))。 当发现Heapster资源耗尽,应考虑调整计算Heapster内存请求的公式 (参考上述PR)。
+
+关于如何检测插件是否达到资源上限 参考 [计算资源的故障排除章节](/docs/concepts/configuration/manage-compute-resources-container/#troubleshooting)。
+
+[将来](http://issue.k8s.io/13048),我们期望基于集群规模来设置集群插件的资源限制,并且在集群规模增长或缩小时能够动态调整。
+欢迎提出PR来实现这些特性。
+
+### 启动时允许部分失败
+
+因为种种原因 (详见 [#18969](https://github.com/kubernetes/kubernetes/issues/18969)),在 `NUM_NODES` 值很大的情况下执行
+`kube-up.sh`, 可能因为其中一小部分节点没有正常启动而失败。
+这时我们有两种选择:重启集群 (`kube-down.sh` 然后再 `kube-up.sh`),或者在执行 `kube-up.sh`之前,
+将环境变量 `ALLOWED_NOTREADY_NODES` 设置为合适的值。 这将允许 `kube-up.sh` 以少于 `NUM_NODES` 的节点数量启动集群。 依据失败的具体原因,另外的节点可能在后面加入集群,或者集群节点数量将保持在 `NUM_NODES - ALLOWED_NOTREADY_NODES`。
diff --git a/cn/docs/admin/high-availability/index.md b/cn/docs/admin/high-availability/index.md
index f8d851e236..2994680cfa 100644
--- a/cn/docs/admin/high-availability/index.md
+++ b/cn/docs/admin/high-availability/index.md
@@ -9,7 +9,7 @@ title: 构建高可用集群
本文描述了如何构建一个高可用(high-availability, HA)的Kubernetes集群。这是一个非常高级的主题。
对于仅希望使用Kubernetes进行试验的用户,推荐使用更简单的配置工具进行搭建,例如:
-[Minikube](/docs/getting-started-guides/minikube/),或者尝试使用[Google Container Engine](https://cloud.google.com/container-engine/) 来运行Kubernetes。
+[Minikube](/docs/getting-started-guides/minikube/),或者尝试使用[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) 来运行Kubernetes。
此外,当前在我们的端到端(e2e)测试环境中,没有对Kubernetes高可用的支持进行连续测试。我们将会增加这个连续测试项,但当前对单节点master的安装测试得更加严格。
diff --git a/cn/docs/admin/kubelet-authentication-authorization.md b/cn/docs/admin/kubelet-authentication-authorization.md
index 6d26b1c670..03ab5fd64b 100644
--- a/cn/docs/admin/kubelet-authentication-authorization.md
+++ b/cn/docs/admin/kubelet-authentication-authorization.md
@@ -36,6 +36,8 @@ To enable API bearer tokens (including service account tokens) to be used to aut
* start the kubelet with the `--authentication-token-webhook`, `--kubeconfig`, and `--require-kubeconfig` flags
* the kubelet calls the `TokenReview` API on the configured API server to determine user information from bearer tokens
+**Note:** The flag `--require-kubeconfig` is deprecated as of Kubernetes 1.8, this will be removed in a future version. You no longer need to use `--require-kubeconfig` in Kubernetes 1.8.
+
## Kubelet authorization
Any request that is successfully authenticated (including an anonymous request) is then authorized. The default authorization mode is `AlwaysAllow`, which allows all requests.
@@ -52,6 +54,8 @@ To subdivide access to the kubelet API, delegate authorization to the API server
* start the kubelet with the `--authorization-mode=Webhook`, `--kubeconfig`, and `--require-kubeconfig` flags
* the kubelet calls the `SubjectAccessReview` API on the configured API server to determine whether each request is authorized
+**Note:** The flag `--require-kubeconfig` is deprecated as of Kubernetes 1.8, this will be removed in a future version. You no longer need to use `--require-kubeconfig` in Kubernetes 1.8.
+
The kubelet authorizes API requests using the same [request attributes](/docs/admin/authorization/#request-attributes) approach as the apiserver.
The verb is determined from the incoming request's HTTP verb:
diff --git a/cn/docs/admin/multiple-zones.md b/cn/docs/admin/multiple-zones.md
index 4eac17c49f..daf2d53d86 100644
--- a/cn/docs/admin/multiple-zones.md
+++ b/cn/docs/admin/multiple-zones.md
@@ -10,13 +10,13 @@ title: 多区域运行
Kubernetes 从v1.2开始支持将集群运行在多个故障域中。
(GCE 中称其为 "区(Zones)", AWS 中称其为 "可用区(Availability Zones)",这里我们也称其为 "区")。
-它是广泛意义上的集群联邦特性的轻量级版本 (之前被称为 ["Ubernetes"](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/federation/federation.md))。
+它是广泛意义上的集群联邦特性的轻量级版本 (之前被称为 ["Ubernetes"](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/multicluster/federation.md))。
完整的集群联邦能够将多个分别运行在不同区或云供应商(或本地数据中心)的集群集中管理。
然而,很多用户只是希望通过将单一云供应商上的Kubernetes集群运行在多个区域,来提高集群的可用性,
这就是1.2版本中提供的对多区域的支持。
(之前被称为 "Ubernetes Lite")。
-多区域的支持是有明确限制的: Kubernetes集群能够运行在多个区,但必须在同一个地域内 (云供应商也须一致)。
+多区域的支持是有明确限制的: Kubernetes集群能够运行在多个区,但必须在同一个地域内 (云供应商也须一致)。
目前只有GCE和AWS自动支持 (尽管在其他云甚至裸机上,也很容易通过为节点和卷添加合适的标签来实现类似的支持)。
@@ -59,7 +59,7 @@ Kubernetes 从v1.2开始支持将集群运行在多个故障域中。
## 演练
-接下来我们将介绍如何同时在 GCE 和 AWS 上创建和使用多区域的集群。 为此,你需要创建一个完整的集群
+接下来我们将介绍如何同时在 GCE 和 AWS 上创建和使用多区域的集群。 为此,你需要创建一个完整的集群
(指定 `MULTIZONE=true`),然后再次执行 `kube-up`(指定 `KUBE_USE_EXISTING_MASTER=true`)来添加其他区域的节点。
### 创建集群
diff --git a/cn/docs/admin/node-conformance.md b/cn/docs/admin/node-conformance.md
new file mode 100644
index 0000000000..6be4ba50a0
--- /dev/null
+++ b/cn/docs/admin/node-conformance.md
@@ -0,0 +1,84 @@
+---
+approvers:
+- Random-Liu
+title: 节点设置校验
+---
+
+* TOC
+{:toc}
+
+## 节点合规性测试
+
+*节点合规性测试* 是一个容器化的测试框架,提供了针对节点的系统验证和功能测试。 该测试主要检测节点是否满足 Kubernetes 的最低要求,通过检测的节点有资格加入 Kubernetes 集群。
+
+## 限制
+
+在 Kubernetes 1.5版本中,节点合规性测试存在以下限制:
+
+* 节点合规性测试只支持 Docker 作为容器运行时环境。
+
+## 节点的前提条件
+
+为运行节点合规性测试,节点必须满足与标准的 Kubernetes 节点同样的前提条件。最基本地, 节点应安装以下组件:
+
+* 容器运行时 (Docker)
+* Kubelet
+
+## 运行节点合规性测试
+
+执行以下步骤来运行节点合规性测试:
+
+1. 因为测试框架会启动一个本地的 master 来测试 Kubelet,
+所以将 Kubelet 指向本机 `--api-servers="http://localhost:8080"。 还有一些其他 Kubelet 参数可能需要注意:
+ * `--pod-cidr`: 如果使用 `kubenet`, 需要为 Kubelet 任意指定一个 CIDR, 例如 `--pod-cidr=10.180.0.0/24`。
+ * `--cloud-provider`: 如果使用 `--cloud-provider=gce`,需要移除这个参数来运行测试。
+
+2. 执行以下命令来运行节点合规性测试:
+
+```shell
+# $CONFIG_DIR 是 Kubelet 的 manifest 文件路径。
+# $LOG_DIR 是测试结果输出的路径。
+sudo docker run -it --rm --privileged --net=host \
+ -v /:/rootfs -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
+ gcr.io/google_containers/node-test:0.2
+```
+
+## 针对其他硬件体系结构运行节点合规性测试
+
+Kubernetes 也为其他硬件体系结构的系统提供了节点合规性测试的 Docker 镜像:
+
+ Arch | Image |
+--------|:-----------------:|
+ amd64 | node-test-amd64 |
+ arm | node-test-arm |
+ arm64 | node-test-arm64 |
+
+## 运行选定的测试
+
+为运行指定的测试,用正则表达式来描述将要运行的测试,并重载 `FOCUS` 环境变量。
+
+```shell
+sudo docker run -it --rm --privileged --net=host \
+ -v /:/rootfs:ro -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
+ -e FOCUS=MirrorPod \ # 只运行MirrorPod测试
+ gcr.io/google_containers/node-test:0.2
+```
+
+为跳过指定的测试,用正则表达式来描述将要跳过的测试,并重载 `SKIP` 环境变量。
+
+```shell
+sudo docker run -it --rm --privileged --net=host \
+ -v /:/rootfs:ro -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
+ -e SKIP=MirrorPod \ # 运行除MirrorPod外的所有测试
+ gcr.io/google_containers/node-test:0.2
+```
+
+节点合规性测试是[节点端到端测试](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/devel/e2e-node-tests.md)的一个容器化的版本。
+默认情况下, 它会运行所有的合规性测试用例。
+
+理论上,只要合理地配置容器和挂载所需的卷,就可以运行任何的节点端到端测试用例。 但是这里 **强烈建议只运行合规性测试**,因为运行非合规性测试需要很多复杂的配置。
+
+## 注意事项
+
+* 测试会在节点上遗留一些Docker镜像, 包括节点合规性测试本身的镜像,和功能测试相关的镜像。
+* 测试会在节点上遗留一些死的容器。这些容器是在功能测试的过程中创建的。
diff --git a/cn/docs/admin/ovs-networking.md b/cn/docs/admin/ovs-networking.md
index 7153f2a7b1..5b4fe7f5f8 100644
--- a/cn/docs/admin/ovs-networking.md
+++ b/cn/docs/admin/ovs-networking.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- thockin
title: Kubernetes OpenVSwitch GRE/VxLAN 网络
---
diff --git a/cn/docs/admin/service-accounts-admin.md b/cn/docs/admin/service-accounts-admin.md
new file mode 100644
index 0000000000..bf3e0783f9
--- /dev/null
+++ b/cn/docs/admin/service-accounts-admin.md
@@ -0,0 +1,89 @@
+---
+approvers:
+- bprashanth
+- davidopp
+- lavalamp
+- liggitt
+title: 管理Service Accounts
+---
+
+*这是一篇针对service accounts(服务账户)的集群管理员指南。 它呈现了 [User Guide to Service Accounts](/docs/user-guide/service-accounts)中的信息。*
+
+*对授权和用户账户的支持已在规划中,当前并不完备,为了更好地描述service accounts,有时这些不完善的特性也会被提及。*
+
+## 用户账户与服务账户
+
+Kubernetes 区分用户账户和服务账户的概念主要基于以下原因:
+
+ - 用户账户是针对人而言的。 服务账户是针对运行在pod中的进程而言的。
+ - 用户账户是全局性的。 其名称在集群各namespace中都是全局唯一的,未来的用户资源不会做namespace隔离,
+ 服务账户是namespace隔离的。
+ - 通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 (即权限最小化原则)。
+ - 对人员和服务账户审计所考虑的因素可能不同。
+ - 针对复杂系统的配置可能包含系统组件相关的各种服务账户的定义。 因为服务账户可以定制化地创建,并且有namespace级别的名称,这种配置是很轻量的。
+
+## 服务账户的自动化
+
+三个独立组件协作完成服务账户相关的自动化:
+
+ - 服务账户准入控制器(Service account admission controller)
+ - Token控制器(Token controller)
+ - 服务账户控制器(Service account controller)
+
+### 服务账户准入控制器
+
+对pod的改动通过一个被称为[Admission Controller](/docs/admin/admission-controllers)的插件来实现。它是apiserver的一部分。
+当pod被创建或更新时,它会同步地修改pod。 当该插件处于激活状态(在大多数发行版中都是默认的),当pod被创建或更新时它会进行以下动作:
+
+ 1. 如果该pod没有 `ServiceAccount` 设置,将其 `ServiceAccount` 设为 `default`。
+ 2. 保证pod所关联的 `ServiceAccount` 存在,否则拒绝该pod。
+ 4. 如果pod不包含 `ImagePullSecrets`设置,那么 将 `ServiceAccount`中的`ImagePullSecrets` 信息添加到pod中。
+ 5. 将一个包含用于API访问的token的 `volume` 添加到pod中。
+ 6. 将挂载于 `/var/run/secrets/kubernetes.io/serviceaccount` 的 `volumeSource`添加到pod下的每个容器中。
+
+### Token管理器
+
+Token管理器是controller-manager的一部分。 以异步的形式工作:
+
+- 检测服务账户的创建,并且创建相应的Secret以支持API访问。
+- 检测服务账户的删除,并且删除所有相应的服务账户Token Secret。
+- 检测Secret的增加,保证相应的服务账户存在,如有需要,为Secret增加token。
+- 检测Secret的删除,如有需要,从相应的服务账户中移除引用。
+
+你需要通过 `--service-account-private-key-file` 参数项传入一个服务账户私钥文件至Token管理器。 私钥用于为生成的服务账户token签名。
+同样地,你需要通过 `--service-account-key-file` 参数将对应的公钥传入kube-apiserver。 公钥用于认证过程中的token校验。
+
+#### 创建额外的 API tokens
+
+控制器中有专门的循环来保证每个服务账户中都存在API token对应的Secret。 当需要为服务账户创建额外的API token时,创建一个类型为 `ServiceAccountToken` 的Secret,并在annotation中引用服务账户,控制器会生成token并更新:
+
+secret.json:
+
+```json
+{
+ "kind": "Secret",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "mysecretname",
+ "annotations": {
+ "kubernetes.io/service-account.name": "myserviceaccount"
+ }
+ },
+ "type": "kubernetes.io/service-account-token"
+}
+```
+
+```shell
+kubectl create -f ./secret.json
+kubectl describe secret mysecretname
+```
+
+#### 删除/失效 服务账户token
+
+```shell
+kubectl delete secret mysecretname
+```
+
+### 服务账户管理器
+
+服务账户管理器管理各命名空间下的服务账户,并且保证每个活跃的命名空间下存在一个名为 "default" 的服务账户
diff --git a/cn/docs/concepts/architecture/cloud-controller.md b/cn/docs/concepts/architecture/cloud-controller.md
new file mode 100644
index 0000000000..644e3e7d0a
--- /dev/null
+++ b/cn/docs/concepts/architecture/cloud-controller.md
@@ -0,0 +1,248 @@
+title: 云控制器管理器的基本概念
+
+## 云控制器管理器
+
+云控制器管理器(CCM)这个概念创建的初衷是为了让特定的云服务供应商代码和Kubernetes核心相互独立演化。云控制器管理器与其他主要组件如Kubernetes控制器管理器,API服务器和调度程序同时运行。云控制器管理器也可以作为Kubernetes的插件启动,这种情况下,CCM运行在Kubernetes系统之上。
+
+云控制器管理器基于插件机制设计,允许新的云服务供应商通过插件轻松地与Kubernetes集成。目前已经有在Kubernetes上加入新的云服务供应商计划,并为云服务供应商提供从原先的旧模式迁移到新CCM模式的方案。
+
+本文讨论了云控制器管理器背后的概念,并提供了相关功能的详细信息。
+
+下面这张图描述了没有云控制器管理器的Kubernetes集群架构:
+
+
+
+## 设计
+
+在上图中,Kubernetes和云服务供应商通过几个不同的组件进行了集成,分别是:
+
+* Kubelet
+* Kubernetes 控制管理器
+* Kubernetes API服务器
+
+而CCM整合了前三个组件中的所有依赖于云的逻辑,用来创建与云的单点集成。新架构如下图所示:
+
+
+
+## CCM的组件
+
+CCM突破了Kubernetes控制器管理器(KCM)的一些功能,并将其作为一个独立的进程运行。具体而言,它打破了KCM中与云相关的控制器。KCM具有以下依赖于云的控制器引擎:
+
+* 节点控制器
+* 卷控制器
+* 路由控制器
+* 服务控制器
+
+在1.8版本中,当前运行中的CCM从上面的列表中运行以下控制器:
+
+* 节点控制器
+* 路由控制器
+* 服务控制器
+
+另外,它运行另一个名为 PersistentVolumeLabels Controller 的控制器。这个控制器负责对在GCP和AWS云里创建的PersistentVolumes的域(Zone)和区(Region)标签进行设置。
+
+**注意**:卷控制器被特意设计为CCM之外的一部分。由于其中涉及到的复杂性和对现有供应商特定卷的逻辑抽象,因此决定了卷控制器不会被移动到CCM之中。
+
+原本计划使用CCM来支持卷的目的是为了引入FlexVolume卷来支持可插拔卷。然而,官方正在计划使用更具备竞争力的CSI来取代FlexVolume卷。
+
+考虑到这些正在进行中的变化,我们决定暂时停止当前工作直至CSI准备就绪。
+
+云服务供应商工作组(wg-cloud-provider)正在开展相关工作,以实现通过CCM支持PersistentVolume的功能。详细信息请参见[kubernetes/kubernetes#52371](https://github.com/kubernetes/kubernetes/pull/52371)。
+
+## CCM功能
+
+CCM从Kubernetes组件中继承了与云服务供应商相关的功能。本节基于被CCM继承其功能的组件展开描述。
+
+### 1. Kubernetes 控制器管理器
+
+CCM的大部分功能都来自KCM。 如上一节所述,CCM运行以下控制引擎:
+
+* 节点控制器
+* 路由控制器
+* 服务控制器
+* PersistentVolumeLabels控制器
+
+#### 节点控制器
+
+节点控制器负责通过从云服务供应商获得有关在集群中运行的节点的信息来初始化节点。节点控制器执行以下功能:
+
+1.使用云特定域(Zone)/区(Region)标签初始化节点。
+
+1.使用特定于云的实例详细信息初始化节点,例如类型和大小。
+
+1.获取节点的网络地址和主机名。
+
+1.如果节点无响应,检查该节点是否已从云中删除。如果该节点已从云中删除,则删除Kubernetes节点对象。
+
+#### 路由控制器
+
+路由控制器负责为云配置正确的路由,以便Kubernetes集群中不同节点上的容器可以相互通信。路由控制器仅适用于Google Compute Engine平台。
+
+#### 服务控制器
+
+服务控制器负责监听服务的创建、更新和删除事件。根据Kubernetes中各个服务的当前状态,它将配置云负载平衡器(如ELB或Google LB)以反映Kubernetes中的服务状态。此外,它还确保云负载均衡器的服务后端保持最新。
+
+#### PersistentVolumeLabels 控制器
+
+PersistentVolumeLabels控制器在AWS的EBS卷、GCE的PD卷创建时申请标签,这使得用户不再需要手动设置这些卷标签。
+
+这些标签对于pod的调度工作是非常重要的,因为这些卷只能在它们所在的域(Zone)/区(Region)内工作,因此所有使用这些卷的pod都必须要在同一个域/区中才能保证进行调度正常进行。
+
+PersistentVolumeLabels控制器是专门为CCM创建的; 也就是说,在CCM创建之前它是不存在的。这样做是为了将Kubernetes API服务器(它是一个许可控制器)中的PV标签逻辑移动到CCM。 它不在KCM上运行。
+
+### 2. Kubelet
+
+Node控制器包含kubelet中依赖于云的功能。在系统引入CCM组件之前,是由kubelet采用包含云特定信息的方式对节点进行初始化,如IP地址、区(Region)/域(Zone)标签和实例类型信息;引入CCM之后,这部分的初始化操作就从kubelet转移到了CCM中。
+
+在引入CCM后的新的模型中,kubelet采用不包含云特定信息的方式初始化一个节点。但是,它会为新创建的节点添加一个污点,使得该节点不可被立即调度,直到CCM使用包含云的特定信息初始化节点后,才会删除该污点,使得该节点可被调度。
+
+### 3. Kubernetes API服务器
+
+PersistentVolumeLabels控制器将Kubernetes API服务器的依赖于云的功能移至CCM,如前面部分所述。
+
+## 插件机制
+
+云控制器管理器使用Go接口与外部对接从而实现功能扩展。具体来说,它使用了[这里](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/cloud.go)定义的CloudProvider接口。
+
+上面强调的四个共享控制器的实现,以及一些辅助设施(scaffolding)和共享的云服务供应商接口,将被保留在Kubernetes核心当中。但云服务供应商特有的实现将会建立在核心之外,并实现核心中定义的接口。
+
+有关开发插件的更多信息,请参阅
+[开发云控制器管理器](/docs/tasks/administrators-cluster/developing-cloud-controller-manager/)。
+
+## 授权
+
+本节分解了CCM对各种API对象的访问,以执行其操作。
+
+### 节点控制器
+
+节点控制器仅适用于节点对象。它需要完全访问权限来获取、列出、创建、更新、修补、监视和删除节点对象。
+
+v1/Node:
+- Get
+- List
+- Create
+- Update
+- Patch
+- Watch
+
+### 路由控制器
+
+路由控制器监听节点对象的创建并配置合适的路由。它需要对节点对象的访问权限。
+
+v1/Node:
+- Get
+
+### 服务控制器
+
+服务控制器侦听服务对象创建、更新和删除事件,然后对这些服务的端点进行恰当的配置。
+
+要访问服务,它需要罗列和监控权限。要更新服务,它需要修补和更新权限。
+
+要为服务设置端点,需要访问创建、列表、获取、监视和更新。
+
+v1/Service:
+- List
+- Get
+- Watch
+- Patch
+- Update
+
+### PersistentVolumeLabels 控制器
+
+PersistentVolumeLabels控制器监听PersistentVolume(PV)创建事件并更新它们。该控制器需要访问列表、查看、获取和更新PV的权限。
+
+v1/PersistentVolume:
+- Get
+- List
+- Watch
+- Update
+
+### 其它
+
+CCM核心的实现需要创建事件的权限,为了确保安全操作,需要创建ServiceAccounts的权限。
+
+v1/Event:
+- Create
+- Patch
+- Update
+
+v1/ServiceAccount:
+- Create
+
+针对CCM的RBAC ClusterRole如下所示:
+
+```yaml
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+ name: cloud-controller-manager
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - events
+ verbs:
+ - create
+ - patch
+ - update
+- apiGroups:
+ - ""
+ resources:
+ - nodes
+ verbs:
+ - '*'
+- apiGroups:
+ - ""
+ resources:
+ - nodes/status
+ verbs:
+ - patch
+- apiGroups:
+ - ""
+ resources:
+ - services
+ verbs:
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - ""
+ resources:
+ - serviceaccounts
+ verbs:
+ - create
+- apiGroups:
+ - ""
+ resources:
+ - persistentvolumes
+ verbs:
+ - get
+ - list
+ - update
+ - watch
+- apiGroups:
+ - ""
+ resources:
+ - endpoints
+ verbs:
+ - create
+ - get
+ - list
+ - watch
+ - update
+```
+
+## 供应商实施
+
+以下云服务供应商为自己的云部署了CCM。
+
+* [Digital Ocean]()
+* [Oracle]()
+* [Azure]()
+* [GCE]()
+* [AWS]()
+
+## 群集管理
+
+[这里](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)提供了配置和运行CCM的完整说明。
diff --git a/cn/docs/concepts/architecture/master-node-communication.md b/cn/docs/concepts/architecture/master-node-communication.md
index e090ed3197..41db6abf44 100644
--- a/cn/docs/concepts/architecture/master-node-communication.md
+++ b/cn/docs/concepts/architecture/master-node-communication.md
@@ -68,4 +68,4 @@ Master 组件通过非安全(没有加密或认证)端口和集群的 apiser
### SSH 隧道
-[Google Container Engine](https://cloud.google.com/container-engine/docs/) 使用 SSH 隧道保护 Master -> Cluster 通信路径。在这种配置下,apiserver 发起一个到集群中每个节点的 SSH 隧道(连接到在 22 端口监听的 ssh 服务)并通过这个隧道传输所有到 kubelet、node、pod 或者 service 的流量。这个隧道保证流量不会在集群运行的私有 GCE 网络之外暴露。
+[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/) 使用 SSH 隧道保护 Master -> Cluster 通信路径。在这种配置下,apiserver 发起一个到集群中每个节点的 SSH 隧道(连接到在 22 端口监听的 ssh 服务)并通过这个隧道传输所有到 kubelet、node、pod 或者 service 的流量。这个隧道保证流量不会在集群运行的私有 GCE 网络之外暴露。
diff --git a/cn/docs/concepts/architecture/nodes.md b/cn/docs/concepts/architecture/nodes.md
index f5159814d7..5ddc4ee7e4 100644
--- a/cn/docs/concepts/architecture/nodes.md
+++ b/cn/docs/concepts/architecture/nodes.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- caesarxuchao
- dchen1107
diff --git a/cn/docs/concepts/cluster-administration/certificates.md b/cn/docs/concepts/cluster-administration/certificates.md
new file mode 100644
index 0000000000..6de8e29fda
--- /dev/null
+++ b/cn/docs/concepts/cluster-administration/certificates.md
@@ -0,0 +1,248 @@
+---
+cn-approvers:
+- lichuqiang
+title: 证书
+---
+
+* TOC
+{:toc}
+
+## 创建证书
+
+当使用客户端证书进行认证时,用户可以使用现有部署脚本,或者通过 `easyrsa`、`openssl` 或
+`cfssl` 手动生成证书。
+
+### 使用现有部署脚本
+
+**现有部署脚本** 位于
+`cluster/saltbase/salt/generate-cert/make-ca-cert.sh`。
+
+执行该脚本时需传入两个参数。 第一个参数为 API 服务器的 IP 地址,第二个参数为对象的候补名称列表,
+形如 `IP: 或 DNS:`。
+
+脚本生成三个文件: `ca.crt`、`server.crt` 和 `server.key`。
+
+最后,将以下参数加入到 API 服务器的启动参数中:
+
+```
+--client-ca-file=/srv/kubernetes/ca.crt
+--tls-cert-file=/srv/kubernetes/server.crt
+--tls-private-key-file=/srv/kubernetes/server.key
+```
+
+### easyrsa
+
+使用 **easyrsa** 能够手动地为集群生成证书。
+
+1. 下载、解压并初始化 easyrsa3 的补丁版本。
+
+ curl -L -O https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
+ tar xzf easy-rsa.tar.gz
+ cd easy-rsa-master/easyrsa3
+ ./easyrsa init-pki
+1. 生成 CA(通过 `--batch` 参数设置自动模式。 通过 `--req-cn` 设置默认使用的 CN)
+
+ ./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
+1. 生成服务器证书和密钥。
+ 参数 `--subject-alt-name` 设置了访问 API 服务器时可能使用的 IP 和 DNS 名称。 `MASTER_CLUSTER_IP`
+ 通常为 `--service-cluster-ip-range` 参数中指定的服务 CIDR 的 首个 IP 地址,`--service-cluster-ip-range`同时用于
+ API 服务器和控制器管理器组件。 `--days` 参数用于设置证书的有效期限。
+ 下面的示例还假设用户使用 `cluster.local` 作为默认的 DNS 域名。
+
+ ./easyrsa --subject-alt-name="IP:${MASTER_IP}"\
+ "IP:${MASTER_CLUSTER_IP},"\
+ "DNS:kubernetes,"\
+ "DNS:kubernetes.default,"\
+ "DNS:kubernetes.default.svc,"\
+ "DNS:kubernetes.default.svc.cluster,"\
+ "DNS:kubernetes.default.svc.cluster.local" \
+ --days=10000 \
+ build-server-full server nopass
+1. 拷贝 `pki/ca.crt`、 `pki/issued/server.crt` 和 `pki/private/server.key` 至您的目录。
+1. 填充并在 API 服务器的启动参数中添加以下参数:
+
+ --client-ca-file=/yourdirectory/ca.crt
+ --tls-cert-file=/yourdirectory/server.crt
+ --tls-private-key-file=/yourdirectory/server.key
+
+### openssl
+
+使用 **openssl** 能够手动地为集群生成证书。
+
+1. 生成密钥位数为 2048 的 ca.key:
+
+ openssl genrsa -out ca.key 2048
+1. 依据 ca.key 生成 ca.crt (使用 -days 参数来设置证书有效时间):
+
+ openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
+1. 生成密钥位数为 2048 的 server.key:
+
+ openssl genrsa -out server.key 2048
+1. 创建用于生成证书签名请求(CSR)的配置文件。
+ 确保在将其保存至文件(如`csr.conf`)之前将尖括号标记的值(如``)
+ 替换为你想使用的真实值。 注意:`MASTER_CLUSTER_IP` 是前面小节中描述的 API 服务器的服务集群 IP
+ (service cluster IP)。 下面的示例也假设用户使用 `cluster.local` 作为默认的 DNS 域名。
+
+ [ req ]
+ default_bits = 2048
+ prompt = no
+ default_md = sha256
+ req_extensions = req_ext
+ distinguished_name = dn
+
+ [ dn ]
+ C =
+ ST =
+ L =
+ O =
+ OU =
+ CN =
+
+ [ req_ext ]
+ subjectAltName = @alt_names
+
+ [ alt_names ]
+ DNS.1 = kubernetes
+ DNS.2 = kubernetes.default
+ DNS.3 = kubernetes.default.svc
+ DNS.4 = kubernetes.default.svc.cluster
+ DNS.5 = kubernetes.default.svc.cluster.local
+ IP.1 =
+ IP.2 =
+
+ [ v3_ext ]
+ authorityKeyIdentifier=keyid,issuer:always
+ basicConstraints=CA:FALSE
+ keyUsage=keyEncipherment,dataEncipherment
+ extendedKeyUsage=serverAuth,clientAuth
+ subjectAltName=@alt_names
+1. 基于配置文件生成证书签名请求:
+
+ openssl req -new -key server.key -out server.csr -config csr.conf
+1. 使用 ca.key、ca.crt 和 server.csr 生成服务器证书:
+
+ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
+ -CAcreateserial -out server.crt -days 10000 \
+ -extensions v3_ext -extfile csr.conf
+1. 查看证书:
+
+ openssl x509 -noout -text -in ./server.crt
+
+最后,添加同样的参数到 API 服务器的启动参数中。
+
+### cfssl
+
+**cfssl** 是另一种用来生成证书的工具。
+
+1. 按如下所示的方式下载、解压并准备命令行工具。
+ 注意:你可能需要基于硬件架构和你所使用的 cfssl 版本对示例命令进行修改。
+
+ curl -LO https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o cfssl
+ chmod +x cfssl
+ curl -LO https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o cfssljson
+ chmod +x cfssljson
+ curl -LO https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o cfssl-certinfo
+ chmod +x cfssl-certinfo
+1. 创建目录来存放物料,并初始化 cfssl:
+
+ mkdir cert
+ cd cert
+ ../cfssl print-defaults config > config.json
+ ../cfssl print-defaults csr > csr.json
+1. 创建用来生成 CA 文件的 JSON 配置文件,例如 `ca-config.json`:
+
+ {
+ "signing": {
+ "default": {
+ "expiry": "8760h"
+ },
+ "profiles": {
+ "kubernetes": {
+ "usages": [
+ "signing",
+ "key encipherment",
+ "server auth",
+ "client auth",
+ ],
+ "expiry": "8760h"
+ }
+ }
+ }
+ }
+1. 创建用来生成 CA 证书签名请求(CSR)的 JSON 配置文件,例如 `ca-csr.json`。
+ 确保将尖括号标记的值替换为你想使用的真实值。
+
+ {
+ "CN": "kubernetes",
+ "key": {
+ "algo": "rsa",
+ "size": 2048
+ },
+ "names":[{
+ "C": "",
+ "ST": "",
+ "L": "",
+ "O": "",
+ "OU": "",
+ }]
+ }
+1. 生成 CA 密钥(`ca-key.pem`)和证书(`ca.pem`):
+
+ ../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
+1. 按如下所示的方式创建用来为 API 服务器生成密钥和证书的 JSON 配置文件。
+ 确保将尖括号标记的值替换为你想使用的真实值。 `MASTER_CLUSTER_IP` 是前面小节中描述的
+ API 服务器的服务集群 IP。 下面的示例也假设用户使用 `cluster.local` 作为默认的 DNS 域名。
+
+ {
+ "CN": "kubernetes",
+ "hosts": [
+ "127.0.0.1",
+ "",
+ "",
+ "kubernetes",
+ "kubernetes.default",
+ "kubernetes.default.svc",
+ "kubernetes.default.svc.cluster",
+ "kubernetes.default.svc.cluster.local"
+ ],
+ "key": {
+ "algo": "rsa",
+ "size": 2048
+ },
+ "names": [{
+ "C": "",
+ "ST": "",
+ "L": "",
+ "O": "",
+ "OU": ""
+ }]
+ }
+1. 为 API 服务器生成密钥和证书,生成的秘钥和证书分别默认保存在文件 `server-key.pem`
+ 和 `server.pem` 中:
+
+ ../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
+ --config=ca-config.json -profile=kubernetes \
+ server-csr.json | ../cfssljson -bare server
+
+
+## 分发自签名 CA 证书
+
+客户端节点可能拒绝承认自签名 CA 证书有效。
+对于非生产环境的部署,或运行在企业防火墙后的部署,用户可以向所有客户端分发自签名 CA 证书,
+并刷新本地的有效证书列表。
+
+在每个客户端上执行以下操作:
+
+```bash
+$ sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt
+$ sudo update-ca-certificates
+Updating certificates in /etc/ssl/certs...
+1 added, 0 removed; done.
+Running hooks in /etc/ca-certificates/update.d....
+done.
+```
+
+## 证书 API
+
+您可以按照[这里](/docs/tasks/tls/managing-tls-in-a-cluster)记录的方式,
+使用 `certificates.k8s.io` API 来准备 x509 证书,用于认证。
diff --git a/cn/docs/concepts/cluster-administration/cloud-providers.md b/cn/docs/concepts/cluster-administration/cloud-providers.md
new file mode 100644
index 0000000000..130acd2916
--- /dev/null
+++ b/cn/docs/concepts/cluster-administration/cloud-providers.md
@@ -0,0 +1,108 @@
+---
+title: 云供应商
+---
+
+{% capture overview %}
+本文介绍了如何管理运行在特定云供应商上的 Kubernetes 集群。
+{% endcapture %}
+
+{% capture body %}
+# AWS
+本节介绍在 Amazon Web Services 上运行 Kubernetes 时可以使用的所有配置。
+
+## 负载均衡器
+用户可以通过配置注解(annotations)来设置 [外部负载均衡器](/docs/tasks/access-application-cluster/create-external-load-balancer/),以在 AWS 中使用特定功能,如下所示:
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: example
+ namespace: kube-system
+ labels:
+ run: example
+ annotations:
+ service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:xx-xxxx-x:xxxxxxxxx:xxxxxxx/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx #replace this value
+ service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
+spec:
+ type: LoadBalancer
+ ports:
+ - port: 443
+ targetPort: 5556
+ protocol: TCP
+ selector:
+ app: example
+```
+可以使用 _注解_ 将不同的设置应用于 AWS 中的负载平衡器服务。 下面描述了 AWS ELB 所支持的注解:
+
+* `service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval`:用于指定访问日志的间隔。
+* `service.beta.kubernetes.io/aws-load-balancer-access-log-enabled`:用于在服务中启用或禁用日志访问。
+* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name`:用于指定访问日志的 S3 桶名称。
+* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix`:用于指定访问日志的 S3 桶前缀。
+* `service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags`:用于在服务中指定一个逗号分隔的键值对列表,它将作为附加标签被记录在 ELB 中。 例如: `"Key1=Val1,Key2=Val2,KeyNoVal1=,KeyNoVal2"`。
+* `service.beta.kubernetes.io/aws-load-balancer-backend-protocol`:用于在服务中指定监听器后端(pod)所使用的协议。 如果指定 `http` (默认) 或 `https`, 将创建一个终止连接和解析头的 HTTPS 监听器。 如果设置为 `ssl` 或 `tcp`, 将会使用 “原生的” SSL 监听器。 如果设置为 `http` 且不使用 `aws-load-balancer-ssl-cert`,将使用 HTTP 监听器。
+* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`:用于在服务中请求安全监听器,其值为合法的证书 ARN(Amazon Resource Name)。 更多内容,请参考 [ELB 监听器配置](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html)。 证书 ARN 是 IAM(身份和访问管理) 或 CM(证书管理)类型的 ARN,例如 `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`。
+* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled`:用于在服务中启用或禁用连接耗尽(connection draining)。
+* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout`:用于在服务中指定连接耗尽超时时间。
+* `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout`:用于在服务中指定空闲连接超时时间。
+* `service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled`:用于在服务中启用或禁用跨区域负载平衡。
+* `service.beta.kubernetes.io/aws-load-balancer-extra-security-groups`:用于在服务中指定要添加到创建的 ELB 中的其他安全组。
+* `service.beta.kubernetes.io/aws-load-balancer-internal`:用于在服务中表明需要内部 ELB。
+* `service.beta.kubernetes.io/aws-load-balancer-proxy-protocol`:用于在 ELB 上启用代理协议。 当前仅接受 `*` 值,也就是在所有 ELB 后端启用代理协议。 将来可能进行调整,只允许特定的后端设置代理协议。
+* `service.beta.kubernetes.io/aws-load-balancer-ssl-ports`:用于在服务中指定一个逗号分隔的端口列表,这些端口会使用 SSL/HTTPS 监听器。 默认为 `*`(全部)
+
+AWS 相关的注解信息取自 [aws.go](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/aws/aws.go) 文件的注释。
+
+# OpenStack
+本节介绍了使用 OpenStack 运行 Kubernetes 时所有可用的配置。
+
+## cloud.conf
+Kubernetes 知道如何通过文件 cloud.conf 与 OpenStack 进行交互。 该文件会为 Kubernetes 提供证书和 OpenStack 认证端点的区位信息。
+用户可以通过在其中指定以下信息来创建 cloud.conf 文件。
+
+### 最小配置
+这是一个最小配置的例子,它涉及最常用的值:
+
+```yaml
+[Global]
+username=user
+password=pass
+auth-url=https:///identity/v3
+tenant-id=c869168a828847f39f7f06edd7305637
+domain-id=2a73b8f597c04551a0fdc8e95544be8a
+
+[LoadBalancer]
+subnet-id=6937f8fa-858d-4bc9-a3a5-18d2c957166a
+```
+
+#### 全局配置
+* `username`:指 keystone 中设置的一个合法用户的用户名。
+* `password`:指 keystone 中设置的一个合法用户的密码。
+* `auth-url`:用于认证的 keystone API 的 URL 。 在 OpenStack 控制面板上,可以在 “访问和安全(Access and Security)> api 访问(API Access)> 凭证(Credentials)” 路径下找到它。
+* `tenant-id`:用于指定要创建资源的项目 ID。
+* `domain-id`:用于指定用户所属的域(domain)ID。
+
+#### 负载均衡器
+* `subnet-id`:用于指定要创建的负载均衡器所在的子网 ID。 可以在 “Network > Networks” 路径下找到它。 点击相应的网络获取其子网。
+
+### 可选配置
+
+#### 块存储
+
+Kubernetes 利用 OpenStack 服务目录对它知道如何使用的服务进行定位,包括 Cinder 块存储服务。 然而,云供应商的配置中包含一个附加选项,可以影响块存储 API 的使用方式:
+
+* `bs-version`:指所使用的块存储 API 版本。 其合法值为
+ `v1`、 `v2`、 `v3` 和 `auto`。 `auto` 为默认值,将使用底层 Openstack 所支持的块存储 API 的最新版本。
+
+如果在 OpenStack 上部署 Kubernetes <= 1.8 的版本,同时使用路径而不是端口来区分端点(endpoints),那么可能需要显式设置 `bs-version` 参数。 基于路径的端点形如 `http://foo.bar/volume` ,而基于端口的的端点形如
+`http://foo.bar:xxx`。
+
+在使用基于路径的端点,并且 Kubernetes 使用较旧的自动检索逻辑的环境中,尝试卷卸载(detachment)会返回 `BS API version autodetection failed.` 错误。 为了解决这个问题,可以通过添加以下内容到云供应商配置中,来强制使用 Cinder API V2 版本。
+
+```yaml
+[BlockStorage]
+bs-version=v2
+```
+{% endcapture %}
+
+{% include templates/concept.md %}
diff --git a/cn/docs/concepts/cluster-administration/device-plugins.md b/cn/docs/concepts/cluster-administration/device-plugins.md
new file mode 100644
index 0000000000..656df45899
--- /dev/null
+++ b/cn/docs/concepts/cluster-administration/device-plugins.md
@@ -0,0 +1,96 @@
+---
+approvers:
+title: 设备插件
+description: 使用 Kubernetes 设备插件框架来为 GPUs、 NICs、 FPGAs、 InfiniBand 和其他类似的需要供应商特别设置的资源开发插件。
+---
+
+{% include feature-state-alpha.md %}
+
+{% capture overview %}
+从1.8版本开始,Kubernetes 提供了一套
+[设备插件框架](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-management/device-plugin.md),
+使得供应商能够在不改动 Kubernetes 核心代码的情况下,向 kubelet 发布它们的资源。
+供应商可以实现一个手动或以 DaemonSet 形式部署的插件,而不是编写自定义的 Kubernetes 代码。
+插件的目标设备包括 GPUs、 高性能 NICs、 FPGAs、 InfiniBand
+和其他类似的可能需要供应商特定的初始化和设置的计算资源。
+{% endcapture %}
+
+{% capture body %}
+
+## 设备插件注册
+
+设备插件功能通过 `DevicePlugins` 功能入口控制, 该功能默认是禁用的。
+当设备插件功能被启用时,kubelet 会对外提供一个 `Registration` gRPC 服务:
+
+```gRPC
+service Registration {
+ rpc Register(RegisterRequest) returns (Empty) {}
+}
+```
+设备插件通过该 gRPC 服务将自身注册到 kubelet 。
+注册过程中,设备插件需要发送:
+
+ * 它的 Unix 套接字名称。
+ * 所基于的设备插件 API 版本。
+ * 希望发布的 `ResourceName` 。 这里的 `ResourceName` 需要符合
+ [扩展资源命名方案](https://github.com/kubernetes/kubernetes/pull/48922),
+ 形如 `vendor-domain/resource` 。
+ 例如,Nvidia GPU 资源被发布为 `nvidia.com/gpu` 。
+
+注册成功后,设备插件将其管理的设备列表发送至 kubelet ,然后 kubelet 负责将这些资源作为 kubelet 节点状态更新的一部分,通知 apiserver 。
+例如, 设备插件注册 `vendor-domain/foo` 到 kubelet ,
+并上报了节点上的两个健康的设备后,节点状态将更新, 发布2个 `vendor-domain/foo` 。
+
+然后,开发者可以在 [容器](/docs/api-reference/{{page.version}}/#container-v1-core)
+规格中通过使用与
+[不透明整数型资源](/docs/tasks/configure-pod-container/opaque-integer-resource/)
+中同样的流程来请求使用设备。
+在1.8版本中, 扩展资源仅支持整型的资源,且容器规格中声明的 `limit` 与 `request` 必须相等。
+
+## 设备插件实现
+
+设备插件的工作流程一般包括以下步骤:
+
+* 初始化。 在这个阶段,设备插件执行供应商特定的初始化和设置,以确保设备处于就绪状态。
+
+* 插件通过主机路径 `/var/lib/kubelet/device-plugins/` 下的一个 Unix 套接字启动 gRPC 服务,该服务实现了以下接口:
+
+ ```gRPC
+ service DevicePlugin {
+ // ListAndWatch returns a stream of List of Devices
+ // Whenever a Device state change or a Device disapears, ListAndWatch
+ // returns the new list
+ rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
+
+ // Allocate is called during container creation so that the Device
+ // Plugin can run device specific operations and instruct Kubelet
+ // of the steps to make the Device available in the container
+ rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
+ }
+ ```
+
+* 插件通过主机路径 `/var/lib/kubelet/device-plugins/kubelet.sock` 下的 Unix 套接字将自身注册到 kubelet 。
+
+* 注册成功之后,设备插件以服务模式运行,其间持续监测设备健康状态,并在任何设备状态变化时上报到 kubelet 。
+插件也负责服务 `Allocate` gRPC 请求。 在 `Allocate` 过程中,插件可能会做设备特定的准备动作; 如 GPU 清理 或 QRNG 初始化。
+如操作成功,设备插件会返回一个 `AllocateResponse` ,它包含了用于访问分配的设备的容器运行时配置信息。 kubelet 将该信息传递到容器运行时。
+
+我们期望设备插件能够监测到 kubelet 重启,并将自身重新注册到新的 kubelet 实例中。 在1.8版本中,新的 kubelet 实例启动时,会清理当前 `/var/lib/kubelet/device-plugins` 路径下已存在的 Unix 套接字。 通过这一事件,设备插件能够监测到其 Unix 套接字被删除,并重新对自身进行注册。
+
+## 设备插件部署
+
+设备插件可以手动部署,也可以作为 DaemonSet 进行部署。 以 DaemonSet 形式部署的好处是设备插件故障时,
+Kubernetes能够重新启动 Pods 。 否则就需要额外的设备插件故障恢复机制。
+目录 `/var/lib/kubelet/device-plugins` 需要访问特权,
+所以设备插件必须在特权的安全上下文环境下运行。
+如果设备插件以 DaemonSet 形式运行, `/var/lib/kubelet/device-plugins`
+目录必须在插件的 [PodSpec](/docs/api-reference/{{page.version}}/#podspec-v1-core) 中以 [Volume](/docs/api-reference/{{page.version}}/#volume-v1-core) 的形式挂载。
+
+## 示例
+
+设备插件实现的示例,参考
+[基于 COS 操作系统的 nvidia GPU 设备插件](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu)。
+
+{% endcapture %}
+
+{% include templates/concept.md %}
diff --git a/cn/docs/concepts/cluster-administration/federation.md b/cn/docs/concepts/cluster-administration/federation.md
index f9a51dfb6c..752a4e30ce 100644
--- a/cn/docs/concepts/cluster-administration/federation.md
+++ b/cn/docs/concepts/cluster-administration/federation.md
@@ -107,7 +107,7 @@ Kubernetes集群数量选择也许是一个相对静止的选择,因为对其
{% endcapture %}
{% capture whatsnext %}
-* 进一步学习[联邦提案](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/federation.md)。
+* 进一步学习[联邦提案](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/multicluster/federation.md)。
* 集群联邦参考该[配置指导](/docs/tutorials/federation/set-up-cluster-federation-kubefed/)。
* 查看[Kubecon2016浅谈联邦](https://www.youtube.com/watch?v=pq9lbkmxpS8)
{% endcapture %}
diff --git a/cn/docs/concepts/cluster-administration/proxies.md b/cn/docs/concepts/cluster-administration/proxies.md
new file mode 100644
index 0000000000..76637b7a58
--- /dev/null
+++ b/cn/docs/concepts/cluster-administration/proxies.md
@@ -0,0 +1,63 @@
+---
+title: Kubernetes 中的代理
+---
+
+{% capture overview %}
+本文讲述了 Kubernetes 中所使用的代理。
+{% endcapture %}
+
+{% capture body %}
+
+## 代理
+
+用户在使用 Kubernetes 的过程中可能遇到几种不同的代理(proxy):
+
+ 1. [kubectl proxy](/docs/tasks/access-application-cluster/access-cluster/#directly-accessing-the-rest-api):
+
+ - 运行在用户的桌面或 pod 中
+ - 从本机地址到 Kubernetes apiserver 的代理
+ - 客户端到代理使用 HTTP 协议
+ - 代理到 apiserver 使用 HTTPS 协议
+ - 指向 apiserver
+ - 添加认证头信息
+
+ 1. [apiserver proxy](/docs/tasks/access-application-cluster/access-cluster/#discovering-builtin-services):
+
+ - 是一个建立在 apiserver 内部的“堡垒”
+ - 将集群外部的用户与群集 IP 相连接,这些IP是无法通过其他方式访问的
+ - 运行在 apiserver 进程内
+ - 客户端到代理使用 HTTPS 协议 (如果配置 apiserver 使用 HTTP 协议,则使用 HTTP 协议)
+ - 通过可用信息进行选择,代理到目的地可能使用 HTTP 或 HTTPS 协议
+ - 可以用来访问 Node、 Pod 或 Service
+ - 当用来访问 Service 时,会进行负载均衡
+
+ 1. [kube proxy](/docs/concepts/services-networking/service/#ips-and-vips):
+
+ - 在每个节点上运行
+ - 代理 UDP 和 TCP
+ - 不支持 HTTP
+ - 提供负载均衡能力
+ - 只用来访问 Service
+
+ 1. apiserver 之前的代理/负载均衡器:
+
+ - 在不同集群间的存在形式和实现不同 (如 nginx)
+ - 位于所有客户端和一个或多个 apiserver 之间
+ - 存在多个 apiserver 时,扮演负载均衡器的角色
+
+ 1. 外部服务的云负载均衡器:
+
+ - 由一些云供应商提供 (如AWS ELB、 Google Cloud Load Balancer)
+ - Kubernetes service 为 `LoadBalancer` 类型时自动创建
+ - 只使用 UDP/TCP 协议
+ - 不同云供应商的实现不同。
+
+Kubernetes 用户通常只需要关心前两种类型的代理,集群管理员通常需要确保后面几种类型的代理设置正确。
+
+## 请求重定向
+
+代理已经取代重定向功能,重定向已被弃用。
+
+{% endcapture %}
+
+{% include templates/concept.md %}
diff --git a/cn/docs/concepts/configuration/commands.yaml b/cn/docs/concepts/configuration/commands.yaml
index 8d58007db4..2327d25827 100644
--- a/cn/docs/concepts/configuration/commands.yaml
+++ b/cn/docs/concepts/configuration/commands.yaml
@@ -10,3 +10,4 @@ spec:
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
+ restartPolicy: OnFailure
diff --git a/cn/docs/concepts/configuration/manage-compute-resources-container.md b/cn/docs/concepts/configuration/manage-compute-resources-container.md
new file mode 100644
index 0000000000..1e15f39e3f
--- /dev/null
+++ b/cn/docs/concepts/configuration/manage-compute-resources-container.md
@@ -0,0 +1,298 @@
+---
+title: Managing Compute Resources for Containers
+---
+
+{% capture overview %}
+
+当您定义 [Pod](/docs/user-guide/pods) 的时候可以选择为每个容器指定需要的 CPU 和内存(RAM)大小。当为容器指定了资源请求后,调度器就能够更好的判断出将容器调度到哪个节点上。如果您还为容器指定了资源限制,节点上的资源就可以按照指定的方式做竞争。关于资源请求和限制的不同点和更多资料请参考 [Resource QoS](https://git.k8s.io/community/contributors/design-proposals/resource-qos.md)。
+
+{% endcapture %}
+
+
+{% capture body %}
+
+## 资源类型
+
+*CPU* 和 *内存* 都是 *资源类型*。资源类型具有基本单位。CPU 的单位是 core,内存的单位是 byte。
+
+CPU和内存统称为*计算资源*,也可以称为*资源*。计算资源的数量是可以被请求、分配和消耗的可测量的。它们与 [API 资源](/docs/api/) 不同。 API 资源(如 Pod 和 [Service](/docs/user-guide/services))是可通过 Kubernetes API server 读取和修改的对象。
+
+## Pod 和 容器的资源请求和限制
+
+Pod 中的每个容器都可以指定以下的一个或者多个值:
+
+- `spec.containers[].resources.limits.cpu`
+- `spec.containers[].resources.limits.memory`
+- `spec.containers[].resources.requests.cpu`
+- `spec.containers[].resources.requests.memory`
+
+尽管只能在个别容器上指定请求和限制,但是我们可以方便地计算出 Pod 资源请求和限制。特定资源类型的Pod 资源请求/限制是 Pod 中每个容器的该类型的资源请求/限制的总和。
+
+## CPU 的含义
+
+CPU 资源的限制和请求以 *cpu* 为单位。
+
+Kubernetes 中的一个 cpu 等于:
+
+- 1 AWS vCPU
+- 1 GCP Core
+- 1 Azure vCore
+- 1 *Hyperthread* 在带有超线程的裸机 Intel 处理器上
+
+允许浮点数请求。具有 `spec.containers[].resources.requests.cpu` 为 0.5 的容器保证了一半 CPU 要求 1 CPU的一半。表达式 `0.1` 等价于表达式 `100m`,可以看作 “100 millicpu”。有些人说成是“一百毫 cpu”,其实说的是同样的事情。具有小数点(如 `0.1`)的请求由 API 转换为`100m`,精度不超过 `1m`。因此,可能会优先选择 `100m` 的形式。
+
+CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单核、双核、48核的机器中的意义是一样的。
+
+## 内存的含义
+
+内存的限制和请求以字节为单位。您可以使用以下后缀之一作为平均整数或定点整数表示内存:E,P,T,G,M,K。您还可以使用两个字母的等效的幂数:Ei,Pi,Ti ,Gi,Mi,Ki。例如,以下代表大致相同的值:
+
+```shell
+128974848, 129e6, 129M, 123Mi
+```
+
+下面是个例子。
+
+以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: frontend
+spec:
+ containers:
+ - name: db
+ image: mysql
+ resources:
+ requests:
+ memory: "64Mi"
+ cpu: "250m"
+ limits:
+ memory: "128Mi"
+ cpu: "500m"
+ - name: wp
+ image: wordpress
+ resources:
+ requests:
+ memory: "64Mi"
+ cpu: "250m"
+ limits:
+ memory: "128Mi"
+ cpu: "500m"
+```
+
+## 具有资源请求的 Pod 如何调度
+
+当您创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。请注意,尽管节点上的实际内存或 CPU 资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。当资源使用量稍后增加时,例如在请求率的每日峰值期间,这可以防止节点上的资源短缺。
+
+## 具有资源限制的 Pod 如何运行
+
+当 kubelet 启动一个 Pod 的容器时,它会将 CPU 和内存限制传递到容器运行时。
+
+当使用 Docker 时:
+
+- `spec.containers[].resources.requests.cpu` 的值将转换成 millicore 值,这是个浮点数,并乘以1024,这个数字中的较大者或2用作 `docker run` 命令中的[ `--cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint) 标志的值。
+- `spec.containers[].resources.limits.cpu` 被转换成 millicore 值。被乘以 100000 然后 除以 1000。这个数字用作 `docker run` 命令中的 [`--cpu-quota`](https://docs.docker.com/engine/reference/run/#/cpu-quota-constraint) 标志的值。[`--cpu-quota` ] 标志被设置成了 100000,表示测量配额使用的默认100ms 周期。如果 [`--cpu-cfs-quota`] 标志设置为 true,则 kubelet 会强制执行 cpu 限制。从 Kubernetes 1.2 版本起,此标志默认为 true。
+- `spec.containers[].resources.limits.memory` 被转换为整型,作为 `docker run` 命令中的 [`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) 标志的值。
+
+如果容器超过其内存限制,则可能会被终止。如果可重新启动,则与所有其他类型的运行时故障一样,kubelet 将重新启动它。
+
+如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。
+
+容器可能被允许也可能不被允许超过其 CPU 限制时间。但是,由于 CPU 使用率过高,不会被杀死。
+
+要确定容器是否由于资源限制而无法安排或被杀死,请参阅 [疑难解答](#troubleshooting) 部分。
+
+## 监控计算资源使用
+
+Pod 的资源使用情况被报告为 Pod 状态的一部分。
+
+如果为集群配置了 [可选监控](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-monitoring/README.md),则可以从监控系统检索 Pod 资源的使用情况。
+
+## 疑难解答
+
+### 我的 Pod 处于 pending 状态且事件信息显示 failedScheduling
+
+如果调度器找不到任何该 Pod 可以匹配的节点,则该 Pod 将保持不可调度状态,直到找到一个可以被调度到的位置。每当调度器找不到 Pod 可以调度的地方时,会产生一个事件,如下所示:
+
+```shell
+$ kubectl describe pod frontend | grep -A 3 Events
+Events:
+ FirstSeen LastSeen Count From Subobject PathReason Message
+ 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
+```
+
+在上述示例中,由于节点上的 CPU 资源不足,名为 “frontend” 的 Pod 将无法调度。由于内存不足(PodExceedsFreeMemory),类似的错误消息也可能会导致失败。一般来说,如果有这种类型的消息而处于 pending 状态,您可以尝试如下几件事情:
+
+```shell
+$ kubectl describe nodes e2e-test-minion-group-4lw4
+Name: e2e-test-minion-group-4lw4
+[ ... lines removed for clarity ...]
+Capacity:
+ alpha.kubernetes.io/nvidia-gpu: 0
+ cpu: 2
+ memory: 7679792Ki
+ pods: 110
+Allocatable:
+ alpha.kubernetes.io/nvidia-gpu: 0
+ cpu: 1800m
+ memory: 7474992Ki
+ pods: 110
+[ ... lines removed for clarity ...]
+Non-terminated Pods: (5 in total)
+ Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
+ --------- ---- ------------ ---------- --------------- -------------
+ kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
+ kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
+ kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
+ kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
+ kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
+Allocated resources:
+ (Total limits may be over 100 percent, i.e., overcommitted.)
+ CPU Requests CPU Limits Memory Requests Memory Limits
+ ------------ ---------- --------------- -------------
+ 680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)
+```
+
+在上面的输出中,您可以看到如果 Pod 请求超过 1120m CPU 或者 6.23Gi 内存,节点将无法满足。
+
+通过查看 `Pods` 部分,您将看到哪些 Pod 占用的节点上的资源。
+
+Pod 可用的资源量小于节点容量,因为系统守护程序使用一部分可用资源。 [NodeStatus](/docs/resources-reference/{{page.version}}/#nodestatus-v1-core) 的 `allocatable` 字段给出了可用于 Pod 的资源量。有关更多信息,请参阅 [节点可分配资源](https://git.k8s.io/community/contributors/design-proposals/node-allocatable.md)。
+
+可以将 [资源配额](/docs/concepts/policy/resource-quotas/) 功能配置为限制可以使用的资源总量。如果与 namespace 配合一起使用,就可以防止一个团队占用所有资源。
+
+## 我的容器被终止了
+
+您的容器可能因为资源枯竭而被终止了。要查看容器是否因为遇到资源限制而被杀死,请在相关的 Pod 上调用 `kubectl describe pod`:
+
+```shell
+[12:54:41] $ kubectl describe pod simmemleak-hra99
+Name: simmemleak-hra99
+Namespace: default
+Image(s): saadali/simmemleak
+Node: kubernetes-node-tf0f/10.240.216.66
+Labels: name=simmemleak
+Status: Running
+Reason:
+Message:
+IP: 10.244.2.75
+Replication Controllers: simmemleak (1/1 replicas created)
+Containers:
+ simmemleak:
+ Image: saadali/simmemleak
+ Limits:
+ cpu: 100m
+ memory: 50Mi
+ State: Running
+ Started: Tue, 07 Jul 2015 12:54:41 -0700
+ Last Termination State: Terminated
+ Exit Code: 1
+ Started: Fri, 07 Jul 2015 12:54:30 -0700
+ Finished: Fri, 07 Jul 2015 12:54:33 -0700
+ Ready: False
+ Restart Count: 5
+Conditions:
+ Type Status
+ Ready False
+Events:
+ FirstSeen LastSeen Count From SubobjectPath Reason Message
+ Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
+ Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine
+ Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
+ Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
+ Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
+```
+
+在上面的例子中,`Restart Count: 5` 意味着 Pod 中的 `simmemleak` 容器被终止并重启了五次。
+
+您可以使用 `kubectl get pod` 命令加上 `-o go-template=...` 选项来获取之前终止容器的状态。
+
+```shell{% raw %}
+[13:59:01] $ kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc
+Container Name: simmemleak
+LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]{% endraw %}
+```
+
+您可以看到容器因为 `reason:OOM killed` 被终止,`OOM` 表示 Out Of Memory。
+
+## 不透明整型资源(Alpha功能)
+
+Kubernetes 1.5 版本中引入不透明整型资源。不透明的整数资源允许集群运维人员发布新的节点级资源,否则系统将不了解这些资源。
+
+用户可以在 Pod 的 spec 中消费这些资源,就像 CPU 和内存一样。调度器负责资源计量,以便在不超过可用量的同时分配给 Pod。
+
+**注意:** 不透明整型资源在 kubernetes 1.5 中还是 Alpha 版本。只实现了资源计量,节点级别的隔离还处于积极的开发阶段。
+
+不透明整型资源是以 `pod.alpha.kubernetes.io/opaque-int-resource-` 为前缀的资源。API server 将限制这些资源的数量为整数。*有效* 数量的例子有 `3`、`3000m` 和 `3Ki`。*无效*数量的例子有 `0.5` 和 `1500m`。
+
+申请使用不透明整型资源需要两步。首先,集群运维人员必须在一个或多个节点上通告每个节点不透明的资源。然后,用户必须在 Pod 中请求不透明资源。
+
+要发布新的不透明整型资源,集群运维人员应向 API server 提交 `PATCH` HTTP请求,以指定集群中节点的`status.capacity` 的可用数量。在此操作之后,节点的 `status.capacity` 将包括一个新的资源。 `status.allocatable` 字段由 kubelet 异步地使用新资源自动更新。请注意,由于调度器在评估 Pod 适应度时使用节点 `status.allocatable` 值,所以在使用新资源修补节点容量和请求在该节点上调度资源的第一个 pod 之间可能会有短暂的延迟。
+
+**示例**
+
+这是一个 HTTP 请求,master 节点是 k8s-master,在 k8s-node-1 节点上通告 5 个 “foo” 资源。
+
+```http
+PATCH /api/v1/nodes/k8s-node-1/status HTTP/1.1
+Accept: application/json
+Content-Type: application/json-patch+json
+Host: k8s-master:8080
+
+[
+ {
+ "op": "add",
+ "path": "/status/capacity/pod.alpha.kubernetes.io~1opaque-int-resource-foo",
+ "value": "5"
+ }
+]
+```
+
+```shell
+curl --header "Content-Type: application/json-patch+json" \
+--request PATCH \
+--data '[{"op": "add", "path": "/status/capacity/pod.alpha.kubernetes.io~1opaque-int-resource-foo", "value": "5"}]' \
+http://k8s-master:8080/api/v1/nodes/k8s-node-1/status
+```
+
+**注意:** 在前面的请求中,`~1` 是 patch 路径中 `/` 字符的编码。JSON-Patch 中的操作路径值被解释为 JSON-Pointer。更多详细信息请参阅 [IETF RFC 6901, section 3](https://tools.ietf.org/html/rfc6901#section-3)。
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: my-pod
+spec:
+ containers:
+ - name: my-container
+ image: myimage
+ resources:
+ requests:
+ cpu: 2
+ pod.alpha.kubernetes.io/opaque-int-resource-foo: 1
+```
+
+## 计划改进
+
+在 kubernetes 1.5 版本中仅允许在容器上指定资源量。计划改进对所有容器在 Pod 中共享资源的计量,如 [emptyDir volume](/docs/concepts/storage/volumes/#emptydir)。
+
+在 kubernetes 1.5 版本中仅支持容器对 CPU 和内存的申请和限制。计划增加新的资源类型,包括节点磁盘空间资源和一个可支持自定义 [资源类型](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/resources.md) 的框架。
+
+Kubernetes 通过支持通过多级别的 [服务质量](http://issue.k8s.io/168) 来支持资源的过度使用。
+
+在 kubernetes 1.5 版本中,一个 CPU 单位在不同的云提供商和同一云提供商的不同机器类型中的意味都不同。例如,在 AWS 上,节点的容量报告为 [ECU](http://aws.amazon.com/ec2/faqs/),而在 GCE 中报告为逻辑内核。我们计划修改 cpu 资源的定义,以便在不同的提供商和平台之间保持一致。
+
+{% endcapture %}
+
+{% capture whatsnext %}
+
+- 获取将 [CPU 和内存资源分配给容器](/docs/tasks/configure-pod-container/assign-cpu-ram-container/) 的实践经验
+- [容器](/docs/api-reference/{{page.version}}/#container-v1-core)
+- [ResourceRequirements](/docs/resources-reference/{{page.version}}/#resourcerequirements-v1-core)
+
+{% endcapture %}
+
+{% include templates/concept.md %}
+
diff --git a/cn/docs/concepts/configuration/overview.md b/cn/docs/concepts/configuration/overview.md
deleted file mode 100644
index febbc6726f..0000000000
--- a/cn/docs/concepts/configuration/overview.md
+++ /dev/null
@@ -1,93 +0,0 @@
----
-approvers:
-- mikedanese
-title: Configuration Best Practices
----
-
-{% capture overview %}
-This document highlights and consolidates configuration best practices that are introduced throughout the user-guide, getting-started documentation, and examples.
-
-This is a living document. If you think of something that is not on this list but might be useful to others, please don't hesitate to file an issue or submit a PR.
-{% endcapture %}
-
-{% capture body %}
-## General Config Tips
-
-- When defining configurations, specify the latest stable API version (currently v1).
-
-- Configuration files should be stored in version control before being pushed to the cluster. This allows quick roll-back of a configuration if needed. It also aids with cluster re-creation and restoration if necessary.
-
-- Write your configuration files using YAML rather than JSON. Though these formats can be used interchangeably in almost all scenarios, YAML tends to be more user-friendly.
-
-- Group related objects into a single file whenever it makes sense. One file is often easier to manage than several. See the [guestbook-all-in-one.yaml](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/all-in-one/guestbook-all-in-one.yaml) file as an example of this syntax.
-
- Note also that many `kubectl` commands can be called on a directory, so you can also call `kubectl create` on a directory of config files. See below for more details.
-
-- Don't specify default values unnecessarily, in order to simplify and minimize configs, and to reduce error. For example, omit the selector and labels in a `ReplicationController` if you want them to be the same as the labels in its `podTemplate`, since those fields are populated from the `podTemplate` labels by default. See the [guestbook app's](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) .yaml files for some [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/frontend-deployment.yaml) of this.
-
-- Put an object description in an annotation to allow better introspection.
-
-
-## "Naked" Pods vs Replication Controllers and Jobs
-
-- If there is a viable alternative to naked pods (in other words: pods not bound to a [replication controller](/docs/user-guide/replication-controller)), go with the alternative. Naked pods will not be rescheduled in the event of node failure.
-
- Replication controllers are almost always preferable to creating pods, except for some explicit [`restartPolicy: Never`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) scenarios. A [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) object (currently in Beta) may also be appropriate.
-
-
-## Services
-
-- It's typically best to create a [service](/docs/concepts/services-networking/service/) before corresponding [replication controllers](/docs/concepts/workloads/controllers/replicationcontroller/). This lets the scheduler spread the pods that comprise the service.
-
- You can also use this process to ensure that at least one replica works before creating lots of them:
-
- 1. Create a replication controller without specifying replicas (this will set replicas=1);
- 2. Create a service;
- 3. Then scale up the replication controller.
-
-- Don't use `hostPort` unless it is absolutely necessary (for example: for a node daemon). It specifies the port number to expose on the host. When you bind a Pod to a `hostPort`, there are a limited number of places to schedule a pod due to port conflicts— you can only schedule as many such Pods as there are nodes in your Kubernetes cluster.
-
- If you only need access to the port for debugging purposes, you can use the [kubectl proxy and apiserver proxy](/docs/tasks/access-kubernetes-api/http-proxy-access-api/) or [kubectl port-forward](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/).
- You can use a [Service](/docs/concepts/services-networking/service/) object for external service access.
-
- If you explicitly need to expose a pod's port on the host machine, consider using a [NodePort](/docs/user-guide/services/#type-nodeport) service before resorting to `hostPort`.
-
-- Avoid using `hostNetwork`, for the same reasons as `hostPort`.
-
-- Use _headless services_ for easy service discovery when you don't need kube-proxy load balancing. See [headless services](/docs/user-guide/services/#headless-services).
-
-## Using Labels
-
-- Define and use [labels](/docs/user-guide/labels/) that identify __semantic attributes__ of your application or deployment. For example, instead of attaching a label to a set of pods to explicitly represent some service (For example, `service: myservice`), or explicitly representing the replication controller managing the pods (for example, `controller: mycontroller`), attach labels that identify semantic attributes, such as `{ app: myapp, tier: frontend, phase: test, deployment: v3 }`. This will let you select the object groups appropriate to the context— for example, a service for all "tier: frontend" pods, or all "test" phase components of app "myapp". See the [guestbook](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) app for an example of this approach.
-
- A service can be made to span multiple deployments, such as is done across [rolling updates](/docs/tasks/run-application/rolling-update-replication-controller/), by simply omitting release-specific labels from its selector, rather than updating a service's selector to match the replication controller's selector fully.
-
-- To facilitate rolling updates, include version info in replication controller names, for example as a suffix to the name. It is useful to set a 'version' label as well. The rolling update creates a new controller as opposed to modifying the existing controller. So, there will be issues with version-agnostic controller names. See the [documentation](/docs/tasks/run-application/rolling-update-replication-controller/) on the rolling-update command for more detail.
-
- Note that the [Deployment](/docs/concepts/workloads/controllers/deployment/) object obviates the need to manage replication controller 'version names'. A desired state of an object is described by a Deployment, and if changes to that spec are _applied_, the deployment controller changes the actual state to the desired state at a controlled rate. (Deployment objects are currently part of the [`extensions` API Group](/docs/concepts/overview/kubernetes-api/#api-groups).)
-
-- You can manipulate labels for debugging. Because Kubernetes replication controllers and services match to pods using labels, this allows you to remove a pod from being considered by a controller, or served traffic by a service, by removing the relevant selector labels. If you remove the labels of an existing pod, its controller will create a new pod to take its place. This is a useful way to debug a previously "live" pod in a quarantine environment. See the [`kubectl label`](/docs/concepts/overview/working-with-objects/labels/) command.
-
-## Container Images
-
-- The [default container image pull policy](/docs/concepts/containers/images/) is `IfNotPresent`, which causes the [Kubelet](/docs/admin/kubelet/) to not pull an image if it already exists. If you would like to always force a pull, you must specify a pull image policy of `Always` in your .yaml file (`imagePullPolicy: Always`) or specify a `:latest` tag on your image.
-
- That is, if you're specifying an image with other than the `:latest` tag, for example `myimage:v1`, and there is an image update to that same tag, the Kubelet won't pull the updated image. You can address this by ensuring that any updates to an image bump the image tag as well (for example, `myimage:v2`), and ensuring that your configs point to the correct version.
-
- **Note:** You should avoid using `:latest` tag when deploying containers in production, because this makes it hard to track which version of the image is running and hard to roll back.
-
-- To work only with a specific version of an image, you can specify an image with its digest (SHA256). This approach guarantees that the image will never update. For detailed information about working with image digests, see [the Docker documentation](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier).
-
-## Using kubectl
-
-- Use `kubectl create -f ` where possible. This looks for config objects in all `.yaml`, `.yml`, and `.json` files in `` and passes them to `create`.
-
-- Use `kubectl delete` rather than `stop`. `Delete` has a superset of the functionality of `stop`, and `stop` is deprecated.
-
-- Use kubectl bulk operations (via files and/or labels) for get and delete. See [label selectors](/docs/user-guide/labels/#label-selectors) and [using labels effectively](/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively).
-
-- Use `kubectl run` and `expose` to quickly create and expose single container Deployments. See the [quick start guide](/docs/user-guide/quick-start/) for an example.
-
-{% endcapture %}
-
-{% include templates/concept.md %}
diff --git a/cn/docs/concepts/configuration/secret.md b/cn/docs/concepts/configuration/secret.md
new file mode 100644
index 0000000000..9b61a725eb
--- /dev/null
+++ b/cn/docs/concepts/configuration/secret.md
@@ -0,0 +1,587 @@
+---
+approvers:
+- mikedanese
+title: Secret
+---
+
+`Secret` 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。将这些信息放在 `secret` 中比放在 `pod` 的定义或者 docker 镜像中来说更加安全和灵活。参阅 [Secret 设计文档](https://git.k8s.io/community/contributors/design-proposals/secrets.md) 获取更多详细信息。
+
+* TOC
+{:toc}
+## Secret 概览
+
+Secret 是一种包含少量敏感信息例如密码、token 或 key 的对象。这样的信息可能会被放在 Pod spec 中或者镜像中;将其放在一个 secret 对象中可以更好地控制它的用途,并降低意外暴露的风险。
+
+用户可以创建 secret,同时系统也创建了一些 secret。
+
+要使用 secret,pod 需要引用 secret。Pod 可以用两种方式使用 secret:作为 [volume](/docs/concepts/storage/volumes/) 中的文件被挂载到 pod 中的一个或者多个容器里,或者当 kubelet 为 pod 拉取镜像时使用。
+
+### 内置 secret
+
+#### Service Account 使用 API 凭证自动创建和附加 secret
+
+Kubernetes 自动创建包含访问 API 凭据的 secret,并自动修改您的 pod 以使用此类型的 secret。
+
+如果需要,可以禁用或覆盖自动创建和使用API凭据。但是,如果您需要的只是安全地访问 apiserver,我们推荐这样的工作流程。
+
+参阅 [Service Account](/docs/user-guide/service-accounts) 文档获取关于 Service Account 如何工作的更多信息。
+
+### 创建您自己的 Secret
+
+#### 使用 kubectl 创建 Secret
+
+假设有些 pod 需要访问数据库。这些 pod 需要使用的用户名和密码在您本地机器的 `./username.txt` 和 `./password.txt` 文件里。
+
+```shell
+# Create files needed for rest of example.
+$ echo -n "admin" > ./username.txt
+$ echo -n "1f2d1e2e67df" > ./password.txt
+```
+
+`kubectl create secret` 命令将这些文件打包到一个 Secret 中并在 API server 中创建了一个对象。
+
+```shell
+$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
+secret "db-user-pass" created
+```
+
+您可以这样检查刚创建的 secret:
+
+```shell
+$ kubectl get secrets
+NAME TYPE DATA AGE
+db-user-pass Opaque 2 51s
+
+$ kubectl describe secrets/db-user-pass
+Name: db-user-pass
+Namespace: default
+Labels:
+Annotations:
+
+Type: Opaque
+
+Data
+====
+password.txt: 12 bytes
+username.txt: 5 bytes
+```
+
+请注意,默认情况下,`get` 和 `describe` 命令都不会显示文件的内容。这是为了防止将 secret 中的内容被意外暴露给从终端日志记录中刻意寻找它们的人。
+
+请参阅 [解码 secret](#decoding-a-secret) 了解如何查看它们的内容。
+
+#### 手动创建 Secret
+
+您也可以先以 json 或 yaml 格式在文件中创建一个 secret 对象,然后创建该对象。
+
+每一项必须是 base64 编码:
+
+```shell
+$ echo -n "admin" | base64
+YWRtaW4=
+$ echo -n "1f2d1e2e67df" | base64
+MWYyZDFlMmU2N2Rm
+```
+
+现在可以像这样写一个 secret 对象:
+
+```yaml
+apiVersion: v1
+kind: Secret
+metadata:
+ name: mysecret
+type: Opaque
+data:
+ username: YWRtaW4=
+ password: MWYyZDFlMmU2N2Rm
+```
+
+数据字段是一个映射。它的键必须匹配 [`DNS_SUBDOMAIN`](https://git.k8s.io/community/contributors/design-proposals/identifiers.md),前导点也是可以的。这些值可以是任意数据,使用 base64 进行编码。
+
+使用 [`kubectl create`](/docs/user-guide/kubectl/v1.7/#create) 创建 secret:
+
+```shell
+$ kubectl create -f ./secret.yaml
+secret "mysecret" created
+```
+
+**编码注意:** secret 数据的序列化 JSON 和 YAML 值使用 base64 编码成字符串。换行符在这些字符串中无效,必须省略。当在 Darwin/OS X 上使用 `base64` 实用程序时,用户应避免使用 `-b` 选项来拆分长行。另外,对于 Linux 用户如果 `-w` 选项不可用的话,应该添加选项 `-w 0` 到 `base64` 命令或管道 `base64 | tr -d '\n' ` 。
+
+#### 解码 Secret
+
+可以使用 `kubectl get secret` 命令获取 secret。例如,获取在上一节中创建的 secret:
+
+```shell
+$ kubectl get secret mysecret -o yaml
+apiVersion: v1
+data:
+ username: YWRtaW4=
+ password: MWYyZDFlMmU2N2Rm
+kind: Secret
+metadata:
+ creationTimestamp: 2016-01-22T18:41:56Z
+ name: mysecret
+ namespace: default
+ resourceVersion: "164619"
+ selfLink: /api/v1/namespaces/default/secrets/mysecret
+ uid: cfee02d6-c137-11e5-8d73-42010af00002
+type: Opaque
+```
+
+解码密码字段:
+
+```shell
+$ echo "MWYyZDFlMmU2N2Rm" | base64 --decode
+1f2d1e2e67df
+```
+
+### 使用 Secret
+
+Secret 可以作为数据卷被挂载,或作为环境变量暴露出来以供 pod 中的容器使用。它们也可以被系统的其他部分使用,而不直接暴露在 pod 内。例如,它们可以保存凭据,系统的其他部分应该用它来代表您与外部系统进行交互。
+
+#### 在 Pod 中使用 Secret 文件
+
+在 Pod 中的 volume 里使用 Secret:
+
+1. 创建一个 secret 或者使用已有的 secret。多个 pod 可以引用同一个 secret。
+2. 修改您的 pod 的定义在 `spec.volumes[]` 下增加一个 volume。可以给这个 volume 随意命名,它的 `spec.volumes[].secret.secretName` 必须等于 secret 对象的名字。
+3. 将 `spec.containers[].volumeMounts[]` 加到需要用到该 secret 的容器中。指定 `spec.containers[].volumeMounts[].readOnly = true` 和 `spec.containers[].volumeMounts[].mountPath` 为您想要该 secret 出现的尚未使用的目录。
+4. 修改您的镜像并且/或者命令行让程序从该目录下寻找文件。Secret 的 `data` 映射中的每一个键都成为了 `mountPath` 下的一个文件名。
+
+这是一个在 pod 中使用 volume 挂在 secret 的例子:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod
+spec:
+ containers:
+ - name: mypod
+ image: redis
+ volumeMounts:
+ - name: foo
+ mountPath: "/etc/foo"
+ readOnly: true
+ volumes:
+ - name: foo
+ secret:
+ secretName: mysecret
+```
+
+您想要用的每个 secret 都需要在 `spec.volumes` 中指明。
+
+如果 pod 中有多个容器,每个容器都需要自己的 `volumeMounts` 配置块,但是每个 secret 只需要一个 `spec.volumes`。
+
+您可以打包多个文件到一个 secret 中,或者使用的多个 secret,怎样方便就怎样来。
+
+**向特性路径映射 secret 密钥**
+
+我们还可以控制 Secret key 映射在 volume 中的路径。您可以使用 `spec.volumes[].secret.items` 字段修改每个 key 的目标路径:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod
+spec:
+ containers:
+ - name: mypod
+ image: redis
+ volumeMounts:
+ - name: foo
+ mountPath: "/etc/foo"
+ readOnly: true
+ volumes:
+ - name: foo
+ secret:
+ secretName: mysecret
+ items:
+ - key: username
+ path: my-group/my-username
+```
+
+将会发生什么呢:
+
+- `username` secret 存储在 `/etc/foo/my-group/my-username` 文件中而不是 `/etc/foo/username` 中。
+- `password` secret 没有被映射
+
+如果使用了 `spec.volumes[].secret.items`,只有在 `items` 中指定的 key 被映射。要使用 secret 中所有的 key,所有这些都必须列在 `items` 字段中。所有列出的密钥必须存在于相应的 secret 中。否则,不会创建卷。
+
+**Secret 文件权限**
+
+您还可以指定 secret 将拥有的权限模式位文件。如果不指定,默认使用 `0644`。您可以为整个保密卷指定默认模式,如果需要,可以覆盖每个密钥。
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod
+spec:
+ containers:
+ - name: mypod
+ image: redis
+ volumeMounts:
+ - name: foo
+ mountPath: "/etc/foo"
+ volumes:
+ - name: foo
+ secret:
+ secretName: mysecret
+ defaultMode: 256
+```
+
+然后,secret 将被挂载到 `/etc/foo` 目录,所有通过该 secret volume 挂载创建的文件的权限都是 `0400`。
+
+请注意,JSON 规范不支持八进制符号,因此使用 256 值作为 0400 权限。如果您使用 yaml 而不是 json 作为 pod,则可以使用八进制符号以更自然的方式指定权限。
+
+您还可以使用映射,如上一个示例,并为不同的文件指定不同的权限,如下所示:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod
+spec:
+ containers:
+ - name: mypod
+ image: redis
+ volumeMounts:
+ - name: foo
+ mountPath: "/etc/foo"
+ volumes:
+ - name: foo
+ secret:
+ secretName: mysecret
+ items:
+ - key: username
+ path: my-group/my-username
+ mode: 511
+```
+
+在这种情况下,导致 `/etc/foo/my-group/my-username` 的文件的权限值为 `0777`。由于 JSON 限制,必须以十进制格式指定模式。
+
+请注意,如果稍后阅读此权限值可能会以十进制格式显示。
+
+**从 Volume 中消费 secret 值**
+
+在挂载的 secret volume 的容器内,secret key 将作为文件,并且 secret 的值使用 base-64 解码并存储在这些文件中。这是在上面的示例容器内执行的命令的结果:
+
+```shell
+$ ls /etc/foo/
+username
+password
+$ cat /etc/foo/username
+admin
+$ cat /etc/foo/password
+1f2d1e2e67df
+```
+
+容器中的程序负责从文件中读取 secret。
+
+**挂载的 secret 被自动更新**
+
+当已经在 volume 中被消费的 secret 被更新时,被映射的 key 也将被更新。
+
+Kubelet 在周期性同步时检查被挂载的 secret 是不是最新的。但是,它正在使用其基于本地 ttl 的缓存来获取当前的 secret 值。结果是,当 secret 被更新的时刻到将新的 secret 映射到 pod 的时刻的总延迟可以与 kubelet 中的secret 缓存的 kubelet sync period + ttl 一样长。
+
+#### Secret 作为环境变量
+
+将 secret 作为 pod 中的环境变量使用:
+
+1. 创建一个 secret 或者使用一个已存在的 secret。多个 pod 可以引用同一个 secret。
+2. 修改 Pod 定义,为每个要使用 secret 的容器添加对应 secret key 的环境变量。消费secret key 的环境变量应填充 secret 的名称,并键入 `env[x].valueFrom.secretKeyRef`。
+3. 修改镜像并/或者命令行,以便程序在指定的环境变量中查找值。
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: secret-env-pod
+spec:
+ containers:
+ - name: mycontainer
+ image: redis
+ env:
+ - name: SECRET_USERNAME
+ valueFrom:
+ secretKeyRef:
+ name: mysecret
+ key: username
+ - name: SECRET_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: mysecret
+ key: password
+ restartPolicy: Never
+```
+
+**消费环境变量里的 Secret 值**
+
+在一个消耗环境变量 secret 的容器中,secret key 作为包含 secret 数据的 base-64 解码值的常规环境变量。这是从上面的示例在容器内执行的命令的结果:
+
+```shell
+$ echo $SECRET_USERNAME
+admin
+$ echo $SECRET_PASSWORD
+1f2d1e2e67df
+```
+
+#### 使用 imagePullSecret
+
+imagePullSecret 是将包含 Docker(或其他)镜像注册表密码的 secret 传递给 Kubelet 的一种方式,因此可以代表您的 pod 拉取私有镜像。
+
+**手动指定 imagePullSecret**
+
+imagePullSecret 的使用在 [镜像文档](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) 中说明。
+
+### 安排 imagePullSecrets 自动附加
+
+您可以手动创建 imagePullSecret,并从 serviceAccount 引用它。使用该 serviceAccount 创建的任何 pod 和默认使用该 serviceAccount 的 pod 将会将其的 imagePullSecret 字段设置为服务帐户的 imagePullSecret 字段。有关该过程的详细说明,请参阅 [将 ImagePullSecrets 添加到服务帐户](/docs/tasks/configure-pod-container/configure-service-account/#adding-imagepullsecrets-to-a-service-account)。
+
+#### 自动挂载手动创建的 Secret
+
+手动创建的 secret(例如包含用于访问 github 帐户的令牌)可以根据其服务帐户自动附加到 pod。请参阅 [使用 PodPreset 向 Pod 中注入信息](/docs/tasks/run-application/podpreset/) 以获取该进程的详细说明。
+
+## 详细
+
+### 限制
+
+验证 secret volume 来源确保指定的对象引用实际上指向一个类型为 Secret 的对象。因此,需要在依赖于它的任何 pod 之前创建一个 secret。
+
+Secret API 对象驻留在命名空间中。它们只能由同一命名空间中的 pod 引用。
+
+每个 secret 的大小限制为1MB。这是为了防止创建非常大的 secret 会耗尽 apiserver 和 kubelet 的内存。然而,创建许多较小的 secret 也可能耗尽内存。更全面得限制 secret 对内存使用的功能还在计划中。
+
+Kubelet 仅支持从 API server 获取的 Pod 使用 secret。这包括使用 kubectl 创建的任何 pod,或间接通过 replication controller 创建的 pod。它不包括通过 kubelet `--manifest-url` 标志,其 `--config` 标志或其 REST API 创建的pod(这些不是创建 pod 的常用方法)。
+
+必须先创建 secret,除非将它们标记为可选项,否则必须在将其作为环境变量在 pod 中使用之前创建 secret。对不存在的 secret 的引用将阻止其启动。
+
+使用 `secretKeyRef` ,引用指定的 secret 中的不存在的 key ,这会阻止 pod 的启动。
+
+对于通过 `envFrom` 填充环境变量的 secret,这些环境变量具有被认为是无效环境变量名称的 key 将跳过这些键。该 pod 将被允许启动。将会有一个事件,其原因是 `InvalidVariableNames`,该消息将包含被跳过的无效键的列表。该示例显示一个 pod,它指的是包含2个无效键,1badkey 和 2alsobad 的默认/mysecret ConfigMap。
+
+```shell
+$ kubectl get events
+LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
+0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.
+```
+
+### Secret 与 Pod 生命周期的联系
+
+通过 API 创建 Pod 时,不会检查应用的 secret 是否存在。一旦 Pod 被调度,kubelet 就会尝试获取该 secret 的值。如果获取不到该 secret,或者暂时无法与 API server 建立连接,kubelet 将会定期重试。Kubelet 将会报告关于 pod 的事件,并解释它无法启动的原因。一旦获取到 secret,kubelet将创建并装载一个包含它的卷。在所有 pod 的卷被挂载之前,都不会启动 pod 的容器。
+
+## 使用案例
+
+### 使用案例:包含 ssh 密钥的 pod
+
+创建一个包含 ssh key 的 secret:
+
+```shell
+$ kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
+```
+
+**安全性注意事项**:发送自己的 ssh 密钥之前要仔细思考:集群的其他用户可能有权访问该密钥。使用您想要共享 Kubernetes 群集的所有用户可以访问的服务帐户,如果它们遭到入侵,可以撤销。
+
+现在我们可以创建一个使用 ssh 密钥引用 secret 的pod,并在一个卷中使用它:
+
+```yaml
+kind: Pod
+apiVersion: v1
+metadata:
+ name: secret-test-pod
+ labels:
+ name: secret-test
+spec:
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: ssh-key-secret
+ containers:
+ - name: ssh-test-container
+ image: mySshImage
+ volumeMounts:
+ - name: secret-volume
+ readOnly: true
+ mountPath: "/etc/secret-volume"
+```
+
+当容器中的命令运行时,密钥的片段将可在以下目录:
+
+```shell
+/etc/secret-volume/ssh-publickey
+/etc/secret-volume/ssh-privatekey
+```
+
+然后容器可以自由使用密钥数据建立一个 ssh 连接。
+
+### 使用案例:包含 prod/test 凭据的 pod
+
+下面的例子说明一个 pod 消费一个包含 prod 凭据的 secret,另一个 pod 使用测试环境凭据消费 secret。
+
+创建 secret:
+
+```shell
+$ kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
+secret "prod-db-secret" created
+$ kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
+secret "test-db-secret" created
+```
+
+创建 pod :
+
+```yaml
+apiVersion: v1
+kind: List
+items:
+- kind: Pod
+ apiVersion: v1
+ metadata:
+ name: prod-db-client-pod
+ labels:
+ name: prod-db-client
+ spec:
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: prod-db-secret
+ containers:
+ - name: db-client-container
+ image: myClientImage
+ volumeMounts:
+ - name: secret-volume
+ readOnly: true
+ mountPath: "/etc/secret-volume"
+- kind: Pod
+ apiVersion: v1
+ metadata:
+ name: test-db-client-pod
+ labels:
+ name: test-db-client
+ spec:
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: test-db-secret
+ containers:
+ - name: db-client-container
+ image: myClientImage
+ volumeMounts:
+ - name: secret-volume
+ readOnly: true
+ mountPath: "/etc/secret-volume"
+```
+
+这两个容器将在其文件系统上显示以下文件,其中包含每个容器环境的值:
+
+```shell
+/etc/secret-volume/username
+/etc/secret-volume/password
+```
+
+请注意,两个 pod 的 spec 配置中仅有一个字段有所不同;这有助于使用普通的 pod 配置模板创建具有不同功能的 pod。您可以使用两个 service account 进一步简化基本 pod spec:一个名为 `prod-user` 拥有 `prod-db-secret` ,另一个称为 `test-user` 拥有 `test-db-secret` 。然后,pod spec 可以缩短为,例如:
+
+```yaml
+kind: Pod
+apiVersion: v1
+metadata:
+ name: prod-db-client-pod
+ labels:
+ name: prod-db-client
+spec:
+ serviceAccount: prod-db-client
+ containers:
+ - name: db-client-container
+ image: myClientImage
+```
+
+### 使用案例:Secret 卷中以点号开头的文件
+
+为了将数据“隐藏”起来(即文件名以点号开头的文件),简单地说让该键以一个点开始。例如,当如下 secret 被挂载到卷中:
+
+```yaml
+kind: Secret
+apiVersion: v1
+metadata:
+ name: dotfile-secret
+data:
+ .secret-file: dmFsdWUtMg0KDQo=
+---
+kind: Pod
+apiVersion: v1
+metadata:
+ name: secret-dotfiles-pod
+spec:
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: dotfile-secret
+ containers:
+ - name: dotfile-test-container
+ image: gcr.io/google_containers/busybox
+ command:
+ - ls
+ - "-l"
+ - "/etc/secret-volume"
+ volumeMounts:
+ - name: secret-volume
+ readOnly: true
+ mountPath: "/etc/secret-volume"
+```
+
+`Secret-volume` 将包含一个单独的文件,叫做 `.secret-file`,`dotfile-test-container` 的 `/etc/secret-volume/.secret-file` 路径下将有该文件。
+
+**注意**
+
+以点号开头的文件在 `ls -l` 的输出中被隐藏起来了;列出目录内容时,必须使用 `ls -la` 才能查看它们。
+
+### 使用案例:Secret 仅对 pod 中的一个容器可见
+
+考虑以下一个需要处理 HTTP 请求的程序,执行一些复杂的业务逻辑,然后使用 HMAC 签署一些消息。因为它具有复杂的应用程序逻辑,所以在服务器中可能会出现一个未被注意的远程文件读取漏洞,这可能会将私钥暴露给攻击者。
+
+这可以在两个容器中分为两个进程:前端容器,用于处理用户交互和业务逻辑,但无法看到私钥;以及可以看到私钥的签名者容器,并且响应来自前端的简单签名请求(例如通过本地主机网络)。
+
+使用这种分割方法,攻击者现在必须欺骗应用程序服务器才能进行任意的操作,这可能比使其读取文件更难。
+
+
+
+## 最佳实践
+
+### 客户端使用 Secret API
+
+当部署与 secret API 交互的应用程序时,应使用诸如 [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) 之类的 [授权策略](https://kubernetes.io/docs/admin/authorization/) 来限制访问。
+
+Secret 中的值对于不同的环境来说重要性可能不同,例如对于 Kubernetes 集群内部(例如 service account 令牌)和集群外部来说就不一样。即使一个应用程序可以理解其期望的与之交互的 secret 有多大的能力,但是同一命名空间中的其他应用程序却可能不这样认为。
+
+由于这些原因,在命名空间中 `watch` 和 `list` secret 的请求是非常强大的功能,应该避免这样的行为,因为列出 secret 可以让客户端检查所有 secret 是否在该命名空间中。在群集中`watch` 和 `list` 所有 secret 的能力应该只保留给最有特权的系统级组件。
+
+需要访问 secrets API 的应用程序应该根据他们需要的 secret 执行 `get` 请求。这允许管理员限制对所有 secret 的访问,同时设置 [白名单访问](https://kubernetes.io/docs/admin/authorization/rbac/#referring-to-resources) 应用程序需要的各个实例。
+
+为了提高循环获取的性能,客户端可以设计引用 secret 的资源,然后 `watch` 资源,在引用更改时重新请求 secret。此外,还提出了一种 [”批量监控“ API](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/bulk_watch.md) 来让客户端 `watch` 每个资源,该功能可能会在将来的 Kubernetes 版本中提供。
+
+## 安全属性
+
+### 保护
+
+因为 `secret` 对象可以独立于使用它们的 `pod` 而创建,所以在创建、查看和编辑 pod 的流程中 secret 被暴露的风险较小。系统还可以对 `secret` 对象采取额外的预防措施,例如避免将其写入到磁盘中可能的位置。
+
+只有当节点上的 pod 需要用到该 secret 时,该 secret 才会被发送到该节点上。它不会被写入磁盘,而是存储在 tmpfs 中。一旦依赖于它的 pod 被删除,它就被删除。
+
+在大多数 Kubernetes 项目维护的发行版中,用户与 API server 之间的通信以及从 API server 到 kubelet 的通信都受到 SSL/TLS 的保护。通过这些通道传输时,secret 受到保护。
+
+节点上的 secret 数据存储在 tmpfs 卷中,因此不会传到节点上的其他磁盘。
+
+同一节点上的很多个 pod 可能拥有多个 secret。但是,只有 pod 请求的 secret 在其容器中才是可见的。因此,一个 pod 不能访问另一个 Pod 的 secret。
+
+Pod 中有多个容器。但是,pod 中的每个容器必须请求其挂载卷中的 secret 卷才能在容器内可见。这可以用于 [在 Pod 级别构建安全分区](#使用案例secret-仅对-pod-中的一个容器可见)。
+
+### 风险
+
+- API server 的 secret 数据以纯文本的方式存储在 etcd 中,因此:
+ - 管理员应该限制 admin 用户访问 etcd;
+ - API server 中的 secret 数据位于 etcd 使用的磁盘上;管理员可能希望在不再使用时擦除/粉碎 etcd 使用的磁盘
+- 如果您将 secret 数据编码为 base64 的清单(JSON 或 YAML)文件,共享该文件或将其检入代码库,这样的话该密码将会被泄露。 Base64 编码不是一种加密方式,一样也是纯文本。
+- 应用程序在从卷中读取 secret 后仍然需要保护 secret 的值,例如不会意外记录或发送给不信任方。
+- 可以创建和使用 secret 的 pod 的用户也可以看到该 secret 的值。即使 API server 策略不允许用户读取 secret 对象,用户也可以运行暴露 secret 的 pod。
+- 如果运行了多个副本,那么这些 secret 将在它们之间共享。默认情况下,etcd 不能保证与 SSL/TLS 的对等通信,尽管可以进行配置。
+- 目前,任何节点的 root 用户都可以通过模拟 kubelet 来读取 API server 中的任何 secret。只有向实际需要它们的节点发送 secret 才能限制单个节点的根漏洞的影响,该功能还在计划中。
\ No newline at end of file
diff --git a/cn/docs/concepts/containers/container-environment-variables.md b/cn/docs/concepts/containers/container-environment-variables.md
new file mode 100644
index 0000000000..354115ddea
--- /dev/null
+++ b/cn/docs/concepts/containers/container-environment-variables.md
@@ -0,0 +1,61 @@
+---
+approvers:
+- mikedanese
+- thockin
+title: 容器环境变量
+---
+
+{% capture overview %}
+
+本文介绍容器环境中对容器可用的资源。
+
+{% endcapture %}
+
+{:toc}
+
+{% capture body %}
+
+## 容器环境
+
+Kubernetes 容器环境为容器提供了几类重要的资源:
+
+* 一个文件系统,其中包含一个[镜像](/docs/concepts/containers/images/)和一个或多个[卷](/docs/concepts/storage/volumes/)。
+* 容器本身相关的信息。
+* 集群中其他对象相关的信息。
+
+### 容器信息
+
+容器的 *hostname* 是容器所在的 Pod 名称。 可以通过 `hostname` 命令或调用 libc 中的
+[`gethostname`](http://man7.org/linux/man-pages/man2/gethostname.2.html)
+函数来获取。
+
+Pod 名称和名字空间可以通过
+[downward API](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/) 以环境变量方式访问。
+
+与 Docker 镜像中静态指定的环境变量一样,Pod 中用户定义的环境变量也可用于容器。
+
+### 集群信息
+
+容器创建时运行的所有服务的列表都会作为环境变量提供给容器。
+这些环境变量与 Docker 链接语法相匹配。
+
+对一个名为 *foo*,映射到名为 *bar* 的容器端口的服务,
+会定义如下变量:
+
+```shell
+FOO_SERVICE_HOST=<服务所在的主机地址>
+FOO_SERVICE_PORT=<服务所启用的端口>
+```
+
+服务具有专用 IP 地址,如果启用了 [DNS 插件](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/),还可以在容器中通过 DNS 进行访问。
+
+{% endcapture %}
+
+{% capture whatsnext %}
+
+* 查看[容器生命周期挂钩(hooks)](/docs/concepts/containers/container-lifecycle-hooks/)了解更多。
+* 获取[为容器生命周期事件附加处理程序](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/)的实践经验。
+
+{% endcapture %}
+
+{% include templates/concept.md %}
diff --git a/cn/docs/concepts/containers/images.md b/cn/docs/concepts/containers/images.md
index a50c57b5a0..19dfa52de4 100644
--- a/cn/docs/concepts/containers/images.md
+++ b/cn/docs/concepts/containers/images.md
@@ -31,7 +31,7 @@ title: 镜像
- 使用Google Container Registry
- 每个集群分别配置
- - 在Google Compute Engine 或者 Google Container Engine上自动配置
+ - 在Google Compute Engine 或者 Google Kubernetes Engine上自动配置
- 所有的pod都能读取项目的私有仓库
- 使用 AWS EC2 Container Registry (ECR)
- 使用IAM角色和策略来控制对ECR仓库的访问
@@ -51,7 +51,7 @@ title: 镜像
### 使用 Google Container Registry
Kuberetes运行在Google Compute Engine (GCE)时原生支持[Google ContainerRegistry (GCR)]
(https://cloud.google.com/tools/container-registry/)。如果kubernetes集群运行在GCE
-或者Google Container Engine (GKE)上,使用镜像全名(e.g. gcr.io/my_project/image:tag)即可。
+或者Google Kubernetes Engine 上,使用镜像全名(e.g. gcr.io/my_project/image:tag)即可。
集群中的所有pod都会有读取这个仓库中镜像的权限。
@@ -112,7 +112,7 @@ Kubelet会获取并且定期刷新ECR的凭证。它需要以下权限
### 配置Nodes对私有仓库认证
-**注意:** 如果在Google Container Engine (GKE)上运行集群,每个节点上都会有`.dockercfg`文件,它包含对Google Container Registry的凭证。
+**注意:** 如果在Google Kubernetes Engine 上运行集群,每个节点上都会有`.dockercfg`文件,它包含对Google Container Registry的凭证。
不需要使用以下方法。
**注意:** 如果在AWS EC2上运行集群且准备使用EC2 Container Registry (ECR),每个node上的kubelet会管理和更新ECR的登录凭证。不需要使用以下方法。
@@ -175,7 +175,7 @@ $ kubectl describe pods/private-image-test-1 | grep "Failed"
### 提前拉取镜像
-**注意:** 如果在Google Container Engine (GKE)上运行集群,每个节点上都会有`.dockercfg`文件,它包含对Google Container Registry的凭证。
+**注意:** 如果在Google Kubernetes Engine 上运行集群,每个节点上都会有`.dockercfg`文件,它包含对Google Container Registry的凭证。
不需要使用以下方法。
**注意:** 该方法适用于能够对节点进行配置的情况。该方法在GCE及在其它能自动配置节点的云平台上并不适合。
@@ -193,7 +193,7 @@ $ kubectl describe pods/private-image-test-1 | grep "Failed"
### 在pod上指定ImagePullSecrets
-**注意:** GKE,GCE及其他自动创建node的云平台上,推荐使用本方法。
+**注意:** Google Kubernetes Engine,GCE及其他自动创建node的云平台上,推荐使用本方法。
Kuberentes支持在pod中指定仓库密钥。
@@ -262,7 +262,7 @@ spec:
也可以在[serviceAccount](/docs/user-guide/service-accounts) 资源中设置imagePullSecrets自动设置`imagePullSecrets`
-`imagePullSecrets`可以和每个node上的`.docker/config.json`一起使用,他们将共同生效。本方法在Google Container Engine (GKE)
+`imagePullSecrets`可以和每个node上的`.docker/config.json`一起使用,他们将共同生效。本方法在Google Kubernetes Engine
也能正常工作。
### 使用场景
diff --git a/cn/docs/concepts/overview/components.md b/cn/docs/concepts/overview/components.md
index 8275ba4df6..75a9bd0d46 100644
--- a/cn/docs/concepts/overview/components.md
+++ b/cn/docs/concepts/overview/components.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- lavalamp
title: Kubernetes 组件
redirect_from:
@@ -39,7 +39,7 @@ Master 组件可以在集群中的任何节点上运行。然而,为了简单
### 云控制器管理器-(cloud-controller-manager)
-cloud-controller-manager 是用于与底层云提供商交互的控制器。云控制器管理器二进制是 Kubernetes v1.6 版本中引入的 Alpha 功能。
+cloud-controller-manager 是用于与底层云提供商交互的控制器。云控制器管理器可执行组件是 Kubernetes v1.6 版本中引入的 Alpha 功能。
cloud-controller-manager 仅运行云提供商特定的控制器循环。您必须在 kube-controller-manager 中禁用这些控制器循环,您可以通过在启动 kube-controller-manager 时将 `--cloud-provider` 标志设置为`external`来禁用控制器循环。
diff --git a/cn/docs/concepts/overview/kubernetes-api.md b/cn/docs/concepts/overview/kubernetes-api.md
new file mode 100644
index 0000000000..d164080b4e
--- /dev/null
+++ b/cn/docs/concepts/overview/kubernetes-api.md
@@ -0,0 +1,98 @@
+# Kubernetes API 概述
+
+[API协议文档](https://git.k8s.io/community/contributors/devel/api-conventions.md)描述了主系统和API概念。
+
+[API参考文档](https://kubernetes.io/docs/reference)描述了API整体规范。
+
+[访问文档](https://kubernetes.io/docs/admin/accessing-the-api)讨论了通过远程访问API的相关问题。
+
+Kubernetes API是系统描述性配置的基础。 [Kubectl](https://kubernetes.io/docs/user-guide/kubectl/) 命令行工具被用于创建、更新、删除、获取API对象。
+
+Kubernetes 通过API资源存储自己序列化状态(现在存储在[etcd](https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/))。
+
+Kubernetes 被分成多个组件,各部分通过API相互交互。
+
+## API 变更
+
+根据经验,任何成功的系统都需要随着新的用例出现或现有用例发生变化的情况下,进行相应的进化与调整。因此,我们希望Kubernetes API也可以保持持续的进化和调整。同时,在较长一段时间内,我们也希望与现有客户端版本保持良好的向下兼容性。一般情况下,增加新的API资源和资源字段不会导致向下兼容性问题发生;但如果是需要删除一个已有的资源或者字段,那么必须通过[API废弃流程](/docs/reference/deprecation-policy/)来进行。
+
+参考[API变更文档](https://git.k8s.io/community/contributors/devel/api_changes.md),了解兼容性变更的要素以及如何变更API的流程。
+
+## API Swagger 定义
+
+Kubernetes使用 [Swagger v1.2](http://swagger.io/) 与 [OpenAPI](https://www.openapis.org/) 记录API所有细节。Kubernetes apiserver (即 “master”)提供了一个API接口用于获取 Swagger 1.2 Kubernetes API 规范 ,默认在路径 **`/swaggerapi`** 下。你也可以为API服务器可以设置 **`-enable-swagger-ui=true`** 来启用API界面,之后使用浏览器访问 **`/swagger-ui`**,浏览API文档。
+
+
+Kubernetes从1.4版本开始,也支持通过 [**`/swagger.json`**](https://git.k8s.io/kubernetes/api/openapi-spec/swagger.json) 来访问 OpenAPI 形式给出的API文档。在我们将 Swagger v1.2 切换到 OpenAPI (aka Swagger v2.0) 期间,一部分工具(如 kubectl 与 swagger-ui )会继续使用 1.2 版本规范。Kubernetes 1.5 版本中的 OpenAPI 规范是 Beta 版本。
+
+Kubernetes实现了另一种基于Protobuf的序列化格式,该格式主要用于集群内通信,并在[设计方案](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/protobuf.md)中进行了说明,每个模式的IDL文件位于定义API对象的Go软件包中。
+
+## API 版本
+
+为了使删除字段或者重构资源表示更加容易,Kubernetes 支持多个API版本。每一个版本都在不同API路径下,例如 **`/api/v1`** 或者 **`/apis/extensions/v1beta1`**。
+
+我们选择在API级别进行版本化,而不是在资源或字段级别进行版本化,以确保API提供清晰,一致的系统资源和行为视图,并控制对已废止的API和/或实验性API的访问。 JSON和Protobuf序列化模式遵循架构更改的相同准则 - 下面的所有描述都同时适用于这两种格式。
+
+请注意,API版本控制和软件版本控制只有间接相关性。 [API和发行版本建议](https://git.k8s.io/community/contributors/design-proposals/release/versioning.md)描述了API版本与软件版本之间的关系。
+
+不同的API版本名称意味着不同级别的软件稳定性和支持程度。 每个级别的标准在[API变更文档](https://git.k8s.io/community/contributors/devel/api_changes.md#alpha-beta-and-stable-versions)中有更详细的描述。 内容主要概括如下:
+
+* Alpha 测试版本:
+
+ * 版本名称包含了 **`alpha`** (例如:**`v1alpha1`**)。
+
+ * 可能是有缺陷的。启用该功能可能会带来隐含的问题,默认情况是关闭的。
+
+ * 支持的功能可能在没有通知的情况下随时删除。
+
+ * API的更改可能会带来兼容性问题,但是在后续的软件发布中不会有任何通知。
+
+ * 由于bugs风险的增加和缺乏长期的支持,推荐在短暂的集群测试中使用。
+
+* Beta 测试版本:
+
+ * 版本名称包含了 **`beta`** (例如: **`v2beta3`**)。
+
+ * 代码已经测试过。启用该功能被认为是安全的,功能默认已启用。
+
+ * 所有已支持的功能不会被删除,细节可能会发生变化。
+
+ * 对象的模式和/或语义可能会在后续的beta测试版或稳定版中以不兼容的方式进行更改。 发生这种情况时,我们将提供迁移到下一个版本的说明。 这可能需要删除、编辑和重新创建API对象。执行编辑操作时需要谨慎行事,这可能需要停用依赖该功能的应用程序。
+
+ * 建议仅用于非业务关键型用途,因为后续版本中可能存在不兼容的更改。 如果您有多个可以独立升级的群集,则可以放宽此限制。
+
+ * **请尝试我们的 beta 版本功能并且给出反馈!一旦他们退出 beta 测试版,我们可能不会做出更多的改变。**
+
+* 稳定版本:
+
+ * 版本名称是 **`vX`**,其中 **`X`** 是整数。
+
+ * 功能的稳定版本将出现在许多后续版本的发行软件中。
+
+## API 组
+
+为了更容易地扩展Kubernetes API,我们实现了[*`API组`*](https://git.k8s.io/community/contributors/design-proposals/api-machinery/api-group.md)。 API组在REST路径和序列化对象的 **`apiVersion`** 字段中指定。
+
+目前有几个API组正在使用中:
+
+1. 核心组(通常被称为遗留组)位于REST路径 **`/api/v1`** 并使用 **`apiVersion:v1`**。
+
+1. 指定的组位于REST路径 **`/apis/$GROUP_NAME/$VERSION`**,并使用 **`apiVersion:$GROUP_NAME/$VERSION`**(例如 **`apiVersion:batch/v1`**)。 在[Kubernetes API参考](https://kubernetes.io/docs/reference/)中可以看到支持的API组的完整列表。
+
+社区支持使用以下两种方式来提供自定义资源对API进行扩展[自定义资源](https://kubernetes.io/docs/concepts/api-extension/custom-resources/):
+
+1. [CustomResourceDefinition](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)适用于具有非常基本的CRUD需求的用户。
+
+1. 即将推出:需要全套Kubernetes API语义的用户可以实现自己的apiserver,并使用[聚合器](https://git.k8s.io/community/contributors/design-proposals/api-machinery/aggregated-api-servers.md)为客户提供无缝的服务。
+
+## 启用 API 组
+
+某些资源和API组默认情况下处于启用状态。 可以通过在apiserver上设置 **`--runtime-config`** 来启用或禁用它们。 **`--runtime-config`** 接受逗号分隔的值。 例如:要禁用batch/v1,请设置**`--runtime-config=batch/v1=false`**,以启用batch/v2alpha1,请设置**`--runtime-config=batch/v2alpha1`**。 该标志接受描述apiserver的运行时配置的逗号分隔的一组键值对。
+
+重要:启用或禁用组或资源需要重新启动apiserver和控制器管理器来使得 **`--runtime-config`** 更改生效。
+
+## 启用组中资源
+
+DaemonSets,Deployments,HorizontalPodAutoscalers,Ingress,Jobs和ReplicaSets是默认启用的。 其他扩展资源可以通过在apiserver上设置 **`--runtime-config`** 来启用。**`--runtime-config`** 接受逗号分隔的值。
+
+例如:要禁用 Deployment 和 Ingress,请设置 **`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/ingress=false`**
\ No newline at end of file
diff --git a/cn/docs/concepts/policy/pod-security-policy.md b/cn/docs/concepts/policy/pod-security-policy.md
index 6d269c89b2..5cc7ab07f3 100644
--- a/cn/docs/concepts/policy/pod-security-policy.md
+++ b/cn/docs/concepts/policy/pod-security-policy.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- pweil-
title: Pod 安全策略
redirect_from:
diff --git a/cn/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md b/cn/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md
index dc0fec24cd..3ad1239021 100644
--- a/cn/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md
+++ b/cn/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- rickypai
- thockin
title: 使用 HostAliases 向 Pod /etc/hosts 文件添加条目
diff --git a/cn/docs/concepts/services-networking/dns-pod-service.md b/cn/docs/concepts/services-networking/dns-pod-service.md
index e1792c4657..1ce39cde26 100644
--- a/cn/docs/concepts/services-networking/dns-pod-service.md
+++ b/cn/docs/concepts/services-networking/dns-pod-service.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- davidopp
- thockin
title: DNS Pod 与 Service
diff --git a/cn/docs/concepts/services-networking/ingress.md b/cn/docs/concepts/services-networking/ingress.md
deleted file mode 100644
index f77b809e67..0000000000
--- a/cn/docs/concepts/services-networking/ingress.md
+++ /dev/null
@@ -1,298 +0,0 @@
----
-approvers:
-- bprashanth
-title: Ingress Resources
----
-
-* TOC
-{:toc}
-
-__Terminology__
-
-Throughout this doc you will see a few terms that are sometimes used interchangeably elsewhere, that might cause confusion. This section attempts to clarify them.
-
-* Node: A single virtual or physical machine in a Kubernetes cluster.
-* Cluster: A group of nodes firewalled from the internet, that are the primary compute resources managed by Kubernetes.
-* Edge router: A router that enforces the firewall policy for your cluster. This could be a gateway managed by a cloud provider or a physical piece of hardware.
-* Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the [Kubernetes networking model](/docs/concepts/cluster-administration/networking/). Examples of a Cluster network include Overlays such as [flannel](https://github.com/coreos/flannel#flannel) or SDNs such as [OVS](/docs/admin/ovs-networking/).
-* Service: A Kubernetes [Service](/docs/concepts/services-networking/service/) that identifies a set of pods using label selectors. Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network.
-
-## What is Ingress?
-
-Typically, services and pods have IPs only routable by the cluster network. All traffic that ends up at an edge router is either dropped or forwarded elsewhere. Conceptually, this might look like:
-
-```
- internet
- |
- ------------
- [ Services ]
-```
-
-An Ingress is a collection of rules that allow inbound connections to reach the cluster services.
-
-```
- internet
- |
- [ Ingress ]
- --|-----|--
- [ Services ]
-```
-
-It can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, offer name based virtual hosting etc. Users request ingress by POSTing the Ingress resource to the API server. An [Ingress controller](#ingress-controllers) is responsible for fulfilling the Ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic in an HA manner.
-
-## Prerequisites
-
-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/GKE 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/controllers/nginx#running-multiple-ingress-controllers) and [here](https://git.k8s.io/ingress/controllers/gce/BETA_LIMITATIONS.md#disabling-glbc).
-
-Make sure you review the [beta limitations](https://git.k8s.io/ingress/controllers/gce/BETA_LIMITATIONS.md) of this controller. In environments other than GCE/GKE, you need to [deploy a controller](https://git.k8s.io/ingress/controllers) as a pod.
-
-## The Ingress Resource
-
-A minimal Ingress might look like:
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: test-ingress
- annotations:
- ingress.kubernetes.io/rewrite-target: /
-spec:
- rules:
- - http:
- paths:
- - path: /testpath
- backend:
- serviceName: test
- servicePort: 80
-```
-
-*POSTing this to the API server will have no effect if you have not configured an [Ingress controller](#ingress-controllers).*
-
-__Lines 1-6__: As with all other Kubernetes config, an Ingress needs `apiVersion`, `kind`, and `metadata` fields. For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/) and [ingress configuration rewrite](https://github.com/kubernetes/ingress/blob/master/controllers/nginx/configuration.md#rewrite).
-
-__Lines 7-9__: Ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) has all the information needed to configure a loadbalancer or proxy server. Most importantly, it contains a list of rules matched against all incoming requests. Currently the Ingress resource only supports http rules.
-
-__Lines 10-11__: Each http rule contains the following information: A host (e.g.: foo.bar.com, defaults to * in this example), a list of paths (e.g.: /testpath) each of which has an associated backend (test:80). Both the host and path must match the content of an incoming request before the loadbalancer directs traffic to the backend.
-
-__Lines 12-14__: A backend is a service:port combination as described in the [services doc](/docs/concepts/services-networking/service/). Ingress traffic is typically sent directly to the endpoints matching a backend.
-
-__Global Parameters__: For the sake of simplicity the example Ingress has no global parameters, see the [API reference](https://releases.k8s.io/{{page.githubbranch}}/staging/src/k8s.io/api/extensions/v1beta1/types.go) for a full definition of the resource. One can specify a global default backend in the absence of which requests that don't match a path in the spec are sent to the default backend of the Ingress controller.
-
-## Ingress controllers
-
-In order for the Ingress resource to work, the cluster must have an Ingress controller running. This is unlike other types of controllers, which typically run as part of the `kube-controller-manager` binary, and which are typically started automatically as part of cluster creation. You need to choose the ingress controller implementation that is the best fit for your cluster, or implement one. Examples and instructions can be found [here](https://git.k8s.io/ingress/controllers).
-
-## Before you begin
-
-The following document describes a set of cross platform features exposed through the Ingress resource. Ideally, all Ingress controllers should fulfill this specification, but we're not there yet. The docs for the GCE and nginx controllers are [here](https://git.k8s.io/ingress/controllers/gce/README.md) and [here](https://git.k8s.io/ingress/controllers/nginx/README.md) respectively. **Make sure you review controller specific docs so you understand the caveats of each one**.
-
-## Types of Ingress
-
-### Single Service Ingress
-
-There are existing Kubernetes concepts that allow you to expose a single service (see [alternatives](#alternatives)), however you can do so through an Ingress as well, by specifying a *default backend* with no rules.
-
-{% include code.html language="yaml" file="ingress.yaml" ghlink="/docs/concepts/services-networking/ingress.yaml" %}
-
-If you create it using `kubectl create -f` you should see:
-
-```shell
-$ kubectl get ing
-NAME RULE BACKEND ADDRESS
-test-ingress - testsvc:80 107.178.254.228
-```
-
-Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy this Ingress. The `RULE` column shows that all traffic send to the IP is directed to the Kubernetes Service listed under `BACKEND`.
-
-### Simple fanout
-
-As described previously, pods within kubernetes have IPs only visible on the cluster network, so we need something at the edge accepting ingress traffic and proxying it to the right endpoints. This component is usually a highly available loadbalancer. An Ingress allows you to keep the number of loadbalancers down to a minimum, for example, a setup like:
-
-```shell
-foo.bar.com -> 178.91.123.132 -> / foo s1:80
- / bar s2:80
-```
-
-would require an Ingress such as:
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: test
- annotations:
- ingress.kubernetes.io/rewrite-target: /
-spec:
- rules:
- - host: foo.bar.com
- http:
- paths:
- - path: /foo
- backend:
- serviceName: s1
- servicePort: 80
- - path: /bar
- backend:
- serviceName: s2
- servicePort: 80
-```
-
-When you create the Ingress with `kubectl create -f`:
-
-```shell
-$ kubectl get ing
-NAME RULE BACKEND ADDRESS
-test -
- foo.bar.com
- /foo s1:80
- /bar s2:80
-```
-The Ingress controller will provision an implementation specific loadbalancer that satisfies the Ingress, as long as the services (s1, s2) exist. When it has done so, you will see the address of the loadbalancer under the last column of the Ingress.
-
-### Name based virtual hosting
-
-Name-based virtual hosts use multiple host names for the same IP address.
-
-```
-foo.bar.com --| |-> foo.bar.com s1:80
- | 178.91.123.132 |
-bar.foo.com --| |-> bar.foo.com s2:80
-```
-
-The following Ingress tells the backing loadbalancer to route requests based on the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4).
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: test
-spec:
- rules:
- - host: foo.bar.com
- http:
- paths:
- - backend:
- serviceName: s1
- servicePort: 80
- - host: bar.foo.com
- http:
- paths:
- - backend:
- serviceName: s2
- servicePort: 80
-```
-
-__Default Backends__: An Ingress with no rules, like the one shown in the previous section, sends all traffic to a single default backend. You can use the same technique to tell a loadbalancer where to find your website's 404 page, by specifying a set of rules *and* a default backend. Traffic is routed to your default backend if none of the Hosts in your Ingress match the Host in the request header, and/or none of the paths match the URL of the request.
-
-### TLS
-
-You can secure an Ingress by specifying a [secret](/docs/user-guide/secrets) that contains a TLS private key and certificate. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If the TLS configuration section in an Ingress specifies different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, e.g.:
-
-```yaml
-apiVersion: v1
-data:
- tls.crt: base64 encoded cert
- tls.key: base64 encoded key
-kind: Secret
-metadata:
- name: testsecret
- namespace: default
-type: Opaque
-```
-
-Referencing this secret in an Ingress will tell the Ingress controller to secure the channel from the client to the loadbalancer using TLS:
-
-```yaml
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: no-rules-map
-spec:
- tls:
- - secretName: testsecret
- backend:
- serviceName: s1
- servicePort: 80
-```
-
-Note that there is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on [nginx](https://git.k8s.io/ingress/controllers/nginx/README.md#https), [GCE](https://git.k8s.io/ingress/controllers/gce/README.md#tls), or any other platform specific Ingress controller to understand how TLS works in your environment.
-
-### Loadbalancing
-
-An Ingress controller is bootstrapped with some loadbalancing policy settings that it applies to all Ingress, such as the loadbalancing algorithm, backend weight scheme etc. More advanced loadbalancing concepts (e.g.: persistent sessions, dynamic weights) are not yet exposed through the Ingress. You can still get these features through the [service loadbalancer](https://git.k8s.io/contrib/service-loadbalancer). With time, we plan to distill loadbalancing patterns that are applicable cross platform into the Ingress resource.
-
-It's also worth noting that even though health checks are not exposed directly through the Ingress, there exist parallel concepts in Kubernetes such as [readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) which allow you to achieve the same end result. Please review the controller specific docs to see how they handle health checks ([nginx](https://git.k8s.io/ingress/controllers/nginx/README.md), [GCE](https://git.k8s.io/ingress/controllers/gce/README.md#health-checks)).
-
-## Updating an Ingress
-
-Say you'd like to add a new Host to an existing Ingress, you can update it by editing the resource:
-
-```shell
-$ kubectl get ing
-NAME RULE BACKEND ADDRESS
-test - 178.91.123.132
- foo.bar.com
- /foo s1:80
-$ kubectl edit ing test
-```
-
-This should pop up an editor with the existing yaml, modify it to include the new Host.
-
-```yaml
-spec:
- rules:
- - host: foo.bar.com
- http:
- paths:
- - backend:
- serviceName: s1
- servicePort: 80
- path: /foo
- - host: bar.baz.com
- http:
- paths:
- - backend:
- serviceName: s2
- servicePort: 80
- path: /foo
-..
-```
-
-saving it will update the resource in the API server, which should tell the Ingress controller to reconfigure the loadbalancer.
-
-```shell
-$ kubectl get ing
-NAME RULE BACKEND ADDRESS
-test - 178.91.123.132
- foo.bar.com
- /foo s1:80
- bar.baz.com
- /foo s2:80
-```
-
-You can achieve the same by invoking `kubectl replace -f` on a modified Ingress yaml file.
-
-## Failing across availability zones
-
-Techniques for spreading traffic across failure domains differs between cloud providers. Please check the documentation of the relevant Ingress controller for details. Please refer to the federation [doc](/docs/concepts/cluster-administration/federation/) for details on deploying Ingress in a federated cluster.
-
-## Future Work
-
-* Various modes of HTTPS/TLS support (e.g.: SNI, re-encryption)
-* Requesting an IP or Hostname via claims
-* Combining L4 and L7 Ingress
-* More Ingress controllers
-
-Please track the [L7 and Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827) for more details on the evolution of the resource, and the [Ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the evolution of various Ingress controllers.
-
-## Alternatives
-
-You can expose a Service in multiple ways that don't directly involve the Ingress resource:
-
-* Use [Service.Type=LoadBalancer](/docs/user-guide/services/#type-loadbalancer)
-* Use [Service.Type=NodePort](/docs/user-guide/services/#type-nodeport)
-* Use a [Port Proxy](https://git.k8s.io/contrib/for-demos/proxy-to-service)
-* Deploy the [Service loadbalancer](https://git.k8s.io/contrib/service-loadbalancer). This allows you to share a single IP among multiple Services and achieve more advanced loadbalancing through Service Annotations.
diff --git a/cn/docs/concepts/services-networking/service.md b/cn/docs/concepts/services-networking/service.md
index c6f2581062..2f7f139377 100644
--- a/cn/docs/concepts/services-networking/service.md
+++ b/cn/docs/concepts/services-networking/service.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- bprashanth
title: Service
redirect_from:
diff --git a/cn/docs/concepts/workloads/controllers/cron-jobs.md b/cn/docs/concepts/workloads/controllers/cron-jobs.md
index ba64ea4032..6d3d990c07 100644
--- a/cn/docs/concepts/workloads/controllers/cron-jobs.md
+++ b/cn/docs/concepts/workloads/controllers/cron-jobs.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- erictune
- soltysh
- janetkuo
diff --git a/cn/docs/concepts/workloads/controllers/daemonset.md b/cn/docs/concepts/workloads/controllers/daemonset.md
index bad6109558..e7058e4bc4 100644
--- a/cn/docs/concepts/workloads/controllers/daemonset.md
+++ b/cn/docs/concepts/workloads/controllers/daemonset.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- erictune
title: DaemonSet
redirect_from:
@@ -95,7 +95,7 @@ DaemonSet 也需要一个 [`.spec`](https://git.k8s.io/community/contributors/de
-Daemon Pod 关心 [Taint 和 Toleration](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),它们会为没有指定 `tolerationSeconds` 的 `node.alpha.kubernetes.io/notReady` 和 `node.alpha.kubernetes.io/unreachable` 的 Taint,创建具有 `NoExecute` 的 Toleration。这确保了当 alpha 特性的 `TaintBasedEvictions` 被启用时,发生节点故障,比如网络分区,这时它们将不会被清除掉(当 `TaintBasedEvictions` 特性没有启用,在这些场景下也不会被清除,但会因为 NodeController 的硬编码行为而被清除,而不会因为 Toleration 导致被清除)。
+Daemon Pod 关心 [Taint 和 Toleration](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),它们会为没有指定 `tolerationSeconds` 的 `node.kubernetes.io/not-ready` 和 `node.alpha.kubernetes.io/unreachable` 的 Taint,创建具有 `NoExecute` 的 Toleration。这确保了当 alpha 特性的 `TaintBasedEvictions` 被启用时,发生节点故障,比如网络分区,这时它们将不会被清除掉(当 `TaintBasedEvictions` 特性没有启用,在这些场景下也不会被清除,但会因为 NodeController 的硬编码行为而被清除,而不会因为 Toleration 导致被清除)。
diff --git a/cn/docs/concepts/workloads/controllers/deployment.md b/cn/docs/concepts/workloads/controllers/deployment.md
index acc21c984e..361b3d528f 100644
--- a/cn/docs/concepts/workloads/controllers/deployment.md
+++ b/cn/docs/concepts/workloads/controllers/deployment.md
@@ -686,7 +686,7 @@ Conditions:
<...>
```
-If you run `kubectl get deployment nginx-deployment -o yaml`, the Deployement status might look like this:
+If you run `kubectl get deployment nginx-deployment -o yaml`, the Deployment status might look like this:
```
status:
diff --git a/cn/docs/concepts/workloads/controllers/garbage-collection.md b/cn/docs/concepts/workloads/controllers/garbage-collection.md
index 1d8a921490..c9af3905b7 100644
--- a/cn/docs/concepts/workloads/controllers/garbage-collection.md
+++ b/cn/docs/concepts/workloads/controllers/garbage-collection.md
@@ -45,7 +45,7 @@ Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经
如果创建该 ReplicaSet,然后查看 Pod 的 metadata 字段,能够看到 OwnerReferences 字段:
```shell
-kubectl create -f https://k8s.io/docs/concepts/abstractions/controllers/my-repset.yaml
+kubectl create -f https://k8s.io/docs/concepts/controllers/my-repset.yaml
kubectl get pods --output=yaml
```
diff --git a/cn/docs/concepts/workloads/controllers/statefulset.md b/cn/docs/concepts/workloads/controllers/statefulset.md
deleted file mode 100644
index 689fea6255..0000000000
--- a/cn/docs/concepts/workloads/controllers/statefulset.md
+++ /dev/null
@@ -1,234 +0,0 @@
----
-approvers:
-- enisoc
-- erictune
-- foxish
-- janetkuo
-- kow3ns
-- smarterclayton
-title: StatefulSets
----
-
-{% capture overview %}
-**StatefulSet is the workload API object used to manage stateful applications.
-StatefulSets are beta in 1.8.**
-
-{% include templates/glossary/snippet.md term="statefulset" length="long" %}
-{% endcapture %}
-
-{% capture body %}
-
-## Using StatefulSets
-
-StatefulSets are valuable for applications that require one or more of the
-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.
-If an application doesn't require any stable identifiers or ordered deployment,
-deletion, or scaling, you should deploy your application with a controller that
-provides a set of stateless replicas. Controllers such as
-[Deployment](/docs/concepts/workloads/controllers/deployment/) or
-[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) may be better suited to your stateless needs.
-
-## Limitations
-
-* StatefulSet is a beta resource, not available in any Kubernetes release prior to 1.5.
-* As with all alpha/beta resources, you can disable StatefulSet through the `--runtime-config` option passed to the apiserver.
-* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](https://github.com/kubernetes/examples/tree/{{page.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.
-
-## Components
-The example below demonstrates the components of a StatefulSet.
-
-* A Headless Service, named nginx, is used to control the network domain.
-* The StatefulSet, named web, has a Spec that indicates that 3 replicas of the nginx container will be launched in unique Pods.
-* The volumeClaimTemplates will provide stable storage using [PersistentVolumes](/docs/concepts/storage/volumes/) provisioned by a PersistentVolume Provisioner.
-
-```yaml
-apiVersion: v1
-kind: Service
-metadata:
- name: nginx
- labels:
- app: nginx
-spec:
- ports:
- - port: 80
- name: web
- clusterIP: None
- selector:
- app: nginx
----
-apiVersion: apps/v1beta2
-kind: StatefulSet
-metadata:
- name: web
-spec:
- selector:
- matchLabels:
- app: nginx # has to match .spec.template.metadata.labels
- serviceName: "nginx"
- replicas: 3 # by default is 1
- template:
- metadata:
- labels:
- app: nginx # has to match .spec.selector.matchLabels
- spec:
- terminationGracePeriodSeconds: 10
- 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
- volumeClaimTemplates:
- - metadata:
- name: www
- spec:
- accessModes: [ "ReadWriteOnce" ]
- storageClassName: my-storage-class
- resources:
- requests:
- storage: 1Gi
-```
-
-## Pod Selector
-You must set the `spec.selector` field of a StatefulSet to match the labels of its `.spec.template.metadata.labels`. Prior to Kubernetes 1.8, the `spec.selector` field was defaulted when omitted. In 1.8 and later versions, failing to specify a matching Pod Selector will result in a validation error during StatefulSet creation.
-
-## Pod Identity
-StatefulSet Pods have a unique identity that is comprised of an ordinal, a
-stable network identity, and stable storage. The identity sticks to the Pod,
-regardless of which node it's (re)scheduled on.
-
-### Ordinal Index
-
-For a StatefulSet with N replicas, each Pod in the StatefulSet will be
-assigned an integer ordinal, in the range [0,N), that is unique over the Set.
-
-### Stable Network ID
-
-Each Pod in a StatefulSet derives its hostname from the name of the StatefulSet
-and the ordinal of the Pod. The pattern for the constructed hostname
-is `$(statefulset name)-$(ordinal)`. The example above will create three Pods
-named `web-0,web-1,web-2`.
-A StatefulSet can use a [Headless Service](/docs/concepts/services-networking/service/#headless-services)
-to control the domain of its Pods. The domain managed by this Service takes the form:
-`$(service name).$(namespace).svc.cluster.local`, where "cluster.local"
-is the [cluster domain](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md).
-As each Pod is created, it gets a matching DNS subdomain, taking the form:
-`$(podname).$(governing service domain)`, where the governing service is defined
-by the `serviceName` field on the StatefulSet.
-
-Here are some examples of choices for Cluster Domain, Service name,
-StatefulSet name, and how that affects the DNS names for the StatefulSet's Pods.
-
-Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain | Pod DNS | Pod Hostname |
--------------- | ----------------- | ----------------- | -------------- | ------- | ------------ |
- cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
- cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
- kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
-
-Note that Cluster Domain will be set to `cluster.local` unless
-[otherwise configured](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md).
-
-### Stable Storage
-
-Kubernetes creates one [PersistentVolume](/docs/concepts/storage/volumes/) for each
-VolumeClaimTemplate. In the nginx example above, each Pod will receive a single PersistentVolume
-with a StorageClass of `my-storage-class` and 1 Gib of provisioned storage. If no StorageClass
-is specified, then the default StorageClass will be used. When a Pod is (re)scheduled
-onto a node, its `volumeMounts` mount the PersistentVolumes associated with its
-PersistentVolume Claims. Note that, the PersistentVolumes associated with the
-Pods' PersistentVolume Claims are not deleted when the Pods, or StatefulSet are deleted.
-This must be done manually.
-
-## Deployment and Scaling Guarantees
-
-* For a StatefulSet with N replicas, when Pods are being deployed, they are created sequentially, in order from {0..N-1}.
-* When Pods are being deleted, they are terminated in reverse order, from {N-1..0}.
-* Before a scaling operation is applied to a Pod, all of its predecessors must be Running and Ready.
-* Before a Pod is terminated, all of its successors must be completely shutdown.
-
-The StatefulSet should not specify a `pod.Spec.TerminationGracePeriodSeconds` of 0. This practice is unsafe and strongly discouraged. For further explanation, please refer to [force deleting StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/).
-
-When the nginx example above is created, three Pods will be deployed in the order
-web-0, web-1, web-2. web-1 will not be deployed before web-0 is
-[Running and Ready](/docs/user-guide/pod-states), and web-2 will not be deployed until
-web-1 is Running and Ready. If web-0 should fail, after web-1 is Running and Ready, but before
-web-2 is launched, web-2 will not be launched until web-0 is successfully relaunched and
-becomes Running and Ready.
-
-If a user were to scale the deployed example by patching the StatefulSet such that
-`replicas=1`, web-2 would be terminated first. web-1 would not be terminated until web-2
-is fully shutdown and deleted. If web-0 were to fail after web-2 has been terminated and
-is completely shutdown, but prior to web-1's termination, web-1 would not be terminated
-until web-0 is Running and Ready.
-
-### Pod Management Policies
-In Kubernetes 1.7 and later, StatefulSet allows you to relax its ordering guarantees while
-preserving its uniqueness and identity guarantees via its `.spec.podManagementPolicy` field.
-
-#### OrderedReady Pod Management
-
-`OrderedReady` pod management is the default for StatefulSets. It implements the behavior
-described [above](#deployment-and-scaling-guarantees).
-
-#### Parallel Pod Management
-
-`Parallel` pod management tells the StatefulSet controller to launch or
-terminate all Pods in parallel, and to not wait for Pods to become Running
-and Ready or completely terminated prior to launching or terminating another
-Pod.
-
-## Update Strategies
-
-In Kubernetes 1.7 and later, StatefulSet's `.spec.updateStrategy` field allows you to configure
-and disable automated rolling updates for containers, labels, resource request/limits, and
-annotations for the Pods in a StatefulSet.
-
-### On Delete
-
-The `OnDelete` update strategy implements the legacy (1.6 and prior) behavior. It is the default
-strategy when `spec.updateStrategy` is left unspecified. When a StatefulSet's
-`.spec.updateStrategy.type` is set to `OnDelete`, the StatefulSet controller will not automatically
-update the Pods in a StatefulSet. Users must manually delete Pods to cause the controller to
-create new Pods that reflect modifications made to a StatefulSet's `.spec.template`.
-
-### Rolling Updates
-
-The `RollingUpdate` update strategy implements automated, rolling update for the Pods in a
-StatefulSet. When a StatefulSet's `.spec.updateStrategy.type` is set to `RollingUpdate`, the
-StatefulSet controller will delete and recreate each Pod in the StatefulSet. It will proceed
-in the same order as Pod termination (from the largest ordinal to the smallest), updating
-each Pod one at a time. It will wait until an updated Pod is Running and Ready prior to
-updating its predecessor.
-
-#### Partitions
-
-The `RollingUpdate` update strategy can be partitioned, by specifying a
-`.spec.updateStrategy.rollingUpdate.partition`. If a partition is specified, all Pods with an
-ordinal that is greater than or equal to the partition will be updated when the StatefulSet's
-`.spec.template` is updated. All Pods with an ordinal that is less than the partition will not
-be updated, and, even if they are deleted, they will be recreated at the previous version. If a
-StatefulSet's `.spec.updateStrategy.rollingUpdate.partition` is greater than its `.spec.replicas`,
-updates to its `.spec.template` will not be propagated to its Pods.
-In most cases you will not need to use a partition, but they are useful if you want to stage an
-update, roll out a canary, or perform a phased roll out.
-
-{% endcapture %}
-{% capture whatsnext %}
-
-* Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set).
-
-{% endcapture %}
-{% include templates/concept.md %}
diff --git a/cn/docs/concepts/workloads/pods/init-containers.md b/cn/docs/concepts/workloads/pods/init-containers.md
index 47c31535c0..e075dbbec6 100644
--- a/cn/docs/concepts/workloads/pods/init-containers.md
+++ b/cn/docs/concepts/workloads/pods/init-containers.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- erictune
title: Init 容器
redirect_from:
diff --git a/cn/docs/concepts/workloads/pods/pod-lifecycle.md b/cn/docs/concepts/workloads/pods/pod-lifecycle.md
new file mode 100644
index 0000000000..8420f318bc
--- /dev/null
+++ b/cn/docs/concepts/workloads/pods/pod-lifecycle.md
@@ -0,0 +1,174 @@
+---
+title: Pod 的生命周期
+redirect_from:
+- "/docs/user-guide/pod-states/"
+- "/docs/user-guide/pod-states.html"
+---
+
+{% capture overview %}
+
+{% comment %}Updated: 4/14/2015{% endcomment %}
+{% comment %}Edited and moved to Concepts section: 2/2/17{% endcomment %}
+
+该页面将描述 Pod 的生命周期。
+
+{% endcapture %}
+
+{% capture body %}
+
+## Pod phase
+
+Pod 的 `status` 定义在 [PodStatus](/docs/resources-reference/v1.7/#podstatus-v1-core) 对象中,其中有一个 `phase` 字段。
+
+Pod 的运行阶段(phase)是 Pod 在其生命周期中的简单宏观概述。该阶段并不是对容器或 Pod 的综合汇总,也不是为了做为综合状态机。
+
+Pod 相位的数量和含义是严格指定的。除了本文档中列举的内容外,不应该再假定 Pod 有其他的 `phase` 值。
+
+下面是 `phase` 可能的值:
+
+- 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
+- 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
+- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
+- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
+- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
+
+## Pod 状态
+
+Pod 有一个 PodStatus 对象,其中包含一个 [PodCondition](/docs/resources-reference/v1.7/#podcondition-v1-core) 数组。 PodCondition 数组的每个元素都有一个 `type` 字段和一个 `status` 字段。`type` 字段是字符串,可能的值有 PodScheduled、Ready、Initialized 和 Unschedulable。`status` 字段是一个字符串,可能的值有 True、False 和 Unknown。
+
+## 容器探针
+
+[探针](/docs/resources-reference/v1.7/#probe-v1-core) 是由 [kubelet](/docs/admin/kubelet/) 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 [Handler](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Handler)。有三种类型的处理程序:
+
+- [ExecAction](/docs/resources-reference/v1.7/#execaction-v1-core):在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
+- [TCPSocketAction](/docs/resources-reference/v1.7/#tcpsocketaction-v1-core):对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
+- [HTTPGetAction](/docs/resources-reference/v1.7/#httpgetaction-v1-core):对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
+
+每次探测都将获得以下三种结果之一:
+
+- 成功:容器通过了诊断。
+- 失败:容器未通过诊断。
+- 未知:诊断失败,因此不会采取任何行动。
+
+Kubelet 可以选择是否执行在容器上运行的两种探针执行和做出反应:
+
+- `livenessProbe`:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 [重启策略](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 的影响。如果容器不提供存活探针,则默认状态为 `Success`。
+- `readinessProbe`:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 `Failure`。如果容器不提供就绪探针,则默认状态为 `Success`。
+
+### 该什么时候使用存活(liveness)和就绪(readiness)探针?
+
+如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针; kubelet 将根据 Pod 的`restartPolicy` 自动执行正确的操作。
+
+如果您希望容器在探测失败时被杀死并重新启动,那么请指定一个存活探针,并指定`restartPolicy` 为 Always 或 OnFailure。
+
+如果要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是 spec 中的就绪探针的存在意味着 Pod 将在没有接收到任何流量的情况下启动,并且只有在探针探测成功后才开始接收流量。
+
+如果您希望容器能够自行维护,您可以指定一个就绪探针,该探针检查与存活探针不同的端点。
+
+请注意,如果您只想在 Pod 被删除时能够排除请求,则不一定需要使用就绪探针;在删除 Pod 时,Pod 会自动将自身置于未完成状态,无论就绪探针是否存在。当等待 Pod 中的容器停止时,Pod 仍处于未完成状态。
+
+## Pod 和容器状态
+
+有关 Pod 容器状态的详细信息,请参阅 [PodStatus](/docs/resources-reference/v1.7/#podstatus-v1-core) 和 [ContainerStatus](/docs/resources-reference/v1.7/#containerstatus-v1-core)。请注意,报告的 Pod 状态信息取决于当前的 [ContainerState](/docs/resources-reference/v1.7/#containerstatus-v1-core)。
+
+## 重启策略
+
+PodSpec 中有一个 `restartPolicy` 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。 `restartPolicy` 适用于 Pod 中的所有容器。`restartPolicy` 仅指通过同一节点上的 kubelet 重新启动容器。失败的容器由 kubelet 以五分钟为上限的指数退避延迟(10秒,20秒,40秒...)重新启动,并在成功执行十分钟后重置。如 [Pod 文档](/docs/user-guide/pods/#durability-of-pods-or-lack-thereof) 中所述,一旦绑定到一个节点,Pod 将永远不会重新绑定到另一个节点。
+
+## Pod 的生命
+
+一般来说,Pod 不会消失,直到人为销毁他们。这可能是一个人或控制器。这个规则的唯一例外是成功或失败的 `phase` 超过一段时间(由 master 确定)的Pod将过期并被自动销毁。
+
+有三种可用的控制器:
+
+- 使用 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略为 `OnFailure` 或 `Never` 的 Pod。
+
+
+- 对预期不会终止的 Pod 使用 [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/)、[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 和 [Deployment](/docs/concepts/workloads/controllers/deployment/) ,例如 Web 服务器。 ReplicationController 仅适用于具有 `restartPolicy` 为 Always 的 Pod。
+- 提供特定于机器的系统服务,使用 [DaemonSet](/docs/concepts/workloads/controllers/daemonset/) 为每台机器运行一个 Pod 。
+
+所有这三种类型的控制器都包含一个 PodTemplate。建议创建适当的控制器,让它们来创建 Pod,而不是直接自己创建 Pod。这是因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
+
+如果节点死亡或与集群的其余部分断开连接,则 Kubernetes 将应用一个策略将丢失节点上的所有 Pod 的 `phase` 设置为 Failed。
+
+## 示例
+
+### 高级 liveness 探针示例
+
+存活探针由 kubelet 来执行,因此所有的请求都在 kubelet 的网络命名空间中进行。
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ labels:
+ test: liveness
+ name: liveness-http
+spec:
+ containers:
+ - args:
+ - /server
+ image: gcr.io/google_containers/liveness
+ livenessProbe:
+ httpGet:
+ # when "host" is not defined, "PodIP" will be used
+ # host: my-host
+ # when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed
+ # scheme: HTTPS
+ path: /healthz
+ port: 8080
+ httpHeaders:
+ - name: X-Custom-Header
+ value: Awesome
+ initialDelaySeconds: 15
+ timeoutSeconds: 1
+ name: liveness
+```
+
+### 状态示例
+
+- Pod 中只有一个容器并且正在运行。容器成功退出。
+ - 记录完成事件。
+ - 如果 `restartPolicy` 为:
+ - Always:重启容器;Pod `phase` 仍为 Running。
+ - OnFailure:Pod `phase` 变成 Succeeded。
+ - Never:Pod `phase` 变成 Succeeded。
+- Pod 中只有一个容器并且正在运行。容器退出失败。
+ - 记录失败事件。
+ - 如果 `restartPolicy` 为:
+ - Always:重启容器;Pod `phase` 仍为 Running。
+ - OnFailure:重启容器;Pod `phase` 仍为 Running。
+ - Never:Pod `phase` 变成 Failed。
+- Pod 中有两个容器并且正在运行。有一个容器退出失败。
+ - 记录失败事件。
+ - 如果 restartPolicy 为:
+ - Always:重启容器;Pod `phase` 仍为 Running。
+ - OnFailure:重启容器;Pod `phase` 仍为 Running。
+ - Never:不重启容器;Pod `phase` 仍为 Running。
+ - 如果有一个容器没有处于运行状态,并且两个容器退出:
+ - 记录失败事件。
+ - 如果 `restartPolicy` 为:
+ - Always:重启容器;Pod `phase` 仍为 Running。
+ - OnFailure:重启容器;Pod `phase` 仍为 Running。
+ - Never:Pod `phase` 变成 Failed。
+- Pod 中只有一个容器并处于运行状态。容器运行时内存超出限制:
+ - 容器以失败状态终止。
+ - 记录 OOM 事件。
+ - 如果 `restartPolicy` 为:
+ - Always:重启容器;Pod `phase` 仍为 Running。
+ - OnFailure:重启容器;Pod `phase` 仍为 Running。
+ - Never: 记录失败事件;Pod `phase` 仍为 Failed。
+- Pod 正在运行,磁盘故障:
+ - 杀掉所有容器。
+ - 记录适当事件。
+ - Pod `phase` 变成 Failed。
+ - 如果使用控制器来运行,Pod 将在别处重建。
+- Pod 正在运行,其节点被分段。
+ - 节点控制器等待直到超时。
+ - 节点控制器将 Pod `phase` 设置为 Failed。
+ - 如果是用控制器来运行,Pod 将在别处重建。
+
+{% endcapture %}
+
+{% include templates/concept.md %}
+
diff --git a/cn/docs/concepts/workloads/pods/podpreset.md b/cn/docs/concepts/workloads/pods/podpreset.md
new file mode 100644
index 0000000000..76d2d778be
--- /dev/null
+++ b/cn/docs/concepts/workloads/pods/podpreset.md
@@ -0,0 +1,70 @@
+---
+approvers:
+- jessfraz
+title: Pod Preset
+---
+
+{% capture overview %}
+本文提供了 PodPreset 的概述。 在 pod 创建时,用户可以使用 `podpreset` 对象将特定信息注入
+pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。
+{% endcapture %}
+
+{:toc}
+
+{% capture body %}
+## 理解 Pod Preset
+
+`Pod Preset` 是一种 API 资源,在 pod 创建时,用户可以用它将额外的运行时需求信息注入 pod。
+使用[标签选择器(label selector)](/docs/concepts/overview/working-with-objects/labels/#label-selectors)来指定 Pod Preset 所适用的 pod。
+
+使用 Pod Preset 使得 pod 模板编写者不必显式地为每个 pod 设置信息。
+这样,使用特定服务的 pod 模板编写者不需要了解该服务的所有细节。
+
+了解更多的相关背景信息,请参考 [ PodPreset 设计提案](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)。
+
+## PodPreset 如何工作
+
+Kubernetes 提供了准入控制器 (`PodPreset`),该控制器被启用时,会将 Pod Preset
+应用于接收到的 pod 创建请求中。
+当出现 pod 创建请求时,系统会执行以下操作:
+
+1. 检索所有可用 `PodPresets` 。
+1. 检查 `PodPreset` 的标签选择器与要创建的 pod 的标签是否匹配。
+1. 尝试合并 `PodPreset` 中定义的各种资源,并注入要创建的 pod。
+1. 发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 _不注入_ `PodPreset` 信息的情况下创建 pod。
+1. 为改动的 pod spec 添加注解,来表明它被 `PodPreset` 所修改。 注解形如:
+`podpreset.admission.kubernetes.io/podpreset-": ""`。
+
+一个 Pod 可能不与任何 Pod Preset 匹配,也可能匹配多个 Pod Preset。 同时,一个 `PodPreset`
+可能不应用于任何 Pod,也可能应用于多个 Pod。 当 `PodPreset` 应用于一个或多个 Pod 时,Kubernetes
+修改 pod spec。 对于 `Env`、 `EnvFrom` 和 `VolumeMounts` 的改动, Kubernetes 修改 pod
+中所有容器的规格,对于卷的改动,Kubernetes 修改 Pod spec。
+
+**注意:** Pod Preset 能够在适当的时候修改 Pod spec 的 `spec.containers` 字段,
+但是不会应用于 `initContainers` 字段。
+{: .note}
+
+### 为特定 Pod 禁用 Pod Preset
+
+在一些情况下,用户不希望 pod 被 pod preset 所改动,这时,用户可以在 pod spec 中添加形如
+ `podpreset.admission.kubernetes.io/exclude: "true"` 的注解。
+
+## 启用 Pod Preset
+
+为了在集群中使用 Pod Preset,必须确保以下几点:
+
+1. 已启用 api 类型 `settings.k8s.io/v1alpha1/podpreset`。 这可以通过在 API 服务器的
+ `--runtime-config` 配置项中包含 `settings.k8s.io/v1alpha1=true` 来实现。
+1. 已启用准入控制器 `PodPreset`。 启用的一种方式是在 API 服务器的 `--admission-control`
+ 配置项中包含 `PodPreset` 。
+1. 已经通过在相应的名字空间中创建 `PodPreset` 对象,定义了 Pod preset。
+
+{% endcapture %}
+
+{% capture whatsnext %}
+
+* [使用 PodPreset 将信息注入 Pods](/docs/tasks/inject-data-application/podpreset/)
+
+{% endcapture %}
+
+{% include templates/concept.md %}
diff --git a/cn/docs/getting-started-guides/centos/centos_manual_config.md b/cn/docs/getting-started-guides/centos/centos_manual_config.md
index 4ff99653ac..ac79f48dfc 100644
--- a/cn/docs/getting-started-guides/centos/centos_manual_config.md
+++ b/cn/docs/getting-started-guides/centos/centos_manual_config.md
@@ -9,7 +9,7 @@ title: CentOS
## 警告
-本文档适用于Kubernetes 1.1.0,目前已经被[废弃](https://github.com/kubernetes/kubernetes.github.io/issues/1613)。相关内容请参阅最新版[指南](/docs/getting-started-guides/kubeadm/)。
+本文档适用于Kubernetes 1.1.0,目前已经被[废弃](https://github.com/kubernetes/website/issues/1613)。相关内容请参阅最新版[指南](/docs/getting-started-guides/kubeadm/)。
## 前提条件
diff --git a/cn/docs/reference/labels-annotations-taints.md b/cn/docs/reference/labels-annotations-taints.md
new file mode 100644
index 0000000000..fbeffb9587
--- /dev/null
+++ b/cn/docs/reference/labels-annotations-taints.md
@@ -0,0 +1,104 @@
+---
+title: 知名标签(Label)、注解(Annotation)和 Taints
+---
+
+Kubernetes 保留了 kubernetes.io 名字空间下的所有标签和注解。 本文描述了知名的
+kubernetes.io 标签和注解。
+
+本文既作为这些标签和注解值的参考,也就这些标签和注解的赋值进行了说明。
+
+**目录:**
+
+
+- [知名标签、注解和 Taints](#well-known-labels-annotations-and-taints)
+ - [beta.kubernetes.io/arch](#betakubernetesioarch)
+ - [beta.kubernetes.io/os](#betakubernetesioos)
+ - [kubernetes.io/hostname](#kubernetesiohostname)
+ - [beta.kubernetes.io/instance-type](#betakubernetesioinstance-type)
+ - [failure-domain.beta.kubernetes.io/region](#failure-domainbetakubernetesioregion)
+ - [failure-domain.beta.kubernetes.io/zone](#failure-domainbetakubernetesiozone)
+
+
+
+
+## beta.kubernetes.io/arch
+
+示例:`beta.kubernetes.io/arch=amd64`
+
+用于:节点
+
+Kubelet 用 Go 中定义的 `runtime.GOARCH` 值来填充该标签。 这在诸如混用 arm 和 x86 节点的情况下很有用。
+
+## beta.kubernetes.io/os
+
+示例:`beta.kubernetes.io/os=linux`
+
+用于:节点
+
+Kubelet 用该 Go 中定义的 `runtime.GOOS` 值来填充该标签。 这在集群中存在不同操作系统的节点时很有用(尽管当前 Kubernetes 只支持 Linux 操作系统)。
+
+## kubernetes.io/hostname
+
+示例:`kubernetes.io/hostname=ip-172-20-114-199.ec2.internal`
+
+用于:节点
+
+Kubelet 用 hostname 值来填充该标签。 注意:可以通过向 kubelet 传入 `--hostname-override`
+参数对 “真正的” hostname 进行修改。
+
+## beta.kubernetes.io/instance-type
+
+示例:`beta.kubernetes.io/instance-type=m3.medium`
+
+用于:节点
+
+Kubelet 用 `cloudprovider` 中定义的实例类型来填充该标签。 未使用 `cloudprovider` 时不会设置该标签。
+该标签在想要将某些负载定向到特定实例类型的节点上时会很有用,但通常用户更希望依赖 Kubernetes 调度器来执行基于资源的调度,所以用户应该致力于基于属性而不是实例类型来进行调度(例如:需要一个 CPU,而不是 `g2.2xlarge`)。
+
+
+## failure-domain.beta.kubernetes.io/region
+
+参考 [failure-domain.beta.kubernetes.io/zone](#failure-domainbetakubernetesiozone).
+
+## failure-domain.beta.kubernetes.io/zone
+
+示例:
+
+`failure-domain.beta.kubernetes.io/region=us-east-1`
+
+`failure-domain.beta.kubernetes.io/zone=us-east-1c`
+
+用于:节点、PersistentVolume
+
+用于节点: Kubelet 用 `cloudprovider` 中定义的区域(zone)信息来填充该标签。 未使用 `cloudprovider`
+时不会设置该标签,但如果该标签在你的拓扑中有意义的话,应该考虑设置。
+
+用于 PersistentVolume:在 GCE 和 AWS 中,`PersistentVolumeLabel` 准入控制器会自动添加区域标签。
+
+在单区的集群中,Kubernetes 会自动将同一副本控制器或服务下的 pod 分散到不同的节点上 (以降低故障的影响)。
+在多区的集群中,这种分散的行为扩展到跨区的层面 (以降低区域故障的影响)。 跨区分散通过 SelectorSpreadPriority
+来实现。
+
+这是一种尽力而为(best-effort)的处置方式, 如果集群中的区域是异构的 (例如:不同区域之间的节点数量、
+节点类型或 pod 资源需求不同),可能使得 pod 在各区域间无法均匀分布。 如有需要,用户可以使用同质的区域
+(节点数量和类型相同) 来减小 pod 分布不均的可能性。
+
+由于卷不能跨区域挂载(attach),调度器 (通过 VolumeZonePredicate 断言) 也会保证需要特定卷的 pod
+被调度到卷所在的区域中。
+
+
+区域和地域(region)的实际值无关紧要,两者的层次含义也没有严格的定义。 最终期望是,除非整个地域故障,
+否则某一区域节点的故障不应该影响到其他区域的节点。 例如,通常区域间应该避免共用同一个网络交换机。
+具体的规划取决于特定的基础设备—— three-rack 设备所选择的设置与多数据中心截然不同。
+
+如果 `PersistentVolumeLabel` 准入控制器不支持自动为 PersistentVolume 打标签,且用户希望防止 pod
+跨区域进行卷的挂载,应考虑手动打标签 (或对 `PersistentVolumeLabel` 增加支持)。 如果用户的基础设施没有这种约束,则不需要为卷添加区域标签。
+
+
+
+
+
+
+
+[]()
+
diff --git a/cn/docs/tasks/access-application-cluster/access-cluster.md b/cn/docs/tasks/access-application-cluster/access-cluster.md
deleted file mode 100644
index a623ad36bf..0000000000
--- a/cn/docs/tasks/access-application-cluster/access-cluster.md
+++ /dev/null
@@ -1,318 +0,0 @@
----
-title: Accessing Clusters
----
-
-* TOC
-{:toc}
-
-## Accessing the cluster API
-
-### Accessing for the first time with kubectl
-
-When accessing the Kubernetes API for the first time, we suggest using the
-Kubernetes CLI, `kubectl`.
-
-To access a cluster, you need to know the location of the cluster and have credentials
-to access it. Typically, this is automatically set-up when you work through
-a [Getting started guide](/docs/getting-started-guides/),
-or someone else setup the cluster and provided you with credentials and a location.
-
-Check the location and credentials that kubectl knows about with this command:
-
-```shell
-$ kubectl config view
-```
-
-Many of the [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) provide an introduction to using
-kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index).
-
-### Directly accessing the REST API
-
-Kubectl handles locating and authenticating to the apiserver.
-If you want to directly access the REST API with an http client like
-curl or wget, or a browser, there are several ways to locate and authenticate:
-
- - Run kubectl in proxy mode.
- - Recommended approach.
- - Uses stored apiserver location.
- - Verifies identity of apiserver using self-signed cert. No MITM possible.
- - Authenticates to apiserver.
- - In future, may do intelligent client-side load-balancing and failover.
- - Provide the location and credentials directly to the http client.
- - Alternate approach.
- - Works with some types of client code that are confused by using a proxy.
- - Need to import a root cert into your browser to protect against MITM.
-
-#### Using kubectl proxy
-
-The following command runs kubectl in a mode where it acts as a reverse proxy. It handles
-locating the apiserver and authenticating.
-Run it like this:
-
-```shell
-$ kubectl proxy --port=8080 &
-```
-
-See [kubectl proxy](/docs/user-guide/kubectl/v1.6/#proxy) for more details.
-
-Then you can explore the API with curl, wget, or a browser, like so:
-
-```shell
-$ curl http://localhost:8080/api/
-{
- "versions": [
- "v1"
- ]
-}
-```
-
-#### Without kubectl proxy (before v1.3.x)
-
-It is possible to avoid using kubectl proxy by passing an authentication token
-directly to the apiserver, like this:
-
-```shell
-$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
-$ TOKEN=$(kubectl config view | grep token | cut -f 2 -d ":" | tr -d " ")
-$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
-{
- "versions": [
- "v1"
- ]
-}
-```
-
-#### Without kubectl proxy (post v1.3.x)
-
-In Kubernetes version 1.3 or later, `kubectl config view` no longer displays the token. Use `kubectl describe secret...` to get the token for the default service account, like this:
-
-``` shell
-$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
-$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
-$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
-{
- "kind": "APIVersions",
- "versions": [
- "v1"
- ],
- "serverAddressByClientCIDRs": [
- {
- "clientCIDR": "0.0.0.0/0",
- "serverAddress": "10.0.1.149:443"
- }
- ]
-}
-```
-
-The above examples use the `--insecure` flag. This leaves it subject to MITM
-attacks. When kubectl accesses the cluster it uses a stored root certificate
-and client certificates to access the server. (These are installed in the
-`~/.kube` directory). Since cluster certificates are typically self-signed, it
-may take special configuration to get your http client to use root
-certificate.
-
-On some clusters, the apiserver does not require authentication; it may serve
-on localhost, or be protected by a firewall. There is not a standard
-for this. [Configuring Access to the API](/docs/admin/accessing-the-api)
-describes how a cluster admin can configure this. Such approaches may conflict
-with future high-availability support.
-
-### Programmatic access to the API
-
-Kubernetes officially supports [Go](#go-client) and [Python](#python-client)
-client libraries.
-
-#### Go client
-
-* To get the library, run the following command: `go get k8s.io/client-go//kubernetes`. See [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go) to see which versions are supported.
-* Write an application atop of the client-go clients. Note that client-go defines its own API objects, so if needed, please import API definitions from client-go rather than from the main repository, e.g., `import "k8s.io/client-go/1.4/pkg/api/v1"` is correct.
-
-The Go client can use the same [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
-as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://git.k8s.io/client-go/examples/out-of-cluster-client-configuration/main.go).
-
-If the application is deployed as a Pod in the cluster, please refer to the [next section](#accessing-the-api-from-a-pod).
-
-#### Python client
-
-To use [Python client](https://github.com/kubernetes-incubator/client-python), run the following command: `pip install kubernetes`. See [Python Client Library page](https://github.com/kubernetes-incubator/client-python) for more installation options.
-
-The Python client can use the same [kubeconfig file](/docs/user-guide/kubeconfig-file)
-as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://github.com/kubernetes-incubator/client-python/tree/master/examples/example1.py).
-
-#### Other languages
-
-There are [client libraries](/docs/reference/client-libraries/) for accessing the API from other languages.
-See documentation for other libraries for how they authenticate.
-
-### Accessing the API from a Pod
-
-When accessing the API from a pod, locating and authenticating
-to the apiserver are somewhat different.
-
-The recommended way to locate the apiserver within the pod is with
-the `kubernetes` DNS name, which resolves to a Service IP which in turn
-will be routed to an apiserver.
-
-The recommended way to authenticate to the apiserver is with a
-[service account](/docs/tasks/configure-pod-container/configure-service-account/) credential. By kube-system, a pod
-is associated with a service account, and a credential (token) for that
-service account is placed into the filesystem tree of each container in that pod,
-at `/var/run/secrets/kubernetes.io/serviceaccount/token`.
-
-If available, a certificate bundle is placed into the filesystem tree of each
-container at `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`, and should be
-used to verify the serving certificate of the apiserver.
-
-Finally, the default namespace to be used for namespaced API operations is placed in a file
-at `/var/run/secrets/kubernetes.io/serviceaccount/namespace` in each container.
-
-From within a pod the recommended ways to connect to API are:
-
- - run a kubectl proxy as one of the containers in the pod, or as a background
- process within a container. This proxies the
- Kubernetes API to the localhost interface of the pod, so that other processes
- in any container of the pod can access it. See this [example of using kubectl proxy
- in a pod](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/kubectl-container/).
- - use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions.
- They handle locating and authenticating to the apiserver. [example](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go)
-
-In each case, the credentials of the pod are used to communicate securely with the apiserver.
-
-
-## Accessing services running on the cluster
-
-The previous section was about connecting the Kubernetes API server. This section is about
-connecting to other services running on Kubernetes cluster. In Kubernetes, the
-[nodes](/docs/admin/node), [pods](/docs/user-guide/pods) and [services](/docs/user-guide/services) all have
-their own IPs. In many cases, the node IPs, pod IPs, and some service IPs on a cluster will not be
-routable, so they will not be reachable from a machine outside the cluster,
-such as your desktop machine.
-
-### Ways to connect
-
-You have several options for connecting to nodes, pods and services from outside the cluster:
-
- - Access services through public IPs.
- - Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside
- the cluster. See the [services](/docs/user-guide/services) and
- [kubectl expose](/docs/user-guide/kubectl/v1.6/#expose) documentation.
- - Depending on your cluster environment, this may just expose the service to your corporate network,
- or it may expose it to the internet. Think about whether the service being exposed is secure.
- Does it do its own authentication?
- - Place pods behind services. To access one specific pod from a set of replicas, such as for debugging,
- place a unique label on the pod and create a new service which selects this label.
- - In most cases, it should not be necessary for application developer to directly access
- nodes via their nodeIPs.
- - Access services, nodes, or pods using the Proxy Verb.
- - Does apiserver authentication and authorization prior to accessing the remote service.
- Use this if the services are not secure enough to expose to the internet, or to gain
- access to ports on the node IP, or for debugging.
- - Proxies may cause problems for some web applications.
- - Only works for HTTP/HTTPS.
- - Described [here](#manually-constructing-apiserver-proxy-urls).
- - Access from a node or pod in the cluster.
- - Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/v1.6/#exec).
- Connect to other nodes, pods, and services from that shell.
- - Some clusters may allow you to ssh to a node in the cluster. From there you may be able to
- access cluster services. This is a non-standard method, and will work on some clusters but
- not others. Browsers and other tools may or may not be installed. Cluster DNS may not work.
-
-### Discovering builtin services
-
-Typically, there are several services which are started on a cluster by kube-system. Get a list of these
-with the `kubectl cluster-info` command:
-
-```shell
-$ kubectl cluster-info
-
- Kubernetes master is running at https://104.197.5.247
- elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
- kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy
- kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy
- grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
- heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
-```
-
-This shows the proxy-verb URL for accessing each service.
-For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached
-at `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/` if suitable credentials are passed. Logging can also be reached through a kubectl proxy, for example at:
-`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`.
-(See [above](#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.)
-
-#### Manually constructing apiserver proxy URLs
-
-As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you simply append to the service's proxy URL:
-`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*`/proxy`
-
-If you haven't specified a name for your port, you don't have to specify *port_name* in the URL.
-
-##### Examples
-
- * To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: `http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy`
- * To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true`
-
-```json
- {
- "cluster_name" : "kubernetes_logging",
- "status" : "yellow",
- "timed_out" : false,
- "number_of_nodes" : 1,
- "number_of_data_nodes" : 1,
- "active_primary_shards" : 5,
- "active_shards" : 5,
- "relocating_shards" : 0,
- "initializing_shards" : 0,
- "unassigned_shards" : 5
- }
-```
-
-#### Using web browsers to access services running on the cluster
-
-You may be able to put an apiserver proxy url into the address bar of a browser. However:
-
- - Web browsers cannot usually pass tokens, so you may need to use basic (password) auth. Apiserver can be configured to accept basic auth,
- but your cluster may not be configured to accept basic auth.
- - Some web apps may not work, particularly those with client side javascript that construct urls in a
- way that is unaware of the proxy path prefix.
-
-## Requesting redirects
-
-The redirect capabilities have been deprecated and removed. Please use a proxy (see below) instead.
-
-## So Many Proxies
-
-There are several different proxies you may encounter when using Kubernetes:
-
- 1. The [kubectl proxy](#directly-accessing-the-rest-api):
- - runs on a user's desktop or in a pod
- - proxies from a localhost address to the Kubernetes apiserver
- - client to proxy uses HTTP
- - proxy to apiserver uses HTTPS
- - locates apiserver
- - adds authentication headers
- 1. The [apiserver proxy](#discovering-builtin-services):
- - is a bastion built into the apiserver
- - connects a user outside of the cluster to cluster IPs which otherwise might not be reachable
- - runs in the apiserver processes
- - client to proxy uses HTTPS (or http if apiserver so configured)
- - proxy to target may use HTTP or HTTPS as chosen by proxy using available information
- - can be used to reach a Node, Pod, or Service
- - does load balancing when used to reach a Service
- 1. The [kube proxy](/docs/user-guide/services/#ips-and-vips):
- - runs on each node
- - proxies UDP and TCP
- - does not understand HTTP
- - provides load balancing
- - is just used to reach services
- 1. A Proxy/Load-balancer in front of apiserver(s):
- - existence and implementation varies from cluster to cluster (e.g. nginx)
- - sits between all clients and one or more apiservers
- - acts as load balancer if there are several apiservers.
- 1. Cloud Load Balancers on external services:
- - are provided by some cloud providers (e.g. AWS ELB, Google Cloud Load Balancer)
- - are created automatically when the Kubernetes service has type `LoadBalancer`
- - use UDP/TCP only
- - implementation varies by cloud provider.
-
-Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin
-will typically ensure that the latter types are setup correctly.
diff --git a/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md b/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md
new file mode 100644
index 0000000000..0a0b9b953f
--- /dev/null
+++ b/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md
@@ -0,0 +1,186 @@
+---
+title: 同 Pod 内的容器使用共享卷通信
+redirect_from:
+- "/docs/user-guide/pods/multi-container/"
+- "/docs/user-guide/pods/multi-container.html"
+- "/docs/tasks/configure-pod-container/communicate-containers-same-pod/"
+- "/docs/tasks/configure-pod-container/communicate-containers-same-pod.html"
+---
+
+
+{% capture overview %}
+
+
+
+本文旨在说明如何让一个 Pod 内的两个容器使用一个卷(Volume)进行通信。
+
+{% endcapture %}
+
+
+{% capture prerequisites %}
+
+{% include task-tutorial-prereqs.md %}
+
+{% endcapture %}
+
+
+{% capture steps %}
+
+
+## 创建一个包含两个容器的 Pod
+
+
+
+
+在这个练习中,你会创建一个包含两个容器的 Pod。两个容器共享一个卷用于他们之间的通信。
+Pod 的配置文件如下:
+
+{% include code.html language="yaml" file="two-container-pod.yaml" ghlink="/docs/tasks/access-application-cluster/two-container-pod.yaml" %}
+
+
+
+在配置文件中,你可以看到 Pod 有一个共享卷,名为 `shared-data`。
+
+
+
+
+
+配置文件中的第一个容器运行了一个 nginx 服务器。共享卷的挂载路径是 `/usr/share/nginx/html`。
+第二个容器是基于 debian 镜像的,有一个 `/pod-data` 的挂载路径。第二个容器运行了下面的命令然后终止。
+
+ echo Hello from the debian container > /pod-data/index.html
+
+
+
+注意,第二个容器在 nginx 服务器的根目录下写了 `index.html` 文件。
+
+
+创建一个包含两个容器的 Pod:
+
+ kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/two-container-pod.yaml
+
+
+查看 Pod 和容器的信息:
+
+ kubectl get pod two-containers --output=yaml
+
+
+这是输出的一部分:
+
+ apiVersion: v1
+ kind: Pod
+ metadata:
+ ...
+ name: two-containers
+ namespace: default
+ ...
+ spec:
+ ...
+ containerStatuses:
+
+ - containerID: docker://c1d8abd1 ...
+ image: debian
+ ...
+ lastState:
+ terminated:
+ ...
+ name: debian-container
+ ...
+
+ - containerID: docker://96c1ff2c5bb ...
+ image: nginx
+ ...
+ name: nginx-container
+ ...
+ state:
+ running:
+ ...
+
+
+
+你可以看到 debian 容器已经被终止了,而 nginx 服务器依然在运行。
+
+
+进入 nginx 容器的 shell:
+
+ kubectl exec -it two-containers -c nginx-container -- /bin/bash
+
+
+在 shell 中,确认 nginx 还在运行。
+
+ root@two-containers:/# ps aux
+
+
+输出类似于这样:
+
+ USER PID ... STAT START TIME COMMAND
+ root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;
+
+
+
+回忆一下,debian 容器在 nginx 的根目录下创建了 `index.html` 文件。
+使用 `curl` 向 nginx 服务器发送一个 GET 请求:
+
+ root@two-containers:/# apt-get update
+ root@two-containers:/# apt-get install curl
+ root@two-containers:/# curl localhost
+
+
+输出表示 nginx 提供了 debian 容器写的页面:
+
+ Hello from the debian container
+
+{% endcapture %}
+
+
+{% capture discussion %}
+
+
+## 讨论
+
+
+
+
+
+
+
+
+Pod 能有多个容器的主要原因是为了支持辅助应用(helper applications),以协助主应用(primary application)。
+辅助应用的典型例子是数据抽取,数据推送和代理。辅助应用和主应用经常需要相互通信。
+就如这个练习所示,通信通常是通过共享文件系统完成的,或者,也通过回环网络接口 localhost 完成。
+举个网络接口的例子,web 服务器带有一个协助程序用于拉取 Git 仓库的更新。
+
+
+
+
+在本练习中的卷为 Pod 生命周期中的容器相互通信提供了一种方法。如果 Pod 被删除或者重建了,
+任何共享卷中的数据都会丢失。
+
+{% endcapture %}
+
+
+{% capture whatsnext %}
+
+
+
+* 更多学习内容
+[混合容器的方式](http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html)。
+
+
+
+* 学习 [模块化架构的混合容器](http://www.slideshare.net/Docker/slideshare-burns)。
+
+
+
+* 参见 [配置一个使用存储卷的 Pod](/docs/tasks/configure-pod-container/configure-volume-storage/)。
+
+
+* 参见 [卷](/docs/api-reference/{{page.version}}/#volume-v1-core)。
+
+
+* 参见 [Pod](/docs/api-reference/{{page.version}}/#pod-v1-core).
+
+{% endcapture %}
+
+
+{% include templates/task.md %}
diff --git a/cn/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md b/cn/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md
new file mode 100644
index 0000000000..c3583aab6b
--- /dev/null
+++ b/cn/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md
@@ -0,0 +1,316 @@
+---
+title: 配置对多集群的访问
+---
+
+
+{% capture overview %}
+
+本文展示如何使用配置文件来配置对多个集群的访问。 在将集群、用户和上下文定义在一个或多个配置文件中之后,用户可以使用 `kubectl config use-context` 命令快速地在集群之间进行切换。
+
+**注意:** 用于配置集群访问的文件有时被称为 *kubeconfig 文件*。
+这是一种引用配置文件的通用方式,并不意味着存在一个名为 `kubeconfig` 的文件。
+{: .note}
+
+{% endcapture %}
+
+{% capture prerequisites %}
+
+需要安装 [`kubectl`](/docs/tasks/tools/install-kubectl/) 命令行工具。
+
+{% endcapture %}
+
+{% capture steps %}
+
+## 定义集群、用户和上下文
+
+假设用户有两个集群,一个用于正式开发工作,一个用于其它临时用途(scratch)。
+在 `development` 集群中,前端开发者在名为 `frontend` 的名字空间下工作,
+存储开发者在名为 `storage` 的名字空间下工作。 在 `scratch` 集群中,
+开发人员可能在默认名字空间下工作,也可能视情况创建附加的名字空间。 访问开发集群需要通过证书进行认证。 访问其它临时用途的集群需要通过用户名和密码进行认证。
+
+创建名为 `config-exercise` 的目录。 在
+`config-exercise` 目录中,创建名为 `config-demo` 的文件,其内容为:
+
+```yaml
+apiVersion: v1
+kind: Config
+preferences: {}
+
+clusters:
+- cluster:
+ name: development
+- cluster:
+ name: scratch
+
+users:
+- name: developer
+- name: experimenter
+
+contexts:
+- context:
+ name: dev-frontend
+- context:
+ name: dev-storage
+- context:
+ name: exp-scratch
+```
+
+配置文件描述了集群、用户名和上下文。 `config-demo` 文件中含有描述两个集群、两个用户和三个上下文的框架。
+
+进入 `config-exercise` 目录。 输入以下命令,将群集详细信息添加到配置文件中:
+
+```shell
+kubectl config --kubeconfig=config-demo set-cluster development --server=https://1.2.3.4 --certificate-authority=fake-ca-file
+kubectl config --kubeconfig=config-demo set-cluster scratch --server=https://5.6.7.8 --insecure-skip-tls-verify
+```
+
+将用户详细信息添加到配置文件中:
+
+```shell
+kubectl config --kubeconfig=config-demo set-credentials developer --client-certificate=fake-cert-file --client-key=fake-key-seefile
+kubectl config --kubeconfig=config-demo set-credentials experimenter --username=exp --password=some-password
+```
+
+将上下文详细信息添加到配置文件中:
+
+```shell
+kubectl config --kubeconfig=config-demo set-context dev-frontend --cluster=development --namespace=frontend --user=developer
+kubectl config --kubeconfig=config-demo set-context dev-storage --cluster=development --namespace=storage --user=developer
+kubectl config --kubeconfig=config-demo set-context exp-scratch --cluster=scratch --namespace=default --user=experimenter
+```
+
+打开 `config-demo` 文件查看添加的详细信息。 也可以使用 `config view` 命令进行查看:
+
+```shell
+kubectl config --kubeconfig=config-demo view
+```
+
+输出展示了两个集群、两个用户和三个上下文:
+
+```yaml
+apiVersion: v1
+clusters:
+- cluster:
+ certificate-authority: fake-ca-file
+ server: https://1.2.3.4
+ name: development
+- cluster:
+ insecure-skip-tls-verify: true
+ server: https://5.6.7.8
+ name: scratch
+contexts:
+- context:
+ cluster: development
+ namespace: frontend
+ user: developer
+ name: dev-frontend
+- context:
+ cluster: development
+ namespace: storage
+ user: developer
+ name: dev-storage
+- context:
+ cluster: scratch
+ namespace: default
+ user: experimenter
+ name: exp-scratch
+current-context: ""
+kind: Config
+preferences: {}
+users:
+- name: developer
+ user:
+ client-certificate: fake-cert-file
+ client-key: fake-key-file
+- name: experimenter
+ user:
+ password: some-password
+ username: exp
+```
+
+每个上下文包含三部分(集群、用户和名字空间),例如,
+`dev-frontend` 上下文表明:使用 `developer` 用户的凭证来访问 `development` 集群的 `frontend` 名字空间。
+
+设置当前上下文:
+
+```shell
+kubectl config --kubeconfig=config-demo use-context dev-frontend
+```
+
+现在当输入 `kubectl` 命令时,相应动作会应用于 `dev-frontend` 上下文中所列的集群和名字空间,同时,命令会使用 `dev-frontend` 上下文中所列用户的凭证。
+
+使用 `--minify` 参数,来查看与当前上下文相关联的配置信息。
+
+```shell
+kubectl config --kubeconfig=config-demo view --minify
+```
+
+输出结果展示了 `dev-frontend` 上下文相关的配置信息:
+
+```yaml
+apiVersion: v1
+clusters:
+- cluster:
+ certificate-authority: fake-ca-file
+ server: https://1.2.3.4
+ name: development
+contexts:
+- context:
+ cluster: development
+ namespace: frontend
+ user: developer
+ name: dev-frontend
+current-context: dev-frontend
+kind: Config
+preferences: {}
+users:
+- name: developer
+ user:
+ client-certificate: fake-cert-file
+ client-key: fake-key-file
+```
+
+现在假设用户希望在其它临时用途集群中工作一段时间。
+
+将当前上下文更改为 `exp-scratch`:
+
+```shell
+kubectl config --kubeconfig=config-demo use-context exp-scratch
+```
+
+现在用户 `kubectl` 下达的任何命令都将应用于 `scratch` 集群的默认名字空间。 同时,命令会使用 `exp-scratch` 上下文中所列用户的凭证。
+
+查看更新后的当前上下文 `exp-scratch` 相关的配置:
+
+```shell
+kubectl config --kubeconfig=config-demo view --minify
+```
+
+最后,假设用户希望在 `development` 集群中的 `storage` 名字空间下工作一段时间。
+
+将当前上下文更改为 `dev-storage`:
+
+```shell
+kubectl config --kubeconfig=config-demo use-context dev-storage
+```
+
+查看更新后的当前上下文 `dev-storage` 相关的配置:
+
+
+```shell
+kubectl config --kubeconfig=config-demo view --minify
+```
+
+## 创建第二个配置文件
+
+在 `config-exercise` 目录中,创建名为 `config-demo-2` 的文件,其中包含以下内容:
+
+```yaml
+apiVersion: v1
+kind: Config
+preferences: {}
+
+contexts:
+- context:
+ cluster: development
+ namespace: ramp
+ user: developer
+ name: dev-ramp-up
+```
+
+上述配置文件定义了一个新的上下文,名为 `dev-ramp-up`。
+
+## 设置 KUBECONFIG 环境变量
+
+查看是否有名为 `KUBECONFIG` 的环境变量。 如有,保存 `KUBECONFIG` 环境变量当前的值,以便稍后恢复。
+例如,在 Linux 中:
+
+```shell
+export KUBECONFIG_SAVED=$KUBECONFIG
+```
+
+`KUBECONFIG` 环境变量是配置文件路径的列表,该列表在 Linux 和 Mac 中以冒号分隔,在 Windows 中以分号分隔。 如果有 `KUBECONFIG` 环境变量,请熟悉列表中的配置文件。
+
+临时添加两条路径到 `KUBECONFIG` 环境变量中。 例如,在 Linux 中:
+
+```shell
+export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2
+```
+
+在 `config-exercise` 目录中输入以下命令:
+
+```shell
+kubectl config view
+```
+
+输出展示了 `KUBECONFIG` 环境变量中所列举的所有文件合并后的信息。 特别地, 注意合并信息中包含来自 `config-demo-2` 文件的 `dev-ramp-up` 上下文和来自 `config-demo` 文件的三个上下文:
+
+```yaml
+contexts:
+- context:
+ cluster: development
+ namespace: frontend
+ user: developer
+ name: dev-frontend
+- context:
+ cluster: development
+ namespace: ramp
+ user: developer
+ name: dev-ramp-up
+- context:
+ cluster: development
+ namespace: storage
+ user: developer
+ name: dev-storage
+- context:
+ cluster: scratch
+ namespace: default
+ user: experimenter
+ name: exp-scratch
+```
+
+更多关于 kubeconfig 文件如何合并的信息,请参考
+[使用 kubeconfig 文件组织集群访问](/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
+
+## 探索 $HOME/.kube 目录
+
+如果用户已经拥有一个集群,可以使用 `kubectl` 与集群进行交互。 那么很可能在 `$HOME/.kube` 目录下有一个名为 `config` 的文件。
+
+进入 `$HOME/.kube` 目录, 看看那里有什么文件。 通常会有一个名为
+`config` 的文件,目录中可能还有其他配置文件。 请简单地熟悉这些文件的内容。
+
+## 将 $HOME/.kube/config 追加到 KUBECONFIG 环境变量中
+
+如果有 `$HOME/.kube/config` 文件,并且还未列在 `KUBECONFIG` 环境变量中,
+那么现在将它追加到 `KUBECONFIG` 环境变量中。
+例如,在 Linux 中:
+
+```shell
+export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config
+```
+
+在配置练习目录中输入以下命令,来查看当前 `KUBECONFIG` 环境变量中列举的所有文件合并后的配置信息:
+
+```shell
+kubectl config view
+```
+
+## 清理
+
+将 `KUBECONFIG` 环境变量还原为原始值。 例如,在 Linux 中:
+
+```shell
+export KUBECONFIG=$KUBECONFIG_SAVED
+```
+
+{% endcapture %}
+
+{% capture whatsnext %}
+
+* [使用 kubeconfig 文件组织集群访问](/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
+* [kubectl 配置](/docs/user-guide/kubectl/{{page.version}}/)
+
+{% endcapture %}
+
+{% include templates/task.md %}
+
diff --git a/cn/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md b/cn/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md
new file mode 100644
index 0000000000..b38bdd938d
--- /dev/null
+++ b/cn/docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md
@@ -0,0 +1,126 @@
+---
+approvers:
+- bprashanth
+- davidopp
+title: 配置你的云平台防火墙
+---
+
+
+
+
+
+
+许多云服务商(比如 Google Compute Engine)定义防火墙以防止服务无意间暴露到 internet 上。
+当暴露服务给外网时,你可能需要在防火墙上开启一个或者更多的端口来支持服务。
+本文描述了这个过程,以及其他云服务商的具体信息。
+
+
+## 负载均衡(LoadBalancer)服务的访问限制
+
+
+
+
+ 当以 `spec.type: LoadBalancer` 使用服务时,你可以使用 `spec.loadBalancerSourceRanges` 指定允许访问负载均衡的 IP 段。
+ 这个字段采用 CIDR 的 IP 段,Kubernetes 会使用这个段配置防火墙。支持这个功能的平台目前有 Google Compute Engine,Google Kubernetes Engine 和 AWS。
+ 如果云服务商不支持这个功能,这个字段会被忽略。
+
+
+
+ 假设 10.0.0.0/8 是内部的子网。在下面这个例子中,会创建一个只有集群内部 ip 可以访问的负载均衡器。
+ 集群外部的客户端是无法访问这个负载均衡器的。
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: myapp
+spec:
+ ports:
+ - port: 8765
+ targetPort: 9376
+ selector:
+ app: example
+ type: LoadBalancer
+ loadBalancerSourceRanges:
+ - 10.0.0.0/8
+```
+
+
+ 这个例子中,会创建一个只能被 IP 为 130.211.204.1 和 130.211.204.2 的客户端访问的负载据衡器。
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: myapp
+spec:
+ ports:
+ - port: 8765
+ targetPort: 9376
+ selector:
+ app: example
+ type: LoadBalancer
+ loadBalancerSourceRanges:
+ - 130.211.204.1/32
+ - 130.211.204.2/32
+```
+
+
+### 谷歌计算引擎(Google Compute Engine)
+
+
+
+
+当以 `spec.type: LoadBalancer` 使用服务时,防火墙会被自动打开。
+然而,当以 `spec.type: NodePort` 使用服务时,防火墙默认 *不会* 被打开。
+
+
+Google Compute Engine 的防火墙文档在[别处](https://cloud.google.com/compute/docs/networking#firewalls_1)。
+
+
+你可以使用 `gcloud` 命令行工具添加一个防火墙:
+
+```shell
+$ gcloud compute firewall-rules create my-rule --allow=tcp:
+```
+
+
+
+**注意**
+使用 Google Compute Engine 平台的防火墙时有一个重要的关于安全的注意点:
+
+
+
+
+
+
+
+在 Kubernetes v1.0.0 版本,GCE 防火墙是定义按虚拟机(VM)来的,而不是按 ip 来的。
+这就意味着当你在防火墙上打开一个服务端口时,任何在那台虚拟机 IP 上的同一端口的服务
+都有被外部访问的潜在可能。注意,这对于其他 Kubernetes 服务来说不是问题,因为他们监
+听的 IP 地址与主机节点的外部 IP 地址不同。
+
+
+考虑一下:
+
+ * 你创建了一个服务,使用了外部服务均衡 (IP 地址为 1.2.3.4) 和 80 端口。
+ * 你在防火墙上为集群的所有节点都打开了 80 端口,所以外部的服务可以向你的
+ 服务发送数据包。
+ * 你又在虚拟机(IP 为2.3.4.5)上使用 80 端口启动了一台 nginx 服务器.
+ 这个 nginx 在虚拟机的外部 IP 地址上也被暴露到了 internet 上。
+
+
+
+
+因此,在 Google Compute Engine 或者 Google Kubernetes Engine 上开启防火墙端口时请
+小心。你可能无意间把其他服务也暴露给了 internet。
+
+
+这个问题会在 Kubernetes 后续版本中被修复。
+
+
+### 其他云服务商
+
+
+即将更新
+
diff --git a/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md b/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md
new file mode 100644
index 0000000000..f2d82fae7e
--- /dev/null
+++ b/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md
@@ -0,0 +1,223 @@
+---
+title: 使用 Service 把前端连接到后端
+---
+
+
+{% capture overview %}
+
+
+
+
+本任务会描述如何创建前端微服务和后端微服务。后端微服务是一个 hello 欢迎程序。
+前端和后端的连接是通过 Kubernetes 服务对象(Service object)完成的。
+
+{% endcapture %}
+
+
+{% capture objectives %}
+
+
+
+
+* 使用部署对象(Deployment object)创建并运行一个微服务
+* 从后端将流量路由到前端
+* 使用服务对象把前端应用连接到后端应用
+
+{% endcapture %}
+
+
+{% capture prerequisites %}
+
+* {% include task-tutorial-prereqs.md %}
+
+
+* 本任务使用 [外部负载均衡服务](/docs/tasks/access-application-cluster/create-external-load-balancer/),
+ 所以需要对应的可支持此功能的环境。如果你的环境不能支持,你可以使用
+ [NodePort](/docs/user-guide/services/#type-nodeport) 类型的服务代替。
+
+{% endcapture %}
+
+
+{% capture lessoncontent %}
+
+
+### 使用部署对象(Deployment)创建后端
+
+
+
+后端是一个简单的 hello 欢迎微服务应用。这是后端应用的 Deployment 配置文件:
+
+{% include code.html language="yaml" file="hello.yaml" ghlink="/docs/tasks/access-application-cluster/hello.yaml" %}
+
+
+创建后端 Deployment:
+
+```
+kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello.yaml
+```
+
+
+查看后端的 Deployment 信息:
+
+```
+kubectl describe deployment hello
+```
+
+
+输出类似于:
+
+```
+Name: hello
+Namespace: default
+CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
+Labels: app=hello
+ tier=backend
+ track=stable
+Selector: app=hello,tier=backend,track=stable
+Replicas: 7 updated | 7 total | 7 available | 0 unavailable
+StrategyType: RollingUpdate
+MinReadySeconds: 0
+RollingUpdateStrategy: 1 max unavailable, 1 max surge
+OldReplicaSets:
+NewReplicaSet: hello-3621623197 (7/7 replicas created)
+Events:
+...
+```
+
+
+### 创建后端服务对象(Service object)
+
+
+
+
+
+前端连接到后端的关键是 Service。Service 创建一个固定 IP 和 DNS 解析名入口,
+使得后端微服务可达。Service 使用 selector 标签来寻找目标 Pod。
+
+
+首先,浏览 Service 的配置文件:
+
+{% include code.html language="yaml" file="hello-service.yaml" ghlink="/docs/tasks/access-application-cluster/hello-service.yaml" %}
+
+
+
+配置文件中,你可以看到 Service 将流量路由到包含 `app: hello` 和 `tier: backend` 标签的 Pod。
+
+
+创建 `hello` Service:
+
+```
+kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/hello-service.yaml
+```
+
+
+
+此时,你已经有了一个在运行的后端 Deployment,你也有了一个 Service 用于路由网络流量。
+
+
+### 创建前端应用
+
+
+
+
+
+既然你已经有了后端应用,你可以创建一个前端应用连接到后端。前端应用通过 DNS 名连接到后端的工作 Pods。
+DNS 名是 "hello",也就是 Service 配置文件中 `name` 字段的值。
+
+
+
+前端 Deployment 中的 Pods 运行一个 nginx 镜像,这个已经配置好镜像去寻找后端的 hello Service。
+只是 nginx 的配置文件:
+
+{% include code.html file="frontend/frontend.conf" ghlink="/docs/tasks/access-application-cluster/frontend/frontend.conf" %}
+
+
+
+
+与后端类似,前端用包含一个 Deployment 和一个 Service。Service 的配置文件包含了 `type: LoadBalancer`,
+也就是说,Service 会使用你的云服务商的默认负载均衡设备。
+
+{% include code.html language="yaml" file="frontend.yaml" ghlink="/docs/tasks/access-application-cluster/frontend.yaml" %}
+
+
+创建前端 Deployment 和 Service:
+
+```
+kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/frontend.yaml
+```
+
+
+通过输出确认两个资源都已经被创建:
+
+```
+deployment "frontend" created
+service "frontend" created
+```
+
+
+
+
+
+
+**注意**:这个 nginx 配置文件是被打包在 [容器镜像](/docs/tasks/access-application-cluster/frontend/Dockerfile) 里的。
+更好的方法是使用 [ConfigMap](/docs/tasks/configure-pod-container/configmap/),这样的话你可以更轻易地更改配置。
+
+
+### 与前端 Service 交互
+
+
+
+一旦你创建了 LoadBalancer 类型的 Service,你可以使用这条命令查看外部 IP:
+
+```
+kubectl get service frontend
+```
+
+
+
+外部 IP 字段的生成可能需要一些时间。如果是这种情况,外部 IP 会显示为 ``。
+
+```
+NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+frontend 10.51.252.116 80/TCP 10s
+```
+
+
+使用相同的命令直到它显示外部 IP 地址:
+
+```
+NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+frontend 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
+```
+
+
+### 通过前端发送流量
+
+
+
+前端和后端已经完成连接了。你可以使用 curl 命令通过你的前端 Service 的外部 IP 访问服务端点。
+
+```
+curl http://
+```
+
+
+后端生成的消息输出如下:
+
+```
+{"message":"Hello"}
+```
+
+{% endcapture %}
+
+
+{% capture whatsnext %}
+
+
+
+* 了解更多 [Services](/docs/concepts/services-networking/service/)
+* 了解更多 [ConfigMaps](/docs/tasks/configure-pod-container/configmap/)
+
+{% endcapture %}
+
+{% include templates/tutorial.md %}
diff --git a/cn/docs/tasks/access-application-cluster/frontend/frontend.conf b/cn/docs/tasks/access-application-cluster/frontend/frontend.conf
new file mode 100644
index 0000000000..9a1f5a0ed6
--- /dev/null
+++ b/cn/docs/tasks/access-application-cluster/frontend/frontend.conf
@@ -0,0 +1,11 @@
+upstream hello {
+ server hello;
+}
+
+server {
+ listen 80;
+
+ location / {
+ proxy_pass http://hello;
+ }
+}
diff --git a/cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md b/cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md
deleted file mode 100644
index 672495468a..0000000000
--- a/cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md
+++ /dev/null
@@ -1,94 +0,0 @@
----
-title: Use Port Forwarding to Access Applications in a Cluster
----
-
-{% capture overview %}
-
-This page shows how to use `kubectl port-forward` to connect to a Redis
-server running in a Kubernetes cluster. This type of connection can be useful
-for database debugging.
-
-{% endcapture %}
-
-
-{% capture prerequisites %}
-
-* {% include task-tutorial-prereqs.md %}
-
-* Install [redis-cli](http://redis.io/topics/rediscli).
-
-{% endcapture %}
-
-
-{% capture steps %}
-
-## Creating a pod to run a Redis server
-
-1. Create a pod:
-
- kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/redis-master.yaml
-
- The output of a successful command verifies that the pod was created:
-
- pod "redis-master" created
-
-1. Check to see whether the pod is running and ready:
-
- kubectl get pods
-
- When the pod is ready, the output displays a STATUS of Running:
-
- NAME READY STATUS RESTARTS AGE
- redis-master 2/2 Running 0 41s
-
-1. Verify that the Redis server is running in the pod and listening on port 6379:
-
- {% raw %}
- kubectl get pods redis-master --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
- {% endraw %}
-
- The output displays the port:
-
- 6379
-
-## Forward a local port to a port on the pod
-
-1. Forward port 6379 on the local workstation to port 6379 of redis-master pod:
-
- kubectl port-forward redis-master 6379:6379
-
- The output is similar to this:
-
- I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:6379 -> 6379
- I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:6379 -> 6379
-
-1. Start the Redis command line interface:
-
- redis-cli
-
-1. At the Redis command line prompt, enter the `ping` command:
-
- 127.0.0.1:6379>ping
-
- A successful ping request returns PONG.
-
-{% endcapture %}
-
-
-{% capture discussion %}
-
-## Discussion
-
-Connections made to local port 6379 are forwarded to port 6379 of the pod that
-is running the Redis server. With this connection in place you can use your
-local workstation to debug the database that is running in the pod.
-
-{% endcapture %}
-
-
-{% capture whatsnext %}
-Learn more about [kubectl port-forward](/docs/user-guide/kubectl/v1.6/#port-forward).
-{% endcapture %}
-
-
-{% include templates/task.md %}
diff --git a/cn/docs/tasks/access-application-cluster/service-access-application-cluster.md b/cn/docs/tasks/access-application-cluster/service-access-application-cluster.md
deleted file mode 100644
index ebbd195b5e..0000000000
--- a/cn/docs/tasks/access-application-cluster/service-access-application-cluster.md
+++ /dev/null
@@ -1,147 +0,0 @@
----
-title: Use a Service to Access an Application in a Cluster
----
-
-{% capture overview %}
-
-This page shows how to create a Kubernetes Service object that external
-clients can use to access an application running in a cluster. The Service
-provides load balancing for an application that has two running instances.
-
-{% endcapture %}
-
-
-{% capture prerequisites %}
-
-{% include task-tutorial-prereqs.md %}
-
-{% endcapture %}
-
-
-{% capture objectives %}
-
-* Run two instances of a Hello World application.
-* Create a Service object that exposes a node port.
-* Use the Service object to access the running application.
-
-{% endcapture %}
-
-
-{% capture lessoncontent %}
-
-## Creating a service for an application running in two pods
-
-1. Run a Hello World application in your cluster:
-
- kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080
-
- The preceding command creates a
- [Deployment](/docs/concepts/workloads/controllers/deployment/)
- object and an associated
- [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/)
- object. The ReplicaSet has two
- [Pods](/docs/concepts/workloads/pods/pod/),
- each of which runs the Hello World application.
-
-1. Display information about the Deployment:
-
- kubectl get deployments hello-world
- kubectl describe deployments hello-world
-
-1. Display information about your ReplicaSet objects:
-
- kubectl get replicasets
- kubectl describe replicasets
-
-1. Create a Service object that exposes the deployment:
-
- kubectl expose deployment hello-world --type=NodePort --name=example-service
-
-1. Display information about the Service:
-
- kubectl describe services example-service
-
- The output is similar to this:
-
- Name: example-service
- Namespace: default
- Labels: run=load-balancer-example
- Selector: run=load-balancer-example
- Type: NodePort
- IP: 10.32.0.16
- Port: 8080/TCP
- NodePort: 31496/TCP
- Endpoints: 10.200.1.4:8080,10.200.2.5:8080
- Session Affinity: None
- No events.
-
- Make a note of the NodePort value for the service. For example,
- in the preceding output, the NodePort value is 31496.
-
-1. List the pods that are running the Hello World application:
-
- kubectl get pods --selector="run=load-balancer-example" --output=wide
-
- The output is similar to this:
-
- NAME READY STATUS ... IP NODE
- hello-world-2895499144-bsbk5 1/1 Running ... 10.200.1.4 worker1
- hello-world-2895499144-m1pwt 1/1 Running ... 10.200.2.5 worker2
-
-1. Get the public IP address of one of your nodes that is running
- a Hello World pod. How you get this address depends on how you set
- up your cluster. For example, if you are using Minikube, you can
- see the node address by running `kubectl cluster-info`. If you are
- using Google Compute Engine instances, you can use the
- `gcloud compute instances list` command to see the public addresses of your
- nodes. For more information about this command, see the [GCE documentation](https://cloud.google.com/sdk/gcloud/reference/compute/instances/list).
-
-1. On your chosen node, create a firewall rule that allows TCP traffic
- on your node port. For example, if your Service has a NodePort value of
- 31568, create a firewall rule that allows TCP traffic on port 31568. Different
- cloud providers offer different ways of configuring firewall rules. See [the
- GCE documentation on firewall rules](https://cloud.google.com/compute/docs/vpc/firewalls),
- for example.
-
-1. Use the node address and node port to access the Hello World application:
-
- curl http://:
-
- where `` is the public IP address of your node,
- and `` is the NodePort value for your service.
-
- The response to a successful request is a hello message:
-
- Hello Kubernetes!
-
-## Using a service configuration file
-
-As an alternative to using `kubectl expose`, you can use a
-[service configuration file](/docs/user-guide/services/operations)
-to create a Service.
-
-{% endcapture %}
-
-
-{% capture cleanup %}
-
-To delete the Service, enter this command:
-
- kubectl delete services example-service
-
-To delete the Deployment, the ReplicaSet, and the Pods that are running
-the Hello World application, enter this command:
-
- kubectl delete deployment hello-world
-
-{% endcapture %}
-
-
-{% capture whatsnext %}
-
-Learn more about
-[connecting applications with services](/docs/concepts/services-networking/connect-applications-service/).
-{% endcapture %}
-
-{% include templates/tutorial.md %}
-
diff --git a/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md b/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md
index 5ffd280425..408f6b4b41 100644
--- a/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md
+++ b/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- derekwaynecarr
- janetkuo
diff --git a/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md b/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md
index 14844d903e..10caf64853 100644
--- a/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md
+++ b/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md
@@ -20,7 +20,7 @@ title: 更改 PersistentVolume 的回收策略
## 为什么要更改 PersistentVolume 的回收策略
-`PersistentVolumes` 可以有多种回收策略,包括 "Retain"、"Recycle" 和 "Delete"。对于动态配置的 `PersistentVolumes` 来说,默认回收策略为 "Delete"。这表示当用户删除对应的 `PeristentVolumeClaim` 时,动态配置的 volume 将被自动删除。如果 volume 包含重要数据时,这种自动行为可能是不合适的。那种情况下,更适合使用 "Retain" 策略。使用 "Retain" 时,如果用户删除 `PersistentVolumeClaim`,对应的 `PersistentVolume` 不会被删除。相反,它将变为 `Released` 状态,表示所有的数据可以被手动恢复。
+`PersistentVolumes` 可以有多种回收策略,包括 "Retain"、"Recycle" 和 "Delete"。对于动态配置的 `PersistentVolumes` 来说,默认回收策略为 "Delete"。这表示当用户删除对应的 `PersistentVolumeClaim` 时,动态配置的 volume 将被自动删除。如果 volume 包含重要数据时,这种自动行为可能是不合适的。那种情况下,更适合使用 "Retain" 策略。使用 "Retain" 时,如果用户删除 `PersistentVolumeClaim`,对应的 `PersistentVolume` 不会被删除。相反,它将变为 `Released` 状态,表示所有的数据可以被手动恢复。
## 更改 PersistentVolume 的回收策略
diff --git a/cn/docs/tasks/administer-cluster/cluster-management.md b/cn/docs/tasks/administer-cluster/cluster-management.md
index f492a2314d..671bd29989 100644
--- a/cn/docs/tasks/administer-cluster/cluster-management.md
+++ b/cn/docs/tasks/administer-cluster/cluster-management.md
@@ -57,13 +57,13 @@ cluster/gce/upgrade.sh release/stable
```
-### 升级 Google Container Engine (GKE) 集群
+### 升级 Google Kubernetes Engine 集群
-Google Container Engine 自动升级 master 组件(例如 `kube-apiserver`、`kube-scheduler`)至最新版本。它还负责 master 运行的操作系统和其它组件。
+Google Kubernetes Engine 自动升级 master 组件(例如 `kube-apiserver`、`kube-scheduler`)至最新版本。它还负责 master 运行的操作系统和其它组件。
-节点升级过程由用户初始化,[GKE 文档](https://cloud.google.com/container-engine/docs/clusters/upgrade) 里有相关描述。
+节点升级过程由用户初始化,[Google Kubernetes Engine 文档](https://cloud.google.com/kubernetes-engine/docs/clusters/upgrade) 里有相关描述。
### 在其他平台上升级集群
@@ -80,7 +80,7 @@ Google Container Engine 自动升级 master 组件(例如 `kube-apiserver`、`
## 调整集群大小
-如果集群资源短缺,您可以轻松的添加更多的机器,如果集群正运行在[节点自注册模式](/docs/admin/node/#self-registration-of-nodes)下的话。如果正在使用的是 GCE 或者 GKE,这将通过调整管理节点的实例组的大小完成。在 [Google Cloud Console page](https://console.developers.google.com) 的 `Compute > Compute Engine > Instance groups > your group > Edit group` 下修改实例数量或使用 gcloud CLI 都可以完成这个任务。
+如果集群资源短缺,您可以轻松的添加更多的机器,如果集群正运行在[节点自注册模式](/docs/admin/node/#self-registration-of-nodes)下的话。如果正在使用的是 GCE 或者 Google Kubernetes Engine,这将通过调整管理节点的实例组的大小完成。在 [Google Cloud Console page](https://console.developers.google.com) 的 `Compute > Compute Engine > Instance groups > your group > Edit group` 下修改实例数量或使用 gcloud CLI 都可以完成这个任务。
```shell
gcloud compute instance-groups managed resize kubernetes-minion-group --size 42 --zone $ZONE
@@ -96,7 +96,7 @@ gcloud compute instance-groups managed resize kubernetes-minion-group --size 42
### 集群自动伸缩
-如果正在使用 GCE 或者 GKE,您可以配置您的集群,使其能够基于 pod 需求自动重新调整大小。
+如果正在使用 GCE 或者 Google Kubernetes Engine,您可以配置您的集群,使其能够基于 pod 需求自动重新调整大小。
如 [Compute Resource](/docs/concepts/configuration/manage-compute-resources-container/) 所述,用户可以控制预留多少 CPU 和内存来分配给 pod。这个信息被 Kubernetes scheduler 用来寻找一个运行 pod 的地方。如果没有一个节点有足够的空闲容量(或者不能满足其他 pod 的需求),这个 pod 就需要等待某些 pod 结束,或者一个新的节点被添加。
@@ -108,7 +108,7 @@ gcloud compute instance-groups managed resize kubernetes-minion-group --size 42
如果发现在一段延时时间内(默认10分钟,将来有可能改变)某些节点不再需要,集群 autoscaler 也会缩小集群。
-集群 autoscaler 在每一个实例组(GCE)或节点池(GKE)上配置。
+集群 autoscaler 在每一个实例组(GCE)或节点池(Google Kubernetes Engine)上配置。
如果您使用 GCE,那么您可以在使用 kube-up.sh 脚本创建集群的时候启用它。要想配置集群 autoscaler,您需要设置三个环境变量:
@@ -126,7 +126,7 @@ KUBE_ENABLE_CLUSTER_AUTOSCALER=true KUBE_AUTOSCALER_MIN_NODES=3 KUBE_AUTOSCALER_
```
-在 GKE 上,您可以在创建、更新集群或创建一个特别的节点池(您希望自动伸缩的)时,通过给对应的 `gcloud` 命令传递 `--enable-autoscaling` `--min-nodes` 和 `--max-nodes` 来配置集群 autoscaler。
+在 Google Kubernetes Engine 上,您可以在创建、更新集群或创建一个特别的节点池(您希望自动伸缩的)时,通过给对应的 `gcloud` 命令传递 `--enable-autoscaling` `--min-nodes` 和 `--max-nodes` 来配置集群 autoscaler。
示例:
diff --git a/cn/docs/tasks/administer-cluster/cpu-management-policies.md b/cn/docs/tasks/administer-cluster/cpu-management-policies.md
new file mode 100644
index 0000000000..78266c47e0
--- /dev/null
+++ b/cn/docs/tasks/administer-cluster/cpu-management-policies.md
@@ -0,0 +1,143 @@
+---
+title: 控制节点上的CPU管理策略
+---
+
+* TOC
+{:toc}
+
+按照设计,Kubernetes 对 pod 执行相关的很多方面进行了抽象,使得用户不必关心。然而,为了正常运行,有些工作负载要求在延迟和/或性能方面有更强的保证。 为此,kubelet 提供方法来实现更复杂的负载放置策略,同时保持抽象,避免显式的放置指令。
+
+## CPU 管理策略
+
+默认情况下,kubelet 使用 [CFS 配额](https://en.wikipedia.org/wiki/Completely_Fair_Scheduler) 来执行 pod 的 CPU 约束。当节点上运行了很多 CPU 密集的 pod 时,工作负载可能会迁移到不同的 CPU 核,这取决于调度时 pod 是否被扼制,以及哪些 CPU 核是可用的。许多工作负载对这种迁移不敏感,因此无需任何干预即可正常工作。
+
+然而,有些工作负载的性能明显地受到 CPU 缓存亲和性以及调度延迟的影响,对此,kubelet 提供了可选的 CPU 管理策略,来确定节点上的一些分配偏好。
+
+### 配置
+
+CPU 管理器(CPU Manager)作为 alpha 特性引入 Kubernetes 1.8 版本。 必须在 kubelet 特性开关中显式启用:
+`--feature-gates=CPUManager=true`。
+
+CPU 管理策略通过 kubelet 参数 `--cpu-manager-policy` 来指定,
+有两种支持策略:
+
+* `none`:默认策略,表示现有的调度行为。
+* `static`:允许为节点上具有某些资源特征的 pod 赋予增强的 CPU 亲和性和独占性。
+
+CPU管理器定期通过 CRI 写入资源更新,以保证内存中 CPU 分配与 cgroupfs 一致。同步频率通过新增的 Kubelet 配置参数
+`--cpu-manager-reconcile-period` 来设置。 如不指定,默认与 `--node-status-update-frequency` 的周期相同。
+
+### None 策略
+
+`none` 策略显式地启用现有的默认 CPU 亲和方案,不提供操作系统调度器默认行为之外的亲和性策略。 通过 CFS 配额来实现
+[Guaranteed pods](/docs/tasks/configure-pod-container/quality-service-pod/) 的 CPU 使用限制。
+
+### Static 策略
+
+`static` 策略针对具有整数型 CPU `requests` 的 pod ,它允许该类 pod 中的容器访问节点上的独占 CPU 资源。这种独占性是使用 [cpuset cgroup 控制器](https://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt) 来实现的。
+
+**注意:** 诸如容器运行时和 kubelet 本身的系统服务可以继续在这些独占 CPU 上运行。独占性仅针对其他 pod。
+{: .note}
+
+**注意:** 该策略的 alpha 版本不保证 Kubelet 重启前后的静态独占性分配。
+{: .note}
+
+该策略管理一个共享 CPU 资源池,最初,该资源池包含节点上所有的 CPU 资源。可用的独占性 CPU 资源数量等于节点的 CPU 总量减去通过 `--kube-reserved` 或 `--system-reserved` 参数保留的 CPU 。通过这些参数预留的 CPU 是以整数方式,按物理内核 ID 升序从初始共享池获取的。 共享池是 `BestEffort` 和 `Burstable` pod 运行的 CPU 集合。`Guaranteed` pod 中的容器,如果声明了非整数值的 CPU `requests` ,也将运行在共享池的 CPU 上。只有 `Guaranteed` pod 中,指定了整数型 CPU `requests` 的容器,才会被分配独占 CPU 资源。
+
+**注意:** 当启用 static 策略时,要求使用 `--kube-reserved` 和/或 `--system-reserved` 来保证预留的 CPU 值大于零。 这是因为零预留 CPU 值可能使得共享池变空。
+{: .note}
+
+当 `Guaranteed` pod 调度到节点上时,如果其容器符合静态分配要求,相应的 CPU 会被从共享池中移除,并放置到容器的 cpuset 中。因为这些容器所使用的 CPU 受到调度域本身的限制,所以不需要使用 CFS 配额来进行 CPU 的绑定。换言之,容器 cpuset 中的 CPU 数量与 pod 规格中指定的整数型 CPU `limit` 相等。这种静态分配增强了 CPU 亲和性,减少了 CPU 密集的工作负载在节流时引起的上下文切换。
+
+考虑以下 Pod 规格的容器:
+
+```yaml
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+```
+
+该 pod 属于 `BestEffort` 服务质量类型,因为其未指定 `requests` 或
+`limits` 值。 所以该容器运行在共享 CPU 池中。
+
+```yaml
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+ resources:
+ limits:
+ memory: "200Mi"
+ requests:
+ memory: "100Mi"
+```
+
+该 pod 属于 `Burstable` 服务质量类型,因为其资源 `requests` 不等于
+`limits`, 且未指定 `cpu` 数量。所以该容器运行在共享 CPU 池中。
+
+```yaml
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+ resources:
+ limits:
+ memory: "200Mi"
+ cpu: "2"
+ requests:
+ memory: "100Mi"
+ cpu: "1"
+```
+
+该 pod 属于 `Burstable` 服务质量类型,因为其资源 `requests` 不等于 `limits`。所以该容器运行在共享 CPU 池中。
+
+```yaml
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+ resources:
+ limits:
+ memory: "200Mi"
+ cpu: "2"
+ requests:
+ memory: "200Mi"
+ cpu: "2"
+```
+
+该 pod 属于 `Guaranteed` 服务质量类型,因为其 `requests` 值与 `limits`相等。
+同时,容器对 CPU 资源的限制值是一个大于或等于 1 的整数值。所以,该 `nginx` 容器被赋予 2 个独占 CPU。
+
+
+```yaml
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+ resources:
+ limits:
+ memory: "200Mi"
+ cpu: "1.5"
+ requests:
+ memory: "200Mi"
+ cpu: "1.5"
+```
+
+该 pod 属于 `Guaranteed` 服务质量类型,因为其 `requests` 值与 `limits`相等。但是容器对 CPU 资源的限制值是一个小数。所以该容器运行在共享 CPU 池中。
+
+
+```yaml
+spec:
+ containers:
+ - name: nginx
+ image: nginx
+ resources:
+ limits:
+ memory: "200Mi"
+ cpu: "2"
+```
+
+该 pod 属于 `Guaranteed` 服务质量类型,因其指定了 `limits` 值,
+同时当未显式指定时,`requests` 值被设置为与 `limits` 值相等。同时,容器对 CPU 资源的限制值是一个大于或等于 1 的整数值。所以,该 `nginx` 容器被赋予 2 个独占 CPU。
+
diff --git a/cn/docs/tasks/administer-cluster/cpu-memory-limit.md b/cn/docs/tasks/administer-cluster/cpu-memory-limit.md
index 46808eeb71..b437c8a2f0 100644
--- a/cn/docs/tasks/administer-cluster/cpu-memory-limit.md
+++ b/cn/docs/tasks/administer-cluster/cpu-memory-limit.md
@@ -1,5 +1,5 @@
---
-assignees:
+approvers:
- derekwaynecarr
- janetkuo
title: 设置 Pod CPU 和内存限制
@@ -14,9 +14,8 @@ redirect_from:
-默认情况下,Pod 运行没有限制 CPU 和内存。
-这意味着系统中的任何 Pod 将能够像执行该 Pod 所在的节点一样,使用足够多 CPU 和内存。
-
+默认情况下,Pod 运行没有限制 CPU 使用量和内存使用量。
+这意味着当前系统中的任何 Pod 能够使用该 Pod 运行节点的所有 CPU 和内存资源。
这个例子演示了如何限制 Kubernetes [Namespace](/docs/tasks/administer-cluster/namespaces-walkthrough/),以此来控制每个 Pod 的最小/最大资源限额。
@@ -47,7 +46,7 @@ namespace "limit-example" created
-注意到 `kubectl` 命令将打印出被创建或修改的资源的类型和名称,也会在后面的命令中使用到:
+可以看到 `kubectl` 命令将打印出被创建或修改的资源的类型和名称,也会在后面的命令中使用到:
```shell
$ kubectl get namespaces
@@ -69,7 +68,7 @@ limitrange "mylimits" created
-让我们描述一下在该 Namespace 中被强加的限制:
+让我们查看一下在该 Namespace 中被强加的限制:
```shell
$ kubectl describe limits mylimits --namespace=limit-example
@@ -251,7 +250,7 @@ default Active 12m
{% capture whatsnext %}
-* 查看 [LimitRange 设计文档](https://git.k8s.io/community/contributors/design-proposals/admission_control_limit_range.md) 获取更多信息。
+* 查看 [LimitRange 设计文档](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-management/admission_control_limit_range.md) 获取更多信息。
* 查看 [资源](/docs/concepts/configuration/manage-compute-resources-container/) 获取关于 Kubernetes 资源模型的详细描述。
{% endcapture %}
diff --git a/cn/docs/tasks/administer-cluster/ip-masq-agent.md b/cn/docs/tasks/administer-cluster/ip-masq-agent.md
deleted file mode 100644
index 04625647c6..0000000000
--- a/cn/docs/tasks/administer-cluster/ip-masq-agent.md
+++ /dev/null
@@ -1,112 +0,0 @@
----
-title: IP Masquerade Agent User Guide
----
-
-{% capture overview %}
-This page shows how to configure and enable the ip-masq-agent.
-{% endcapture %}
-
-{% capture prerequisites %}
-
-{% include task-tutorial-prereqs.md %}
-
-{% endcapture %}
-
-{% capture discussion %}
-## IP Masquerade Agent User Guide
-
-The ip-masq-agent configures iptables rules to hide a pod's IP address behind the cluster node's IP address. This is typically done when sending traffic to destinations outside the cluster's pod [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) range.
-
-### **Key Terms**
-
-* **NAT (Network Address Translation)**
- Is a method of remapping one IP address to another by modifying either the source and/or destination address information in the IP header. Typically performed by a device doing IP routing.
-* **Masquerading**
- A form of NAT that is typically used to perform a many to one address translation, where multiple source IP addresses are masked behind a single address, which is typically the device doing the IP routing. In Kubernetes this is the Node's IP address.
-* **CIDR (Classless Inter-Domain Routing)**
- Based on the variable-length subnet masking, allows specifying arbitrary-length prefixes. CIDR introduced a new method of representation for IP addresses, now commonly known as **CIDR notation**, in which an address or routing prefix is written with a suffix indicating the number of bits of the prefix, such as 192.168.2.0/24.
-* **Link Local**
- A link-local address is a network address that is valid only for communications within the network segment or the broadcast domain that the host is connected to. Link-local addresses for IPv4 are defined in the address block 169.254.0.0/16 in CIDR notation.
-
-The ip-masq-agent configures iptables rules to handle masquerading node/pod IP addresses when sending traffic to destinations outside the cluster node's IP and the Cluster IP range. This essentially hides pod IP addresses behind the cluster node's IP address. In some environments, traffic to "external" addresses must come from a known machine address. For example, in Google Cloud, any traffic to the internet must come from a VM's IP. When containers are used, as in GKE, the Pod IP will be rejected for egress. To avoid this, we must hide the Pod IP behind the VM's own IP address - generally known as "masquerade". By default, the agent is configured to treat the three private IP ranges specified by [RFC 1918](https://tools.ietf.org/html/rfc1918) as non-masquerade [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). These ranges are 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. The agent will also treat link-local (169.254.0.0/16) as a non-masquerade CIDR by default. The agent is configured to reload its configuration from the location */etc/config/ip-masq-agent* every 60 seconds, which is also configurable.
-
-
-
-The agent configuration file must be written in YAML or JSON syntax, and may contain three optional keys:
-
-* **nonMasqueradeCIDRs:** A list of strings in [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) notation that specify the non-masquerade ranges.
-* **masqLinkLocal:** A Boolean (true / false) which indicates whether to masquerade traffic to the link local prefix 169.254.0.0/16. False by default.
-* **resyncInterval:** An interval at which the agent attempts to reload config from disk. e.g. '30s' where 's' is seconds, 'ms' is milliseconds etc...
-
-Traffic to 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) ranges will NOT be masqueraded. Any other traffic (assumed to be internet) will be masqueraded. An example of a local destination from a pod could be its Node's IP address as well as another node's address or one of the IP addresses in Cluster's IP range. Any other traffic will be masqueraded by default. The below entries show the default set of rules that are applied by the ip-masq-agent:
-
-```
-iptables -t nat -L IP-MASQ-AGENT
-RETURN all -- anywhere 169.254.0.0/16 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
-RETURN all -- anywhere 10.0.0.0/8 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
-RETURN all -- anywhere 172.16.0.0/12 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
-RETURN all -- anywhere 192.168.0.0/16 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
-MASQUERADE all -- anywhere anywhere /* ip-masq-agent: outbound traffic should be subject to MASQUERADE (this match must come after cluster-local CIDR matches) */ ADDRTYPE match dst-type !LOCAL
-
-```
-
-By default, in GCE/GKE starting with Kubernetes version 1.7.0, if network policy is enabled or you are using a cluster CIDR not in the 10.0.0.0/8 range, the ip-masq-agent will run in your cluster. If you are running in another environment, you can add the ip-masq-agent [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) to your cluster:
-
-{% endcapture %}
-
-{% capture steps %}
-
-## Create an ip-masq-agent
-To create an ip-masq-agent, run the following kubectl command:
-
-`
-kubectl create -f https://raw.githubusercontent.com/kubernetes-incubator/ip-masq-agent/master/ip-masq-agent.yaml
-`
-
-You must also apply the appropriate node label to any nodes in your cluster that you want the agent to run on.
-
-`
-kubectl label nodes my-node beta.kubernetes.io/masq-agent-ds-ready=true
-`
-
-More information can be found in the ip-masq-agent documentation [here](https://github.com/kubernetes-incubator/ip-masq-agent)
-
-In most cases, the default set of rules should be sufficient; however, if this is not the case for your cluster, you can create and apply a [ConfigMap](/docs/tasks/configure-pod-container/configmap/) to customize the IP ranges that are affected. For example, to allow only 10.0.0.0/8 to be considered by the ip-masq-agent, you can create the following [ConfigMap](/docs/tasks/configure-pod-container/configmap/) in a file called "config".
-**Note:** It is important that the file is called config since, by default, that will be used as the key for lookup by the ip-masq-agent:
-
-```
-nonMasqueradeCIDRs:
- - 10.0.0.0/8
-resyncInterval: 60s
-
-```
-
-Run the following command to add the config map to your cluster:
-
-```
-kubectl create configmap ip-masq-agent --from-file=config --namespace=kube-system
-```
-
-This will update a file located at */etc/config/ip-masq-agent* which is periodically checked every *resyscInterval* and applied to the cluster node.
-After the resync interval has expired, you should see the iptables rules reflect your changes:
-
-```
-iptables -t nat -L IP-MASQ-AGENT
-Chain IP-MASQ-AGENT (1 references)
-target prot opt source destination
-RETURN all -- anywhere 169.254.0.0/16 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL
-RETURN all -- anywhere 10.0.0.0/8 /* ip-masq-agent: cluster-local
-MASQUERADE all -- anywhere anywhere /* ip-masq-agent: outbound traffic should be subject to MASQUERADE (this match must come after cluster-local CIDR matches) */ ADDRTYPE match dst-type !LOCAL
-```
-
-By default, the link local range (169.254.0.0/16) is also handled by the ip-masq agent, which sets up the appropriate iptables rules. To have the ip-masq-agent ignore link local, you can set *masqLinkLocal* to true in the config map.
-
-```
-nonMasqueradeCIDRs:
- - 10.0.0.0/8
-resyncInterval: 60s
-masqLinkLocal: true
-```
-{% endcapture %}
-
-{% include templates/task.md %}
diff --git a/cn/docs/tasks/administer-cluster/static-pod.md b/cn/docs/tasks/administer-cluster/static-pod.md
index 7c32e2d26d..0539e1e8ed 100644
--- a/cn/docs/tasks/administer-cluster/static-pod.md
+++ b/cn/docs/tasks/administer-cluster/static-pod.md
@@ -6,7 +6,7 @@ title: 静态Pods
**如果你正在运行Kubernetes集群并且使用静态pods在每个节点上起一个pod,那么最好使用[DaemonSet](/cn/docs/concepts/workloads/controllers/daemonset/)!**
-*静态pods*直接由特定节点上的kubelet进程来管理,不通过主控节点上的API服务器。静态pod不关联任何replicationcontroller,它由kubelet进程自己来监控,当pod崩溃时重启该pod。对于静态pod没有健康检查。静态pod始终绑定在某一个kubelet,并且始终运行在同一个节点上。
+*静态pods*直接由特定节点上的kubelet进程来管理,不通过主控节点上的API服务器。静态pod不关联任何replication controller,它由kubelet进程自己来监控,当pod崩溃时重启该pod。对于静态pod没有健康检查。静态pod始终绑定在某一个kubelet,并且始终运行在同一个节点上。
Kubelet自动为每一个静态pod在Kubernetes的API服务器上创建一个镜像Pod(Mirror Pod),因此可以在API服务器查询到该pod,但是不被API服务器控制(例如不能删除)。
diff --git a/cn/docs/tasks/configure-pod-container/configmap.md b/cn/docs/tasks/configure-pod-container/configmap.md
deleted file mode 100644
index 352ea85c11..0000000000
--- a/cn/docs/tasks/configure-pod-container/configmap.md
+++ /dev/null
@@ -1,256 +0,0 @@
----
-approvers:
-- eparis
-- pmorie
-title: Configure Containers Using a ConfigMap
----
-
-
-{% capture overview %}
-
-This page shows you how to configure an application using a ConfigMap. ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable.
-
-{% endcapture %}
-
-{% capture prerequisites %}
-
-* {% include task-tutorial-prereqs.md %}
-
-{% endcapture %}
-
-
-{% capture steps %}
-
-## Use kubectl to create a ConfigMap
-
-Use the `kubectl create configmap` command to create configmaps from [directories](#creating-configmaps-from-directories), [files](#creating-configmaps-from-files), or [literal values](#creating-configmaps-from-literal-values):
-
-```shell
-kubectl create configmap
-```
-
-where \ is the name you want to assign to the ConfigMap and \ is the directory, file, or literal value to draw the data from.
-
-The data source corresponds to a key-value pair in the ConfigMap, where
-
-* key = the file name or the key you provided on the command line, and
-* value = the file contents or the literal value you provided on the command line.
-
-You can use [`kubectl describe`](/docs/user-guide/kubectl/v1.6/#describe) or [`kubectl get`](/docs/user-guide/kubectl/v1.6/#get) to retrieve information about a ConfigMap. The former shows a summary of the ConfigMap, while the latter returns the full contents of the ConfigMap.
-
-### Create ConfigMaps from directories
-
-You can use `kubectl create configmap` to create a ConfigMap from multiple files in the same directory.
-
-For example:
-
-```shell
-kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl
-```
-
-combines the contents of the `docs/user-guide/configmap/kubectl/` directory
-
-```shell
-ls docs/user-guide/configmap/kubectl/
-game.properties
-ui.properties
-```
-
-into the following ConfigMap:
-
-```shell
-kubectl describe configmaps game-config
-Name: game-config
-Namespace: default
-Labels:
-Annotations:
-
-Data
-====
-game.properties: 158 bytes
-ui.properties: 83 bytes
-```
-
-The `game.properties` and `ui.properties` files in the `docs/user-guide/configmap/kubectl/` directory are represented in the `data` section of the ConfigMap.
-
-```shell
-kubectl get configmaps game-config -o yaml
-```
-
-```yaml
-apiVersion: v1
-data:
- game.properties: |
- enemies=aliens
- lives=3
- enemies.cheat=true
- enemies.cheat.level=noGoodRotten
- secret.code.passphrase=UUDDLRLRBABAS
- secret.code.allowed=true
- secret.code.lives=30
- ui.properties: |
- color.good=purple
- color.bad=yellow
- allow.textmode=true
- how.nice.to.look=fairlyNice
-kind: ConfigMap
-metadata:
- creationTimestamp: 2016-02-18T18:52:05Z
- name: game-config
- namespace: default
- resourceVersion: "516"
- selfLink: /api/v1/namespaces/default/configmaps/game-config-2
- uid: b4952dc3-d670-11e5-8cd0-68f728db1985
-```
-
-### Create ConfigMaps from files
-
-You can use `kubectl create configmap` to create a ConfigMap from an individual file, or from multiple files.
-
-For example,
-
-```shell
-kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties
-```
-
-would produce the following ConfigMap:
-
-```shell
-kubectl describe configmaps game-config-2
-Name: game-config-2
-Namespace: default
-Labels:
-Annotations:
-
-Data
-====
-game.properties: 158 bytes
-```
-
-You can pass in the `--from-file` argument multiple times to create a ConfigMap from multiple data sources.
-
-```shell
-kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties
-```
-
-```shell
-kubectl describe configmaps game-config-2
-Name: game-config-2
-Namespace: default
-Labels:
-Annotations:
-
-Data
-====
-game.properties: 158 bytes
-ui.properties: 83 bytes
-```
-
-#### Define the key to use when creating a ConfigMap from a file
-
-You can define a key other than the file name to use in the `data` section of your ConfigMap when using the `--from-file` argument:
-
-```shell
-kubectl create configmap game-config-3 --from-file==
-```
-
-where `` is the key you want to use in the ConfigMap and `` is the location of the data source file you want the key to represent.
-
-For example:
-
-```shell
-kubectl create configmap game-config-3 --from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties
-
-kubectl get configmaps game-config-3 -o yaml
-```
-
-```yaml
-apiVersion: v1
-data:
- game-special-key: |
- enemies=aliens
- lives=3
- enemies.cheat=true
- enemies.cheat.level=noGoodRotten
- secret.code.passphrase=UUDDLRLRBABAS
- secret.code.allowed=true
- secret.code.lives=30
-kind: ConfigMap
-metadata:
- creationTimestamp: 2016-02-18T18:54:22Z
- name: game-config-3
- namespace: default
- resourceVersion: "530"
- selfLink: /api/v1/namespaces/default/configmaps/game-config-3
- uid: 05f8da22-d671-11e5-8cd0-68f728db1985
-```
-
-### Create ConfigMaps from literal values
-
-You can use `kubectl create configmap` with the `--from-literal` argument to define a literal value from the command line:
-
-```shell
-kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
-```
-
-You can pass in multiple key-value pairs. Each pair provided on the command line is represented as a separate entry in the `data` section of the ConfigMap.
-
-```shell
-kubectl get configmaps special-config -o yaml
-```
-
-```yaml
-apiVersion: v1
-data:
- special.how: very
- special.type: charm
-kind: ConfigMap
-metadata:
- creationTimestamp: 2016-02-18T19:14:38Z
- name: special-config
- namespace: default
- resourceVersion: "651"
- selfLink: /api/v1/namespaces/default/configmaps/special-config
- uid: dadce046-d673-11e5-8cd0-68f728db1985
-```
-
-{% endcapture %}
-
-{% capture discussion %}
-
-## Understanding ConfigMaps
-
-ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable.
-The ConfigMap API resource stores configuration data as key-value pairs. The data can be consumed in pods or provide the configurations for system components such as controllers. ConfigMap is similar to [Secrets](/docs/concepts/configuration/secret/), but provides a means of working with strings that don't contain sensitive information. Users and system components alike can store configuration data in ConfigMap.
-
-**Note:** ConfigMaps should reference properties files, not replace them. Think of the ConfigMap as representing something similar to the Linux `/etc` directory and its contents. For example, if you create a [Kubernetes Volume](/docs/concepts/storage/volumes/) from a ConfigMap, each data item in the ConfigMap is represented by an individual file in the volume.
-{: .note}
-
-The ConfigMap's `data` field contains the configuration data. As shown in the example below, this can be simple -- like individual properties defined using `--from-literal` -- or complex -- like configuration files or JSON blobs defined using `--from-file`.
-
-```yaml
-kind: ConfigMap
-apiVersion: v1
-metadata:
- creationTimestamp: 2016-02-18T19:14:38Z
- name: example-config
- namespace: default
-data:
- # example of a simple property defined using --from-literal
- example.property.1: hello
- example.property.2: world
- # example of a complex property defined using --from-file
- example.property.file: |-
- property.1=value-1
- property.2=value-2
- property.3=value-3
-```
-
-{% endcapture %}
-
-{% capture whatsnext %}
-* See [Using ConfigMap Data in Pods](/docs/tasks/configure-pod-container/configure-pod-configmap).
-* Follow a real world example of [Configuring Redis using a ConfigMap](/docs/tutorials/configuration/configure-redis-using-configmap/).
-{% endcapture %}
-
-{% include templates/task.md %}
diff --git a/cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md b/cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md
deleted file mode 100644
index a842c449cd..0000000000
--- a/cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md
+++ /dev/null
@@ -1,301 +0,0 @@
----
-title: Configure Liveness and Readiness Probes
----
-
-{% capture overview %}
-
-This page shows how to configure liveness and readiness probes for Containers.
-
-The [kubelet](/docs/admin/kubelet/) uses liveness probes to know when to
-restart a Container. For example, liveness probes could catch a deadlock,
-where an application is running, but unable to make progress. Restarting a
-Container in such a state can help to make the application more available
-despite bugs.
-
-The kubelet uses readiness probes to know when a Container is ready to start
-accepting traffic. A Pod is considered ready when all of its Containers are ready.
-One use of this signal is to control which Pods are used as backends for Services.
-When a Pod is not ready, it is removed from Service load balancers.
-
-{% endcapture %}
-
-{% capture prerequisites %}
-
-{% include task-tutorial-prereqs.md %}
-
-{% endcapture %}
-
-{% capture steps %}
-
-## Define a liveness command
-
-Many applications running for long periods of time eventually transition to
-broken states, and cannot recover except by being restarted. Kubernetes provides
-liveness probes to detect and remedy such situations.
-
-In this exercise, you create a Pod that runs a Container based on the
-`gcr.io/google_containers/busybox` image. Here is the configuration file for the Pod:
-
-{% include code.html language="yaml" file="exec-liveness.yaml" ghlink="/docs/tasks/configure-pod-container/exec-liveness.yaml" %}
-
-In the configuration file, you can see that the Pod has a single Container.
-The `periodSeconds` field specifies that the kubelet should perform a liveness
-probe every 5 seconds. The `initialDelaySeconds` field tells the kubelet that it
-should wait 5 second before performing the first probe. To perform a probe, the
-kubelet executes the command `cat /tmp/healthy` in the Container. If the
-command succeeds, it returns 0, and the kubelet considers the Container to be alive and
-healthy. If the command returns a non-zero value, the kubelet kills the Container
-and restarts it.
-
-When the Container starts, it executes this command:
-
-```shell
-/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
-```
-
-For the first 30 seconds of the Container's life, there is a `/tmp/healthy` file.
-So during the first 30 seconds, the command `cat /tmp/healthy` returns a success
-code. After 30 seconds, `cat /tmp/healthy` returns a failure code.
-
-Create the Pod:
-
-```shell
-kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/exec-liveness.yaml
-```
-
-Within 30 seconds, view the Pod events:
-
-```
-kubectl describe pod liveness-exec
-```
-
-The output indicates that no liveness probes have failed yet:
-
-```shell
-FirstSeen LastSeen Count From SubobjectPath Type Reason Message
---------- -------- ----- ---- ------------- -------- ------ -------
-24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
-23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "gcr.io/google_containers/busybox"
-23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "gcr.io/google_containers/busybox"
-23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
-23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
-```
-
-After 35 seconds, view the Pod events again:
-
-```shell
-kubectl describe pod liveness-exec
-```
-
-At the bottom of the output, there are messages indicating that the liveness
-probes have failed, and the containers have been killed and recreated.
-
-```shell
-FirstSeen LastSeen Count From SubobjectPath Type Reason Message
---------- -------- ----- ---- ------------- -------- ------ -------
-37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
-36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "gcr.io/google_containers/busybox"
-36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "gcr.io/google_containers/busybox"
-36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
-36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
-2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
-```
-
-Wait another 30 seconds, and verify that the Container has been restarted:
-
-```shell
-kubectl get pod liveness-exec
-```
-
-The output shows that `RESTARTS` has been incremented:
-
-```shell
-NAME READY STATUS RESTARTS AGE
-liveness-exec 1/1 Running 1 1m
-```
-
-## Define a liveness HTTP request
-
-Another kind of liveness probe uses an HTTP GET request. Here is the configuration
-file for a Pod that runs a container based on the `gcr.io/google_containers/liveness`
-image.
-
-{% include code.html language="yaml" file="http-liveness.yaml" ghlink="/docs/tasks/configure-pod-container/http-liveness.yaml" %}
-
-In the configuration file, you can see that the Pod has a single Container.
-The `livenessProbe` field specifies that the kubelet should perform a liveness
-probe every 3 seconds. The `initialDelaySeconds` field tells the kubelet that it
-should wait 3 seconds before performing the first probe. To perform a probe, the
-kubelet sends an HTTP GET request to the server that is running in the Container
-and listening on port 8080. If the handler for the server's `/healthz` path
-returns a success code, the kubelet considers the Container to be alive and
-healthy. If the handler returns a failure code, the kubelet kills the Container
-and restarts it.
-
-Any code greater than or equal to 200 and less than 400 indicates success. Any
-other code indicates failure.
-
-You can see the source code for the server in
-[server.go](https://github.com/kubernetes/kubernetes/blob/master/test/images/liveness/server.go).
-
-For the first 10 seconds that the Container is alive, the `/healthz` handler
-returns a status of 200. After that, the handler returns a status of 500.
-
-```go
-http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
- duration := time.Now().Sub(started)
- if duration.Seconds() > 10 {
- w.WriteHeader(500)
- w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
- } else {
- w.WriteHeader(200)
- w.Write([]byte("ok"))
- }
-})
-```
-
-The kubelet starts performing health checks 3 seconds after the Container starts.
-So the first couple of health checks will succeed. But after 10 seconds, the health
-checks will fail, and the kubelet will kill and restart the Container.
-
-To try the HTTP liveness check, create a Pod:
-
-```shell
-kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/http-liveness.yaml
-```
-
-After 10 seconds, view Pod events to verify that liveness probes have failed and
-the Container has been restarted:
-
-```shell
-kubectl describe pod liveness-http
-```
-
-## Define a TCP liveness probe
-
-A third type of liveness probe uses a TCP Socket. With this configuration, the
-kubelet will attempt to open a socket to your container on the specified port.
-If it can establish a connection, the container is considered healthy, if it
-can’t it is considered a failure.
-
-{% include code.html language="yaml" file="tcp-liveness-readiness.yaml" ghlink="/docs/tasks/configure-pod-container/tcp-liveness-readiness.yaml" %}
-
-As you can see, configuration for a TCP check is quite similar to an HTTP check.
-This example uses both readiness and liveness probes. The kubelet will send the
-first readiness probe 5 seconds after the container starts. This will attempt to
-connect to the `goproxy` container on port 8080. If the probe succeeds, the pod
-will be marked as ready. The kubelet will continue to run this check every 10
-seconds.
-
-In addition to the readiness probe, this configuration includes a liveness probe.
-The kubelet will run the first liveness probe 15 seconds after the container
-starts. Just like the readiness probe, this will attempt to connect to the
-`goproxy` container on port 8080. If the liveness probe fails, the container
-will be restarted.
-
-## Use a named port
-
-You can use a named
-[ContainerPort](/docs/api-reference/{{page.version}}/#containerport-v1-core)
-for HTTP or TCP liveness checks:
-
-```yaml
-ports:
-- name: liveness-port
- containerPort: 8080
- hostPort: 8080
-
-livenessProbe:
- httpGet:
- path: /healthz
- port: liveness-port
-```
-
-## Define readiness probes
-
-Sometimes, applications are temporarily unable to serve traffic.
-For example, an application might need to load large data or configuration
-files during startup. In such cases, you don't want to kill the application,
-but you don’t want to send it requests either. Kubernetes provides
-readiness probes to detect and mitigate these situations. A pod with containers
-reporting that they are not ready does not receive traffic through Kubernetes
-Services.
-
-Readiness probes are configured similarly to liveness probes. The only difference
-is that you use the `readinessProbe` field instead of the `livenessProbe` field.
-
-```yaml
-readinessProbe:
- exec:
- command:
- - cat
- - /tmp/healthy
- initialDelaySeconds: 5
- periodSeconds: 5
-```
-
-Configuration for HTTP and TCP readiness probes also remains identical to
-liveness probes.
-
-Readiness and liveness probes can be used in parallel for the same container.
-Using both can ensure that traffic does not reach a container that is not ready
-for it, and that containers are restarted when they fail.
-
-## Configure Probes
-
-{% comment %}
-Eventually, some of this section could be moved to a concept topic.
-{% endcomment %}
-
-[Probes](/docs/api-reference/{{page.version}}/#probe-v1-core) have a number of fields that
-you can use to more precisely control the behavior of liveness and readiness
-checks:
-
-* `initialDelaySeconds`: Number of seconds after the container has started
-before liveness probes are initiated.
-* `periodSeconds`: How often (in seconds) to perform the probe. Default to 10
-seconds. Minimum value is 1.
-* `timeoutSeconds`: Number of seconds after which the probe times out. Defaults
-to 1 second. Minimum value is 1.
-* `successThreshold`: Minimum consecutive successes for the probe to be
-considered successful after having failed. Defaults to 1. Must be 1 for
-liveness. Minimum value is 1.
-* `failureThreshold`: Minimum consecutive failures for the probe to be
-considered failed after having succeeded. Defaults to 3. Minimum value is 1.
-
-[HTTP probes](/docs/api-reference/{{page.version}}/#httpgetaction-v1-core)
-have additional fields that can be set on `httpGet`:
-
-* `host`: Host name to connect to, defaults to the pod IP. You probably want to
-set "Host" in httpHeaders instead.
-* `scheme`: Scheme to use for connecting to the host. Defaults to HTTP.
-* `path`: Path to access on the HTTP server.
-* `httpHeaders`: Custom headers to set in the request. HTTP allows repeated headers.
-* `port`: Name or number of the port to access on the container. Number must be
-in the range 1 to 65535.
-
-For an HTTP probe, the kubelet sends an HTTP request to the specified path and
-port to perform the check. The kubelet sends the probe to the container’s IP address,
-unless the address is overridden by the optional `host` field in `httpGet`.
-In most scenarios, you do not want to set the `host` field. Here's one scenario
-where you would set it. Suppose the Container listens on 127.0.0.1 and the Pod's
-`hostNetwork` field is true. Then `host`, under `httpGet`, should be set to 127.0.0.1.
-If your pod relies on virtual hosts, which is probably the more common case,
-you should not use `host`, but rather set the `Host` header in `httpHeaders`.
-
-{% endcapture %}
-
-{% capture whatsnext %}
-
-* Learn more about
-[Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes).
-
-### Reference
-
-* [Pod](/docs/api-reference/{{page.version}}/#pod-v1-core)
-* [Container](/docs/api-reference/{{page.version}}/#container-v1-core)
-* [Probe](/docs/api-reference/{{page.version}}/#probe-v1-core)
-
-{% endcapture %}
-
-{% include templates/task.md %}
diff --git a/cn/docs/tasks/configure-pod-container/configure-service-account.md b/cn/docs/tasks/configure-pod-container/configure-service-account.md
deleted file mode 100644
index 55e115bd10..0000000000
--- a/cn/docs/tasks/configure-pod-container/configure-service-account.md
+++ /dev/null
@@ -1,231 +0,0 @@
----
-approvers:
-- bprashanth
-- liggitt
-- thockin
-title: Configure Service Accounts for Pods
----
-
-A service account provides an identity for processes that run in a Pod.
-
-*This is a user introduction to Service Accounts. See also the
-[Cluster Admin Guide to Service Accounts](/docs/admin/service-accounts-admin).*
-
-**Note:** This document describes how service accounts behave in a cluster set up
-as recommended by the Kubernetes project. Your cluster administrator may have
-customized the behavior in your cluster, in which case this documentation may
-not apply.
-{: .note}
-
-When you (a human) access the cluster (e.g. using `kubectl`), you are
-authenticated by the apiserver as a particular User Account (currently this is
-usually `admin`, unless your cluster administrator has customized your
-cluster). Processes in containers inside pods can also contact the apiserver.
-When they do, they are authenticated as a particular Service Account (e.g.
-`default`).
-
-## Use the Default Service Account to access the API server.
-
-When you create a pod, if you do not specify a service account, it is
-automatically assigned the `default` service account in the same namespace.
-If you get the raw json or yaml for a pod you have created (e.g. `kubectl get pods/podname -o yaml`),
-you can see the `spec.serviceAccountName` field has been
-[automatically set](/docs/user-guide/working-with-resources/#resources-are-automatically-modified).
-
-You can access the API from inside a pod using automatically mounted service account credentials,
-as described in [Accessing the Cluster](/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod).
-The API permissions a service account has depend on the [authorization plugin and policy](/docs/admin/authorization/#a-quick-note-on-service-accounts) in use.
-
-In version 1.6+, you can opt out of automounting API credentials for a service account by setting
-`automountServiceAccountToken: false` on the service account:
-
-```yaml
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: build-robot
-automountServiceAccountToken: false
-...
-```
-
-In version 1.6+, you can also opt out of automounting API credentials for a particular pod:
-
-```yaml
-apiVersion: v1
-kind: Pod
-metadata:
- name: my-pod
-spec:
- serviceAccountName: build-robot
- automountServiceAccountToken: false
- ...
-```
-
-The pod spec takes precedence over the service account if both specify a `automountServiceAccountToken` value.
-
-## Use Multiple Service Accounts.
-
-Every namespace has a default service account resource called `default`.
-You can list this and any other serviceAccount resources in the namespace with this command:
-
-```shell
-$ kubectl get serviceAccounts
-NAME SECRETS AGE
-default 1 1d
-```
-
-You can create additional ServiceAccount objects like this:
-
-```shell
-$ cat > /tmp/serviceaccount.yaml < /tmp/build-robot-secret.yaml <
-Annotations: kubernetes.io/service-account.name=build-robot,kubernetes.io/service-account.uid=870ef2a5-35cf-11e5-8d06-005056b45392
-
-Type: kubernetes.io/service-account-token
-
-Data
-====
-ca.crt: 1220 bytes
-token: ...
-namespace: 7 bytes
-```
-
-**Note:** The content of `token` is elided here.
-{: .note}
-
-## Add ImagePullSecrets to a service account
-
-First, create an imagePullSecret, as described [here](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod).
-Next, verify it has been created. For example:
-
-```shell
-$ kubectl get secrets myregistrykey
-NAME TYPE DATA AGE
-myregistrykey kubernetes.io/.dockerconfigjson 1 1d
-```
-
-Next, modify the default service account for the namespace to use this secret as an imagePullSecret.
-
-```shell
-kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
-```
-
-Interactive version requiring manual edit:
-
-```shell
-$ kubectl get serviceaccounts default -o yaml > ./sa.yaml
-$ cat sa.yaml
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- creationTimestamp: 2015-08-07T22:02:39Z
- name: default
- namespace: default
- resourceVersion: "243024"
- selfLink: /api/v1/namespaces/default/serviceaccounts/default
- uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
-secrets:
-- name: default-token-uudge
-$ vi sa.yaml
-[editor session not shown]
-[delete line with key "resourceVersion"]
-[add lines with "imagePullSecret:"]
-$ cat sa.yaml
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- creationTimestamp: 2015-08-07T22:02:39Z
- name: default
- namespace: default
- selfLink: /api/v1/namespaces/default/serviceaccounts/default
- uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
-secrets:
-- name: default-token-uudge
-imagePullSecrets:
-- name: myregistrykey
-$ kubectl replace serviceaccount default -f ./sa.yaml
-serviceaccounts/default
-```
-
-Now, any new pods created in the current namespace will have this added to their spec:
-
-```yaml
-spec:
- imagePullSecrets:
- - name: myregistrykey
-```
-
-
diff --git a/cn/docs/tasks/configure-pod-container/http-liveness.yaml b/cn/docs/tasks/configure-pod-container/http-liveness.yaml
index 8485e3444e..6381ab3d1a 100644
--- a/cn/docs/tasks/configure-pod-container/http-liveness.yaml
+++ b/cn/docs/tasks/configure-pod-container/http-liveness.yaml
@@ -6,20 +6,16 @@ metadata:
name: liveness-http
spec:
containers:
-
- name: liveness
-
args:
- /server
-
image: gcr.io/google_containers/liveness
-
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- - name: X-Custom-Header
- value: Awesome
+ - name: X-Custom-Header
+ value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
diff --git a/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml b/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml
index c62028d7ef..73045a9ac0 100644
--- a/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml
+++ b/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml
@@ -15,19 +15,3 @@ spec:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml b/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml
index 9928b6d608..703b7c4c14 100644
--- a/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml
+++ b/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml
@@ -4,8 +4,8 @@ metadata:
name: private-reg
spec:
containers:
- - name: private-reg-container
- image:
+ - name: private-reg-container
+ image:
imagePullSecrets:
- - name: regsecret
+ - name: regsecret
diff --git a/cn/docs/tasks/debug-application-cluster/debug-cluster.md b/cn/docs/tasks/debug-application-cluster/debug-cluster.md
new file mode 100644
index 0000000000..834c0e6506
--- /dev/null
+++ b/cn/docs/tasks/debug-application-cluster/debug-cluster.md
@@ -0,0 +1,114 @@
+---
+title: 集群故障排查
+---
+
+本篇文档是介绍集群故障排查的;我们假设对于你碰到的问题,你已经排除了是由应用程序造成的。
+对于应用的调试,请参阅[应用故障排查指南](/cn/docs/tasks/debug-application-cluster/debug-application)。
+你也可以访问[troubleshooting document](/docs/troubleshooting/)来获取更多的信息。
+
+## 显示出集群的节点列表
+
+调试的第一步是查看所有的节点是否都正确的注册。
+
+运行
+
+```shell
+kubectl get nodes
+```
+
+接下来,验证你的所有节点都能够显示出来,并且都处于`Ready`状态。
+
+## 查看logs
+
+现在,挖掘出集群更深层的信息就需要登录到相关的机器上。下面是相关log文件所在的位置。
+(注意,对于基于systemd的系统,你可能需要使用`journalctl`)
+
+
+### Master
+
+ * /var/log/kube-apiserver.log - API Server, 提供API服务
+ * /var/log/kube-scheduler.log - Scheduler, 负责调度决策
+ * /var/log/kube-controller-manager.log - 管理replication controllers的控制器
+
+### Worker Nodes
+
+ * /var/log/kubelet.log - Kubelet, 管控节点上运行的容器
+ * /var/log/kube-proxy.log - Kube Proxy, 负责服务的负载均衡
+
+## 集群故障模式的概述
+
+下面是一个不完整的列表,列举了一些可能出错的场景,以及通过调整集群配置来解决相关问题的方法。
+
+根本原因:
+
+ - VM(s)关机
+ - 集群之间,或者集群和用户之间网络分裂
+ - Kubernetes软件本身崩溃了
+ - 数据丢失或者持久化存储不可用(如:GCE PD 或 AWS EBS卷)
+ - 操作错误,如:Kubernetes或者应用程序配置错误
+
+具体情况:
+
+ - Apiserver所在的VM关机或者apiserver崩溃
+ - 结果
+ - 不能停止,更新,或者启动新的pods,services,replication controller
+ - 现有的pods和services在不依赖Kubernetes API的情况下应该能继续正常工作
+ - Apiserver 后端存储丢失
+ - 结果
+ - apiserver应该不能起来
+ - kubelets将不能访问它,但是能够继续运行之前的Pods和提供相同的服务代理
+ - 在apiserver重启之前,需要手动恢复或者重创apiserver的状态
+
+ - Kubernetes服务组件(节点控制器,副本控制器,调度器等等)所在的VM关机或者崩溃
+ - 当前,这些控制器是和apiserver共存的,它们不可用的现象是与apiserver类似的
+ - 将来,这些控制器也会复制为多份,并且可能为非共存的
+ - 它们没有自己的持久状态
+ - 单个节点(VM或者物理机)关机
+ - 结果
+ - 此节点上的所有Pods都停止运行
+ - 网络分裂(Network partition)
+ - 结果
+ - partition A认为partition B中所有的节点都down掉了;partition B认为apiserver是down掉了(假定master所在的VM位于partition A内)。
+ - Kubelet软件故障
+ - 结果
+ - 崩溃的kubelet就不能在其所在的节点上启动新的pods
+ - kubelet可能删掉pods或者不删
+ - 节点被标识为非健康态
+ - 副本控制器会在其它的节点上启动新的pods
+ - 集群操作错误
+ - 结果
+ - 丢失pods,服务等等
+ - 丢失apiserver后端存储
+ - 用户无法读取API
+ - 等等
+
+缓解措施:
+
+- 措施:对于IaaS上的VMs,使用IaaS的自动VM重启功能
+ - 缓解:Apiserver VM关机或apiserver崩溃
+ - 缓解:Kubernetes服务组件所在的VM关机或崩溃
+
+- 措施: 对于具有apiserver+etcd的VM,使用IaaS提供的可靠的存储(例如GCE PD或者AWS EBS卷)
+ - 缓解:Apiserver后端存储的丢失
+
+- 措施:使用(实验)[高可用性](/docs/admin/high-availability)的配置
+ - 缓解:master VM关机或者master组件(scheduler, API server, controller-managing)崩馈
+ - 将容许一个或多个节点或组件同时出现故障
+ - 缓解:apiserver后端存储(例如etcd的数据目录)丢失
+ - 假定你使用了集群化的etcd。
+
+- 措施:定期的对apiserver的PDs/EBS卷进行快照
+ - 缓解:apiserver后端存储丢失
+ - 缓解:一些操作错误的场景
+ - 缓解:一些Kubernetes软件本身故障的场景
+
+- 措施:在pods的前面使用副本控制器或服务
+ - 缓解:节点关机
+ - 缓解:Kubelet软件故障
+
+- 措施:应用(容器)设计成容许异常重启
+ - 缓解:节点关机
+ - 缓解:Kubelet软件故障
+
+- 措施:[多个独立的集群](/docs/admin/multi-cluster)(并且避免一次性地对所有的集群进行有风险性的修改)
+ - 缓解:以上列出的所有情况
diff --git a/cn/docs/tasks/inject-data-application/commands.yaml b/cn/docs/tasks/inject-data-application/commands.yaml
index 8d58007db4..2327d25827 100644
--- a/cn/docs/tasks/inject-data-application/commands.yaml
+++ b/cn/docs/tasks/inject-data-application/commands.yaml
@@ -10,3 +10,4 @@ spec:
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
+ restartPolicy: OnFailure
diff --git a/cn/docs/tasks/inject-data-application/distribute-credentials-secure.md b/cn/docs/tasks/inject-data-application/distribute-credentials-secure.md
new file mode 100644
index 0000000000..62ff4c1aaa
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/distribute-credentials-secure.md
@@ -0,0 +1,165 @@
+---
+title: 使用 Secret 安全地分发凭证
+---
+
+{% capture overview %}
+本文展示如何安全地将敏感数据(如密码和加密密钥)注入到 Pods 中。
+{% endcapture %}
+
+{% capture prerequisites %}
+
+{% include task-tutorial-prereqs.md %}
+
+{% endcapture %}
+
+{% capture steps %}
+
+## 将 secret 数据转换为 base-64 形式
+
+假设用户想要有两条 secret 数据:用户名 `my-app` 和密码
+`39528$vdg7Jb`。 首先使用 [Base64 编码](https://www.base64encode.org/) 将用户名和密码转化为 base-64 形式。 这里是一个 Linux 示例:
+
+ echo -n 'my-app' | base64
+ echo -n '39528$vdg7Jb' | base64
+
+结果显示 base-64 形式的用户名为 `bXktYXBw`,
+base-64 形式的密码为 `Mzk1MjgkdmRnN0pi`。
+
+## 创建 Secret
+
+这里是一个配置文件,可以用来创建存有用户名和密码的 Secret:
+
+{% include code.html language="yaml" file="secret.yaml" ghlink="/docs/tasks/inject-data-application/secret.yaml" %}
+
+1. 创建 Secret
+
+ kubectl create -f secret.yaml
+
+ **注意:** 如果想要跳过 Base64 编码的步骤,可以使用 `kubectl create secret` 命令来创建 Secret:
+ {: .note}
+
+ kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
+
+1. 查看 Secret 相关信息:
+
+ kubectl get secret test-secret
+
+ 输出:
+
+ NAME TYPE DATA AGE
+ test-secret Opaque 2 1m
+
+1. 查看 Secret 相关的更多详细信息:
+
+ kubectl describe secret test-secret
+
+ 输出:
+
+ Name: test-secret
+ Namespace: default
+ Labels:
+ Annotations:
+
+ Type: Opaque
+
+ Data
+ ====
+ password: 13 bytes
+ username: 7 bytes
+
+## 创建可以通过卷访问 secret 数据的 Pod
+
+这里是一个可以用来创建 pod 的配置文件:
+
+{% include code.html language="yaml" file="secret-pod.yaml" ghlink="/docs/tasks/inject-data-application/secret-pod.yaml" %}
+
+1. 创建 Pod:
+
+ kubectl create -f secret-pod.yaml
+
+1. 确认 Pod 正在运行:
+
+ kubectl get pod secret-test-pod
+
+ 输出:
+
+ NAME READY STATUS RESTARTS AGE
+ secret-test-pod 1/1 Running 0 42m
+
+
+1. 在 Pod 中运行的容器中获取一个 shell:
+
+ kubectl exec -it secret-test-pod -- /bin/bash
+
+1. secret 数据通过挂载在 `/etc/secret-volume` 目录下的卷暴露在容器中。
+在 shell 中,进入 secret 数据被暴露的目录:
+
+ root@secret-test-pod:/# cd /etc/secret-volume
+
+1. 在 shell 中,列出 `/etc/secret-volume` 目录的文件:
+
+ root@secret-test-pod:/etc/secret-volume# ls
+
+ 输出显示了两个文件,每个对应一条 secret 数据:
+
+ password username
+
+1. 在 shell 中,显示 `username` 和 `password` 文件的内容:
+
+ root@secret-test-pod:/etc/secret-volume# cat username; echo; cat password; echo
+
+ 输出为用户名和密码:
+
+ my-app
+ 39528$vdg7Jb
+
+## 创建通过环境变量访问 secret 数据的 Pod
+
+这里是一个可以用来创建 pod 的配置文件:
+
+{% include code.html language="yaml" file="secret-envars-pod.yaml" ghlink="/docs/tasks/inject-data-application/secret-envars-pod.yaml" %}
+
+1. 创建 Pod:
+
+ kubectl create -f secret-envars-pod.yaml
+
+1. 确认 Pod 正在运行:
+
+ kubectl get pod secret-envars-test-pod
+
+ 输出:
+
+ NAME READY STATUS RESTARTS AGE
+ secret-envars-test-pod 1/1 Running 0 4m
+
+1. 在 Pod 中运行的容器中获取一个 shell:
+
+ kubectl exec -it secret-envars-test-pod -- /bin/bash
+
+1. 在 shell 中,显示环境变量:
+
+ root@secret-envars-test-pod:/# printenv
+
+ 输出包括用户名和密码:
+
+ ...
+ SECRET_USERNAME=my-app
+ ...
+ SECRET_PASSWORD=39528$vdg7Jb
+
+{% endcapture %}
+
+{% capture whatsnext %}
+
+* 了解更多关于 [Secrets](/docs/concepts/configuration/secret/)。
+* 了解 [Volumes](/docs/concepts/storage/volumes/)。
+
+### 参考
+
+* [Secret](/docs/api-reference/{{page.version}}/#secret-v1-core)
+* [Volume](/docs/api-reference/{{page.version}}/#volume-v1-core)
+* [Pod](/docs/api-reference/{{page.version}}/#pod-v1-core)
+
+{% endcapture %}
+
+{% include templates/task.md %}
diff --git a/cn/docs/tasks/inject-data-application/podpreset-allow-db-merged.yaml b/cn/docs/tasks/inject-data-application/podpreset-allow-db-merged.yaml
new file mode 100644
index 0000000000..73d93312fa
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-allow-db-merged.yaml
@@ -0,0 +1,37 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: website
+ labels:
+ app: website
+ role: frontend
+ annotations:
+ podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
+spec:
+ containers:
+ - name: website
+ image: ecorp/website
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ - mountPath: /etc/app/config.json
+ readOnly: true
+ name: secret-volume
+ ports:
+ - containerPort: 80
+ env:
+ - name: DB_PORT
+ value: "6379"
+ - name: duplicate_key
+ value: FROM_ENV
+ - name: expansion
+ value: $(REPLACE_ME)
+ envFrom:
+ - configMapRef:
+ name: etcd-env-config
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
+ - name: secret-volume
+ secret:
+ secretName: config-details
diff --git a/cn/docs/tasks/inject-data-application/podpreset-allow-db.yaml b/cn/docs/tasks/inject-data-application/podpreset-allow-db.yaml
new file mode 100644
index 0000000000..96f6dbfe20
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-allow-db.yaml
@@ -0,0 +1,31 @@
+apiVersion: settings.k8s.io/v1alpha1
+kind: PodPreset
+metadata:
+ name: allow-database
+ namespace: myns
+spec:
+ selector:
+ matchLabels:
+ role: frontend
+ env:
+ - name: DB_PORT
+ value: 6379
+ - name: duplicate_key
+ value: FROM_ENV
+ - name: expansion
+ value: $(REPLACE_ME)
+ envFrom:
+ - configMapRef:
+ name: etcd-env-config
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ - mountPath: /etc/app/config.json
+ readOnly: true
+ name: secret-volume
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
+ - name: secret-volume
+ secret:
+ secretName: config-details
diff --git a/cn/docs/tasks/inject-data-application/podpreset-configmap.yaml b/cn/docs/tasks/inject-data-application/podpreset-configmap.yaml
new file mode 100644
index 0000000000..806a880bff
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-configmap.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: etcd-env-config
+data:
+ number_of_members: "1"
+ initial_cluster_state: new
+ initial_cluster_token: DUMMY_ETCD_INITIAL_CLUSTER_TOKEN
+ discovery_token: DUMMY_ETCD_DISCOVERY_TOKEN
+ discovery_url: http://etcd_discovery:2379
+ etcdctl_peers: http://etcd:2379
+ duplicate_key: FROM_CONFIG_MAP
+ REPLACE_ME: "a value"
+
diff --git a/cn/docs/tasks/inject-data-application/podpreset-conflict-pod.yaml b/cn/docs/tasks/inject-data-application/podpreset-conflict-pod.yaml
new file mode 100644
index 0000000000..9061b9f5e8
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-conflict-pod.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: website
+ labels:
+ app: website
+ role: frontend
+spec:
+ containers:
+ - name: website
+ image: ecorp/website
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ ports:
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
+ - containerPort: 80
diff --git a/cn/docs/tasks/inject-data-application/podpreset-conflict-preset.yaml b/cn/docs/tasks/inject-data-application/podpreset-conflict-preset.yaml
new file mode 100644
index 0000000000..ab70b14d28
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-conflict-preset.yaml
@@ -0,0 +1,19 @@
+apiVersion: settings.k8s.io/v1alpha1
+kind: PodPreset
+metadata:
+ name: allow-database
+ namespace: myns
+spec:
+ selector:
+ matchLabels:
+ role: frontend
+ env:
+ - name: DB_PORT
+ value: "6379"
+ volumeMounts:
+ - mountPath: /cache
+ name: other-volume
+ volumes:
+ - name: other-volume
+ emptyDir: {}
+
diff --git a/cn/docs/tasks/inject-data-application/podpreset-merged.yaml b/cn/docs/tasks/inject-data-application/podpreset-merged.yaml
new file mode 100644
index 0000000000..0a5dfce0b5
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-merged.yaml
@@ -0,0 +1,25 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: website
+ labels:
+ app: website
+ role: frontend
+ annotations:
+ podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
+spec:
+ containers:
+ - name: website
+ image: ecorp/website
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ ports:
+ - containerPort: 80
+ env:
+ - name: DB_PORT
+ value: "6379"
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
+
diff --git a/cn/docs/tasks/inject-data-application/podpreset-multi-merged.yaml b/cn/docs/tasks/inject-data-application/podpreset-multi-merged.yaml
new file mode 100644
index 0000000000..dd6a7197ef
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-multi-merged.yaml
@@ -0,0 +1,29 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: website
+ labels:
+ app: website
+ role: frontend
+ annotations:
+ podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
+ podpreset.admission.kubernetes.io/podpreset-proxy: "resource version"
+spec:
+ containers:
+ - name: website
+ image: ecorp/website
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ - mountPath: /etc/proxy/configs
+ name: proxy-volume
+ ports:
+ - containerPort: 80
+ env:
+ - name: DB_PORT
+ value: "6379"
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
+ - name: proxy-volume
+ emptyDir: {}
diff --git a/cn/docs/tasks/inject-data-application/podpreset-pod.yaml b/cn/docs/tasks/inject-data-application/podpreset-pod.yaml
new file mode 100644
index 0000000000..82c590a924
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-pod.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: website
+ labels:
+ app: website
+ role: frontend
+spec:
+ containers:
+ - name: website
+ image: ecorp/website
+ ports:
+ - containerPort: 80
+
diff --git a/cn/docs/tasks/inject-data-application/podpreset-preset.yaml b/cn/docs/tasks/inject-data-application/podpreset-preset.yaml
new file mode 100644
index 0000000000..c5d34437f2
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-preset.yaml
@@ -0,0 +1,18 @@
+apiVersion: settings.k8s.io/v1alpha1
+kind: PodPreset
+metadata:
+ name: allow-database
+ namespace: myns
+spec:
+ selector:
+ matchLabels:
+ role: frontend
+ env:
+ - name: DB_PORT
+ value: "6379"
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
diff --git a/cn/docs/tasks/inject-data-application/podpreset-proxy.yaml b/cn/docs/tasks/inject-data-application/podpreset-proxy.yaml
new file mode 100644
index 0000000000..20dab81f36
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-proxy.yaml
@@ -0,0 +1,15 @@
+apiVersion: settings.k8s.io/v1alpha1
+kind: PodPreset
+metadata:
+ name: proxy
+ namespace: myns
+spec:
+ selector:
+ matchLabels:
+ role: frontend
+ volumeMounts:
+ - mountPath: /etc/proxy/configs
+ name: proxy-volume
+ volumes:
+ - name: proxy-volume
+ emptyDir: {}
diff --git a/cn/docs/tasks/inject-data-application/podpreset-replicaset-merged.yaml b/cn/docs/tasks/inject-data-application/podpreset-replicaset-merged.yaml
new file mode 100644
index 0000000000..97f16fde1f
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-replicaset-merged.yaml
@@ -0,0 +1,30 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ labels:
+ app: guestbook
+ tier: frontend
+ annotations:
+ podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
+spec:
+ containers:
+ - name: php-redis
+ image: gcr.io/google_samples/gb-frontend:v3
+ resources:
+ requests:
+ cpu: 100m
+ memory: 100Mi
+ volumeMounts:
+ - mountPath: /cache
+ name: cache-volume
+ env:
+ - name: GET_HOSTS_FROM
+ value: dns
+ - name: DB_PORT
+ value: "6379"
+ ports:
+ - containerPort: 80
+ volumes:
+ - name: cache-volume
+ emptyDir: {}
+
diff --git a/cn/docs/tasks/inject-data-application/podpreset-replicaset.yaml b/cn/docs/tasks/inject-data-application/podpreset-replicaset.yaml
new file mode 100644
index 0000000000..e3ad37470c
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset-replicaset.yaml
@@ -0,0 +1,29 @@
+apiVersion: apps/v1beta2
+kind: ReplicaSet
+metadata:
+ name: frontend
+spec:
+ replicas: 3
+ selector:
+ matchLabels:
+ tier: frontend
+ matchExpressions:
+ - {key: tier, operator: In, values: [frontend]}
+ template:
+ metadata:
+ labels:
+ app: guestbook
+ tier: frontend
+ spec:
+ containers:
+ - name: php-redis
+ image: gcr.io/google_samples/gb-frontend:v3
+ resources:
+ requests:
+ cpu: 100m
+ memory: 100Mi
+ env:
+ - name: GET_HOSTS_FROM
+ value: dns
+ ports:
+ - containerPort: 80
diff --git a/cn/docs/tasks/inject-data-application/podpreset.md b/cn/docs/tasks/inject-data-application/podpreset.md
new file mode 100644
index 0000000000..af28ac14c0
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/podpreset.md
@@ -0,0 +1,124 @@
+---
+approvers:
+- jessfraz
+title: 使用 PodPreset 将信息注入 Pods
+---
+
+在 pod 创建时,用户可以使用 `podpreset` 对象将 secrets、卷挂载和环境变量等信息注入其中。
+本文展示了一些 `PodPreset` 资源使用的示例。
+用户可以从[理解 Pod Presets](/docs/concepts/workloads/pods/podpreset/) 中了解 PodPresets 的整体情况。
+
+* TOC
+{:toc}
+
+## 创建 Pod Preset
+
+### 简单的 Pod Spec 示例
+
+这里是一个简单的示例,展示了如何通过 Pod Preset 修改 Pod spec 。
+
+**用户提交的 pod spec:**
+
+{% include code.html language="yaml" file="podpreset-pod.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-pod.yaml" %}
+
+**Pod Preset 示例:**
+
+{% include code.html language="yaml" file="podpreset-preset.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-preset.yaml" %}
+
+**通过准入控制器后的 Pod spec:**
+
+{% include code.html language="yaml" file="podpreset-merged.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-merged.yaml" %}
+
+### 带有 `ConfigMap` 的 Pod Spec 示例
+
+这里的示例展示了如何通过 Pod Preset 修改 Pod spec,Pod Preset 中定义了 `ConfigMap` 作为环境变量取值来源。
+
+**用户提交的 pod spec:**
+
+{% include code.html language="yaml" file="podpreset-pod.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-pod.yaml" %}
+
+**用户提交的 `ConfigMap`:**
+
+{% include code.html language="yaml" file="podpreset-configmap.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-configmap.yaml" %}
+
+**Pod Preset 示例:**
+
+{% include code.html language="yaml" file="podpreset-allow-db.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-allow-db.yaml" %}
+
+**通过准入控制器后的 Pod spec:**
+
+{% include code.html language="yaml" file="podpreset-allow-db-merged.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-allow-db-merged.yaml" %}
+
+### 带有 Pod Spec 的 ReplicaSet 示例
+
+以下示例展示了(通过 ReplicaSet 创建 pod 后)只有 pod spec 会被 Pod Preset 所修改。
+
+**用户提交的 ReplicaSet:**
+
+{% include code.html language="yaml" file="podpreset-replicaset.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-replicaset.yaml" %}
+
+**Pod Preset 示例:**
+
+{% include code.html language="yaml" file="podpreset-preset.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-preset.yaml" %}
+
+**通过准入控制器后的 Pod spec:**
+
+注意 ReplicaSet spec 没有改变,用户必须检查单独的 pod 来验证 PodPreset 已被应用。
+
+{% include code.html language="yaml" file="podpreset-replicaset-merged.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-replicaset-merged.yaml" %}
+
+### 多 PodPreset 示例
+
+这里的示例展示了如何通过多个 Pod 注入策略修改 Pod spec。
+
+**用户提交的 pod spec:**
+
+{% include code.html language="yaml" file="podpreset-pod.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-pod.yaml" %}
+
+**Pod Preset 示例:**
+
+{% include code.html language="yaml" file="podpreset-preset.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-preset.yaml" %}
+
+**另一个 Pod Preset 示例:**
+
+{% include code.html language="yaml" file="podpreset-proxy.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-proxy.yaml" %}
+
+**通过准入控制器后的 Pod spec:**
+
+{% include code.html language="yaml" file="podpreset-multi-merged.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-multi-merged.yaml" %}
+
+### 冲突示例
+
+这里的示例展示了 Pod Preset 与原 Pod 存在冲突时,Pod spec 不会被修改。
+
+**用户提交的 pod spec:**
+
+{% include code.html language="yaml" file="podpreset-conflict-pod.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-conflict-pod.yaml" %}
+
+**Pod Preset 示例:**
+
+{% include code.html language="yaml" file="podpreset-conflict-preset.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-conflict-preset.yaml" %}
+
+**因存在冲突,通过准入控制器后的 Pod spec 不会改变:**
+
+{% include code.html language="yaml" file="podpreset-conflict-pod.yaml" ghlink="/cn/docs/tasks/inject-data-application/podpreset-conflict-pod.yaml" %}
+
+**如果运行 `kubectl describe...` 用户会看到以下事件:**
+
+```
+$ kubectl describe ...
+....
+Events:
+ FirstSeen LastSeen Count From SubobjectPath Reason Message
+ Tue, 07 Feb 2017 16:56:12 -0700 Tue, 07 Feb 2017 16:56:12 -0700 1 {podpreset.admission.kubernetes.io/podpreset-allow-database } conflict Conflict on pod preset. Duplicate mountPath /cache.
+```
+
+## 删除 Pod Preset
+
+一旦用户不再需要 pod preset,可以使用 `kubectl` 进行删除:
+
+```shell
+$ kubectl delete podpreset allow-database
+podpreset "allow-database" deleted
+```
+
diff --git a/cn/docs/tasks/inject-data-application/secret-envars-pod.yaml b/cn/docs/tasks/inject-data-application/secret-envars-pod.yaml
new file mode 100644
index 0000000000..1637c0eac3
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/secret-envars-pod.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: secret-envars-test-pod
+spec:
+ containers:
+ - name: envars-test-container
+ image: nginx
+ env:
+ - name: SECRET_USERNAME
+ valueFrom:
+ secretKeyRef:
+ name: test-secret
+ key: username
+ - name: SECRET_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: test-secret
+ key: password
diff --git a/cn/docs/tasks/inject-data-application/secret-pod.yaml b/cn/docs/tasks/inject-data-application/secret-pod.yaml
new file mode 100644
index 0000000000..78633c477c
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/secret-pod.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: secret-test-pod
+spec:
+ containers:
+ - name: test-container
+ image: nginx
+ volumeMounts:
+ # name must match the volume name below
+ - name: secret-volume
+ mountPath: /etc/secret-volume
+ # The secret data is exposed to Containers in the Pod through a Volume.
+ volumes:
+ - name: secret-volume
+ secret:
+ secretName: test-secret
diff --git a/cn/docs/tasks/inject-data-application/secret.yaml b/cn/docs/tasks/inject-data-application/secret.yaml
new file mode 100644
index 0000000000..64627d638f
--- /dev/null
+++ b/cn/docs/tasks/inject-data-application/secret.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: test-secret
+data:
+ username: bXktYXBwCg==
+ password: Mzk1MjgkdmRnN0piCg==
diff --git a/cn/docs/tasks/manage-daemon/rollback-daemon-set.md b/cn/docs/tasks/manage-daemon/rollback-daemon-set.md
new file mode 100644
index 0000000000..c9684be648
--- /dev/null
+++ b/cn/docs/tasks/manage-daemon/rollback-daemon-set.md
@@ -0,0 +1,138 @@
+---
+approvers:
+- janetkuo
+title: 对 DaemonSet 执行回滚
+---
+
+{% capture overview %}
+
+本文展示了如何对 DaemonSet 执行回滚。
+
+{% endcapture %}
+
+
+{% capture prerequisites %}
+
+* DaemonSet 滚动升级历史和 DaemonSet 回滚特性仅在 Kubernetes 1.7 及以后版本的 `kubectl` 中支持。
+* 确保您了解如何 [对 DaemonSet 执行滚动升级](/docs/tasks/manage-daemon/update-daemon-set/)。
+
+{% endcapture %}
+
+
+{% capture steps %}
+
+## 对 DaemonSet 执行回滚
+
+### 步骤 1: 找到想要 DaemonSet 回滚到的历史版本(revision)
+
+如果只想回滚到最后一个版本,可以跳过这一步。
+
+列出 DaemonSet 的所有版本:
+
+```shell
+kubectl rollout history daemonset
+```
+
+该命令返回 DaemonSet 版本列表:
+
+```shell
+daemonsets ""
+REVISION CHANGE-CAUSE
+1 ...
+2 ...
+...
+```
+
+* 在创建时,DaemonSet 的变化原因从 `kubernetes.io/change-cause` 注解(annotation)复制到其版本中。 用户可以在 `kubectl` 中指定 `--record=true` ,将执行的命令记录在变化原因注解中。
+
+执行以下命令,来查看指定版本的详细信息:
+
+```shell
+kubectl rollout history daemonset --revision=1
+```
+
+该命令返回相应版本的详细信息:
+
+```shell
+daemonsets "" with revision #1
+Pod Template:
+Labels: foo=bar
+Containers:
+app:
+ Image: ...
+ Port: ...
+ Environment: ...
+ Mounts: ...
+Volumes: ...
+```
+
+### 步骤 2: 回滚到指定版本
+
+```shell
+# 在 --to-revision 中指定您从步骤 1 中获取的版本序号
+kubectl rollout undo daemonset --to-revision=
+```
+
+如果成功,命令会返回:
+
+```shell
+daemonset "" rolled back
+```
+
+如果 `--to-revision` 参数未指定,将选中最近的版本。
+
+### 步骤 3: 观察 DaemonSet 回滚进度
+
+`kubectl rollout undo daemonset` 向服务器表明启动 DaemonSet 回滚。 真正的回滚是在服务器端异步完成的。
+
+执行以下命令,来观察 DaemonSet 回滚进度:
+
+```shell
+kubectl rollout status ds/
+```
+
+回滚完成时,输出形如:
+
+```shell
+daemonset "" successfully rolled out
+```
+
+{% endcapture %}
+
+
+{% capture discussion %}
+
+## 理解 DaemonSet 版本
+
+在前面的 `kubectl rollout history` 步骤中,您获得了一个版本列表,每个版本都存储在名为
+ `ControllerRevision` 的资源中。 `ControllerRevision` 仅在 Kubernetes 1.7 及以后的版本中可用。
+
+查找原始的版本资源,来查看每个版本中存储了什么内容:
+
+```shell
+kubectl get controllerrevision -l =
+```
+
+该命令返回 `ControllerRevisions` 列表:
+
+```shell
+NAME CONTROLLER REVISION AGE
+- DaemonSet/ 1 1h
+- DaemonSet/ 2 1h
+```
+
+每个 `ControllerRevision` 中存储了相应 DaemonSet 版本的注解和模板。
+
+`kubectl rollout undo` 采用特定 `ControllerRevision` ,并用
+`ControllerRevision` 中存储的模板代替 DaemonSet 的模板。
+`kubectl rollout undo` 相当于通过其他命令(如 `kubectl edit` 或 `kubectl apply`)将 DaemonSet 模板更新至先前的版本。
+
+注意 DaemonSet 版本只会向前滚动。 也就是说,回滚完成后,所回滚到的 `ControllerRevision` 版本号 (`.revision` 字段) 会增加。 例如,如果用户在系统中有版本 1 和版本 2,并从版本 2 回滚到版本 1 ,带有 `.revision: 1` 的`ControllerRevision` 将变为 `.revision: 3`。
+
+## 故障排除
+
+* 查看 [DaemonSet 滚动升级故障排除](/docs/tasks/manage-daemon/update-daemon-set/#troubleshooting)。
+
+{% endcapture %}
+
+{% include templates/task.md %}
diff --git a/cn/docs/tasks/manage-hugepages/scheduling-hugepages.md b/cn/docs/tasks/manage-hugepages/scheduling-hugepages.md
new file mode 100644
index 0000000000..1055b1fdd0
--- /dev/null
+++ b/cn/docs/tasks/manage-hugepages/scheduling-hugepages.md
@@ -0,0 +1,69 @@
+---
+approvers:
+- derekwaynecarr
+title: 管理巨页(HugePages)
+---
+
+{% capture overview %}
+{% include feature-state-alpha.md %}
+
+作为 **alpha** 特性,Kubernetes 支持在 Pod 应用中使用预先分配的巨页(或称“大页面”,下文统称为“巨页”)。 本文描述了用户如何使用巨页,以及当前的限制。
+
+{% endcapture %}
+
+{% capture prerequisites %}
+
+1. 为了使节点能够上报巨页容量,Kubernetes 节点必须预先分配巨页。
+ 每个节点只能预先分配一种特定规格的巨页。
+1. 用户必须在整个系统中将专用的 **alpha** 特性开关 `HugePages` 设置为 true: `--feature-gates=HugePages=true`。
+
+节点会自动发现全部巨页资源,并作为可供调度的资源进行上报。
+
+{% endcapture %}
+
+{% capture steps %}
+
+## API
+
+用户可以通过在容器级别的资源需求中使用资源名称 `hugepages-` 来使用巨页,其中的 size 是特定节点上支持的以整数值表示的最小二进制单位。 例如,如果节点支持 2048KiB 的页面规格, 它将暴露可供调度的资源 `hugepages-2Mi`。 与 CPU 或内存不同,巨页不支持过量使用(overcommit)。
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ generateName: hugepages-volume-
+spec:
+ containers:
+ - image: fedora:latest
+ command:
+ - sleep
+ - inf
+ name: example
+ volumeMounts:
+ - mountPath: /hugepages
+ name: hugepage
+ resources:
+ limits:
+ hugepages-2Mi: 100Mi
+ volumes:
+ - name: hugepage
+ emptyDir:
+ medium: HugePages
+```
+
+- 巨页的资源需求和限制必须相等。 该条件在指定了资源限制,而没有指定需求的情况下默认成立。
+- 巨页是被隔离在 pod 作用域的,计划在将来的迭代中实现容器级别的隔离。
+- 巨页对 EmptyDir 卷提供支持,EmptyDir 卷所使用的巨页,不能够超出 pod 请求的内存容量。
+- 通过带有 `SHM_HUGETLB` 的 `shmget()` 使用巨页的应用,必须运行在一个与
+ `proc/sys/vm/hugetlb_shm_group` 匹配的补充组下。
+
+## (待实现的)特性
+
+- 在 pod 级别隔离的基础上,支持巨页在容器级别的隔离。
+- 作为服务质量特性,保证巨页的 NUMA 局部性。
+- 支持 ResourceQuota 。
+- 支持 LimitRange 。
+
+{% endcapture %}
+
+{% include templates/task.md %}
diff --git a/cn/docs/tasks/run-application/horizontal-pod-autoscale.md b/cn/docs/tasks/run-application/horizontal-pod-autoscale.md
deleted file mode 100644
index 941d54205f..0000000000
--- a/cn/docs/tasks/run-application/horizontal-pod-autoscale.md
+++ /dev/null
@@ -1,154 +0,0 @@
----
-approvers:
-- fgrzadkowski
-- jszczepkowski
-- directxman12
-title: Horizontal Pod Autoscaling
----
-
-This document describes the current state of Horizontal Pod Autoscaling in Kubernetes.
-
-## What is Horizontal Pod Autoscaling?
-
-With Horizontal Pod Autoscaling, Kubernetes automatically scales the number of pods
-in a replication controller, deployment or replica set based on observed CPU utilization
-(or, with alpha support, on some other, application-provided metrics). Note that Horizontal
-Pod Autoscaling does not apply to objects that can't be scaled, for example, DaemonSet.
-
-The Horizontal Pod Autoscaler is implemented as a Kubernetes API resource and a controller.
-The resource determines the behavior of the controller.
-The controller periodically adjusts the number of replicas in a replication controller or deployment
-to match the observed average CPU utilization to the target specified by user.
-
-## How does the Horizontal Pod Autoscaler work?
-
-
-
-The Horizontal Pod Autoscaler is implemented as a control loop, with a period controlled
-by the controller manager's `--horizontal-pod-autoscaler-sync-period` flag (with a default
-value of 30 seconds).
-
-During each period, the controller manager queries the resource utilization against the
-metrics specified in each HorizontalPodAutoscaler definition. The controller manager
-obtains the metrics from either the resource metrics API (for per-pod resource metrics),
-or the custom metrics API (for all other metrics).
-
-* For per-pod resource metrics (like CPU), the controller fetches the metrics
- from the resource metrics API for each pod targeted by the HorizontalPodAutoscaler.
- Then, if a target utilization value is set, the controller calculates the utilization
- value as a percentage of the equivalent resource request on the containers in
- each pod. If a target raw value is set, the raw metric values are used directly.
- The controller then takes the mean of the utilization or the raw value (depending on the type
- of target specified) across all targeted pods, and produces a ratio used to scale
- the number of desired replicas.
-
- Please note that if some of the pod's containers do not have the relevant resource request set,
- CPU utilization for the pod will not be defined and the autoscaler will not take any action
- for that metric. See the [autoscaling algorithm design document](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#autoscaling-algorithm) for further
- details about how the autoscaling algorithm works.
-
-* For per-pod custom metrics, the controller functions similarly to per-pod resource metrics,
- except that it works with raw values, not utilization values.
-
-* For object metrics, a single metric is fetched (which describes the object
- in question), and compared to the target value, to produce a ratio as above.
-
-The HorizontalPodAutoscaler controller can fetch metrics in two different ways: direct Heapster
-access, and REST client access.
-
-When using direct Heapster access, the HorizontalPodAutoscaler queries Heapster directly
-through the API server's service proxy subresource. Heapster needs to be deployed on the
-cluster and running in the kube-system namespace.
-
-See [Support for custom metrics](#support-for-custom-metrics) for more details on REST client access.
-
-The autoscaler accesses corresponding replication controller, deployment or replica set by scale sub-resource.
-Scale is an interface that allows you to dynamically set the number of replicas and examine each of their current states.
-More details on scale sub-resource can be found [here](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#scale-subresource).
-
-
-## API Object
-
-The Horizontal Pod Autoscaler is an API resource in the Kubernetes `autoscaling` API group.
-The current stable version, which only includes support for CPU autoscaling,
-can be found in the `autoscaling/v1` API version.
-
-The alpha version, which includes support for scaling on memory and custom metrics,
-can be found in `autoscaling/v2alpha1`. The new fields introduced in `autoscaling/v2alpha1`
-are preserved as annotations when working with `autoscaling/v1`.
-
-More details about the API object can be found at
-[HorizontalPodAutoscaler Object](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#horizontalpodautoscaler-object).
-
-## Support for Horizontal Pod Autoscaler in kubectl
-
-Horizontal Pod Autoscaler, like every API resource, is supported in a standard way by `kubectl`.
-We can create a new autoscaler using `kubectl create` command.
-We can list autoscalers by `kubectl get hpa` and get detailed description by `kubectl describe hpa`.
-Finally, we can delete an autoscaler using `kubectl delete hpa`.
-
-In addition, there is a special `kubectl autoscale` command for easy creation of a Horizontal Pod Autoscaler.
-For instance, executing `kubectl autoscale rc foo --min=2 --max=5 --cpu-percent=80`
-will create an autoscaler for replication controller *foo*, with target CPU utilization set to `80%`
-and the number of replicas between 2 and 5.
-The detailed documentation of `kubectl autoscale` can be found [here](/docs/user-guide/kubectl/v1.6/#autoscale).
-
-
-## Autoscaling during rolling update
-
-Currently in Kubernetes, it is possible to perform a [rolling update](/docs/tasks/run-application/rolling-update-replication-controller/) by managing replication controllers directly,
-or by using the deployment object, which manages the underlying replication controllers for you.
-Horizontal Pod Autoscaler only supports the latter approach: the Horizontal Pod Autoscaler is bound to the deployment object,
-it sets the size for the deployment object, and the deployment is responsible for setting sizes of underlying replication controllers.
-
-Horizontal Pod Autoscaler does not work with rolling update using direct manipulation of replication controllers,
-i.e. you cannot bind a Horizontal Pod Autoscaler to a replication controller and do rolling update (e.g. using `kubectl rolling-update`).
-The reason this doesn't work is that when rolling update creates a new replication controller,
-the Horizontal Pod Autoscaler will not be bound to the new replication controller.
-
-## Support for multiple metrics
-
-Kubernetes 1.6 adds support for scaling based on multiple metrics. You can use the `autoscaling/v2alpha1` API
-version to specify multiple metrics for the Horizontal Pod Autoscaler to scale on. Then, the Horizontal Pod
-Autoscaler controller will evaluate each metric, and propose a new scale based on that metric. The largest of the
-proposed scales will be used as the new scale.
-
-## Support for custom metrics
-
-**Note**: Kubernetes 1.2 added alpha support for scaling based on application-specific metrics using special annotations.
-Support for these annotations was removed in Kubernetes 1.6 in favor of the `autoscaling/v2alpha1` API. While the old method for collecting
-custom metrics is still available, these metrics will not be available for use by the Horizontal Pod Autoscaler, and the former
-annotations for specifying which custom metrics to scale on are no longer honored by the Horizontal Pod Autoscaler controller.
-
-Kubernetes 1.6 adds support for making use of custom metrics in the Horizontal Pod Autoscaler.
-You can add custom metrics for the Horizontal Pod Autoscaler to use in the `autoscaling/v2alpha1` API.
-Kubernetes then queries the new custom metrics API to fetch the values of the appropriate custom metrics.
-
-### Requirements
-
-To use custom metrics with your Horizontal Pod Autoscaler, you must set the necessary configurations when deploying your cluster:
-
-* [Enable the API aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/) if you have not already done so.
-
-* Register your resource metrics API and your
-custom metrics API with the API aggregation layer. Both of these API servers must be running *on* your cluster.
-
- * *Resource Metrics API*: You can use Heapster's implementation of the resource metrics API, by running Heapster with its `--api-server` flag set to true.
-
- * *Custom Metrics API*: This must be provided by a separate component. To get started with boilerplate code, see the [kubernetes-incubator/custom-metrics-apiserver](https://github.com/kubernetes-incubator/custom-metrics-apiserver) and the [k8s.io/metrics](https://github.com/kubernetes/metrics) repositories.
-
-* Set the appropriate flags for kube-controller-manager:
-
- * `--horizontal-pod-autoscaler-use-rest-clients` should be true.
-
- * `--kubeconfig ` OR `--master `
-
- Note that either the `--master` or `--kubeconfig` flag can be used; `--master` will override `--kubeconfig` if both are specified. These flags specify the location of the API aggregation layer, allowing the controller manager to communicate to the API server.
-
- In Kubernetes 1.7, the standard aggregation layer that Kubernetes provides runs in-process with the kube-apiserver, so the target IP address can be found with `kubectl get pods --selector k8s-app=kube-apiserver --namespace kube-system -o jsonpath='{.items[0].status.podIP}'`.
-
-## Further reading
-
-* Design documentation: [Horizontal Pod Autoscaling](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md).
-* kubectl autoscale command: [kubectl autoscale](/docs/user-guide/kubectl/v1.6/#autoscale).
-* Usage example of [Horizontal Pod Autoscaler](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/).
diff --git a/cn/docs/tasks/run-application/run-stateless-application-deployment.md b/cn/docs/tasks/run-application/run-stateless-application-deployment.md
index ef228f9d66..610f91334a 100644
--- a/cn/docs/tasks/run-application/run-stateless-application-deployment.md
+++ b/cn/docs/tasks/run-application/run-stateless-application-deployment.md
@@ -42,7 +42,7 @@ title: 使用Deployment运行一个无状态应用
kubectl describe deployment nginx-deployment
- user@computer:~/kubernetes.github.io$ kubectl describe deployment nginx-deployment
+ user@computer:~/website$ kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
diff --git a/cn/docs/tasks/tls/certificate-rotation.md b/cn/docs/tasks/tls/certificate-rotation.md
new file mode 100644
index 0000000000..726eb5bd73
--- /dev/null
+++ b/cn/docs/tasks/tls/certificate-rotation.md
@@ -0,0 +1,64 @@
+---
+approvers:
+- jcbsmpsn
+- mikedanese
+title: 证书轮换
+---
+
+{% capture overview %}
+本文展示如何在 kubelet 中启用并配置证书轮换。
+{% endcapture %}
+
+{% capture prerequisites %}
+
+* 要求 Kubernetes 1.8.0 或更高的版本
+
+* Kubelet 证书轮换在 1.8.0 版本中处于 beta 阶段, 这意味着该特性可能在没有通知的情况下发生变化。
+
+{% endcapture %}
+
+{% capture steps %}
+
+## 概述
+
+Kubelet 使用证书进行 Kubernetes API 的认证。
+默认情况下,这些证书的签发期限为一年,所以不需要太频繁地进行更新。
+
+Kubernetes 1.8 版本中包含 beta 特性 [kubelet 证书轮换](/docs/tasks/administer-cluster/certificate-rotation/),
+在当前证书即将过期时,
+将自动生成新的秘钥,并从 Kubernetes API 申请新的证书。 一旦新的证书可用,它将被用于与
+Kubernetes API 间的连接认证。
+
+## 启用客户端证书轮换
+
+ `kubelet` 进程接收 `--rotate-certificates` 参数,该参数决定 kubelet 在当前使用的证书即将到期时,
+是否会自动申请新的证书。 由于证书轮换是 beta 特性,必须通过参数 `--feature-gates=RotateKubeletClientCertificate=true` 进行启用。
+
+
+`kube-controller-manager` 进程接收
+`--experimental-cluster-signing-duration` 参数,该参数控制证书签发的有效期限。
+
+## 理解证书轮换配置
+
+当 kubelet 启动时,如被配置为自举(使用`--bootstrap-kubeconfig` 参数),kubelet 会使用其初始证书连接到
+Kubernetes API ,并发送证书签名的请求。 可以通过以下方式查看证书签名请求的状态:
+
+```sh
+kubectl get csr
+```
+
+最初,来自节点上 kubelet 的证书签名请求处于 `Pending` 状态。 如果证书签名请求满足特定条件,
+控制器管理器会自动批准,此时请求会处于 `Approved` 状态。 接下来,控制器管理器会签署证书,
+证书的有效期限由 `--experimental-cluster-signing-duration` 参数指定,签署的证书会被附加到证书签名请求中。
+
+Kubelet 会从 Kubernetes API 取回签署的证书,并将其写入磁盘,存储位置通过 `--cert-dir` 参数指定。
+然后 kubelet 会使用新的证书连接到 Kubernetes API。
+
+当签署的证书即将到期时,kubelet 会使用 Kubernetes API,发起新的证书签名请求。
+同样地,控制器管理器会自动批准证书请求,并将签署的证书附加到证书签名请求中。 Kubelet
+会从 Kubernetes API 取回签署的证书,并将其写入磁盘。 然后它会更新与 Kubernetes API
+的连接,使用新的证书重新连接到 Kubernetes API。
+
+{% endcapture %}
+
+{% include templates/task.md %}
diff --git a/cn/docs/tasks/tls/managing-tls-in-a-cluster.md b/cn/docs/tasks/tls/managing-tls-in-a-cluster.md
deleted file mode 100644
index 30299af8c4..0000000000
--- a/cn/docs/tasks/tls/managing-tls-in-a-cluster.md
+++ /dev/null
@@ -1,205 +0,0 @@
----
-title: Manage TLS Certificates in a Cluster
-approvers:
-- mikedanese
-- beacham
-- liggit
----
-
-* TOC
-{:toc}
-
-## Overview
-
-Every Kubernetes cluster has a cluster root Certificate Authority (CA). The CA
-is generally used by cluster components to validate the API server's
-certificate, by the API server to validate kubelet client certificates, etc. To
-support this, the CA certificate bundle is distributed to every node in the
-cluster and is distributed as a secret attached to default service accounts.
-Optionally, your workloads can use this CA to establish trust. Your application
-can request a certificate signing using the `certificates.k8s.io` API using a
-protocol that is similar to the
-[ACME draft](https://github.com/ietf-wg-acme/acme/).
-
-## Trusting TLS in a Cluster
-
-Trusting the cluster root CA from an application running as a pod usually
-requires some extra application configuration. You will need to add the CA
-certificate bundle to the list of CA certificates that the TLS client or server
-trusts. For example, you would do this with a golang TLS config by parsing the
-certificate chain and adding the parsed certificates to the `Certificates` field
-in the [`tls.Config`](https://godoc.org/crypto/tls#Config) struct.
-
-The CA certificate bundle is automatically mounted into pods using the default
-service account at the path `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
-If you are not using the default service account, ask a cluster administrator to
-build a configmap containing the certificate bundle that you have access to use.
-
-## Requesting a Certificate
-
-The following section demonstrates how to create a TLS certificate for a
-Kubernetes service accessed through DNS.
-
-### Step 0. Download and install CFSSL
-
-The cfssl tools used in this example can be downloaded at
-[https://pkg.cfssl.org/](https://pkg.cfssl.org/).
-
-### Step 1. Create a Certificate Signing Request
-
-Generate a private key and certificate signing request (or CSR) by running
-the following command:
-
-```console
-$ cat <
-Annotations:
-CreationTimestamp: Tue, 21 Mar 2017 07:03:51 -0700
-Requesting User: yourname@example.com
-Status: Pending
-Subject:
- Common Name: my-svc.my-namespace.svc.cluster.local
- Serial Number:
-Subject Alternative Names:
- DNS Names: my-svc.my-namespace.svc.cluster.local
- IP Addresses: 172.168.0.24
- 10.0.34.2
-Events:
-```
-
-### Step 3. Get the Certificate Signing Request Approved
-
-Approving the certificate signing request is either done by an automated
-approval process or on a one off basis by a cluster administrator. More
-information on what this involves is covered below.
-
-### Step 4. Download the Certificate and Use It
-
-Once the CSR is signed and approved you should see the following:
-
-```console
-$ kubectl get csr
-NAME AGE REQUESTOR CONDITION
-my-svc.my-namespace 10m yourname@example.com Approved,Issued
-```
-
-You can download the issued certificate and save it to a `server.crt` file
-by running the following:
-
-```console
-$ kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
- | base64 -d > server.crt
-```
-
-Now you can use `server.crt` and `server-key.pem` as the keypair to start
-your HTTPS server.
-
-## Approving Certificate Signing Requests
-
-A Kubernetes administrator (with appropriate permissions) can manually approve
-(or deny) Certificate Signing Requests by using the `kubectl certificate
-approve` and `kubectl certificate deny` commands. However if you intend
-to make heavy usage of this API, you might consider writing an automated
-certificates controller.
-
-Whether a machine or a human using kubectl as above, the role of the approver is
-to verify that the CSR satisfies two requirements:
-
-1. The subject of the CSR controls the private key used to sign the CSR. This
- addresses the threat of a third party masquerading as an authorized subject.
- In the above example, this step would be to verify that the pod controls the
- private key used to generate the CSR.
-2. The subject of the CSR is authorized to act in the requested context. This
- addresses the threat of an undesired subject joining the cluster. In the
- above example, this step would be to verify that the pod is allowed to
- participate in the requested service.
-
-If and only if these two requirements are met, the approver should approve
-the CSR and otherwise should deny the CSR.
-
-## A Word of **Warning** on the Approval Permission
-
-The ability to approve CSRs decides who trusts who within the cluster. This
-includes who the Kubernetes API trusts. The ability to approve CSRs should
-not be granted broadly or lightly. The requirements of the challenge
-noted in the previous section and the repercussions of issuing a specific
-certificate should be fully understood before granting this permission. See
-[here](/docs/admin/authentication#x509-client-certs) for information on how
-certificates interact with authentication.
-
-## A Note to Cluster Administrators
-
-This tutorial assumes that a signer is setup to serve the certificates API. The
-Kubernetes controller manager provides a default implementation of a signer. To
-enable it, pass the `--cluster-signing-cert-file` and
-`--cluster-signing-key-file` parameters to the controller manager with paths to
-your Certificate Authority's keypair.
diff --git a/cn/docs/tutorials/kubernetes-basics/expose-intro.html b/cn/docs/tutorials/kubernetes-basics/expose-intro.html
index 301df7376d..623c5f3efc 100644
--- a/cn/docs/tutorials/kubernetes-basics/expose-intro.html
+++ b/cn/docs/tutorials/kubernetes-basics/expose-intro.html
@@ -27,12 +27,19 @@ title: 使用服务发布您的应用程序