Compare commits

..

7 Commits

Author SHA1 Message Date
Jim Angel 4ea18c1e18 Update config.toml (#13411)
* Update config.toml

* Update config.toml
2019-03-25 18:47:16 -07:00
Jim Angel 30daa99d59 modified config.toml for 1.13 release (#11495)
1.13 + 4 latest releases supported by sig-docs.
2018-12-03 15:10:54 -08:00
Shuo Li cb7f8f176e zh_trans_docs_concepts_index_1.10 (#10745)
* zh_trans_docs_concepts_index_1.10

* update trans
2018-11-10 20:01:18 -08:00
Zach Corleissen dca12ad65d Update site config for l10n teams and 1.11 info (#10668)
Update OWNERS_ALIASES to be current

Fix OWNERS files syntax

Fix currentUrl

Fix currentUrl again
2018-10-23 15:56:48 -07:00
Takuya N 888d51e10c Relocate some yaml files to the proper directory (#10219) 2018-09-11 11:28:39 -07:00
Harshvardhan Karn 47f465358c fix version selector in v1.10 (#9502)
* fix version selector in v1.10

- add `version-1.11` in `v1.10` version selector

Signed-off-by: harshvkarn <harshvkarn54@gmail.com>

* remove v1.6 support from version selector

- `v1.6` is deprecated, so remove `v1.6` from version selector

Signed-off-by: harshvkarn <harshvkarn54@gmail.com>

* fix docsbranch for 1.11
2018-07-18 16:00:21 -07:00
Andrew Chen 62d3c40673 Fix currentUrl var in deprecation-warning.html (#9280)
* Update TOML to archive 1.10

* fix var syntax (+1 squashed commit)
Squashed commits:
[a5e0fd5] Fix currentUrl var in deprecation-warning.html
2018-06-27 15:40:21 -07:00
6863 changed files with 249321 additions and 646263 deletions
-1
View File
@@ -1 +0,0 @@
**
-20
View File
@@ -1,20 +0,0 @@
[*]
end_of_line = lf
insert_final_newline = false
charset = utf-8
max_line_length = 80
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{css,html,js,json,sass,md,mmark,toml,yaml}]
indent_style = space
indent_size = 2
[*.{sh}]
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
+22
View File
@@ -0,0 +1,22 @@
<!-- Thanks for filing an issue! Before submitting, please fill in the following information. -->
<!--Required Information-->
**This is a...**
<!-- choose one by changing [ ] to [x] -->
- [ ] Feature Request
- [ ] Bug Report
**Problem:**
**Proposed Solution:**
**Page to Update:**
https://kubernetes.io/...
<!--Optional Information (remove the comment tags around information you would like to include)-->
<!--Kubernetes Version:-->
<!--Additional Information:-->
-23
View File
@@ -1,23 +0,0 @@
---
name: Bug Report
about: Report a bug encountered with Kubernetes Website
labels:
- kind/bug
---
**This is a Bug Report**
<!-- Thanks for filing an issue! Before submitting, please fill in the following information. -->
<!-- See https://kubernetes.io/docs/contribute/start/ for guidance on writing an actionable issue description. -->
<!--Required Information-->
**Problem:**
**Proposed Solution:**
**Page to Update:**
https://kubernetes.io/...
<!--Optional Information (remove the comment tags around information you would like to include)-->
<!--Kubernetes Version:-->
<!--Additional Information:-->
-18
View File
@@ -1,18 +0,0 @@
---
name: Feature Request
about: Suggest a/an feature/enhancement to the Kubernetes Website project
labels:
- kind/feature
---
**This is a Feature Request**
<!-- Please only use this template for submitting feature/enhancement requests -->
<!-- See https://kubernetes.io/docs/contribute/start/ for guidance on writing an actionable issue description. -->
**What would you like to be added**
<!-- Describe as precisely as possible how this feature/enhancement should work from the user perspective. What should be changed, etc. -->
**Why is this needed**
**Comments**
<!-- Any additional related comments that might help. Drawings/mockups would be extremely helpful (if required). -->
-19
View File
@@ -1,19 +0,0 @@
---
name: Support Request
about: Support request or question relating to Kubernetes Website project
labels:
- kind/support
---
**This is Support**
<!--
STOP -- PLEASE READ!
GitHub is not the right place for support requests.
If you're looking for help, check [Stack Overflow](https://stackoverflow.com/questions/tagged/kubernetes)
You can also post your question on the [Kubernetes Slack](http://slack.k8s.io/) or the [Discuss Kubernetes](https://discuss.kubernetes.io/) forum.
If the matter is security related, please disclose it privately via https://kubernetes.io/security/.
-->
+7 -23
View File
@@ -1,24 +1,8 @@
<!-- 🛈
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> For 1.11 Features: set Milestone to 1.11 and Base Branch to release-1.11
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> NOTE: After opening the PR, please *un-check and re-check* the ["Allow edits from maintainers"](https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/) box so that maintainers can work on your patch and speed up the review process. This is a temporary workaround to address a known issue with GitHub.>
>
> Please delete this note before submitting the pull request.
Hello!
Remember to ADD A DESCRIPTION and delete this note before submitting
your pull request. The description should explain what will change,
and why.
PLEASE title the FIRST commit appropriately, so that if you squash all
your commits into one, the combined commit message makes sense.
For overall help on editing and submitting pull requests, visit:
https://kubernetes.io/docs/contribute/start/#improve-existing-content
Use the default base branch, “master”, if you're documenting existing
features in the English localization.
If you're working on a different localization (not English), see
https://kubernetes.io/docs/contribute/new-content/overview/#choose-which-git-branch-to-use
for advice.
If you're documenting a feature that will be part of a future release, see
https://kubernetes.io/docs/contribute/new-content/new-features/ for advice.
-->
![Allow edits from maintainers checkbox](https://help.github.com/assets/images/help/pull_requests/allow-maintainers-to-make-edits-sidebar-checkbox.png)
+1 -6
View File
@@ -1,6 +1,7 @@
**/.DS_Store
**/desktop.ini
_site/**
.sass-cache/**
CNAME
.travis.yml
.idea/
@@ -28,9 +29,3 @@ nohup.out
# Hugo output
public/
resources/
# Netlify Functions build output
package-lock.json
functions/
node_modules/
-3
View File
@@ -1,3 +0,0 @@
[submodule "themes/docsy"]
path = themes/docsy
url = https://github.com/google/docsy.git
-16
View File
@@ -1,16 +0,0 @@
DirectoryPath: public/docs
IgnoreDirectoryMissingTrailingSlash: true
CheckExternal: false
IgnoreAltMissing: true
CheckImages: false
CheckScripts: false
CheckMeta: false
CheckMetaRefresh: false
CheckLinks: false
EnforceHTML5: false
EnforceHTTPS: false
IgnoreDirectoryMissingTrailingSlash: false
IgnoreInternalEmptyHash: true
IgnoreEmptyHref: true
IgnoreDirs:
- "reference/generated/kubernetes-api"
+22
View File
@@ -0,0 +1,22 @@
language: go
go:
- 1.9.3
# Don't want default ./... here:
install:
- export PATH=$GOPATH/bin:$PATH
- mkdir -p $HOME/gopath/src/k8s.io
- mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/website && cd $HOME/gopath/src/k8s.io/website
# Fetch dependencies for us to run the tests in test/examples_test.go
- go get -t -v k8s.io/website/test
# Make sure we are testing against the correct branch
- pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.10 && popd
# Simplified deduplication of dependencies.
- cp -L -R $GOPATH/src/k8s.io/kubernetes/vendor/ $GOPATH/src/
- rm -r $GOPATH/src/k8s.io/kubernetes/vendor/
script:
# TODO(bep)
- go test -v k8s.io/website/test #fixed by https://github.com/kubernetes/website/pull/8388
#- ./verify-docs-format.sh
+2 -5
View File
@@ -9,8 +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 the
[Kubernetes Code of Conduct Committee](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct) <conduct@kubernetes.io>.
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
@@ -18,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](https://kubernetes.io/docs/contribute/style/page-content-types/).
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
@@ -35,5 +34,3 @@ Note that code issues should be filed against the main kubernetes repository, wh
### Submitting Documentation Pull Requests
If you're fixing an issue in the existing documentation, you should submit a PR against the master branch. Follow [these instructions to create a documentation pull request against the kubernetes.io repository](http://kubernetes.io/docs/home/contribute/create-pull-request/).
For more information, see [contributing to Kubernetes docs](https://kubernetes.io/docs/contribute/).
+5 -9
View File
@@ -6,29 +6,25 @@
FROM alpine:latest
LABEL maintainer="Luc Perkins <lperkins@linuxfoundation.org>"
MAINTAINER Luc Perkins <lperkins@linuxfoundation.org>
RUN apk add --no-cache \
curl \
git \
openssh-client \
rsync \
build-base \
libc6-compat \
npm && \
npm install -D autoprefixer postcss-cli
rsync
ARG HUGO_VERSION
RUN mkdir -p /usr/local/src && \
cd /usr/local/src && \
curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz | tar -xz && \
curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz && \
mv hugo /usr/local/bin/hugo && \
curl -L https://bin.equinox.io/c/dhgbqpS8Bvy/minify-stable-linux-amd64.tgz | tar -xz && \
mv minify /usr/local/bin && \
addgroup -Sg 1000 hugo && \
adduser -Sg hugo -u 1000 -h /src hugo
WORKDIR /src
USER hugo:hugo
EXPOSE 1313
+19 -73
View File
@@ -1,87 +1,33 @@
HUGO_VERSION = $(shell grep ^HUGO_VERSION netlify.toml | tail -n 1 | cut -d '=' -f 2 | tr -d " \"\n")
NODE_BIN = node_modules/.bin
NETLIFY_FUNC = $(NODE_BIN)/netlify-lambda
DOCKER = docker
HUGO_VERSION = 0.40.3
DOCKER_IMAGE = kubernetes-hugo
DOCKER_RUN = $(DOCKER) run --rm --interactive --tty --volume $(PWD):/src
# The CONTAINER_ENGINE variable is used for specifying the container engine. By default 'docker' is used
# but this can be overridden when calling make, e.g.
# CONTAINER_ENGINE=podman make container-image
CONTAINER_ENGINE ?= docker
IMAGE_VERSION=$(shell scripts/hash-files.sh Dockerfile Makefile | cut -c 1-12)
CONTAINER_IMAGE = kubernetes-hugo:v$(HUGO_VERSION)-$(IMAGE_VERSION)
CONTAINER_RUN = $(CONTAINER_ENGINE) run --rm --interactive --tty --volume $(CURDIR):/src
CCRED=\033[0;31m
CCEND=\033[0m
.PHONY: all build build-preview help serve
.PHONY: all build sass build-preview help serve
help: ## Show this help.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
module-check:
@git submodule status --recursive | awk '/^[+-]/ {printf "\033[31mWARNING\033[0m Submodule not initialized: \033[34m%s\033[0m\n",$$2}' 1>&2
all: build ## Build site with production settings and put deliverables in _site.
all: build ## Build site with production settings and put deliverables in ./public
sass: # Rebuild the SASS source into CSS
node-sass --output-style compact ./src/sass/styles.sass ./static/css/styles.css
node-sass --output-style compact ./src/sass/case_study_styles.sass ./static/css/case_study_styles.css
build: module-check ## Build site with production settings and put deliverables in ./public
hugo --minify
build: ## Build site with production settings and put deliverables in _site.
hugo
build-preview: module-check ## Build site with drafts and future posts enabled
hugo --buildDrafts --buildFuture
build-preview: ## Build site with drafts and future posts enabled.
hugo -D -F
deploy-preview: ## Deploy preview site via netlify
hugo --enableGitInfo --buildFuture -b $(DEPLOY_PRIME_URL)
functions-build:
$(NETLIFY_FUNC) build functions-src
check-headers-file:
scripts/check-headers-file.sh
production-build: build check-headers-file ## Build the production site and ensure that noindex headers aren't added
non-production-build: ## Build the non-production site, which adds noindex headers to prevent indexing
hugo --enableGitInfo
serve: module-check ## Boot the development server.
hugo server --buildFuture
serve: ## Boot the development server.
hugo server
docker-image:
@echo -e "$(CCRED)**** The use of docker-image is deprecated. Use container-image instead. ****$(CCEND)"
$(MAKE) container-image
$(DOCKER) build . --tag $(DOCKER_IMAGE) --build-arg HUGO_VERSION=$(HUGO_VERSION)
docker-build:
@echo -e "$(CCRED)**** The use of docker-build is deprecated. Use container-build instead. ****$(CCEND)"
$(MAKE) container-build
$(DOCKER_RUN) $(DOCKER_IMAGE) hugo
docker-serve:
@echo -e "$(CCRED)**** The use of docker-serve is deprecated. Use container-serve instead. ****$(CCEND)"
$(MAKE) container-serve
container-image:
$(CONTAINER_ENGINE) build . \
--network=host \
--tag $(CONTAINER_IMAGE) \
--build-arg HUGO_VERSION=$(HUGO_VERSION)
container-build: module-check
$(CONTAINER_RUN) --read-only --mount type=tmpfs,destination=/tmp,tmpfs-mode=01777 $(CONTAINER_IMAGE) sh -c "npm ci && hugo --minify"
container-serve: module-check
$(CONTAINER_RUN) --read-only --mount type=tmpfs,destination=/tmp,tmpfs-mode=01777 -p 1313:1313 $(CONTAINER_IMAGE) hugo server --buildFuture --bind 0.0.0.0 --destination /tmp/hugo --cleanDestinationDir
test-examples:
scripts/test_examples.sh install
scripts/test_examples.sh run
.PHONY: link-checker-setup
link-checker-image-pull:
$(CONTAINER_ENGINE) pull wjdp/htmltest
docker-internal-linkcheck:
@echo -e "$(CCRED)**** The use of docker-internal-linkcheck is deprecated. Use container-internal-linkcheck instead. ****$(CCEND)"
$(MAKE) container-internal-linkcheck
container-internal-linkcheck: link-checker-image-pull
$(CONTAINER_RUN) $(CONTAINER_IMAGE) hugo --config config.toml,linkcheck-config.toml --buildFuture
$(CONTAINER_ENGINE) run --mount type=bind,source=$(CURDIR),target=/test --rm wjdp/htmltest htmltest
stage:
$(DOCKER_RUN) -p 1313:1313 $(DOCKER_IMAGE) hugo server --watch --bind 0.0.0.0
+7 -14
View File
@@ -1,17 +1,10 @@
# See the OWNERS docs at https://go.k8s.io/owners
# Reviewers can /lgtm /approve but not sufficient for auto-merge without an
# approver
reviewers:
- sig-docs-en-reviews # Defined in OWNERS_ALIASES
- sig-docs-en-reviews
# Approvers have all the ability of reviewers but their /approve makes
# auto-merge happen if a /lgtm exists, or vice versa, or they can do both
# No need for approvers to also be listed as reviewers
approvers:
- sig-docs-en-owners # Defined in OWNERS_ALIASES
emeritus_approvers:
# - chenopis, commented out to disable PR assignments
# - jaredbhatti, commented out to disable PR assignments
# - steveperry-53, commented out to disable PR assignments
- stewart-yu
- zacharysarah
labels:
- sig/docs
- sig-docs-en-owners
+257 -198
View File
@@ -1,216 +1,275 @@
aliases:
sig-docs-blog-owners: # Approvers for blog content
- castrojo
- kbarnard10
- onlydole
- zacharysarah
- mrbobbytables
sig-docs-blog-reviewers: # Reviewers for blog content
- castrojo
- cody-clark
- kbarnard10
- mrbobbytables
- onlydole
- parispittman
- vonguard
sig-docs-de-owners: # Admins for German content
- bene2k1
- mkorbi
- rlenferink
sig-docs-de-reviews: # PR reviews for German content
- bene2k1
- mkorbi
- rlenferink
sig-docs-en-owners: # Admins for English content
- annajung
sig-api-machinery: #Team: API Server; GH: sig-api-machinery-pr-reviews; e.g. Annotations, Labels
- lavalamp
- sttts
- liggitt
- smarterclayton
- deads2k
sig-apps: #Team: Workloads; GH: sig-apps-pr-reviews; e.g. ConfigMaps, CronJobs, CustomResourceDefinitions, DaemonSets, Deployments, Jobs, Secrets, StatefulSets
- enisoc
- erictune
- foxish
- janetkuo
- kow3ns
- lukaszo
- mfojtik
- smarterclayton
- soltysh
- tnozicka
sig-architecture: #GH: sig-architecture-pr-reviews
- smarterclayton
- bgrant0607
sig-auth: #GH: sig-auth-pr-reviews
- php-coder
- liggitt
- mikedanese
- ericchiang
- mattmoyer
- enj
- deads2k
- davidopp
sig-autoscaling: #GH: sig-autoscaling-pr-reviews
- DirectXMan12
- bskiba
- aleksandra-malinowska
- MaciekPytel
- davidopp
- mwielgus
sig-aws: #Amazon AWS
- justinsb
- kris-nova
- chrislovecnm
- mfburnett
sig-azure: #Microsoft Azure
- andyzhangx
- feiskyer
- justaugustus
- karataliu
- khenidak
sig-big-data: #GH: sig-big-data-pr-reviews
- foxish
sig-cli: #Team: CLI; GH: sig-cli-pr-reviews; e.g. kubectl
- adohe
- deads2k
- derekwaynecarr
- dims
- dshulyak
- eparis
- ericchiang
- ghodss
- mengqiy
- rootfs
- shiywang
- smarterclayton
- soltysh
- sttts
sig-cluster-lifecycle-kubeadm-approvers: # Approving changes to kubeadm documentation
- timothysc
- lukemarsden
- luxas
- roberthbailey
- fabriziopandini
sig-cluster-lifecycle-kubeadm-reviewers: # Reviewing kubeadm documentation
- timothysc
- lukemarsden
- luxas
- roberthbailey
- fabriziopandini
- kad
- xiangpengzhao
- stealthybox
- liztio
- chuckha
- detiber
- dixudx
sig-cluster-ops:
- zehicle
- jdumars
sig-contribex: #aka Contributor Experience; GH: sig-contributor-experience-pr-reviews
- rmmh
- cblecker
- apelisse
- grodrigues3
- spxtr
sig-contributor-experience: #GH: sig-contributor-experience-pr-reviews
- rmmh
- cblecker
- apelisse
- grodrigues3
- spxtr
sig-docs: #Team: documentation; GH: sig-docs-maintainers
- bradamant3
- bradtopol
- celestehorgan
- irvifa
- jimangel
- chenopis
- jaredbhatti
- kbarnard10
- kbhawkey
- onlydole
- savitharaghunathan
- sftim
- mistyhacks
- ryanmcginnis
- steveperry-53
- tengqm
- tfogo
- xiangpengzhao
- zacharysarah
- zhangxiaoyu-zidif
- zparnold
sig-docs-en-owners: #Team: Documentation; GH: sig-docs-en-owners
- bradamant3
- bradtopol
- chenopis
- jaredbhatti
- kbarnard10
- mistyhacks
- ryanmcginnis
- steveperry-53
- stewart-yu
- tengqm
- tfogo
- zacharysarah
- zparnold
sig-docs-en-reviews: # PR reviews for English content
- bradtopol
- celestehorgan
- daminisatya
sig-docs-en-reviews: #Team: Documentation; GH: sig-docs-pr-reviews
- jimangel
- kbarnard10
- kbhawkey
- onlydole
- rajeshdeshpande02
- sftim
- steveperry-53
- tengqm
- zparnold
sig-docs-es-owners: # Admins for Spanish content
- raelga
- alexbrand
sig-docs-es-reviews: # PR reviews for Spanish content
- raelga
- alexbrand
# glo-pena
- electrocucaracha
sig-docs-fr-owners: # Admins for French content
- remyleone
- perriea
- rekcah78
- yastij
- smana
- rbenzair
- abuisine
- erickhun
- jygastaud
- awkif
- oussemos
- anthonydahanne
- feloy
sig-docs-fr-reviews: # PR reviews for French content
- remyleone
- perriea
- rekcah78
- yastij
- smana
- rbenzair
- abuisine
- erickhun
- jygastaud
- awkif
- oussemos
- anthonydahanne
- feloy
sig-docs-hi-owners: # Admins for Hindi content
- avidLearnerInProgress
- daminisatya
- mittalyashu
sig-docs-hi-reviews: # PR reviews for Hindi content
- avidLearnerInProgress
- daminisatya
- mittalyashu
sig-docs-id-owners: # Admins for Indonesian content
- girikuncoro
- irvifa
sig-docs-id-reviews: # PR reviews for Indonesian content
- girikuncoro
- irvifa
- wahyuoi
- phanama
- danninov
sig-docs-it-owners: # Admins for Italian content
- fabriziopandini
- Fale
- mattiaperi
- micheleberardi
sig-docs-it-reviews: # PR reviews for Italian content
- fabriziopandini
- Fale
- mattiaperi
- micheleberardi
sig-docs-ja-owners: # Admins for Japanese content
# cstoku
- inductor
- rajakavitha1
- stewart-yu
- xiangpengzhao
- zhangxiaoyu
sig-docs-ja-owners: #Team: Japanese docs localization; GH: sig-docs-ja-owners
- cstoku
- nasa9084
sig-docs-ja-reviews: # PR reviews for Japanese content
- bells17
# cstoku
- inductor
- kakts
- tnir
sig-docs-ja-reviews: #Team: Japanese docs PR reviews; GH:sig-docs-ja-reviews
- cstoku
- makocchi-git
# MasayaAoyama
- MasayaAoyama
- nasa9084
# oke-py
sig-docs-ko-owners: # Admins for Korean content
- tnir
sig-docs-ko-owners: #Team Korean docs localization; GH: sig-docs-ko-owners
- ClaudiaJKang
- gochist
sig-docs-ko-reviews: #Team Korean docs reviews; GH: sig-docs-ko-reviews
- ClaudiaJKang
- gochist
- ianychoi
- seokho-son
- ysyukr
sig-docs-ko-reviews: # PR reviews for Korean content
- ClaudiaJKang
- gochist
- ianychoi
- seokho-son
- ysyukr
- pjhwa
sig-docs-leads: # Website chairs and tech leads
- irvifa
- jimangel
- kbarnard10
- kbhawkey
- onlydole
- sftim
sig-docs-zh-owners: # Admins for Chinese content
# chenopis
- chenrui333
# dchen1107
# haibinxie
# hanjiayao
# lichuqiang
- SataQiu
- tanjunchen
sig-docs-zh-owners: #Team Chinese docs localization; GH: sig-docs-zh-owners
- dchen1107
- haibinxie
- hanjiayao
- lichuqiang
- tengqm
- xichengliudui
# zhangxiaoyu-zidif
sig-docs-zh-reviews: # PR reviews for Chinese content
- chenrui333
- howieyuen
- xiangpengzhao
- zhangxiaoyu-zidif
sig-docs-zh-reviews: #Team Chinese docs reviews; GH: sig-docs-zh-reviews
- idealhack
- pigletfly
- SataQiu
- tanjunchen
- tengqm
- xichengliudui
# zhangxiaoyu-zidif
sig-docs-pt-owners: # Admins for Portuguese content
- femrtnz
- jcjesus
- devlware
- jhonmike
sig-docs-pt-reviews: # PR reviews for Portugese content
- femrtnz
- jcjesus
- devlware
- jhonmike
sig-docs-vi-owners: # Admins for Vietnamese content
- huynguyennovem
- ngtuna
- truongnh1992
sig-docs-vi-reviews: # PR reviews for Vietnamese content
- huynguyennovem
- ngtuna
- truongnh1992
sig-docs-ru-owners: # Admins for Russian content
- msheldyakov
- aisonaku
- potapy4
- dianaabv
sig-docs-ru-reviews: # PR reviews for Russian content
- Arhell
- msheldyakov
- aisonaku
- potapy4
- dianaabv
sig-docs-pl-owners: # Admins for Polish content
- mfilocha
- nvtkaszpir
sig-docs-pl-reviews: # PR reviews for Polish content
- mfilocha
- nvtkaszpir
- kpucynski
sig-docs-uk-owners: # Admins for Ukrainian content
- anastyakulyk
- butuzov
- MaxymVlasov
sig-docs-uk-reviews: # PR reviews for Ukrainian content
- anastyakulyk
- Arhell
- butuzov
- xiangpengzhao
- zhangxiaoyu-zidif
sig-federation: #Team: Federation; e.g. Federated Clusters
- csbell
sig-gcp: #Google Cloud Platform; GH: sig-gcp-pr-reviews
- abgworrall
sig-instrumentation: #GH: sig-instrumentation-pr-reviews; e.g. metrics, logging, events
- DirectXMan12
- x13n
- kawych
- brancz
- fabxc
- loburm
- piosz
- fgrzadkowski
sig-multicluster: #GH: sig-multicluster-pr-reviews; e.g. resiliency against availability zone outages; hybrid clouds; spanning multiple cloud providers; migration to public clouds
- madhusudancs
- marun
- jianhuiz
- shashidharatd
- nikhiljindal
- quinton-hoole
- mwielgus
- csbell
sig-network: #Team: Network; GH: sig-network-pr-reviews; e.g. Ingress, Network Policies, Services
- bowei
- caseydavenport
- danwinship
- dcbw
- dnardo
- freehan
- mrhohn
- nicksardo
- thockin
sig-node: #Team: Node; GH: sig-node-pr-reviews; e.g. Containers, Docker, Images, OS images, Pods, Registries
- Random-Liu
- dashpole
- dchen1107
- derekwaynecarr
- dims
- feiskyer
- mtaufen
- ncdc
- pmorie
- resouer
- sjpotter
- tallclair
- tmrts
- vishh
- yifan-gu
- yujuhong
sig-onprem: #On-premises; GH: sig-onprem-pr-reviews
- zen
- idvoretskyi
- MaxymVlasov
- Potapy4
- pigmej
- feiskyer
- nebril
sig-openstack: #GH: sig-openstack-pr-reviews
- hogepodge
- dklyle
- rjmorse
sig-pm: #aka Product Management
- apsinha
- idvoretskyi
- calebamiles
sig-product-management:
- apsinha
- idvoretskyi
- calebamiles
sig-release: #GH: sig-release-pr-reviews
- calebamiles
- enisoc
- pwittrock
sig-rktnetes:
- calebamiles
sig-scalability: #GH: sig-scalability-pr-reviews
- jbeda
- spiffxp
- lavalamp
- countspongebob
sig-scheduling: #Team: Sharing; GH: sig-scheduling-pr-reviews; e.g. Scheduler
- bsalamat
- davidopp
- jayunit100
- k82cn
- resouer
- timothysc
- wojtek-t
sig-service-catalog: #GH: sig-service-catalog-pr-reviews; e.g. Service Broker
- pmorie
- jessfraz
- pwittrock
- droot
- seans3
sig-storage: #Team: Storage; GH: sig-storage-pr-reviews; e.g. Volumes
- childsb
- jsafrane
- rootfs
- saad-ali
- matchstick
- msau42
sig-testing: #GH: sig-testing-pr-reviews
- fejta
- ixdy
- rmmh
- spiffxp
- spxtr
sig-ui: #User Interface
- danielromlein
- floreks
sig-windows:
- michmike
-81
View File
@@ -1,81 +0,0 @@
# Kubernetes Dokumentation
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Herzlich willkommen! Dieses Repository enthält alle Assets, die zur Erstellung der [Kubernetes-Website und Dokumentation](https://kubernetes.io/) erforderlich sind. Wir freuen uns sehr, dass Sie dazu beitragen wollen!
## Beiträge zur Dokumentation
Sie können auf die Schaltfläche **Fork** im oberen rechten Bereich des Bildschirms klicken, um eine Kopie dieses Repositorys in Ihrem GitHub-Konto zu erstellen. Diese Kopie wird als *Fork* bezeichnet. Nehmen Sie die gewünschten Änderungen an Ihrem Fork vor. Wenn Sie bereit sind, diese Änderungen an uns zu senden, gehen Sie zu Ihrem Fork und erstellen Sie eine neue Pull-Anforderung, um uns darüber zu informieren.
Sobald Ihre Pull-Anfrage erstellt wurde, übernimmt ein Rezensent von Kubernetes die Verantwortung für klares, umsetzbares Feedback. Als Eigentümer des Pull-Request **liegt es in Ihrer Verantwortung Ihren Pull-Reqest enstsprechend des Feedbacks, dass Sie vom Kubernetes-Reviewer erhalten haben abzuändern.** Beachten Sie auch, dass Sie am Ende mehr als einen Rezensenten von Kubernetes erhalten, der Ihnen Feedback gibt, oder dass Sie Rückmeldungen von einem Rezensenten von Kubernetes erhalten, der sich von demjenigen unterscheidet, der ursprünglich für das Feedback zugewiesen wurde. In einigen Fällen kann es vorkommen, dass einer Ihrer Prüfer bei Bedarf eine technische Überprüfung von einem [Kubernetes Tech-Reviewer](https://github.com/kubernetes/website/wiki/tech-reviewers) anfordert. Reviewer geben ihr Bestes, um zeitnah Feedback zu geben, die Antwortzeiten können jedoch je nach den Umständen variieren.
Weitere Informationen zum Beitrag zur Kubernetes-Dokumentation finden Sie unter:
* [Mitwirkung beginnen](https://kubernetes.io/docs/contribute/start/)
* [Ihre Dokumentationsänderungen bereitstellen](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Seitenvorlagen verwenden](http://kubernetes.io/docs/contribute/style/page-content-types/)
* [Dokumentationsstil-Handbuch](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Übersetzung der Kubernetes-Dokumentation](https://kubernetes.io/docs/contribute/localization/)
## `README.md`'s Localizing Kubernetes Documentation
### Deutsch
Die Betreuer der deutschen Lokalisierung erreichen Sie unter:
* Benedikt Rollik ([@bene2k1](https://github.com/bene2k1))
* Max Körbächer ([@mkorbi](https://github.com/mkorbi))
* [Slack Kanal](https://kubernetes.slack.com/messages/kubernetes-docs-de)
## Site lokal mit Docker ausführen
Um die Kubernetes-Website lokal laufen zu lassen, empfiehlt es sich, ein spezielles [Docker](https://docker.com) Image auszuführen, das den statischen Site-Generator [Hugo](https://gohugo.io) enthält.
> Unter Windows benötigen Sie einige weitere Tools, die Sie mit [Chocolatey](https://chocolatey.org) installieren können.
`choco install make`
> Wenn Sie die Website lieber lokal ohne Docker ausführen möchten, finden Sie weitere Informationen unter [Website lokal mit Hugo ausführen](#Die-Site-lokal-mit-Hugo-ausführen).
Wenn Sie Docker [installiert](https://www.docker.com/get-started) haben, erstellen Sie das Docker-Image `kubernetes-hugo` lokal:
```bash
make container-image
```
Nachdem das Image erstellt wurde, können Sie die Site lokal ausführen:
```bash
make container-serve
```
Öffnen Sie Ihren Browser unter http://localhost:1313, um die Site anzuzeigen. Wenn Sie Änderungen an den Quelldateien vornehmen, aktualisiert Hugo die Site und erzwingt eine Browseraktualisierung.
## Die Site lokal mit Hugo ausführen
Hugo-Installationsanweisungen finden Sie in der [offiziellen Hugo-Dokumentation](https://gohugo.io/getting-started/installing/). Stellen Sie sicher, dass Sie die Hugo-Version installieren, die in der Umgebungsvariablen `HUGO_VERSION` in der Datei [`netlify.toml`](netlify.toml#L9) angegeben ist.
So führen Sie die Site lokal aus, wenn Sie Hugo installiert haben:
```bash
make serve
```
Dadurch wird der lokale Hugo-Server an Port 1313 gestartet. Öffnen Sie Ihren Browser unter http://localhost:1313, um die Site anzuzeigen. Wenn Sie Änderungen an den Quelldateien vornehmen, aktualisiert Hugo die Site und erzwingt eine Browseraktualisierung.
## Community, Diskussion, Beteiligung und Unterstützung
Erfahren Sie auf der [Community-Seite](http://kubernetes.io/community/) wie Sie mit der Kubernetes-Community interagieren können.
Sie können die Betreuer dieses Projekts unter folgender Adresse erreichen:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Verhaltensregeln
Die Teilnahme an der Kubernetes-Community unterliegt dem [Kubernetes-Verhaltenskodex](code-of-conduct.md).
## Vielen Dank!
Kubernetes lebt vom Community Engagement und wir freuen uns sehr über Ihre Beiträge zu unserer Website und unserer Dokumentation!
-76
View File
@@ -1,76 +0,0 @@
# La documentación de Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Bienvenido!
Este repositorio contiene todos los recursos necesarios para construir el [sitio web de Kubernetes y su documentación](https://kubernetes.io/). ¡Estamos encantados de que quiera contribuir!
## Contribuyendo con la documentación
Puede hacer clic en el botón **Fork** situado en la esquina superior derecha de la pantalla para crear una copia de este repositorio en su cuenta de GitHub. A ese tipo de copia se le llama **Fork** (bifurcación) y le permite editar el contenido del repositorio en su copia personal. Realice los cambios que quiera en su **fork** y, cuando esté listo para enviarnos esos cambios, vaya a **fork** en repositorio en su GitHub y cree una nueva **pull request** para que tengamos constancia de la propuesta de cambios.
Una vez la **pull request** ha sido creada, un revisor de Kubernetes asumirá la responsabilidad de proporcionar comentarios claros y prácticos sobre como continuar. Como propietario de la PR, **es su responsabilidad modificar la pull request para abordar los comentarios proporcionados por el revisor de Kubernetes.** Tenga en cuenta que algunas veces puede terminar teniendo más de un revisor de Kubernetes participando en la revisión, por lo que es posible que reciba comentarios de más revisores a parte del asignado originalmente en la creación de la **pull request**. Además, en algunas ocasiones, es posible que uno de sus revisores solicite una revisión técnica por parte de un [revisor técnico de Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) si lo considera necesario.
Los revisores harán todo lo posible para proporcionar toda la información necesaria para que la **pull request** siga adelante en un tiempo razonable, pero este tiempo de respuesta puede variar según las circunstancias.
Para obtener más información sobre cómo contribuir a la documentación de Kubernetes, puede consultar:
* [Empezando a contribuir](https://kubernetes.io/docs/contribute/start/)
* [Visualizando sus cambios en su entorno local](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Utilizando las plantillas de las páginas](http://kubernetes.io/docs/contribute/style/page-content-types/)
* [Guía de estilo de la documentación](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Traduciendo la documentación de Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Levantando el sitio web kubernetes.io en su entorno local con Docker
El método recomendado para levantar una copia local del sitio web kubernetes.io es utilizando la imagen de [Docker](https://docker.com) que incluye el generador de sitios estáticos [Hugo](https://gohugo.io).
> Para Windows, algunas otras herramientas como Make son necesarias. Puede instalarlas utilizando el gestor [Chocolatey](https://chocolatey.org). `choco install make` o siguiendo las instrucciones de [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm).
> Si prefiere levantar el sitio web sin utilizar **Docker**, puede seguir las instrucciones disponibles en la sección [Levantando kubernetes.io en local con Hugo](#levantando-kubernetesio-en-local-con-hugo).
Una vez tenga Docker [configurado en su máquina](https://www.docker.com/get-started), puede construir la imagen de Docker `kubernetes-hugo` localmente ejecutando el siguiente comando en la raíz del repositorio:
```bash
make container-image
```
Una vez tenga la imagen construida, puede levantar el sitio web ejecutando:
```bash
make container-serve
```
Abra su navegador y visite http://localhost:1313 para acceder a su copia local del sitio. A medida que vaya haciendo cambios en el código fuente, Hugo irá actualizando la página y forzará la actualización en el navegador.
## Levantando kubernetes.io en local con Hugo
Revise la [documentación oficial de Hugo](https://gohugo.io/getting-started/installing/) para obtener las instrucciones de instalación en su sistema operativo. Asegúrese de instalar la versión de Hugo especificada en la variable de entorno `HUGO_VERSION` del fichero [`netlify.toml`](netlify.toml#L9).
Para levantar el sitio localmente una vez Hugo está instalado en su sistema, puede ejecutar el siguiente comando:
```bash
make serve
```
Este comando levantará un servidor de Hugo en el puerto **1313** al que podrá acceder visitando http://localhost:1313 y dónde podrá visualizar su copia local del sitio web. A medida que vaya haciendo cambios en el código fuente, Hugo irá actualizando la página y forzará la actualización en el navegador.
## Comunidad, discusión, contribuir y soporte
Aprenda como participar en la comunidad de Kubernetes visitando la [página de comunidad](http://kubernetes.io/community/).
Puede ponerse en contacto con los mantenedores de este proyecto en:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Código de conducta
La participación en la comunidad de Kubernetes está regulada por el [Código de Conducta de Kubernetes](code-of-conduct.md).
## ¡Muchas gracias!
Kubernetes es posible gracias a la participación de la comunidad y la documentación es vital para facilitar el acceso al proyecto.
Agradecemos muchísimo sus contribuciones a nuestro sitio web y nuestra documentación.
-83
View File
@@ -1,83 +0,0 @@
# Documentation de Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Bienvenue !
Ce référentiel contient toutes les informations nécessaires à la construction du site web et de la documentation de Kubernetes.
Nous sommes très heureux que vous vouliez contribuer !
## Contribuer à la rédaction des docs
Vous pouvez cliquer sur le bouton **Fork** en haut à droite de l'écran pour créer une copie de ce dépôt dans votre compte GitHub.
Cette copie s'appelle un *fork*.
Faites tous les changements que vous voulez dans votre fork, et quand vous êtes prêt à nous envoyer ces changements, allez dans votre fork et créez une nouvelle pull request pour nous le faire savoir.
Une fois votre pull request créée, un examinateur de Kubernetes se chargera de vous fournir une revue claire et exploitable.
En tant que propriétaire de la pull request, **il est de votre responsabilité de modifier votre pull request pour tenir compte des commentaires qui vous ont été fournis par l'examinateur de Kubernetes.**
Notez également que vous pourriez vous retrouver avec plus d'un examinateur de Kubernetes pour vous fournir des commentaires ou vous pourriez finir par recevoir des commentaires d'un autre examinateur que celui qui vous a été initialement affecté pour vous fournir ces commentaires.
De plus, dans certains cas, l'un de vos examinateurs peut demander un examen technique à un [examinateur technique de Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) au besoin.
Les examinateurs feront de leur mieux pour fournir une revue rapidement, mais le temps de réponse peut varier selon les circonstances.
Pour plus d'informations sur la contribution à la documentation Kubernetes, voir :
* [Commencez à contribuer](https://kubernetes.io/docs/contribute/start/)
* [Aperçu des modifications apportées à votre documentation](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Utilisation des modèles de page](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Documentation Style Guide](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Traduction de la documentation Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Exécuter le site localement en utilisant Docker
La façon recommandée d'exécuter le site web Kubernetes localement est d'utiliser une image spécialisée [Docker](https://docker.com) qui inclut le générateur de site statique [Hugo](https://gohugo.io).
> Si vous êtes sous Windows, vous aurez besoin de quelques outils supplémentaires que vous pouvez installer avec [Chocolatey](https://chocolatey.org). `choco install install make`
> Si vous préférez exécuter le site Web localement sans Docker, voir [Exécuter le site localement avec Hugo](#exécuter-le-site-localement-en-utilisant-hugo) ci-dessous.
Si vous avez Docker [up and running](https://www.docker.com/get-started), construisez l'image Docker `kubernetes-hugo' localement:
```bash
make container-image
```
Une fois l'image construite, vous pouvez exécuter le site localement :
```bash
make container-serve
```
Ouvrez votre navigateur à l'adresse: http://localhost:1313 pour voir le site.
Lorsque vous apportez des modifications aux fichiers sources, Hugo met à jour le site et force le navigateur à rafraîchir la page.
## Exécuter le site localement en utilisant Hugo
Voir la [documentation officielle Hugo](https://gohugo.io/getting-started/installing/) pour les instructions d'installation Hugo.
Assurez-vous d'installer la version Hugo spécifiée par la variable d'environnement `HUGO_VERSION` dans le fichier [`netlify.toml`](netlify.toml#L9).
Pour exécuter le site localement lorsque vous avez Hugo installé :
```bash
make serve
```
Le serveur Hugo local démarrera sur le port 1313.
Ouvrez votre navigateur à l'adresse: http://localhost:1313 pour voir le site.
Lorsque vous apportez des modifications aux fichiers sources, Hugo met à jour le site et force le navigateur à rafraîchir la page.
## Communauté, discussion, contribution et assistance
Apprenez comment vous engager avec la communauté Kubernetes sur la [page communauté](http://kubernetes.io/community/).
Vous pouvez joindre les responsables de ce projet à l'adresse :
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Code de conduite
La participation à la communauté Kubernetes est régie par le [Code de conduite de Kubernetes](code-of-conduct.md).
## Merci !
Kubernetes prospère grâce à la participation de la communauté, et nous apprécions vraiment vos contributions à notre site et à notre documentation !
-84
View File
@@ -1,84 +0,0 @@
# कुबरनेट्स प्रलेखन
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
स्वागत हे! इस रिपॉजिटरी में [कुबरनेट्स वेबसाइट और दस्तावेज](https://kubernetes.io/) बनाने के लिए आवश्यक सभी संपत्तियां हैं। हम बहुत खुश हैं कि आप योगदान करना चाहते हैं!
## डॉक्स में योगदान देना
आप अपने GitHub खाते में इस रिपॉजिटरी की एक copy बनाने के लिए स्क्रीन के ऊपरी-दाएँ क्षेत्र में **Fork** बटन पर क्लिक करें। इस copy को *Fork* कहा जाता है। अपने fork में कोई भी परिवर्तन करना चाहते हैं, और जब आप उन परिवर्तनों को हमारे पास भेजने के लिए तैयार हों, तो अपने fork पर जाएं और हमें इसके बारे में बताने के लिए एक नया pull request बनाएं।
एक बार जब आपका pull request बन जाता है, तो एक कुबरनेट्स समीक्षक स्पष्ट, कार्रवाई योग्य प्रतिक्रिया प्रदान करने की जिम्मेदारी लेगा। pull request के मालिक के रूप में, **यह आपकी जिम्मेदारी है कि आप कुबरनेट्स समीक्षक द्वारा प्रदान की गई प्रतिक्रिया को संबोधित करने के लिए अपने pull request को संशोधित करें।**
यह भी ध्यान दें कि आप एक से अधिक कुबरनेट्स समीक्षक आपको प्रतिक्रिया प्रदान कर सकते हैं या आप एक कुबरनेट्स समीक्षक से प्रतिक्रिया प्राप्त कर सकते हैं जो मूल रूप से आपको प्रतिक्रिया प्रदान करने के लिए दिए गए एक से भिन्न है। इसके अलावा, कुछ मामलों में, आपका एक समीक्षक जरूरत पड़ने पर [कुबेरनेट्स टेक समीक्षक](https://github.com/kubernetes/website/wiki/Tech-reviewers) से तकनीकी समीक्षा प्राप्त कर सकता है। समीक्षक समय पर प्रतिक्रिया देने के लिए पूरी कोशिश करेंगे, लेकिन परिस्थितियों के आधार पर प्रतिक्रिया समय अलग-अलग हो सकता है।
कुबरनेट्स प्रलेखन में योगदान देने के बारे में अधिक जानकारी के लिए, देखें:
* [योगदान देना शुरू करें](https://kubernetes.io/docs/contribute/start/)
* [परिवर्तनों को अंतिम चरण में लेजाएं](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [पेज टेम्पलेट](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [प्रलेखन शैली गाइड](http://kubernetes.io/docs/contribute/style/style-guide/)
* [स्थानीयकरण कुबरनेट्स प्रलेखन](https://kubernetes.io/docs/contribute/localization/)
## `README.md`'s स्थानीयकरण कुबरनेट्स प्रलेखन
आप पर हिंदी स्थानीयकरण के maintainers तक पहुँच सकते हैं:
* Yashu Mittal ([Twitter](https://twitter.com/mittalyashu77), [GitHub](https://github.com/mittalyashu))
* [Slack channel](https://kubernetes.slack.com/messages/kubernetes-docs-hi)
## स्थानीय रूप से डॉकर का उपयोग करके साइट चलाना
कुबरनेट्स वेबसाइट को स्थानीय रूप से चलाने के लिए अनुशंसित तरीका एक विशेष [डॉकर](https://docker.com) image को चलाना है, जिसमें [Hugo](https://gohugo.io) स्टेटिक साइट जनरेटर शामिल है।
> यदि आप विंडोज पर हैं, तो आपको कुछ और टूल्स की आवश्यकता होगी जिन्हें आप [Chocolatey](https://chocolatey.org) के साथ इंस्टॉल कर सकते हैं।
> यदि आप डॉकर के बिना स्थानीय रूप से वेबसाइट चलाना पसंद करते हैं, तो नीचे Hugo का उपयोग करके स्थानीय रूप से साइट चलाना देखें।
यदि आप डॉकर के बिना स्थानीय रूप से वेबसाइट चलाना पसंद करते हैं, तो नीचे दिए गए Hugo का उपयोग करके स्थानीय रूप से [साइट को चलाने](#hugo-का-उपयोग-करते-हुए-स्थानीय-रूप-से-साइट-चलाना) का तरीका देखें।
यदि आप [डॉकर](https://www.docker.com/get-started) चला रहे हैं, तो स्थानीय रूप से `कुबेरनेट्स-ह्यूगो` Docker image बनाएँ:
```bash
make container-image
```
एक बार image बन जाने के बाद, आप साइट को स्थानीय रूप से चला सकते हैं:
```bash
make container-serve
```
साइट देखने के लिए अपने browser को `http://localhost:1313` पर खोलें। जैसा कि आप source फ़ाइलों में परिवर्तन करते हैं, Hugo साइट को अपडेट करता है और browser को refresh करने पर मजबूर करता है।
## Hugo का उपयोग करते हुए स्थानीय रूप से साइट चलाना
Hugo निर्देशों के लिए [आधिकारिक Hugo प्रलेखन](https://gohugo.io/getting-started/installing/) देखें। [`Netlify.toml`](netlify.toml#L9) फ़ाइल में `HUGO_VERSION` environment variable द्वारा निर्दिष्ट Hugo version को install करना सुनिश्चित करें।
जब आप Hugo को install करते हैं तो स्थानीय रूप से साइट को चलाने के लिए:
```bash
make serve
```
यह पोर्ट `1313` पर Hugo सर्वर को शुरू करेगा। साइट देखने के लिए अपने browser को `http://localhost:1313` पर खोलें। जैसा कि आप source फ़ाइलों में परिवर्तन करते हैं, Hugo साइट को अपडेट करता है और एक browser को refresh करने पर मजबूर करता है।
## समुदाय, चर्चा, योगदान और समर्थन
[Community page](http://kubernetes.io/community/) पर कुबरनेट्स समुदाय के साथ जुड़ना सीखें।
आप इस परियोजना के स्थानीयकरण तक पहुँच सकते हैं:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
## कोड ओफ़ कंडक्ट
कुबरनेट्स समुदाय में भागीदारी [कुबरनेट्स कोड ओफ़ कंडक्ट](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/hi.md) द्वारा शासित है.
## धन्यवाद!
कुबरनेट्स सामुदायिक भागीदारी पर पनपती है, और हम वास्तव में हमारी साइट और हमारे प्रलेखन में आपके योगदान की सराहना करते हैं!
कुबरनेट्स आपकी भागीदारी पर निर्भर है, और हम हमारी साइट और प्रलेखन में आपके योगदान का मान करते हैं!
-72
View File
@@ -1,72 +0,0 @@
# Dokumentasi Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Selamat datang! Repositori ini merupakan wadah bagi semua komponen yang dibutuhkan untuk membuat [dokumentasi Kubernetes](https://kubernetes.io/). Kami merasa sangat senang apabila kamu berminat untuk menjadi kontributor!
## Kontribusi pada dokumentasi
Pertama, kamu dapat menekan tombol **Fork** yang berada pada bagian atas layar, untuk menyalin repositori pada akun Github-mu. Salinan ini disebut sebagai **fork**. Kamu dapat menambahkan konten pada **fork** yang kamu miliki, setelah kamu merasa cukup untuk menambahkan konten yang kamu miliki dan ingin memberikan konten tersebut pada kami, kamu dapat melihat **fork** yang telah kamu buat dan membuat **pull request** untuk memberi tahu kami bahwa kamu ingin menambahkan konten yang telah kamu buat.
Setelah kamu membuat sebuah **pull request**, seorang **reviewer** akan memberikan masukan terhadap konten yang kamu sediakan serta beberapa hal yang dapat kamu lakukan apabila perbaikan diperlukan terhadap konten yang telah kamu sediakan. Sebagai seorang yang membuat **pull request**, **sudah menjadi kewajiban kamu untuk melakukan modifikasi terhadap konten yang kamu berikan sesuai dengan masukan yang diberikan oleh seorang reviewer Kubernetes**. Perlu kamu ketahui bahwa kamu dapat saja memiliki lebih dari satu orang **reviewer Kubernetes** atau dalam kasus kamu bisa saja mendapatkan **reviewer Kubernetes** yang berbeda dengan **reviewer Kubernetes** awal yang ditugaskan untuk memberikan masukan terhadap konten yang kamu sediakan. Selain itu, seorang **reviewer Kubernetes** bisa saja meminta masukan teknis dari [reviewer teknis Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) jika diperlukan.
Untuk informasi lebih lanjut mengenai tata cara melakukan kontribusi, kamu dapat melihat tautan di bawah ini:
* [Petunjuk Melakukan Kontribusi](https://kubernetes.io/docs/contribute/start/)
* [Melakukan Tahap Staging pada Konten Dokumentasi yang telah Kamu Sediakan](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Petunjuk Menggunakan Page Templates](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Petunjuk untuk Documentation Style](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Petunjuk untuk Melakukan Lokalisasi Dokumentasi Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Menjalankan Dokumentasi Kubernetes pada Mesin Lokal Kamu
Petunjuk yang disarankan untuk menjalankan Dokumentasi Kubernetes pada mesin lokal kamus adalah dengan menggunakan [Docker](https://docker.com) **image** yang memiliki **package** [Hugo](https://gohugo.io), **Hugo** sendiri merupakan generator website statis.
> Jika kamu menggunakan Windows, kamu mungkin membutuhkan beberapa langkah tambahan untuk melakukan instalasi perangkat lunak yang dibutuhkan. Instalasi ini dapat dilakukan dengan menggunakan [Chocolatey](https://chocolatey.org). `choco install make`
> Jika kamu ingin menjalankan **website** tanpa menggunakan **Docker**, kamu dapat melihat tautan berikut [Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo](#petunjuk-untuk-menjalankan-website-pada-mesin-lokal-dengan-menggunakan-hugo) di bagian bawah.
Jika kamu sudah memiliki **Docker** [yang sudah dapat digunakan](https://www.docker.com/get-started), kamu dapat melakukan **build** `kubernetes-hugo` **Docker image** secara lokal:
```bash
make container-image
```
Setelah **image** berhasil di-**build**, kamu dapat menjalankan website tersebut pada mesin lokal-mu:
```bash
make container-serve
```
Buka **browser** kamu ke http://localhost:1313 untuk melihat laman dokumentasi. Selama kamu melakukan penambahan konten, **Hugo** akan secara otomatis melakukan perubahan terhadap laman dokumentasi apabila **browser** melakukan proses **refresh**.
## Petunjuk untuk menjalankan website pada mesin lokal dengan menggunakan Hugo
Kamu dapat melihat [dokumentasi resmi Hugo](https://gohugo.io/getting-started/installing/) untuk mengetahui langkah yang diperlukan untuk melakukan instalasi **Hugo**. Pastikan kamu melakukan instalasi versi **Hugo** sesuai dengan versi yang tersedia pada **environment variable** `HUGO_VERSION` pada **file**[`netlify.toml`](netlify.toml#L9).
Untuk menjalankan laman pada mesin lokal setelah instalasi **Hugo**, kamu dapat menjalankan perintah berikut:
```bash
make serve
```
Buka **browser** kamu ke http://localhost:1313 untuk melihat laman dokumentasi. Selama kamu melakukan penambahan konten, **Hugo** akan secara otomatis melakukan perubahan terhadap laman dokumentasi apabila **browser** melakukan proses **refresh**.
## Komunitas, Diskusi, Kontribusi, dan Bantuan
Kamu dapat belajar bagaimana tata cara untuk ikut terlibat dalam komunitas Kubernetes melalui [laman komunitas](http://kubernetes.io/community/).
Kamu dapat berinteraksi dengan **maintainers** project ini melalui:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Etika dalam Berkontribusi
Partisipasi dalam komunitas Kubernetes diatur dalam [Etika dalam Berkontribusi pada Kubernetes](code-of-conduct.md).
## Terima Kasih!
Kubernetes sangat menjunjung tinggi partisipasi dari komunitas, dan kami sangat mengapresiasi kontribusi kamu pada laman dan dokumentasi kami!
-71
View File
@@ -1,71 +0,0 @@
# La documentazione di Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Benvenuto! Questo repository contiene tutte le informazioni necessarie per creare la [documentazione e il sito web di Kubernetes](https://kubernetes.io/). Siamo onorati che tu voglia contribuire!
## Come contribuire alla documentazione
Puoi premere il pulsante **Fork** in alto nella parte destra dello schermo per creare una copia di questo repository sotto la tua utenza di GitHub. Questa copia è chiamata un *fork*. Puoi fare tutte le modifiche che vuoi nel tuo fork, e quando sei pronto a mandarci i cambiamenti, vai sulla pagina del tuo fork e crea una nuova pull request per farcelo sapere.
Una volta che hai creato la pull request, un reviewer (revisore) Kubernetes la prenderà in carico per fornire un feedback chiaro e concretamente attuabile. Come owner della pull request, **è tua responsabilità modificare la tua pull request per rispondere al feedback che ti è stato fornito dal reviewer Kubernetes**. Inoltre, tieni presente che potresti ricevere feedback da più di un Reviewer di Kubernetes, incluse quindi persone diverse da quella che ti ha fornito il primo feedback. In alcuni casi, uno dei tuoi reviewer potrebbe richiedere una revisione tecnica da un [technical reviewer di Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) quando necessario. I reviewer faranno del loro meglio per fornire feedback in modo tempestivo, ma i tempi di risposta possono variare in base alle circostanze.
Per maggiori informazioni su come contribuire alla documentazione Kubernetes, vedi:
* [Cominciare a contribuire](https://kubernetes.io/docs/contribute/start/)
* [Vedere le modifiche localmente](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Utilizzare i template delle pagine](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Guida Stilistica per la documentazione di Kubernetes](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Tradurre la documentazione di Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Eseguire il sito Web localmente usando Docker
Il modo consigliato per eseguire localmente il sito Web Kubernetes prevede l'utilizzo di un'immagine [Docker](https://docker.com) inclusa nel sito e configurata con tutti i software necessari, a partire dal generatore di siti web statici [Hugo](https://gohugo.io).
> Se stai utilizzando Windows, avrai bisogno di alcuni strumenti aggiuntivi che puoi installare con [Chocolatey](https://chocolatey.org). `choco install make`
> Se preferisci eseguire il sito Web localmente senza Docker, vedi [Eseguire il sito Web localmente utilizzando Hugo](#eseguire-il-sito-web-localmente-utilizzando-hugo) di seguito.
Se hai Docker [attivo e funzionante](https://www.docker.com/get-started), crea l'immagine Docker `kubernetes-hugo` localmente:
```bash
make container-image
```
Dopo aver creato l'immagine, è possibile eseguire il sito Web localmente:
```bash
make container-serve
```
Apri il tuo browser su http://localhost:1313 per visualizzare il sito Web. Mentre modifichi i file sorgenti, Hugo aggiorna automaticamente il sito Web e forza un aggiornamento della pagina visualizzata nel browser.
## Eseguire il sito Web localmente utilizzando Hugo
Vedi la [documentazione ufficiale di Hugo](https://gohugo.io/getting-started/installing/) per le istruzioni di installazione di Hugo. Assicurati di installare esattamente la versione di Hugo specificata dalla variabile d'ambiente `HUGO_VERSION` nel file [`netlify.toml`](netlify.toml#L9).
Per eseguire il sito Web localmente dopo aver installato Hugo:
```bash
make serve
```
Questo comando avvierà il server Hugo locale sulla porta 1313. Apri il tuo browser su http://localhost:1313 per visualizzare il sito Web. Mentre apporti modifiche ai file di origine, Hugo aggiorna il sito Web e forza un aggiornamento del browser.
## Community, discussioni, contribuire e supporto
Scopri come interagire con la community di Kubernetes nella [pagina della community](http://kubernetes.io/community/).
Puoi contattare i maintainers di questo progetto su:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Codice di condotta
La partecipazione alla comunità Kubernetes è regolata dal [Codice di condotta di Kubernetes](code-of-conduct.md).
## Grazie!
Kubernetes prospera grazie alla partecipazione della comunity e apprezziamo i tuoi contributi al nostro sito Web e alla nostra documentazione!
-145
View File
@@ -1,145 +0,0 @@
# Kubernetesのドキュメント
[![Netlify Status](https://api.netlify.com/api/v1/badges/be93b718-a6df-402a-b4a4-855ba186c97d/deploy-status)](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
このリポジトリには、[KubernetesのWebサイトとドキュメント](https://kubernetes.io/)をビルドするために必要な全アセットが格納されています。貢献に興味を持っていただきありがとうございます!
# リポジトリの使い方
Hugo(Extended version)を使用してWebサイトをローカルで実行することも、コンテナランタイムで実行することもできます。コンテナランタイムを使用することを強くお勧めします。これにより、本番Webサイトとのデプロイメントの一貫性が得られます。
## 前提条件
このリポジトリを使用するには、以下をローカルにインストールする必要があります。
- [npm](https://www.npmjs.com/)
- [Go](https://golang.org/)
- [Hugo(Extended version)](https://gohugo.io/)
- [Docker](https://www.docker.com/)などのコンテナランタイム
開始する前に、依存関係をインストールしてください。リポジトリのクローンを作成し、ディレクトリに移動します。
```
git clone https://github.com/kubernetes/website.git
cd website
```
KubernetesのWebサイトではDocsyというHugoテーマを使用しています。コンテナでWebサイトを実行する場合でも、以下を実行して、サブモジュールおよびその他の開発依存関係をプルすることを強くお勧めします。
```
# pull in the Docsy submodule
git submodule update --init --recursive --depth 1
```
## コンテナを使ってウェブサイトを動かす
コンテナ内でサイトを構築するには、以下を実行してコンテナイメージを構築し、実行します。
```
make container-image
make container-serve
```
お使いのブラウザにて http://localhost:1313 にアクセスしてください。リポジトリ内のソースファイルに変更を加えると、HugoがWebサイトの内容を更新してブラウザに反映します。
## Hugoを使ってローカル環境でWebサイトを動かす
[`netlify.toml`](netlify.toml#L10)ファイルに記述されている`HUGO_VERSION`と同じExtended versionのHugoをインストールするようにしてください。
ローカルでサイトを構築してテストするには、次のコマンドを実行します。
```bash
# install dependencies
npm ci
make serve
```
これで、Hugoのサーバーが1313番ポートを使って開始します。お使いのブラウザにて http://localhost:1313 にアクセスしてください。リポジトリ内のソースファイルに変更を加えると、HugoがWebサイトの内容を更新してブラウザに反映します。
## トラブルシューティング
### error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version
Hugoは、技術的な理由から2種類のバイナリがリリースされています。現在のウェブサイトは**Hugo Extended**バージョンのみに基づいて運営されています。[リリースページ](https://github.com/gohugoio/hugo/releases)で名前に「extended」が含まれるアーカイブを探します。確認するには、`hugo version`を実行し、「extended」という単語を探します。
### macOSにてtoo many open filesというエラーが表示される
macOS上で`make serve`を実行した際に以下のエラーが表示される場合
```
ERROR 2020/08/01 19:09:18 Error: listen tcp 127.0.0.1:1313: socket: too many open files
make: *** [serve] Error 1
```
OS上で同時に開けるファイルの上限を確認してください。
`launchctl limit maxfiles`
続いて、以下のコマンドを実行します(https://gist.github.com/tombigel/d503800a282fcadbee14b537735d202c より引用)。
```
#!/bin/sh
# These are the original gist links, linking to my gists now.
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxfiles.plist
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxproc.plist
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxfiles.plist
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxproc.plist
sudo mv limit.maxfiles.plist /Library/LaunchDaemons
sudo mv limit.maxproc.plist /Library/LaunchDaemons
sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
sudo chown root:wheel /Library/LaunchDaemons/limit.maxproc.plist
sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
```
こちらはmacOSのCatalinaとMojaveで動作を確認しています。
## SIG Docsに参加する
[コミュニティのページ](https://github.com/kubernetes/community/tree/master/sig-docs#meetings)をご覧になることで、SIG Docs Kubernetesコミュニティとの関わり方を学ぶことができます。
本プロジェクトのメンテナーには以下の方法で連絡することができます:
- [Slack](https://kubernetes.slack.com/messages/kubernetes-docs-ja)
- [メーリングリスト](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
## ドキュメントに貢献する
GitHubの画面右上にある**Fork**ボタンをクリックすると、お使いのGitHubアカウントに紐付いた本リポジトリのコピーが作成され、このコピーのことを*フォーク*と呼びます。フォークリポジトリの中ではお好きなように変更を加えていただいて構いません。加えた変更をこのリポジトリに追加したい任意のタイミングにて、フォークリポジトリからPull Reqeustを作成してください。
Pull Requestが作成されると、レビュー担当者が責任を持って明確かつ実用的なフィードバックを返します。Pull Requestの所有者は作成者であるため、**ご自身で作成したPull Requestを編集し、フィードバックに対応するのはご自身の役目です。**
また、状況によっては2人以上のレビュアーからフィードバックが返されたり、アサインされていないレビュー担当者からのフィードバックが来ることがある点もご注意ください。
さらに、特定のケースにおいては、レビュー担当者がKubernetesの技術的なレビュアーに対してレビューを依頼することもあります。レビュー担当者はタイムリーにフィードバックを提供するために最善を尽くしますが、応答時間は状況に応じて異なる場合があります。
Kubernetesのドキュメントへの貢献に関する詳細については以下のページをご覧ください:
* [Kubernetesのドキュメントへの貢献](https://kubernetes.io/ja/docs/contribute/)
* [ページコンテントタイプ](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [ドキュメントのスタイルガイド](https://kubernetes.io/docs/contribute/style/style-guide/)
* [Kubernetesドキュメントの翻訳方法](https://kubernetes.io/docs/contribute/localization/)
## 翻訳された`README.md`一覧
| Language | Language |
|---|---|
|[中国語](README-zh.md)|[韓国語](README-ko.md)|
|[フランス語](README-fr.md)|[ポーランド語](README-pl.md)|
|[ドイツ語](README-de.md)|[ポルトガル語](README-pt.md)|
|[ヒンディー語](README-hi.md)|[ロシア語](README-ru.md)|
|[インドネシア語](README-id.md)|[スペイン語](README-es.md)|
|[イタリア語](README-it.md)|[ウクライナ語](README-uk.md)|
|[日本語](README-ja.md)|[ベトナム語](README-vi.md)|
### 行動規範
Kubernetesコミュニティへの参加については、[CNCFの行動規範](https://github.com/cncf/foundation/blob/master/code-of-conduct.md)によって管理されています。
## ありがとうございます!
Kubernetesはコミュニティの参加によって成長しています。Webサイトおよびドキュメンテーションへの皆さんの貢献に感謝します!
-69
View File
@@ -1,69 +0,0 @@
# 쿠버네티스 문서화
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
환영합니다! 이 저장소는 쿠버네티스 웹사이트 및 문서화를 만드는 데 필요로 하는 모든 asset에 대한 공간을 제공합니다. 여러분이 기여를 원한다는 사실에 매우 기쁩니다!
## 문서에 기여하기
이 저장소에 대한 복제본을 여러분의 GitHub 계정에 생성하기 위해 화면 오른쪽 위 영역에 있는 **Fork** 버튼을 클릭 가능합니다. 이 복제본은 *fork* 라고 부릅니다. 여러분의 fork에서 원하는 임의의 변경 사항을 만들고, 해당 변경 사항을 보낼 준비가 되었다면, 여러분의 fork로 이동하여 새로운 풀 리퀘스트를 만들어 우리에게 알려주시기 바랍니다.
여러분의 풀 리퀘스트가 생성된 이후에는, 쿠버네티스 리뷰어가 명료하고 실행 가능한 피드백을 제공하는 책임을 담당할 것입니다. 풀 리퀘스트의 오너로서, **쿠버네티스 리뷰어로부터 제공받은 피드백을 수용하기 위해 풀 리퀘스트를 수정하는 것은 여러분의 책임입니다.** 또한, 참고로 한 명 이상의 쿠버네티스 리뷰어가 여러분에게 피드백을 제공하는 상황에 처하거나, 또는 여러분에게 피드백을 제공하기로 원래 할당된 사람이 아닌 다른 쿠버네티스 리뷰어로부터 피드백을 받는 상황에 처할 수도 있습니다. 그뿐만 아니라, 몇몇 상황에서는, 필요에 따라 리뷰어 중 한 명이 [쿠버네티스 기술 리뷰어](https://github.com/kubernetes/website/wiki/Tech-reviewers)로부터의 기술 리뷰를 요청할지도 모릅니다. 리뷰어는 제시간에 피드백을 제공하기 위해 최선을 다할 것이지만, 응답 시간은 상황에 따라 달라질 수도 있습니다.
쿠버네티스 문서화에 기여하기와 관련된 보다 자세한 정보는, 다음을 살펴봅니다:
* [기여 시작하기](https://kubernetes.io/docs/contribute/start/)
* [문서화 변경 사항 스테이징하기](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [페이지 템플릿 사용하기](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [문서화 스타일 가이드](http://kubernetes.io/docs/contribute/style/style-guide/)
* [쿠버네티스 문서화 로컬라이징](https://kubernetes.io/docs/contribute/localization/)
## `README.md`에 대한 쿠버네티스 문서화 번역
### 한국어
`README.md` 번역 및 한국어 기여자를 위한 보다 자세한 가이드를 [한국어 README](README-ko.md) 페이지 혹은 [쿠버네티스 문서 한글화 가이드](https://kubernetes.io/ko/docs/contribute/localization_ko/)에서 살펴봅니다.
한국어 번역 메인테이너에게 다음을 통해 연락 가능합니다.
* 이덕준 ([GitHub - @gochist](https://github.com/gochist))
* [Slack channel](https://kubernetes.slack.com/messages/kubernetes-docs-ko)
## 도커를 사용하여 사이트를 로컬에서 실행하기
쿠버네티스 웹사이트를 로컬에서 실행하기 위한 추천하는 방식은 [Hugo](https://gohugo.io) 정적 사이트 생성기를 포함하는 특별한 [도커](https://docker.com) 이미지를 실행하는 것입니다.
> Windows에서 실행하는 경우, [Chocolatey](https://chocolatey.org)로 설치할 수 있는 명명 추가 도구를 필요로 할 것입니다. `choco install make`
> 도커를 사용하지 않고 웹사이트를 로컬에서 실행하기를 선호하는 경우에는, 아래 [Hugo를 사용한 로컬 사이트 실행하기](#hugo를-사용한-로컬-사이트-실행하기)를 살펴봅니다.
도커 [동작 및 실행](https://www.docker.com/get-started) 환경이 있는 경우, 로컬에서 `kubernetes-hugo` 도커 이미지를 빌드 합니다:
```bash
make container-image
```
해당 이미지가 빌드 된 이후, 사이트를 로컬에서 실행할 수 있습니다:
```bash
make container-serve
```
브라우저에서 http://localhost:1313 를 열어 사이트를 살펴봅니다. 소스 파일에 변경 사항이 있을 때, Hugo는 사이트를 업데이트하고 브라우저를 강제로 새로고침합니다.
## Hugo를 사용한 로컬 사이트 실행하기
Hugo 설치 안내를 위해서는 [공식 Hugo 문서화](https://gohugo.io/getting-started/installing/)를 살펴봅니다. [`netlify.toml`](netlify.toml#L9) 파일에 있는 `HUGO_VERSION` 환경 변수에서 지정된 Hugo 버전이 설치되었는지를 확인합니다.
Hugo가 설치되었을 때 로컬에서 사이트를 실행하기 위해 (다음을 실행합니다):
```bash
make serve
```
이를 통해 로컬 Hugo 서버를 1313번 포트에 시작합니다. 브라우저에서 http://localhost:1313 를 열어 사이트를 살펴봅니다. 소스 파일에 변경 사항이 있을 때, Hugo는 사이트를 업데이트하고 브라우저를 강제로 새로고침합니다.
## 감사합니다!
쿠버네티스는 커뮤니티 참여와 함께 생존하며, 우리는 사이트 및 문서화에 대한 여러분의 컨트리뷰션에 대해 정말 감사하게 생각합니다!
-90
View File
@@ -1,90 +0,0 @@
# Dokumentacja projektu Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Witamy!
W tym repozytorium znajdziesz wszystko, czego potrzebujesz do zbudowania [strony internetowej Kubernetesa wraz z dokumentacją](https://kubernetes.io/). Bardzo nam miło, że chcesz wziąć udział w jej współtworzeniu!
## Twój wkład w dokumentację
Możesz kliknąć w przycisk **Fork** w prawym górnym rogu ekranu, aby stworzyć kopię tego repozytorium na swoim koncie GitHub. Taki rodzaj kopii (odgałęzienia) nazywa się *fork*. Zmieniaj w nim, co chcesz, a kiedy będziesz już gotowy/a przesłać te zmiany do nas, przejdź do swojej kopii i stwórz nowy *pull request*, abyśmy zostali o tym poinformowani.
Po stworzeniu *pull request*, jeden z recenzentów projektu Kubernetes podejmie się przekazania jasnych wskazówek pozwalających podjąć następne działania. Na Tobie, jako właścicielu *pull requesta*, **spoczywa odpowiedzialność za wprowadzenie poprawek zgodnie z uwagami recenzenta.** Może też się zdarzyć, że swoje uwagi zgłosi więcej niż jeden recenzent, lub że recenzję będzie robił ktoś inny, niż ten, kto został przydzielony na początku. W niektórych przypadkach, jeśli zajdzie taka potrzeba, recenzent może poprosić dodatkowo o recenzję jednego z [recenzentów technicznych](https://github.com/kubernetes/website/wiki/Tech-reviewers). Recenzenci zrobią wszystko, aby odpowiedzieć sprawnie, ale konkretny czas odpowiedzi zależy od wielu czynników.
Więcej informacji na temat współpracy przy tworzeniu dokumentacji znajdziesz na stronach:
* [Jak rozpocząć współpracę](https://kubernetes.io/docs/contribute/start/)
* [Podgląd wprowadzanych zmian w dokumentacji](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Szablony stron](http://kubernetes.io/docs/contribute/style/page-templates/)
* [Styl pisania dokumentacji](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Lokalizacja dokumentacji Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Różne wersje językowe `README.md`
| | |
|----------------------------------------|----------------------------------------|
| [README po angielsku](README.md) | [README po francusku](README-fr.md) |
| [README po koreańsku](README-ko.md) | [README po niemiecku](README-de.md) |
| [README po portugalsku](README-pt.md) | [README w hindi](README-hi.md) |
| [README po hiszpańsku](README-es.md) | [README po indonezyjsku](README-id.md) |
| [README po chińsku](README-zh.md) | [README po japońsku](README-ja.md) |
| [README po wietnamsku](README-vi.md) | [README po rosyjsku](README-ru.md) |
| [README po włosku](README-it.md) | [README po ukraińsku](README-uk.md) |
| | |
## Jak uruchomić lokalną kopię strony przy pomocy Dockera?
Zalecaną metodą uruchomienia serwisu internetowego Kubernetesa lokalnie jest użycie specjalnego obrazu [Dockera](https://docker.com), który zawiera generator stron statycznych [Hugo](https://gohugo.io).
> Użytkownicy Windows będą potrzebowali dodatkowych narzędzi, które mogą zainstalować przy pomocy [Chocolatey](https://chocolatey.org).
```bash
choco install make
```
> Jeśli wolisz uruchomić serwis lokalnie bez Dockera, przeczytaj [jak uruchomić serwis lokalnie przy pomocy Hugo](#jak-uruchomić-lokalną-kopię-strony-przy-pomocy-hugo) poniżej.
Jeśli [zainstalowałeś i uruchomiłeś](https://www.docker.com/get-started) już Dockera, zbuduj obraz `kubernetes-hugo` lokalnie:
```bash
make container-image
```
Po zbudowaniu obrazu, możesz uruchomić serwis lokalnie:
```bash
make container-serve
```
Aby obejrzeć zawartość serwisu otwórz w przeglądarce adres http://localhost:1313. Po każdej zmianie plików źródłowych, Hugo automatycznie aktualizuje stronę i odświeża jej widok w przeglądarce.
## Jak uruchomić lokalną kopię strony przy pomocy Hugo?
Zajrzyj do [oficjalnej dokumentacji Hugo](https://gohugo.io/getting-started/installing/) po instrukcję instalacji. Upewnij się, że instalujesz rozszerzoną wersję Hugo, określoną przez zmienną środowiskową `HUGO_VERSION` w pliku [`netlify.toml`](netlify.toml#L9).
Aby uruchomić serwis lokalnie po instalacji Hugo, napisz:
```bash
make serve
```
Zostanie uruchomiony lokalny serwer Hugo na porcie 1313. Otwórz w przeglądarce adres http://localhost:1313, aby obejrzeć zawartość serwisu. Po każdej zmianie plików źródłowych, Hugo automatycznie aktualizuje stronę i odświeża jej widok w przeglądarce.
## Społeczność, listy dyskusyjne, uczestnictwo i wsparcie
Zajrzyj na stronę [społeczności](http://kubernetes.io/community/), aby dowiedzieć się, jak możesz zaangażować się w jej działania.
Możesz kontaktować się z gospodarzami projektu za pomocą:
* [Komunikatora Slack](https://kubernetes.slack.com/messages/sig-docs)
* [List dyskusyjnych](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Zasady postępowania
Udział w działaniach społeczności Kubernetes jest regulowany przez [Kodeks postępowania](code-of-conduct.md).
## Dziękujemy!
Kubernetes rozkwita dzięki zaangażowaniu społeczności — doceniamy twój wkład w tworzenie naszego serwisu i dokumentacji!
-76
View File
@@ -1,76 +0,0 @@
# A documentação do Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Bem vindos! Este repositório abriga todos os recursos necessários para criar o [site e documentação do Kubernetes](https://kubernetes.io/). Estamos muito satisfeitos por você querer contribuir!
## Contribuindo com os documentos
Você pode clicar no botão **Fork** na área superior direita da tela para criar uma cópia desse repositório na sua conta do GitHub. Esta cópia é chamada de *fork*. Faça as alterações desejadas no seu fork e, quando estiver pronto para enviar as alterações para nós, vá até o fork e crie uma nova solicitação de pull para nos informar sobre isso.
Depois que seu **pull request** for criado, um revisor do Kubernetes assumirá a responsabilidade de fornecer um feedback claro e objetivo. Como proprietário do pull request, **é sua responsabilidade modificar seu pull request para abordar o feedback que foi fornecido a você pelo revisor do Kubernetes.** Observe também que você pode acabar tendo mais de um revisor do Kubernetes para fornecer seu feedback ou você pode acabar obtendo feedback de um revisor do Kubernetes que é diferente daquele originalmente designado para lhe fornecer feedback. Além disso, em alguns casos, um de seus revisores pode solicitar uma revisão técnica de um [revisor de tecnologia Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers) quando necessário. Os revisores farão o melhor para fornecer feedback em tempo hábil, mas o tempo de resposta pode variar de acordo com as circunstâncias.
Para mais informações sobre como contribuir com a documentação do Kubernetes, consulte:
* [Comece a contribuir](https://kubernetes.io/docs/contribute/start/)
* [Preparando suas alterações na documentação](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Usando Modelos de Página](http://kubernetes.io/docs/contribute/style/page-templates/)
* [Guia de Estilo da Documentação](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Localizando documentação do Kubernetes](https://kubernetes.io/docs/contribute/localization/)
Você pode contactar os mantenedores da localização em Português em:
* Felipe ([GitHub - @femrtnz](https://github.com/femrtnz))
* [Slack channel](https://kubernetes.slack.com/messages/kubernetes-docs-pt)
## Executando o site localmente usando o Docker
A maneira recomendada de executar o site do Kubernetes localmente é executar uma imagem especializada do [Docker](https://docker.com) que inclui o gerador de site estático [Hugo](https://gohugo.io).
> Se você está rodando no Windows, você precisará de mais algumas ferramentas que você pode instalar com o [Chocolatey](https://chocolatey.org). `choco install make`
> Se você preferir executar o site localmente sem o Docker, consulte [Executando o site localmente usando o Hugo](#executando-o-site-localmente-usando-o-hugo) abaixo.
Se você tiver o Docker [em funcionamento](https://www.docker.com/get-started), crie a imagem do Docker do `kubernetes-hugo` localmente:
```bash
make container-image
```
Depois que a imagem foi criada, você pode executar o site localmente:
```bash
make container-serve
```
Abra seu navegador para http://localhost:1313 para visualizar o site. Conforme você faz alterações nos arquivos de origem, Hugo atualiza o site e força a atualização do navegador.
## Executando o site localmente usando o Hugo
Veja a [documentação oficial do Hugo](https://gohugo.io/getting-started/installing/) para instruções de instalação do Hugo. Certifique-se de instalar a versão do Hugo especificada pela variável de ambiente `HUGO_VERSION` no arquivo [`netlify.toml`](netlify.toml#L9).
Para executar o site localmente quando você tiver o Hugo instalado:
```bash
make serve
```
Isso iniciará o servidor Hugo local na porta 1313. Abra o navegador para http://localhost:1313 para visualizar o site. Conforme você faz alterações nos arquivos de origem, Hugo atualiza o site e força a atualização do navegador.
## Comunidade, discussão, contribuição e apoio
Aprenda a se envolver com a comunidade do Kubernetes na [página da comunidade](http://kubernetes.io/community/).
Você pode falar com os mantenedores deste projeto:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Código de conduta
A participação na comunidade Kubernetes é regida pelo [Código de Conduta da Kubernetes](code-of-conduct.md).
## Obrigado!
O Kubernetes conta com a participação da comunidade e nós realmente agradecemos suas contribuições para o nosso site e nossa documentação!
-62
View File
@@ -1,62 +0,0 @@
# Документация по Kubernetes
[![Netlify Status](https://api.netlify.com/api/v1/badges/be93b718-a6df-402a-b4a4-855ba186c97d/deploy-status)](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Добро пожаловать! Данный репозиторий содержит все необходимые файлы для сборки [сайта Kubernetes и документации](https://kubernetes.io/). Мы благодарим вас за старания!
## Запуск сайта с помощью Hugo
Обратитесь к [официальной документации Hugo](https://gohugo.io/getting-started/installing/), чтобы установить Hugo. Убедитесь, что вы установили правильную версию Hugo, которая устанавливается в переменной окружения `HUGO_VERSION` в файле [`netlify.toml`](netlify.toml#L10).
После установки Hugo, чтобы запустить сайт, выполните в консоли:
```bash
git clone https://github.com/kubernetes/website.git
cd website
hugo server --buildFuture
```
Эта команда запустит сервер Hugo на порту 1313. Откройте браузер и перейдите по ссылке http://localhost:1313, чтобы открыть сайт. Если вы отредактируете исходные файлы сайта, Hugo автоматически применит изменения и обновит страницу в браузере.
## Сообщество, обсуждение, вклад и поддержка
Узнайте, как поучаствовать в жизни сообщества Kubernetes на [странице сообщества](http://kubernetes.io/community/).
Вы можете связаться с сопровождающими этого проекта по следующим ссылкам:
- [Канал в Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Рассылка](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
## Вклад в документацию
Нажмите на кнопку **Fork** в правом верхнем углу, чтобы создать копию этого репозитория в ваш GitHub-аккаунт. Эта копия называется *форк-репозиторием*. Делайте любые изменения в вашем форк-репозитории, и когда вы будете готовы опубликовать изменения, откройте форк-репозиторий и создайте новый пулреквест, чтобы уведомить нас.
После того, как вы отправите пулреквест, ревьювер Kubernetes даст по нему обратную связь. Вы, как автор пулреквеста, **должны обновить свой пулреквест после его рассмотрения ревьювером Kubernetes.**
Вполне возможно, что более одного ревьювера Kubernetes оставят свои комментарии или даже может быть так, что новый комментарий ревьювера Kubernetes будет отличаться от первоначального назначенного ревьювера. Кроме того, в некоторых случаях один из ревьюверов может запросить технический обзор у [технического ревьювера Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers), если это будет необходимо. Ревьюверы сделают все возможное, чтобы как можно оперативно оставить свои предложения и пожелания, но время ответа может варьироваться в зависимости от обстоятельств.
Узнать подробнее о том, как поучаствовать в документации Kubernetes, вы можете по ссылкам ниже:
* [Начните вносить свой вклад](https://kubernetes.io/docs/contribute/)
* [Использование шаблонов страниц](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Руководство по оформлению документации](https://kubernetes.io/docs/contribute/style/style-guide/)
* [Руководство по локализации Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Файл `README.md` на других языках
| другие языки | другие языки |
|-------------------------------|-------------------------------|
| [Английский](README.md) | [Французский](README-fr.md) |
| [Корейский](README-ko.md) | [Немецкий](README-de.md) |
| [Португальский](README-pt.md) | [Хинди](README-hi.md) |
| [Испанский](README-es.md) | [Индонезийский](README-id.md) |
| [Китайский](README-zh.md) | [Японский](README-ja.md) |
| [Вьетнамский](README-vi.md) | [Итальянский](README-it.md) |
| [Польский]( README-pl.md) | [Украинский](README-uk.md) |
### Кодекс поведения
Участие в сообществе Kubernetes регулируется [кодексом поведения CNCF](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
## Спасибо!
Kubernetes процветает благодаря сообществу и мы ценим ваш вклад в сайт и документацию!
-85
View File
@@ -1,85 +0,0 @@
<!-- # The Kubernetes documentation -->
# Документація Kubernetes
[![Netlify Status](https://api.netlify.com/api/v1/badges/be93b718-a6df-402a-b4a4-855ba186c97d/deploy-status)](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
<!-- This repository contains the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're glad that you want to contribute! -->
Вітаємо! В цьому репозиторії міститься все необхідне для роботи над [сайтом і документацією Kubernetes](https://kubernetes.io/). Ми щасливі, що ви хочете зробити свій внесок!
<!-- ## Running the website locally using Hugo -->
## Запуск сайту локально зa допомогою Hugo
<!-- See the [official Hugo documentation](https://gohugo.io/getting-started/installing/) for Hugo installation instructions. Make sure to install the Hugo extended version specified by the `HUGO_VERSION` environment variable in the [`netlify.toml`](netlify.toml#L10) file. -->
Для інструкцій з встановлення Hugo дивіться [офіційну документацію](https://gohugo.io/getting-started/installing/). Обов’язково встановіть розширену версію Hugo, яка позначена змінною оточення `HUGO_VERSION` у файлі [`netlify.toml`](netlify.toml#L10).
<!-- To run the website locally when you have Hugo installed: -->
Після встановлення Hugo, запустіть сайт локально командою:
```bash
git clone https://github.com/kubernetes/website.git
cd website
hugo server --buildFuture
```
<!-- This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh. -->
Команда запустить локальний Hugo-сервер на порту 1313. Відкрийте у своєму браузері http://localhost:1313, щоб побачити сайт. По мірі того, як ви змінюєте вихідний код, Hugo актуалізує сайт відповідно до внесених змін і оновлює сторінку у браузері.
<!-- ## Get involved with SIG Docs -->
## Спільнота, обговорення, внесок і підтримка
<!-- Learn more about SIG Docs Kubernetes community and meetings on the [community page](https://github.com/kubernetes/community/tree/master/sig-docs#meetings). -->
Дізнайтеся, як долучитися до спільноти Kubernetes на [сторінці спільноти](http://kubernetes.io/community/).
<!-- You can also reach the maintainers of this project at: -->
Для зв’язку із супроводжуючими проекту скористайтеся:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Поштова розсилка](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
<!-- ## Contributing to the docs -->
## Внесок у документацію
<!-- 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. This copy is 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. -->
Ви можете створити копію цього репозиторія у своєму акаунті на GitHub, натиснувши на кнопку **Fork**, що розташована справа зверху. Ця копія називатиметься *fork* (відгалуження). Зробіть будь-які необхідні зміни у своєму відгалуженні. Коли ви будете готові надіслати їх нам, перейдіть до свого відгалуження і створіть новий pull request, щоб сповістити нас.
<!-- 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.** -->
Після того, як ви створили pull request, рецензент Kubernetes зобов’язується надати вам по ньому чіткий і конструктивний коментар. **Ваш обов’язок як творця pull request - відкоригувати його відповідно до зауважень рецензента Kubernetes.**
<!-- 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 initially assigned to provide you feedback. -->
Також, зауважте: може статися так, що ви отримаєте коментарі від декількох рецензентів Kubernetes або від іншого рецензента, ніж той, якого вам було призначено від початку.
<!-- Furthermore, in some cases, one of your reviewers might ask for a technical review from a Kubernetes tech reviewer when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances. -->
Крім того, за потреби один із ваших рецензентів може запросити технічну перевірку від одного з технічних рецензентів Kubernetes, коли це необхідно. Рецензенти намагатимуться відреагувати вчасно, проте час відповіді може відрізнятися в залежності від обставин.
<!-- For more information about contributing to the Kubernetes documentation, see: -->
Більше інформації про внесок у документацію Kubernetes ви знайдете у наступних джерелах:
* [Внесок: з чого почати](https://kubernetes.io/docs/contribute/)
* [Використання шаблонів сторінок](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Керівництво зі стилю оформлення документації](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Переклад документації Kubernetes іншими мовами](https://kubernetes.io/docs/contribute/localization/)
<!-- ## Localization `README.md`'s -->
## Файл `README.md` іншими мовами
| інші мови | інші мови |
|-------------------------------|-------------------------------|
| [Англійська](README.md) | [Французька](README-fr.md) |
| [Корейська](README-ko.md) | [Німецька](README-de.md) |
| [Португальська](README-pt.md) | [Хінді](README-hi.md) |
| [Іспанська](README-es.md) | [Індонезійська](README-id.md) |
| [Китайська](README-zh.md) | [Японська](README-ja.md) |
| [В'єтнамська](README-vi.md) | [Російська](README-ru.md) |
| [Італійська](README-it.md) | [Польська](README-pl.md) |
<!-- ## Code of conduct -->
## Кодекс поведінки
<!-- Participation in the Kubernetes community is governed by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). -->
Участь у спільноті Kubernetes визначається правилами [Кодексу поведінки СNCF](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
<!-- ## Thank you! -->
## Дякуємо!
<!-- Kubernetes thrives on community participation, and we appreciate your contributions to our website and our documentation! -->
Долучення до спільноти - запорука успішного розвитку Kubernetes. Ми цінуємо ваш внесок у наш сайт і документацію!
-72
View File
@@ -1,72 +0,0 @@
# Tài liệu Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Chào mừng! Kho lưu trữ này chứa tất cả các tài nguyên cần thiết để xây dựng [trang web của Kubernetes và các tài liệu](https://kubernetes.io/). Chúng tôi rất vui vì bạn muốn đóng góp.
## Đóng góp cho tài liệu
Bạn có thể click vào nút **Fork** ở góc trên bên phải màn hình để tạo bản sao của kho lưu trữ này trong tài khoản GitHub của bạn. Bản sao này được gọi là một bản *fork*. Thực hiện bất kì thay đổi nào mà bạn muốn trong bản fork của bạn và khi bạn sẵn sang gửi những thay đổi đó cho chúng tôi, hãy đến bản fork của bạn và tạo một Pull Request mới để cho chúng tôi biết về nó.
Một khi Pull Request của bạn được tạo, reviewer sẽ chịu trách nhiệm cung cấp các phản hồi rõ ràng, có thể thực hiện được. Là chủ sở hữu của pull request, **bạn có trách nhiệm sửa đổi Pull Request của mình để giải quyết các phản hồi bởi reviewer.** Ngoài ra, lưu ý rằng bạn có thể có nhiều hơn một reviewer cung cấp cho bạn các phản hồi hoặc bạn có thể nhận được phản hồi từ reviewer khác với reviewer ban đầu được chỉ định. Hơn nữa, trong một số trường hợp, một trong những reviewer của bạn có thể yêu cầu đánh giá kỹ thuật từ [Kubernetes tech reviewer](https://github.com/kubernetes/website/wiki/Tech-reviewers) khi cần. Các reviewers sẽ cố gắng hết sức để cung cấp phản hồi một cách kịp thời nhưng thời gian phản hồi có thể thay đổi tùy theo hoàn cảnh.
Để biết thêm thông tin về việc đóng góp cho tài liệu Kubernetes, hãy xem:
* [Bắt đầu đóng góp](https://kubernetes.io/docs/contribute/start/)
* [Các giai đoạn thay đổi tài liệu](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Sử dụng các trang templates](http://kubernetes.io/docs/contribute/style/page-templates/)
* [Hướng dẫn biểu mẫu tài liệu](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Địa phương hóa tài liệu Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Chạy website cục bộ dùng Docker
Cách được đề xuất để chạy trang web Kubernetes cục bộ là dùng [Docker](https://docker.com) image chứa trình tạo web tĩnh [Hugo](https://gohugo.io).
> Nếu bạn làm việc trên môi trường Windows, bạn sẽ cần thêm môt vài công cụ mà bạn có thể cài đặt với [Chocolatey](https://chocolatey.org). `choco install make`
> Nếu bạn không muốn dùng Docker để chạy trang web cục bộ, hãy xem [Chạy website cục bộ dùng Hugo](#chạy-website-cục-bộ-dùng-hugo) dưới đây.
Nếu bạn có Docker đang [up và running](https://www.docker.com/get-started), build `kubernetes-hugo` Docker image cục bộ:
```bash
make container-image
```
Khi image đã được built, bạn có thể chạy website cục bộ:
```bash
make container-serve
```
Mở trình duyệt và đến địa chỉ http://localhost:1313 để xem website. Khi bạn thay đổi các file nguồn, Hugo cập nhật website và buộc làm mới trình duyệt.
## Chạy website cục bộ dùng Hugo
Hãy xem [tài liệu chính thức của Hugo](https://gohugo.io/getting-started/installing/) cho việc hướng dẫn cài đặt Hugo. Đảm bảo cài đặt phiên bản mở rộng của Hugo được xác định bởi biến môi trường `HUGO_VERSION` trong file [`netlify.toml`](netlify.toml#L9)
Để chạy website cục bộ khi Hugo được cài đặt:
```bash
make serve
```
Câu lệnh trên sẽ khởi động server Hugo cục bộ trên cổng 1313. Mở trình duyệt và đến địa chỉ http://localhost:1313 để xem website. Khi bạn thay đổi các file nguồn, Hugo cập nhật website và buộc làm mới trình duyệt.
## Cộng đồng, thảo luận, đóng góp và hỗ trợ
Tìm hiểu cách tham gia với cộng đồng Kubernetes trên [trang cộng đồng](http://kubernetes.io/community/).
Bạn có thể tiếp cận những maintainers của dự án này tại:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
### Quy tắc ứng xử
Sự tham gia vào cộng đồng Kubernetes được điểu chỉnh bởi [Kubernetes Code of Conduct](code-of-conduct.md).
## Cảm ơn!
Kubernetes phát triển mạnh mẽ về sự tham gia của cộng đồng và chúng tôi đánh giá cao những đóng góp của bạn cho trang web và tài liệu của chúng tôi!
-160
View File
@@ -1,160 +0,0 @@
# Kubernetes 文档
<!--
# The Kubernetes documentation
-->
[![Netlify Status](https://api.netlify.com/api/v1/badges/be93b718-a6df-402a-b4a4-855ba186c97d/deploy-status)](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
<!--
This repository contains the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're glad that you want to contribute!
-->
本仓库包含了所有用于构建 [Kubernetes 网站和文档](https://kubernetes.io/) 的软件资产。
我们非常高兴您想要参与贡献!
<!--
## Running the website locally using Hugo
See the [official Hugo documentation](https://gohugo.io/getting-started/installing/) for Hugo installation instructions. Make sure to install the Hugo extended version specified by the `HUGO_VERSION` environment variable in the [`netlify.toml`](netlify.toml#L10) file.
-->
## 在本地使用 Hugo 来运行网站
请参考 [Hugo 的官方文档](https://gohugo.io/getting-started/installing/)了解 Hugo 的安装指令。
请确保安装的是 [`netlify.toml`](netlify.toml#L10) 文件中环境变量 `HUGO_VERSION` 所指定的
Hugo 扩展版本。
<!--
Before building the site, clone the Kubernetes website repository:
-->
在构造网站之前,先克隆 Kubernetes website 仓库:
```bash
git clone https://github.com/kubernetes/website.git
cd website
git submodule update --init --recursive
```
<!--
**Note:** The Kubernetes website deploys the [Docsy Hugo theme](https://github.com/google/docsy#readme).
If you have not updated your website repository, the `website/themes/docsy` directory is empty.
The site cannot build without a local copy of the theme.
Update the website theme:
-->
**注意:** Kubernetes 网站要部署 [Docsy Hugo 主题](https://github.com/google/docsy#readme).
如果你还没有更新你本地的 website 仓库,目录 `website/themes/docsy`
会是空目录。
在本地没有主题副本的情况下,网站无法正常构造。
使用下面的命令更新网站主题:
```bash
git submodule update --init --recursive --depth 1
```
<!--
To build and test the site locally, run:
-->
若要在本地构造和测试网站,请运行:
```bash
hugo server --buildFuture
```
<!--
This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
-->
上述命令会在端口 1313 上启动本地 Hugo 服务器。
启动浏览器,打开 http://localhost:1313 来查看网站。
当你对源文件作出修改时,Hugo 会更新网站并强制浏览器执行刷新操作。
<!--
## Get involved with SIG Docs
Learn more about SIG Docs Kubernetes community and meetings on the [community page](https://github.com/kubernetes/community/tree/master/sig-docs#meetings).
You can also reach the maintainers of this project at:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
-->
## 参与 SIG Docs 工作
通过 [社区页面](https://github.com/kubernetes/community/tree/master/sig-docs#meetings)
进一步了解 SIG Docs Kubernetes 社区和会议信息。
你也可以通过以下渠道联系本项目的维护人员:
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
- [邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
<!--
## Contributing to the docs
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. This copy is 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.**
-->
## 为文档做贡献
你也可以点击屏幕右上方区域的 **Fork** 按钮,在你自己的 GitHub
账号下创建本仓库的拷贝。此拷贝被称作 *fork*
你可以在自己的拷贝中任意地修改文档,并在你已准备好将所作修改提交给我们时,
在你自己的拷贝下创建一个拉取请求(Pull Request),以便让我们知道。
一旦你创建了拉取请求,某个 Kubernetes 评审人会负责提供明确的、可执行的反馈意见。
作为拉取请求的拥有者,*修改拉取请求以解决 Kubernetes
评审人所提出的反馈是你的责任*。
<!--
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 initially assigned to provide you feedback.
Furthermore, in some cases, one of your reviewers might ask for a technical review from a Kubernetes tech reviewer when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances.
-->
还要提醒的一点,有时可能会有不止一个 Kubernetes 评审人为你提供反馈意见。
有时候,某个评审人的意见和另一个最初被指派的评审人的意见不同。
更进一步,在某些时候,评审人之一可能会在需要的时候请求 Kubernetes
技术评审人来执行技术评审。
评审人会尽力及时地提供反馈意见,不过具体的响应时间可能会因时而异。
<!--
For more information about contributing to the Kubernetes documentation, see:
* [Contribute to Kubernetes docs](https://kubernetes.io/docs/contribute/)
* [Page Content Types](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Documentation Style Guide](https://kubernetes.io/docs/contribute/style/style-guide/)
* [Localizing Kubernetes Documentation](https://kubernetes.io/docs/contribute/localization/)
-->
有关为 Kubernetes 文档做出贡献的更多信息,请参阅:
* [贡献 Kubernetes 文档](https://kubernetes.io/docs/contribute/)
* [页面内容类型](http://kubernetes.io/docs/contribute/style/page-content-types/)
* [文档风格指南](http://kubernetes.io/docs/contribute/style/style-guide/)
* [本地化 Kubernetes 文档](https://kubernetes.io/docs/contribute/localization/)
## 中文本地化
可以通过以下方式联系中文本地化的维护人员:
* Rui Chen ([GitHub - @chenrui333](https://github.com/chenrui333))
* He Xiaolong ([GitHub - @markthink](https://github.com/markthink))
* [Slack channel](https://kubernetes.slack.com/messages/kubernetes-docs-zh)
<!--
### Code of conduct
Participation in the Kubernetes community is governed by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
-->
### 行为准则
参与 Kubernetes 社区受 [CNCF 行为准则](https://github.com/cncf/foundation/blob/master/code-of-conduct.md)约束。
<!--
## Thank you!
Kubernetes thrives on community participation, and we appreciate your contributions to our website and our documentation!
-->
## 感谢!
Kubernetes 因为社区的参与而蓬勃发展,感谢您对我们网站和文档的贡献!
+41 -133
View File
@@ -1,145 +1,53 @@
# The Kubernetes documentation
## Instructions for Contributing to the Kubernetes Documentation
[![Netlify Status](https://api.netlify.com/api/v1/badges/be93b718-a6df-402a-b4a4-855ba186c97d/deploy-status)](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Welcome! We are very pleased you want to contribute to the Kubernetes documentation.
This repository contains the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're glad that you want to contribute!
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.
# Using this repository
You can run the website locally using Hugo (Extended version), or you can run it in a container runtime. We strongly recommend using the container runtime, as it gives deployment consistency with the live website.
## Prerequisites
To use this repository, you need the following installed locally:
- [npm](https://www.npmjs.com/)
- [Go](https://golang.org/)
- [Hugo (Extended version)](https://gohugo.io/)
- A container runtime, like [Docker](https://www.docker.com/).
Before you start, install the dependencies. Clone the repository and navigate to the directory:
```
git clone https://github.com/kubernetes/website.git
cd website
```
The Kubernetes website uses the [Docsy Hugo theme](https://github.com/google/docsy#readme). Even if you plan to run the website in a container, we strongly recommend pulling in the submodule and other development dependencies by running the following:
```
# pull in the Docsy submodule
git submodule update --init --recursive --depth 1
```
## Running the website using a container
To build the site in a container, run the following to build the container image and run it:
```
make container-image
make container-serve
```
Open up your browser to http://localhost:1313 to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
## Running the website locally using Hugo
Make sure to install the Hugo extended version specified by the `HUGO_VERSION` environment variable in the [`netlify.toml`](netlify.toml#L10) file.
To build and test the site locally, run:
```bash
# install dependencies
npm ci
make serve
```
This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
## Troubleshooting
### error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version
Hugo is shipped in two set of binaries for technical reasons. The current website runs based on the **Hugo Extended** version only. In the [release page](https://github.com/gohugoio/hugo/releases) look for archives with `extended` in the name. To confirm, run `hugo version` and look for the word `extended`.
### Troubleshooting macOS for too many open files
If you run `make serve` on macOS and receive the following error:
```
ERROR 2020/08/01 19:09:18 Error: listen tcp 127.0.0.1:1313: socket: too many open files
make: *** [serve] Error 1
```
Try checking the current limit for open files:
`launchctl limit maxfiles`
Then run the following commands (adapted from https://gist.github.com/tombigel/d503800a282fcadbee14b537735d202c):
```
#!/bin/sh
# These are the original gist links, linking to my gists now.
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxfiles.plist
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxproc.plist
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxfiles.plist
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxproc.plist
sudo mv limit.maxfiles.plist /Library/LaunchDaemons
sudo mv limit.maxproc.plist /Library/LaunchDaemons
sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
sudo chown root:wheel /Library/LaunchDaemons/limit.maxproc.plist
sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
```
This works for Catalina as well as Mojave macOS.
# Get involved with SIG Docs
Learn more about SIG Docs Kubernetes community and meetings on the [community page](https://github.com/kubernetes/community/tree/master/sig-docs#meetings).
You can also reach the maintainers of this project at:
- [Slack](https://kubernetes.slack.com/messages/sig-docs) [Get an invite for this Slack](https://slack.k8s.io/)
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
# Contributing to the docs
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. This copy is 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 initially assigned to provide you feedback.
Furthermore, in some cases, one of your reviewers might ask for a technical review from a Kubernetes tech reviewer when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances.
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:
* [Contribute to Kubernetes docs](https://kubernetes.io/docs/contribute/)
* [Page Content Types](https://kubernetes.io/docs/contribute/style/page-content-types/)
* [Documentation Style Guide](https://kubernetes.io/docs/contribute/style/style-guide/)
* [Localizing Kubernetes Documentation](https://kubernetes.io/docs/contribute/localization/)
* [Contributing to the Kubernetes Documentation](http://kubernetes.io/editdocs/)
* [Creating a Documentation Pull Request](http://kubernetes.io/docs/home/contribute/create-pull-request/)
* [Writing a New Topic](http://kubernetes.io/docs/home/contribute/write-new-topic/)
* [Review Issues](http://kubernetes.io/docs/home/contribute/review-issues/)
* [Staging Your Documentation Changes](http://kubernetes.io/docs/home/contribute/stage-documentation-changes/)
* [Using Page Templates](http://kubernetes.io/docs/home/contribute/page-templates/)
* [Documentation Style Guide](http://kubernetes.io/docs/home/contribute/style-guide/)
# Localization `README.md`'s
## Building the site using Docker
| Language | Language |
|---|---|
|[Chinese](README-zh.md)|[Korean](README-ko.md)|
|[French](README-fr.md)|[Polish](README-pl.md)|
|[German](README-de.md)|[Portuguese](README-pt.md)|
|[Hindi](README-hi.md)|[Russian](README-ru.md)|
|[Indonesian](README-id.md)|[Spanish](README-es.md)|
|[Italian](README-it.md)|[Ukrainian](README-uk.md)|
|[Japanese](README-ja.md)|[Vietnamese](README-vi.md)|
If you'd like, you can build the Kubernetes docs using Docker. To get started, build the image locally:
# Code of conduct
```bash
$ make docker-image
Participation in the Kubernetes community is governed by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
# The underlying command:
$ docker build . \
--tag kubernetes-hugo \
--build-arg HUGO_VERSION=0.40.3
```
# Thank you!
You can create an image for a different version of Hugo by changing the value of the `HUGO_VERSION` argument for the build. You *must* specify a version or the image will not build.
Once the `kubernetes-hugo` image has been built locally, you can build the site:
Kubernetes thrives on community participation, and we appreciate your contributions to our website and our documentation!
```bash
$ make docker-serve
# The underlying command:
$ docker run \
--rm \
--interactive \
--tty \
--volume $(PWD):/src \
kubernetes-hugo:latest \
hugo
```
As when building without using a Docker container, the results of the build will be published to the `public` directory (the default output directory for [Hugo](https://gohugo.io), the static site generator used to build this site).
## Thank you!
Kubernetes thrives on community participation, and we really appreciate your
contributions to our site and our documentation!
-22
View File
@@ -1,22 +0,0 @@
# Security Policy
## Security Announcements
Join the [kubernetes-security-announce] group for security and vulnerability announcements.
You can also subscribe to an RSS feed of the above using [this link][kubernetes-security-announce-rss].
## Reporting a Vulnerability
Instructions for reporting a vulnerability can be found on the
[Kubernetes Security and Disclosure Information] page.
## Supported Versions
Information about supported Kubernetes versions can be found on the
[Kubernetes version and version skew support policy] page on the Kubernetes website.
[kubernetes-security-announce]: https://groups.google.com/forum/#!forum/kubernetes-security-announce
[kubernetes-security-announce-rss]: https://groups.google.com/forum/feed/kubernetes-security-announce/msgs/rss_v2_0.xml?num=50
[Kubernetes version and version skew support policy]: https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions
[Kubernetes Security and Disclosure Information]: https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability
+5 -6
View File
@@ -1,16 +1,15 @@
# Defined below are the security contacts for this repo.
#
# They are the contact point for the Product Security Committee to reach out
# They are the contact point for the Product Security Team to reach out
# to for triaging and handling of incoming issues.
#
# The below names agree to abide by the
# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)
# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
# and will be removed and replaced if they violate that agreement.
#
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
# INSTRUCTIONS AT https://kubernetes.io/security/
irvifa
jimangel
kbarnard10
sftim
chenopis
jaredbhatti
zacharysarah
-12
View File
@@ -1,12 +0,0 @@
---
title: "{{ replace .Name "-" " " | title }}"
content_type: concept
---
<!-- overview -->
<!-- body -->
<!-- Optional section; add links to information related to this topic. -->
## {{% heading "whatsnext" %}}
-21
View File
@@ -1,21 +0,0 @@
---
title: "{{ replace .Name "-" " " | title }}"
content_type: task
---
<!-- overview -->
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}}
<!-- If you set the min-kubernetes-server-version parameter in the page's front matter,
add the version check shortcode {{< version-check >}}.
-->
<!-- steps -->
<!-- discussion -->
<!-- Optional section; add links to information related to this topic. -->
## {{% heading "whatsnext" %}}
-19
View File
@@ -1,19 +0,0 @@
---
title: "{{ replace .Name "-" " " | title }}"
content_type: tutorial
---
<!-- overview -->
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}}
## {{% heading "objectives" %}}
<!-- lessoncontent -->
## {{% heading "cleanup" %}}
<!-- Optional section; add links to information related to this topic. -->
## {{% heading "whatsnext" %}}
-110
View File
@@ -1,110 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 503.1 89.5" style="enable-background:new 0 0 503.1 89.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;stroke:#FFFFFF;stroke-width:5;stroke-miterlimit:10;}
.st1{fill:#326DE6;}
.st2{fill:#FFFFFF;}
</style>
<title>Kubernetes_Logo_Hrz_lockup_REV</title>
<g id="Layer_2">
<g id="Layer_1-2">
<path class="st0" d="M82.3,21.3c-0.5-1.6-1.7-2.9-3.2-3.7L48.6,3c-0.8-0.4-1.7-0.5-2.5-0.5c-0.8,0-1.7,0-2.5,0.2L13.1,17.4
c-1.5,0.7-2.6,2-3,3.7L2.6,54c-0.3,1.7,0.1,3.4,1.1,4.8l21.1,26.1c1.2,1.2,2.9,2,4.6,2.1H63c1.8,0.2,3.5-0.6,4.6-2.1l21.1-26.1
c1-1.4,1.4-3.1,1.2-4.8L82.3,21.3z"/>
<path class="st1" d="M82.3,21.3c-0.5-1.6-1.7-2.9-3.2-3.7L48.6,3c-0.8-0.4-1.7-0.5-2.5-0.5c-0.8,0-1.7,0-2.5,0.2L13.1,17.4
c-1.5,0.7-2.6,2-3,3.7L2.6,54c-0.3,1.7,0.1,3.4,1.1,4.8l21.1,26.1c1.2,1.2,2.9,2,4.6,2.1H63c1.8,0.2,3.5-0.6,4.6-2.1l21.1-26.1
c1-1.4,1.4-3.1,1.2-4.8L82.3,21.3z"/>
<path class="st2" d="M77.6,52.7L77.6,52.7c-0.1,0-0.2,0-0.2-0.1s-0.2-0.1-0.4-0.1c-0.4-0.1-0.8-0.1-1.2-0.1c-0.2,0-0.4,0-0.6-0.1
h-0.1c-1.1-0.1-2.3-0.3-3.4-0.6c-0.3-0.1-0.6-0.4-0.7-0.7C71.1,51,71,51,71,51l0,0l-0.8-0.2c0.4-2.9,0.2-5.9-0.4-8.8
c-0.7-2.9-1.9-5.7-3.5-8.2l0.6-0.6l0,0v-0.1c0-0.3,0.1-0.7,0.3-0.9c0.9-0.8,1.8-1.4,2.8-2l0,0c0.2-0.1,0.4-0.2,0.6-0.3
c0.4-0.2,0.7-0.4,1.1-0.6c0.1-0.1,0.2-0.1,0.3-0.2S72,29,72,28.9l0,0c0.9-0.7,1.1-1.9,0.4-2.8c-0.3-0.4-0.9-0.7-1.4-0.7
c-0.5,0-1,0.2-1.4,0.5l0,0l-0.1,0.1c-0.1,0.1-0.2,0.2-0.3,0.2c-0.3,0.3-0.6,0.6-0.8,0.9c-0.1,0.2-0.3,0.3-0.4,0.4l0,0
c-0.7,0.8-1.6,1.6-2.5,2.2c-0.2,0.1-0.4,0.2-0.6,0.2c-0.1,0-0.3,0-0.4-0.1h-0.1l-0.8,0.5c-0.8-0.8-1.7-1.6-2.5-2.4
c-3.7-2.9-8.3-4.7-13-5.2l-0.1-0.8l0,0L48,22c-0.3-0.2-0.4-0.5-0.5-0.8c0-1.1,0-2.2,0.2-3.4v-0.1c0-0.2,0.1-0.4,0.1-0.6
c0.1-0.4,0.1-0.8,0.2-1.2v-0.6l0,0c0.1-1-0.7-2-1.7-2.1c-0.6-0.1-1.2,0.2-1.7,0.7c-0.4,0.4-0.6,0.9-0.6,1.4l0,0v0.5
c0,0.4,0.1,0.8,0.2,1.2c0.1,0.2,0.1,0.4,0.1,0.6v0.1c0.2,1.1,0.2,2.2,0.2,3.4c-0.1,0.3-0.2,0.6-0.5,0.8L44,22.1l0,0l-0.1,0.8
c-1.1,0.1-2.2,0.3-3.4,0.5c-4.7,1-9,3.5-12.3,7L27.6,30h-0.1c-0.1,0-0.2,0.1-0.4,0.1c-0.2,0-0.4-0.1-0.6-0.2
c-0.9-0.7-1.8-1.5-2.5-2.3l0,0c-0.1-0.2-0.3-0.3-0.4-0.4c-0.3-0.3-0.5-0.6-0.8-0.9c-0.1-0.1-0.2-0.1-0.3-0.2s-0.1-0.1-0.1-0.1l0,0
c-0.4-0.3-0.9-0.5-1.4-0.5c-0.6,0-1.1,0.2-1.4,0.7c-0.6,0.9-0.4,2.1,0.4,2.8l0,0c0.1,0,0.1,0.1,0.1,0.1s0.2,0.2,0.3,0.2
c0.3,0.2,0.7,0.4,1.1,0.6c0.2,0.1,0.4,0.2,0.6,0.3l0,0c1,0.6,2,1.2,2.8,2c0.2,0.2,0.4,0.6,0.3,0.9V33l0,0l0.6,0.6
c-0.1,0.2-0.2,0.3-0.3,0.5C22.4,39,21.1,44.8,22,50.5l-0.8,0.2l0,0c0,0.1-0.1,0.1-0.1,0.1c-0.1,0.3-0.4,0.5-0.7,0.7
c-1.1,0.3-2.2,0.5-3.4,0.6H17c-0.2,0-0.4,0-0.6,0.1c-0.4,0-0.8,0.1-1.2,0.1c-0.1,0-0.2,0.1-0.4,0.1c-0.1,0-0.1,0-0.2,0.1l0,0
c-1.1,0.2-1.8,1.2-1.6,2.3c0,0,0,0,0,0c0.2,0.9,1.1,1.5,2,1.4c0.2,0,0.3,0,0.5-0.1l0,0c0.1,0,0.1,0,0.1-0.1S15.9,56,16,56
c0.4-0.1,0.8-0.3,1.1-0.4c0.2-0.1,0.4-0.2,0.6-0.2h0.1c1.1-0.4,2.1-0.7,3.3-0.9h0.1c0.3,0,0.6,0.1,0.8,0.3c0.1,0,0.1,0.1,0.1,0.1
l0,0l0.9-0.1c1.5,4.6,4.3,8.7,8.2,11.7c0.9,0.7,1.7,1.3,2.7,1.8L33.4,69l0,0c0,0.1,0.1,0.1,0.1,0.1c0.2,0.3,0.2,0.7,0.1,1
c-0.4,1-1,2-1.6,2.9v0.1c-0.1,0.2-0.2,0.3-0.4,0.5s-0.4,0.6-0.7,1c-0.1,0.1-0.1,0.2-0.2,0.3c0,0,0,0.1-0.1,0.1l0,0
c-0.5,1-0.1,2.2,0.8,2.7c0.2,0.1,0.5,0.2,0.7,0.2c0.8,0,1.5-0.5,1.9-1.2l0,0c0,0,0-0.1,0.1-0.1c0-0.1,0.1-0.2,0.2-0.3
c0.1-0.4,0.3-0.7,0.4-1.1l0.2-0.6l0,0c0.3-1.1,0.8-2.1,1.3-3.1c0.2-0.3,0.5-0.5,0.8-0.6c0.1,0,0.1,0,0.1-0.1l0,0l0.4-0.8
c2.8,1.1,5.7,1.6,8.7,1.6c1.8,0,3.6-0.2,5.4-0.7c1.1-0.2,2.2-0.6,3.2-0.9l0.4,0.7l0,0c0.1,0,0.1,0,0.1,0.1
c0.3,0.1,0.6,0.3,0.8,0.6c0.5,1,1,2,1.3,3.1v0.1l0.2,0.6c0.1,0.4,0.2,0.8,0.4,1.1c0.1,0.1,0.1,0.2,0.2,0.3c0,0,0,0.1,0.1,0.1l0,0
c0.4,0.7,1.1,1.2,1.9,1.2c0.3,0,0.5-0.1,0.8-0.2c0.4-0.2,0.8-0.6,0.9-1.1c0.1-0.5,0.1-1-0.1-1.5l0,0c0-0.1-0.1-0.1-0.1-0.1
c0-0.1-0.1-0.2-0.2-0.3c-0.2-0.4-0.4-0.7-0.7-1c-0.1-0.2-0.2-0.3-0.4-0.5V73c-0.7-0.9-1.2-1.9-1.6-2.9c-0.1-0.3-0.1-0.7,0.1-1
c0-0.1,0.1-0.1,0.1-0.1l0,0l-0.3-0.8c5.1-3.1,9-7.9,10.8-13.6l0.8,0.1l0,0c0.1,0,0.1-0.1,0.1-0.1c0.2-0.2,0.5-0.3,0.8-0.3h0.1
c1.1,0.2,2.2,0.5,3.2,0.9h0.1c0.2,0.1,0.4,0.2,0.6,0.2c0.4,0.2,0.7,0.4,1.1,0.5c0.1,0,0.2,0.1,0.4,0.1c0.1,0,0.1,0,0.2,0.1l0,0
c0.2,0.1,0.3,0.1,0.5,0.1c0.9,0,1.7-0.6,2-1.4C79.3,53.7,78.5,52.9,77.6,52.7z M48.7,49.6L46,50.9l-2.7-1.3l-0.7-2.9l1.9-2.4h3
l1.9,2.4L48.7,49.6z M65,43.1c0.5,2.1,0.6,4.2,0.4,6.3l-9.5-2.7l0,0c-0.9-0.2-1.4-1.1-1.2-2c0.1-0.3,0.2-0.5,0.4-0.7l7.5-6.8
C63.7,39,64.5,41,65,43.1z M59.6,33.5l-8.2,5.8c-0.7,0.4-1.7,0.3-2.2-0.4c-0.2-0.2-0.3-0.4-0.3-0.7l-0.6-10.1
C52.7,28.6,56.6,30.5,59.6,33.5L59.6,33.5z M41.5,28.4l2-0.4L43,38l0,0c0,0.9-0.8,1.6-1.7,1.6c-0.3,0-0.5-0.1-0.8-0.2l-8.3-5.9
C34.8,31,38,29.2,41.5,28.4z M29.3,37.2l7.4,6.6l0,0c0.7,0.6,0.8,1.6,0.2,2.3c-0.2,0.3-0.4,0.4-0.8,0.5l-9.7,2.8
C26.1,45.2,27.1,40.9,29.3,37.2z M27.6,54.1l9.9-1.7c0.8,0,1.6,0.5,1.7,1.3c0.1,0.3,0.1,0.7-0.1,1l0,0l-3.8,9.2
C31.8,61.6,29,58.1,27.6,54.1z M50.3,66.5C48.9,66.8,47.5,67,46,67c-2.1,0-4.3-0.4-6.3-1l4.9-8.9c0.5-0.6,1.3-0.8,2-0.4
c0.3,0.2,0.5,0.4,0.8,0.7l0,0l4.8,8.7C51.6,66.2,51,66.3,50.3,66.5z M62.5,57.8c-1.5,2.4-3.6,4.5-6,6l-3.9-9.4
c-0.2-0.8,0.2-1.6,0.9-1.9c0.3-0.1,0.6-0.2,0.9-0.2l10,1.7C63.9,55.4,63.3,56.7,62.5,57.8z"/>
<g id="layer1">
<g id="text4373">
<path id="path2985" class="st2" d="M128.1,48.4c1.1-1.2,2.1-2.4,3.3-3.6c1.1-1.3,2.2-2.5,3.3-3.7c1.1-1.3,2.1-2.4,3-3.5
s1.8-2.1,2.5-2.9H153c-2.6,2.9-5.1,5.8-7.5,8.5c-2.5,2.7-5.1,5.5-8,8.3c1.6,1.5,3.1,3,4.5,4.7c1.5,1.8,3,3.6,4.5,5.6
c1.4,1.9,2.8,3.9,4,5.8c1.2,1.9,2.2,3.7,3,5.3h-12.4c-0.8-1.3-1.7-2.6-2.7-4.1s-2.1-3-3.1-4.6c-1.1-1.5-2.3-3-3.6-4.4
c-1.1-1.3-2.3-2.5-3.6-3.5v16.7h-10.8V18.2l10.8-1.7L128.1,48.4"/>
<path id="path2987" class="st2" d="M191.1,71.4c-2.3,0.6-4.7,1.1-7.1,1.4c-3,0.5-6.1,0.7-9.1,0.7c-2.8,0.1-5.5-0.4-8.1-1.3
c-2-0.8-3.7-2-5.1-3.6c-1.3-1.7-2.2-3.6-2.7-5.7c-0.6-2.3-0.8-4.8-0.8-7.2V34.6H169v19.9c0,3.5,0.5,6,1.4,7.5s2.6,2.3,5.1,2.3
c0.8,0,1.6,0,2.5-0.1s1.6-0.1,2.3-0.3V34.6h10.8L191.1,71.4"/>
<path id="path2989" class="st2" d="M225.7,53.4c0-7-2.6-10.4-7.7-10.4c-1.1,0-2.2,0.1-3.3,0.4c-0.9,0.2-1.8,0.6-2.6,1.1v19.6
c0.5,0.1,1.2,0.2,2,0.3c0.8,0.1,1.7,0.1,2.7,0.1c2.6,0.2,5.1-0.9,6.7-3C225,59.1,225.8,56.3,225.7,53.4 M236.7,53.8
c0,2.8-0.4,5.6-1.4,8.3c-0.8,2.4-2.1,4.5-3.8,6.3c-1.8,1.8-3.9,3.2-6.2,4.1c-2.7,1-5.5,1.4-8.4,1.4c-1.3,0-2.7-0.1-4.1-0.2
c-1.4-0.1-2.8-0.3-4.2-0.4c-1.3-0.2-2.6-0.4-3.9-0.7c-1.3-0.2-2.4-0.5-3.3-0.9V18.2l10.8-1.7v19c1.2-0.5,2.5-0.9,3.8-1.2
c1.4-0.3,2.8-0.4,4.2-0.4c2.5,0,4.9,0.4,7.2,1.5c2,0.9,3.8,2.3,5.2,4c1.5,1.9,2.6,4,3.2,6.3C236.4,48.2,236.7,51,236.7,53.8"/>
<path id="path2991" class="st2" d="M243.2,54c-0.1-3,0.5-6,1.5-8.8c0.9-2.4,2.3-4.5,4.1-6.4c1.7-1.7,3.6-3,5.8-3.8
c2.2-0.9,4.5-1.3,6.8-1.3c5.4,0,9.7,1.7,12.8,5c3.1,3.3,4.7,8.2,4.7,14.5c0,0.6,0,1.3-0.1,2.1s-0.1,1.4-0.1,2h-24.5
c0.2,2.1,1.3,4.1,3.1,5.3c2.2,1.4,4.8,2.1,7.4,2c1.9,0,3.9-0.2,5.8-0.5c1.6-0.3,3.2-0.8,4.7-1.4l1.5,8.8
c-0.7,0.4-1.5,0.6-2.3,0.9c-1.1,0.3-2.2,0.6-3.3,0.7c-1.2,0.2-2.4,0.4-3.8,0.6c-1.3,0.1-2.7,0.2-4.1,0.2c-3.1,0.1-6.1-0.4-9-1.5
c-2.4-0.9-4.5-2.3-6.3-4.1c-1.7-1.8-2.9-4-3.7-6.3C243.6,59.3,243.2,56.7,243.2,54 M268.6,49.9c0-0.9-0.2-1.8-0.5-2.7
c-0.2-0.9-0.7-1.6-1.2-2.3c-0.6-0.7-1.3-1.3-2.1-1.7c-1-0.5-2-0.7-3.1-0.7c-1.1,0-2.1,0.2-3.1,0.7c-0.8,0.4-1.6,0.9-2.2,1.6
c-0.6,0.7-1.1,1.5-1.4,2.4c-0.3,0.9-0.5,1.8-0.6,2.7L268.6,49.9"/>
<path id="path2993" class="st2" d="M310.3,44.2c-1-0.2-2.1-0.5-3.4-0.7c-1.4-0.3-2.8-0.4-4.2-0.4c-0.8,0-1.6,0.1-2.5,0.2
c-0.7,0.1-1.4,0.2-2.1,0.4v29.1h-10.8V36.6c2.2-0.8,4.5-1.4,6.8-1.9c2.9-0.7,5.9-1,8.8-0.9c0.7,0,1.4,0.1,2.1,0.1
c0.8,0,1.6,0.1,2.5,0.3c0.8,0.1,1.6,0.2,2.5,0.4c0.7,0.1,1.4,0.3,2.1,0.6L310.3,44.2"/>
<path id="path2995" class="st2" d="M317.9,35.9c2.3-0.6,4.7-1.1,7.1-1.5c3-0.5,6.1-0.7,9.1-0.7c2.7-0.1,5.4,0.4,8,1.3
c2,0.7,3.8,1.9,5.1,3.5c1.3,1.6,2.2,3.5,2.7,5.5c0.6,2.3,0.8,4.7,0.8,7.1v21.5H340V52.5c0-3.5-0.5-5.9-1.4-7.4
c-0.9-1.4-2.6-2.2-5.1-2.2c-0.8,0-1.6,0-2.5,0.1c-0.9,0-1.6,0.1-2.3,0.2v29.4h-10.8L317.9,35.9"/>
<path id="path2997" class="st2" d="M358.9,54c-0.1-3,0.5-6,1.5-8.8c0.9-2.4,2.3-4.5,4.1-6.4c1.7-1.7,3.6-3,5.8-3.8
c2.2-0.9,4.5-1.3,6.8-1.3c5.4,0,9.7,1.7,12.8,5c3.1,3.3,4.7,8.2,4.7,14.6c0,0.6,0,1.3-0.1,2.1s-0.1,1.4-0.1,2h-24.5
c0.2,2.1,1.3,4.1,3.1,5.3c2.2,1.4,4.8,2.1,7.4,2c1.9,0,3.9-0.2,5.8-0.5c1.6-0.3,3.2-0.8,4.8-1.5l1.5,8.8
c-0.7,0.4-1.5,0.6-2.3,0.9c-1.1,0.3-2.2,0.6-3.3,0.7c-1.2,0.2-2.4,0.4-3.8,0.6c-1.3,0.1-2.7,0.2-4.1,0.2c-3.1,0.1-6.1-0.4-9-1.5
c-2.4-0.9-4.5-2.3-6.3-4.1c-1.7-1.8-2.9-4-3.7-6.3C359.2,59.3,358.8,56.6,358.9,54 M384.2,49.9c0-0.9-0.2-1.8-0.5-2.7
c-0.2-0.9-0.7-1.6-1.2-2.3c-0.6-0.7-1.3-1.3-2.1-1.7c-1-0.5-2-0.7-3.1-0.7c-1.1,0-2.1,0.2-3.1,0.7c-0.8,0.4-1.5,0.9-2.1,1.6
c-0.6,0.7-1.1,1.5-1.4,2.4c-0.3,0.9-0.5,1.8-0.6,2.7L384.2,49.9"/>
<path id="path2999" class="st2" d="M402.6,25.1l10.8-1.7v11.2h13v9h-13V57c-0.1,1.9,0.3,3.8,1.2,5.4c0.8,1.3,2.4,2,4.9,2
c1.2,0,2.4-0.1,3.5-0.3c1.2-0.2,2.3-0.5,3.4-0.9l1.5,8.4c-1.4,0.6-2.9,1-4.4,1.4c-1.9,0.4-3.9,0.6-5.9,0.6
c-2.5,0.1-5-0.3-7.3-1.2c-1.8-0.7-3.4-1.9-4.6-3.3c-1.2-1.5-2-3.3-2.5-5.2c-0.5-2.2-0.7-4.5-0.6-6.7V25.1"/>
<path id="path3001" class="st2" d="M431.9,54c-0.1-3,0.5-6,1.5-8.8c0.9-2.4,2.3-4.5,4.1-6.4c1.7-1.7,3.6-3,5.8-3.8
c2.2-0.9,4.5-1.3,6.8-1.3c5.4,0,9.7,1.7,12.8,5s4.7,8.2,4.7,14.6c0,0.6,0,1.3-0.1,2.1c0,0.8-0.1,1.4-0.1,2H443
c0.2,2.1,1.3,4.1,3.1,5.3c2.2,1.4,4.8,2.1,7.4,2c1.9,0,3.9-0.2,5.8-0.5c1.6-0.3,3.2-0.8,4.7-1.5l1.5,8.8
c-0.7,0.4-1.5,0.6-2.3,0.9c-1.1,0.3-2.2,0.6-3.3,0.7c-1.2,0.2-2.4,0.4-3.8,0.6c-1.3,0.1-2.7,0.2-4.1,0.2c-3.1,0.1-6.1-0.4-9-1.5
c-2.4-0.9-4.5-2.3-6.3-4.1c-1.7-1.8-2.9-4-3.7-6.3C432.3,59.3,431.9,56.6,431.9,54 M457.2,49.9c0-0.9-0.2-1.8-0.5-2.7
c-0.2-0.9-0.7-1.6-1.2-2.3c-0.6-0.7-1.3-1.3-2.1-1.7c-1-0.5-2-0.7-3.1-0.7c-1.1,0-2.1,0.2-3.1,0.7c-0.8,0.4-1.6,0.9-2.2,1.6
c-0.6,0.7-1.1,1.5-1.4,2.4c-0.3,0.9-0.5,1.8-0.6,2.7L457.2,49.9"/>
<path id="path3003" class="st2" d="M487,65c1.4,0.1,2.9-0.1,4.2-0.6c0.8-0.4,1.3-1.3,1.2-2.2c-0.1-1-0.7-1.9-1.6-2.2
c-1.5-0.9-3.2-1.7-4.9-2.2c-1.7-0.6-3.2-1.3-4.6-2c-1.3-0.6-2.4-1.4-3.5-2.4c-1-1-1.7-2.1-2.2-3.4c-0.6-1.5-0.8-3.1-0.8-4.7
c-0.1-3.3,1.4-6.5,4-8.5c2.7-2.1,6.3-3.1,10.9-3.1c2.2,0,4.5,0.2,6.7,0.7c1.7,0.3,3.4,0.7,5.1,1.3l-1.9,8.5
c-1.4-0.5-2.7-0.8-4.1-1.2c-1.6-0.4-3.3-0.5-4.9-0.5c-3.4,0-5.1,0.9-5.1,2.8c0,0.4,0.1,0.8,0.2,1.2c0.2,0.4,0.5,0.7,0.9,1
c0.4,0.3,1,0.6,1.7,1c0.7,0.4,1.7,0.8,2.9,1.2c2,0.7,4,1.6,5.8,2.6c1.4,0.7,2.6,1.6,3.6,2.8c0.9,0.9,1.5,2,1.9,3.3
c0.4,1.4,0.6,2.8,0.6,4.2c0.2,3.4-1.4,6.7-4.3,8.6c-2.8,1.9-6.8,2.9-12,2.9c-2.9,0.1-5.7-0.2-8.5-0.9c-1.6-0.4-3.1-0.9-4.6-1.4
l1.8-8.8c1.8,0.7,3.7,1.3,5.6,1.7C483.1,64.8,485,65,487,65"/>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

-108
View File
@@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500.6 84.5" style="enable-background:new 0 0 500.6 84.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#326DE6;}
.st1{fill:#FFFFFF;}
.st2{fill:#326DE5;}
</style>
<title>Kubernetes_Logo_Hrz_lockup_POS</title>
<g id="Layer_2">
<g id="Layer_1-2">
<path class="st0" d="M79.8,18.8c-0.5-1.6-1.7-2.9-3.2-3.7L46.1,0.5c-0.8-0.4-1.7-0.5-2.5-0.5c-0.8,0-1.7,0-2.5,0.2L10.6,14.9
c-1.5,0.7-2.6,2-3,3.7L0,51.5c-0.3,1.7,0.1,3.4,1.1,4.8l21.1,26.1c1.2,1.2,2.9,2,4.6,2.1h33.7c1.8,0.2,3.5-0.6,4.6-2.1l21.1-26.1
c1-1.4,1.4-3.1,1.2-4.8L79.8,18.8z"/>
<path class="st1" d="M75,50.2L75,50.2c-0.1,0-0.1,0-0.1-0.1S74.6,50,74.5,50c-0.4-0.1-0.8-0.1-1.2-0.1c-0.2,0-0.4,0-0.6-0.1h-0.1
c-1.1-0.1-2.3-0.3-3.4-0.6c-0.3-0.1-0.6-0.4-0.7-0.7c0-0.1-0.1-0.1-0.1-0.1l0,0l-0.8-0.2c0.4-2.9,0.2-5.9-0.4-8.8
c-0.7-2.9-1.9-5.7-3.5-8.2l0.6-0.6l0,0v-0.1c0-0.3,0.1-0.7,0.3-0.9c0.9-0.7,1.8-1.4,2.8-1.9l0,0c0.2-0.1,0.4-0.2,0.6-0.3
c0.4-0.2,0.7-0.4,1.1-0.6c0.1-0.1,0.2-0.1,0.3-0.2s0.1-0.1,0.1-0.1l0,0c0.9-0.7,1.1-1.9,0.4-2.8c-0.3-0.4-0.9-0.7-1.4-0.7
c-0.5,0-1,0.2-1.4,0.5l0,0l-0.1,0.1c-0.1,0.1-0.2,0.2-0.3,0.2c-0.3,0.3-0.6,0.6-0.8,0.9c-0.1,0.2-0.3,0.3-0.4,0.4l0,0
c-0.8,0.8-1.6,1.6-2.5,2.2c-0.2,0.1-0.4,0.2-0.6,0.2c-0.1,0-0.3,0-0.4-0.1H62L61.2,28c-0.8-0.8-1.7-1.6-2.5-2.4
c-3.7-2.9-8.3-4.7-13-5.2l-0.1-0.8l0,0l-0.1-0.1c-0.3-0.2-0.4-0.5-0.5-0.8c0-1.1,0-2.2,0.2-3.4v-0.1c0-0.2,0.1-0.4,0.1-0.6
c0.1-0.4,0.1-0.8,0.2-1.2v-0.6l0,0c0.1-1-0.7-2-1.7-2c-0.6,0-1.2,0.2-1.6,0.6c-0.4,0.4-0.6,0.9-0.6,1.4l0,0v0.5
c0,0.4,0.1,0.8,0.2,1.2c0.1,0.2,0.1,0.4,0.1,0.6v0.1c0.2,1.1,0.2,2.2,0.2,3.4c-0.1,0.3-0.2,0.6-0.5,0.8l-0.1,0.1l0,0l-0.1,0.8
c-1.1,0.1-2.2,0.3-3.4,0.5c-4.7,1-9,3.5-12.3,7l-0.6-0.4H25c-0.1,0-0.2,0.1-0.4,0.1c-0.2,0-0.5-0.1-0.6-0.2
c-0.9-0.7-1.7-1.5-2.5-2.3l0,0c-0.1-0.2-0.3-0.3-0.4-0.4c-0.3-0.3-0.5-0.6-0.8-0.9c-0.1-0.1-0.2-0.1-0.3-0.2s-0.1-0.1-0.1-0.1l0,0
c-0.4-0.3-0.9-0.5-1.4-0.5c-0.6,0-1.1,0.2-1.5,0.7c-0.6,0.9-0.4,2.1,0.4,2.8l0,0c0.1,0,0.1,0.1,0.1,0.1s0.2,0.2,0.3,0.2
c0.3,0.2,0.7,0.4,1.1,0.6c0.2,0.1,0.4,0.2,0.6,0.3l0,0c1,0.6,1.9,1.2,2.8,1.9c0.2,0.2,0.4,0.6,0.3,0.9v0.1l0,0l0.6,0.6
c-0.1,0.2-0.2,0.3-0.3,0.5c-3.1,4.9-4.3,10.7-3.4,16.4l-0.8,0.2l0,0c0,0.1-0.1,0.1-0.1,0.1c-0.1,0.3-0.4,0.5-0.7,0.7
c-1.1,0.3-2.2,0.5-3.4,0.6h-0.1c-0.2,0-0.4,0-0.6,0.1c-0.4,0-0.8,0.1-1.2,0.1c-0.1,0-0.2,0.1-0.4,0.1c-0.1,0-0.1,0-0.2,0.1l0,0
c-1.1,0.2-1.8,1.2-1.6,2.3c0.2,0.9,1.1,1.5,2,1.4c0.2,0,0.3,0,0.5-0.1l0,0c0.1,0,0.1,0,0.1-0.1s0.2-0.1,0.4-0.1
c0.4-0.1,0.8-0.3,1.1-0.4c0.2-0.1,0.4-0.2,0.6-0.2h0.1c1-0.4,2.1-0.7,3.2-0.9h0.1c0.3,0,0.6,0.1,0.8,0.3c0.1,0,0.1,0.1,0.1,0.1
l0,0l0.9-0.1c1.5,4.6,4.3,8.7,8.2,11.7c0.9,0.7,1.7,1.3,2.7,1.8l-0.4,0.8l0,0c0,0.1,0.1,0.1,0.1,0.1c0.2,0.3,0.2,0.7,0.1,1
c-0.4,1-1,2-1.6,2.9v0.1c-0.1,0.2-0.2,0.3-0.4,0.5s-0.4,0.6-0.7,1c-0.1,0.1-0.1,0.2-0.2,0.3c0,0,0,0.1-0.1,0.1l0,0
c-0.5,1-0.1,2.2,0.8,2.7c0.2,0.1,0.5,0.2,0.8,0.2c0.8,0,1.5-0.5,1.9-1.2l0,0c0,0,0-0.1,0.1-0.1c0-0.1,0.1-0.2,0.2-0.3
c0.1-0.4,0.3-0.7,0.4-1.1l0.2-0.6l0,0c0.3-1.1,0.8-2.1,1.3-3.1c0.2-0.3,0.5-0.5,0.8-0.6c0.1,0,0.1,0,0.1-0.1l0,0l0.4-0.8
c2.8,1.1,5.7,1.6,8.7,1.6c1.8,0,3.6-0.2,5.4-0.6c1.1-0.2,2.2-0.6,3.2-0.9l0.4,0.7l0,0c0.1,0,0.1,0,0.1,0.1
c0.3,0.1,0.6,0.3,0.8,0.6c0.5,1,0.9,2,1.3,3v0.1l0.2,0.6c0.1,0.4,0.2,0.8,0.4,1.1c0.1,0.1,0.1,0.2,0.2,0.3c0,0,0,0.1,0.1,0.1l0,0
c0.4,0.7,1.1,1.2,1.9,1.2c0.3,0,0.5-0.1,0.8-0.2c0.4-0.2,0.8-0.6,0.9-1.1c0.1-0.5,0.1-1.1-0.1-1.6l0,0c0-0.1-0.1-0.1-0.1-0.1
c0-0.1-0.1-0.2-0.2-0.3c-0.2-0.4-0.4-0.7-0.7-1c-0.1-0.2-0.2-0.3-0.4-0.5v-0.1c-0.7-0.9-1.2-1.9-1.6-2.9c-0.1-0.3-0.1-0.7,0.1-1
c0-0.1,0.1-0.1,0.1-0.1l0,0l-0.3-0.8c5.2-3.1,9-7.9,10.9-13.6l0.8,0.1l0,0c0.1,0,0.1-0.1,0.1-0.1c0.2-0.2,0.5-0.3,0.8-0.3h0.1
c1.1,0.2,2.2,0.5,3.2,0.9h0.1c0.2,0.1,0.4,0.2,0.6,0.2c0.4,0.2,0.7,0.3,1.1,0.4c0.1,0,0.2,0.1,0.4,0.1c0.1,0,0.1,0,0.2,0.1l0,0
c0.2,0.1,0.3,0.1,0.5,0.1c0.9,0,1.7-0.6,2-1.4C76.7,51.2,76,50.4,75,50.2z M46.2,47.1l-2.7,1.3l-2.7-1.3L40,44.2l1.9-2.4H45
l1.9,2.4L46.2,47.1z M62.5,40.6c0.5,2.1,0.6,4.2,0.4,6.3l-9.5-2.7l0,0c-0.9-0.2-1.4-1.1-1.2-2c0.1-0.3,0.2-0.5,0.4-0.7l7.5-6.8
C61.2,36.5,62,38.5,62.5,40.6L62.5,40.6z M57.1,31L49,36.8c-0.7,0.4-1.7,0.3-2.2-0.4c-0.2-0.2-0.3-0.4-0.3-0.7l-0.6-10.1
C50.1,26.1,54.1,28,57.1,31z M39,25.9l2-0.4l-0.6,10l0,0c0,0.9-0.8,1.6-1.7,1.6c-0.3,0-0.5-0.1-0.8-0.2L29.8,31
C32.3,28.5,35.5,26.7,39,25.9z M26.8,34.7l7.4,6.6l0,0c0.7,0.6,0.8,1.6,0.2,2.3c-0.2,0.3-0.4,0.4-0.8,0.5L24,46.9
C23.6,42.7,24.6,38.4,26.8,34.7z M25.1,51.6l9.9-1.7c0.8,0,1.6,0.5,1.7,1.3c0.1,0.3,0.1,0.7-0.1,1l0,0l-3.8,9.2
C29.3,59.1,26.5,55.6,25.1,51.6z M47.8,64c-1.4,0.3-2.9,0.5-4.4,0.5c-2.1,0-4.3-0.4-6.3-1l4.9-8.9c0.5-0.6,1.3-0.8,2-0.4
c0.3,0.2,0.5,0.4,0.8,0.7l0,0l4.8,8.7C49.1,63.7,48.5,63.8,47.8,64z M60,55.3c-1.5,2.4-3.6,4.5-6,6L50.1,52
c-0.2-0.8,0.1-1.6,0.9-2c0.3-0.1,0.6-0.2,0.9-0.2l10,1.7C61.4,52.9,60.8,54.2,60,55.3z"/>
<g id="layer1">
<g id="text4373">
<path id="path2985" class="st2" d="M125.7,45.9c1.1-1.2,2.1-2.4,3.3-3.6c1.1-1.3,2.2-2.5,3.3-3.7c1.1-1.3,2.1-2.4,3-3.5
s1.8-2.1,2.5-2.9h12.8c-2.6,2.9-5.1,5.8-7.5,8.5c-2.5,2.7-5.1,5.5-8,8.3c1.6,1.5,3.1,3,4.5,4.7c1.5,1.8,3,3.6,4.5,5.6
c1.4,1.9,2.8,3.9,4,5.8c1.2,1.9,2.2,3.7,3,5.3h-12.3c-0.8-1.3-1.7-2.6-2.7-4.1s-2.1-3-3.1-4.6c-1.1-1.5-2.3-3-3.6-4.4
c-1.1-1.3-2.3-2.5-3.6-3.5v16.7h-10.8V15.7l10.8-1.7V45.9"/>
<path id="path2987" class="st2" d="M188.6,68.9c-2.3,0.6-4.7,1.1-7.1,1.4c-3,0.5-6.1,0.7-9.1,0.7c-2.8,0.1-5.5-0.4-8.1-1.3
c-2-0.8-3.7-2-5.1-3.6c-1.3-1.7-2.2-3.6-2.7-5.7c-0.6-2.3-0.8-4.8-0.8-7.2V32.1h10.8V52c0,3.5,0.5,6,1.4,7.5
c0.9,1.5,2.6,2.3,5.1,2.4c0.8,0,1.6,0,2.5-0.1s1.6-0.1,2.3-0.3V32.1h10.8L188.6,68.9"/>
<path id="path2989" class="st2" d="M223.2,50.9c0-7-2.6-10.4-7.7-10.4c-1.1,0-2.2,0.1-3.3,0.4c-0.9,0.2-1.8,0.6-2.6,1.1v19.6
c0.5,0.1,1.2,0.2,2,0.3c0.8,0.1,1.7,0.1,2.7,0.1c2.6,0.2,5.1-0.9,6.7-3C222.5,56.6,223.3,53.8,223.2,50.9 M234.2,51.3
c0,2.8-0.4,5.6-1.4,8.3c-0.8,2.4-2.1,4.5-3.8,6.3c-1.8,1.8-3.9,3.2-6.2,4.1c-2.7,1-5.5,1.4-8.4,1.4c-1.3,0-2.7-0.1-4.1-0.2
c-1.4-0.1-2.8-0.3-4.2-0.4c-1.3-0.2-2.6-0.4-3.9-0.7c-1.3-0.2-2.4-0.6-3.3-1V15.7l10.8-1.7v19c1.2-0.5,2.5-0.9,3.8-1.2
c1.4-0.3,2.8-0.4,4.2-0.4c2.5,0,4.9,0.4,7.2,1.5c2,0.9,3.8,2.3,5.2,4c1.5,1.9,2.6,4,3.2,6.3C233.9,45.7,234.3,48.5,234.2,51.3"
/>
<path id="path2991" class="st2" d="M240.7,51.5c-0.1-3,0.5-6,1.5-8.8c0.9-2.4,2.3-4.5,4.1-6.4c1.7-1.7,3.6-3,5.8-3.8
c2.2-0.9,4.5-1.3,6.8-1.3c5.4,0,9.7,1.7,12.8,5c3.1,3.3,4.7,8.2,4.7,14.6c0,0.6,0,1.3-0.1,2.1s-0.1,1.4-0.1,2h-24.5
c0.2,2.1,1.3,4,3.1,5.2c2.2,1.4,4.8,2.1,7.4,2c1.9,0,3.9-0.2,5.8-0.5c1.6-0.3,3.2-0.8,4.7-1.4l1.5,8.8c-0.7,0.4-1.5,0.6-2.3,0.9
c-1.1,0.3-2.2,0.6-3.3,0.7c-1.2,0.2-2.4,0.4-3.8,0.6c-1.3,0.1-2.7,0.2-4.1,0.2c-3.1,0.1-6.1-0.4-9-1.5c-2.4-0.9-4.5-2.3-6.3-4.1
c-1.7-1.8-2.9-4-3.7-6.3C241.1,56.8,240.7,54.1,240.7,51.5 M266,47.4c0-0.9-0.2-1.8-0.5-2.7c-0.2-0.9-0.7-1.6-1.2-2.3
c-0.6-0.7-1.3-1.3-2.1-1.7c-1-0.5-2-0.7-3.1-0.7c-1.1,0-2.1,0.2-3.1,0.7c-0.8,0.4-1.6,0.9-2.2,1.6c-0.6,0.7-1.1,1.5-1.4,2.4
c-0.3,0.9-0.5,1.8-0.6,2.7L266,47.4"/>
<path id="path2993" class="st2" d="M307.8,41.7c-1-0.2-2.1-0.5-3.4-0.7c-1.4-0.3-2.8-0.4-4.2-0.4c-0.8,0-1.6,0.1-2.5,0.2
c-0.7,0.1-1.4,0.2-2.1,0.4v29.1h-10.8V34.1c2.2-0.8,4.5-1.4,6.8-1.9c2.9-0.7,5.9-1,8.8-0.9c0.7,0,1.4,0.1,2.1,0.1
c0.8,0,1.6,0.1,2.5,0.3c0.8,0.1,1.6,0.2,2.5,0.4c0.7,0.1,1.4,0.3,2.1,0.6L307.8,41.7"/>
<path id="path2995" class="st2" d="M315.4,33.4c2.3-0.6,4.7-1.1,7.1-1.5c3-0.5,6.1-0.7,9.1-0.7c2.7-0.1,5.4,0.4,8,1.3
c2,0.7,3.8,1.9,5.1,3.5c1.3,1.6,2.2,3.5,2.7,5.5c0.6,2.3,0.8,4.7,0.8,7.1v21.5h-10.8V50c0-3.5-0.5-5.9-1.4-7.4
c-0.9-1.4-2.6-2.2-5.1-2.2c-0.8,0-1.6,0-2.5,0.1c-0.9,0-1.6,0.1-2.3,0.2v29.4h-10.8L315.4,33.4"/>
<path id="path2997" class="st2" d="M356.4,51.5c-0.1-3,0.5-6,1.5-8.8c0.9-2.4,2.3-4.5,4.1-6.4c1.7-1.7,3.6-3,5.8-3.8
c2.2-0.9,4.5-1.3,6.8-1.3c5.4,0,9.7,1.7,12.8,5c3.1,3.3,4.7,8.2,4.7,14.6c0,0.6,0,1.3-0.1,2.1c0,0.8-0.1,1.4-0.1,2h-24.5
c0.2,2.1,1.3,4,3.1,5.2c2.2,1.4,4.8,2.1,7.4,2c1.9,0,3.9-0.2,5.8-0.5c1.6-0.3,3.2-0.8,4.7-1.4l1.5,8.8c-0.7,0.4-1.5,0.6-2.3,0.9
c-1.1,0.3-2.2,0.6-3.3,0.7c-1.2,0.2-2.4,0.4-3.8,0.6c-1.3,0.1-2.7,0.2-4.1,0.2c-3.1,0.1-6.1-0.4-9-1.5c-2.4-0.9-4.5-2.3-6.3-4.1
c-1.7-1.8-2.9-4-3.7-6.3C356.7,56.8,356.3,54.1,356.4,51.5 M381.7,47.4c0-0.9-0.2-1.8-0.5-2.7c-0.2-0.9-0.6-1.7-1.2-2.4
c-0.6-0.7-1.3-1.3-2.1-1.7c-1-0.5-2-0.7-3.1-0.7c-1.1,0-2.1,0.2-3.1,0.7c-0.8,0.4-1.6,0.9-2.2,1.6c-0.6,0.7-1.1,1.5-1.4,2.4
c-0.3,0.9-0.5,1.8-0.6,2.7L381.7,47.4"/>
<path id="path2999" class="st2" d="M400.1,22.6l10.8-1.7v11.2h13v9h-13v13.4c-0.1,1.9,0.3,3.8,1.2,5.4c0.8,1.3,2.4,2,4.9,2
c1.2,0,2.4-0.1,3.5-0.3c1.2-0.2,2.3-0.5,3.4-0.9l1.5,8.4c-1.4,0.6-2.9,1-4.4,1.4c-1.9,0.4-3.9,0.6-5.9,0.6
c-2.5,0.1-5-0.3-7.3-1.2c-1.8-0.7-3.4-1.9-4.6-3.3c-1.2-1.5-2-3.3-2.5-5.2c-0.5-2.2-0.7-4.5-0.6-6.7L400.1,22.6"/>
<path id="path3001" class="st2" d="M429.4,51.5c-0.1-3,0.5-6,1.5-8.8c0.9-2.4,2.3-4.5,4.1-6.4c1.7-1.7,3.6-3,5.8-3.8
c2.2-0.9,4.5-1.3,6.8-1.3c5.4,0,9.7,1.7,12.8,5c3.1,3.3,4.7,8.2,4.7,14.6c0,0.6,0,1.3-0.1,2.1c0,0.8-0.1,1.4-0.1,2h-24.5
c0.2,2.1,1.4,4,3.1,5.2c2.2,1.4,4.8,2.1,7.4,2c1.9,0,3.9-0.2,5.8-0.5c1.6-0.3,3.2-0.8,4.7-1.4l1.5,8.8c-0.7,0.4-1.5,0.6-2.3,0.9
c-1.1,0.3-2.2,0.6-3.3,0.7c-1.2,0.2-2.4,0.4-3.8,0.6c-1.3,0.1-2.7,0.2-4.1,0.2c-3.1,0.1-6.1-0.4-9-1.5c-2.4-0.9-4.5-2.3-6.3-4.1
c-1.7-1.8-2.9-4-3.7-6.3C429.8,56.8,429.4,54.1,429.4,51.5 M454.8,47.4c0-0.9-0.2-1.8-0.5-2.7c-0.2-0.9-0.7-1.7-1.2-2.4
c-0.6-0.7-1.3-1.3-2.1-1.7c-1-0.5-2-0.7-3.1-0.7c-1.1,0-2.1,0.2-3.1,0.7c-0.8,0.4-1.6,0.9-2.2,1.6c-0.6,0.7-1.1,1.5-1.4,2.4
c-0.3,0.9-0.5,1.8-0.6,2.7L454.8,47.4"/>
<path id="path3003" class="st2" d="M484.5,62.5c1.4,0.1,2.9-0.1,4.2-0.6c0.8-0.4,1.3-1.3,1.2-2.2c-0.1-1-0.7-1.9-1.6-2.2
c-1.5-0.9-3.2-1.7-4.9-2.2c-1.7-0.6-3.2-1.3-4.6-2c-1.3-0.6-2.4-1.4-3.5-2.4c-1-1-1.7-2.1-2.2-3.4c-0.6-1.5-0.8-3.1-0.8-4.7
c-0.1-3.3,1.4-6.5,4-8.5c2.7-2.1,6.3-3.1,10.9-3.1c2.2,0,4.5,0.2,6.7,0.6c1.7,0.3,3.4,0.7,5.1,1.3l-1.9,8.4
c-1.4-0.5-2.7-0.8-4.1-1.2c-1.6-0.3-3.3-0.5-4.9-0.4c-3.4,0-5.1,0.9-5.1,2.8c0,0.4,0.1,0.8,0.2,1.2c0.2,0.4,0.5,0.7,0.9,1
c0.4,0.3,1,0.6,1.7,1c0.7,0.4,1.7,0.8,2.9,1.2c2,0.7,4,1.6,5.9,2.6c1.4,0.7,2.6,1.6,3.6,2.8c0.9,0.9,1.5,2.1,1.9,3.3
c0.4,1.4,0.6,2.8,0.6,4.2c0.2,3.4-1.4,6.7-4.3,8.6c-2.8,1.9-6.8,2.9-12,2.9c-2.9,0.1-5.7-0.2-8.5-0.9c-1.6-0.4-3.1-0.9-4.6-1.4
l1.8-8.8c1.8,0.7,3.7,1.3,5.6,1.7C480.5,62.3,482.4,62.5,484.5,62.5"/>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 10 KiB

-44
View File
@@ -1,44 +0,0 @@
/*
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function ($) {
"use strict";
var Search = {
init: function () {
$(document).ready(function () {
// Fill the search input form with the current search keywords
const searchKeywords = new URLSearchParams(location.search).get('q');
if (searchKeywords !== null && searchKeywords !== '') {
const searchInput = document.querySelector('.td-search-input');
searchInput.focus();
searchInput.value = searchKeywords;
}
// Set a keydown event
$(document).on("keypress", ".td-search-input", function (e) {
if (e.keyCode !== 13) {
return;
}
var query = $(this).val();
document.location = "{{ "search/" | absURL }}?q=" + query;
return false;
});
});
},
};
Search.init();
})(jQuery);
-850
View File
@@ -1,850 +0,0 @@
@import "reset";
// header
$full-width-paddingX: 20px;
$main-width: 100%;
$main-max-width: 100%;
$header-height: 80px;
$logo-width: 180px;
$nav-buttons-margin-left: 30px;
$hamburger-size: 50px;
// main nav
$main-nav-padding: 140px 0 30px;
$main-nav-h5-margin-bottom: 1em;
$main-nav-h3-margin-bottom: 0.6em;
$nav-box-width: 20%;
$nav-box-sibling-margin-left: calc(20% / 3);
$main-nav-main-sibling-margin-top: 60px;
$main-nav-left-button-size: 50px;
$main-nav-left-button-font-size: 18px;
// hero
$hero-padding-top: 80px;
$headline-wrapper-margin-bottom: 40px;
$quickstart-button-padding: 0 50px;
$vendor-strip-height: 88px;
$vendor-strip-font-size: 16px;
// video
$video-section-height: 200px;
@import "size";
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
body {
background-color: white;
a {
color: $blue;
}
}
section {
position: relative;
background-color: white;
}
section,
header,
footer {
.main-section {
position: relative;
margin: auto;
}
p {
font-size: 14px;
font-weight: 400;
}
.button {
display: inline-block;
border-radius: 6px;
padding: 6px 20px;
line-height: 1.3rem;
color: white;
background-color: $blue;
text-decoration: none;
font-size: 1rem;
border: 0px;
}
#cellophane {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
}
}
// HEADER
#hamburger {
display: inline-block;
position: relative;
margin-left: auto;
vertical-align: middle;
padding: 0;
border: 0;
background: none;
div,
&:before,
&:after {
position: absolute;
left: 15%;
width: 70%;
height: 2px;
background-color: $blue;
transition: 0.3s;
content: "";
}
div {
top: calc(50% - 1px);
}
&:before {
top: 24%;
}
&:after {
bottom: 24%;
}
&:hover {
div,
&:before,
&:after {
background-color: white;
}
}
}
// HERO
.header-hero {
background-image: url(/images/texture.png);
background-color: $dark-grey;
text-align: center;
padding-left: 0;
padding-right: 0;
margin-bottom: 0;
position: relative;
&.bot-bar:after {
display: block;
margin-bottom: -24px;
height: 8px;
width: 100%;
background-color: transparentize(white, 0.9);
content: "";
}
&.no-sub {
h5 {
display: none;
}
h1 {
margin-bottom: 20px;
}
}
}
.td-home .header-hero:after {
display: none;
}
.header-hero {
background-color: $dark-grey;
h5 {
margin: 20px 0;
line-height: 28px;
}
}
#vendorStrip {
position: relative;
ul {
float: left;
}
li {
display: inline-block;
height: 100%;
}
a {
display: block;
height: 100%;
color: white;
font-size: 0.75em;
font-weight: bold;
}
li + li {
margin-left: 0;
}
}
.pi-accordion {
& > .container:first-child > .item:first-child > .title:first-child {
padding-left: 0;
font-size: 1.5em;
font-weight: 700;
}
& > .container:first-child > .item.yah:first-child > .title:first-child {
margin-left: -20px !important;
}
.item {
overflow: hidden;
}
.title {
color: $dark-grey;
position: relative;
padding: 7.5px 10px 7.5px 18px;
cursor: pointer;
transition: 0.3s;
&:hover {
color: $blue;
}
}
a.item > .title {
color: black;
&:hover {
color: $blue;
}
}
div.item > .title {
&:before {
content: "";
position: absolute;
top: 12px;
left: 2px;
border-style: solid;
border-width: 5px 0 5px 8px;
border-color: transparent transparent transparent $blue;
transform: rotate(0deg);
transition: 0.3s;
}
}
.wrapper {
position: relative;
width: 100%;
transition: height 0.3s;
}
.content {
padding-left: 20px;
opacity: 0;
transition: 0.3s;
}
.item.on {
& > .title:before {
transform: rotate(90deg);
}
& > .wrapper > .content {
opacity: 1;
}
}
}
dt {
margin-bottom: 8px;
}
dd {
margin-bottom: 16px;
}
.pi-pushmenu {
display: none;
position: fixed;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.3s;
&.on {
opacity: 1;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
.sled {
position: absolute;
top: 0;
width: 0;
height: 100%;
background-color: white;
overflow: auto;
transition: 0.3s;
}
&.on .sled {
width: 400px;
max-width: 100vw;
}
.top-bar {
height: 0;
line-height: 60px;
background-color: #444;
}
ul {
margin-top: 25px;
}
li {
position: relative;
display: block;
width: 100%;
min-height: 45px;
padding: 0 60px 0 20px;
border-bottom: 1px solid #cccccc;
}
a {
display: inline-block;
width: 100%;
height: 45px;
line-height: 45px;
font-size: 20px;
color: $blue;
}
.button {
background: none;
padding: 0;
}
ul ul {
padding: 0 20px;
li {
min-height: 40px;
}
a {
height: 40px;
line-height: 40px;
font-size: 18px;
color: lighten(#222222, 20%);
}
}
}
.push-menu-close-button {
position: absolute;
top: 0;
right: 0;
width: 50px;
height: 50px;
&:before,
&:after {
content: "";
position: absolute;
top: calc(50% - 1px);
left: 25%;
width: 50%;
height: 2px;
background-color: black;
}
&:before {
transform: rotate(45deg);
}
&:after {
transform: rotate(-45deg);
}
}
// ocean nodes
$ocean-nodes-padding-Y: 60px;
$ocean-nodes-main-margin-bottom: 60px;
$ocean-nodes-h3-margin-bottom: 30px;
// video
$video-section-height: 200px;
// features
$features-h3-margin-bottom: 20px;
$feature-box-div-width: 100%;
$feature-box-margin-bottom: 0;
$feature-box-div-margin-bottom: 40px;
// Home-specific
.td-home {
&.flip-nav,
&.open-nav {
.logo {
background-image: url(/images/nav_logo2.svg);
}
}
}
.header-hero {
margin-bottom: 0;
padding-bottom: 1px;
.main-section {
padding: 0 10px;
margin-bottom: 30px;
}
#vendorStrip {
display: none;
}
}
// Add logo to CNCF section
section#cncf {
padding-top: 60px;
padding-bottom: 140px;
background-image: url(/images/cncf-color.svg);
background-position: center 100px;
background-repeat: no-repeat;
background-size: 300px;
}
// OCEAN NODES
#oceanNodes {
padding-top: $ocean-nodes-padding-Y;
padding-bottom: $ocean-nodes-padding-Y;
a {
color: $blue;
}
.main-section {
margin-bottom: $ocean-nodes-padding-Y;
min-height: 160px;
}
.image-wrapper {
max-width: 75%;
margin: 0 auto 20px;
text-align: center;
img {
width: 100%;
max-width: 160px;
}
}
.main-section:first-child {
.image-wrapper {
max-width: 100%;
img {
max-width: 491px;
}
}
}
h3 {
margin-bottom: $ocean-nodes-h3-margin-bottom;
}
}
// Video thingy
#video {
height: $video-section-height;
}
#video {
width: 100%;
position: relative;
background-position: center center;
background-size: cover;
& > .light-text {
display: none;
// position: absolute;
// top: 50%;
// left: 75%;
width: 500px;
padding-top: 2rem;
// transform: translate(-50%, -50%);
color: white;
}
h2 {
font-size: 32px;
line-height: 44px;
margin-bottom: 20px;
}
p {
margin-bottom: 20px;
}
#desktopKCButton {
position: absolute;
font-size: 18px;
background-color: $dark-grey;
border-radius: 8px;
color: $white;
padding: 20px 10px 20px 10px;
}
#desktopShowVideoButton {
position: relative;
font-size: 24px;
background-color: white;
border-radius: 8px;
color: $blue;
padding: 15px 30px 15px 80px;
margin-bottom: 15px;
&:before {
content: "";
position: absolute;
@include pureCenter(40px);
width: 0;
height: 0;
border-style: solid;
border-width: 10px 0 10px 20px;
border-color: transparent transparent transparent $blue;
}
}
#mobileShowVideoButton {
@include pureCenter;
width: 80px;
height: 80px;
border-radius: 50%;
background-color: transparent;
border: 5px solid rgba(255, 255, 255, 0.2);
overflow: visible;
&:after {
@include pureCenter;
left: 40px;
content: "";
width: 0;
height: 0;
border-style: solid;
border-width: 20px 0 20px 30px;
border-color: transparent transparent transparent #ffffff;
}
}
}
#videoPlayer {
@include fullScreen;
background-color: rgba(0, 0, 0, 0.9);
display: none;
iframe {
@include pureCenter;
@include maintain-aspect-ratio;
}
#closeButton {
position: absolute;
top: 20px;
right: 20px;
width: 50px;
height: 50px;
border: 2px solid transparent;
transition: 0.3s;
&:before,
&:after {
content: "";
position: absolute;
top: calc(50% - 1px);
left: 10%;
width: 80%;
height: 2px;
background-color: white;
}
&:before {
transform: rotate(45deg);
}
&:after {
transform: rotate(-45deg);
}
&:hover {
border-color: white;
}
}
}
// KubeWeekly
#kubeweekly {
background-color: $light-grey;
padding-top: 30px;
padding-bottom: 80px;
background-size: auto;
font-size: 24px;
// font-weight: bold;
h5 {
font-size: 20px;
}
}
.subscribe-button {
border-radius: 6px;
padding: 0 20px;
line-height: 31px;
color: white;
background-color: blue;
text-decoration: none;
font-size: 14px;
}
// Features
#features {
padding-top: 140px;
background-color: $light-grey;
background-image: url(/images/wheel.svg);
background-position: center 60px;
background-repeat: no-repeat;
background-size: 60px;
}
.feature-box {
//padding: 50px 0
width: 100%;
overflow: hidden;
clear: both;
h4 {
line-height: normal;
margin-bottom: 15px;
}
& > div:first-child {
float: left;
}
& > div:last-child {
float: right;
}
}
#features {
h3 {
margin-bottom: $features-h3-margin-bottom;
}
.feature-box {
margin-bottom: $feature-box-margin-bottom;
& > div {
width: $feature-box-div-width;
margin-bottom: $feature-box-div-margin-bottom;
}
}
}
// Talk to us
#talkToUs {
h3,
h4 {
text-align: center;
}
h3 {
margin-bottom: 15px;
}
h4 {
line-height: normal;
margin-bottom: 50px;
br {
display: none;
}
}
#bigSocial {
overflow: hidden;
div {
width: 100%;
float: left;
padding: 30px;
padding-top: 110px;
background-position: center top;
background-size: auto;
background-repeat: no-repeat;
}
div:nth-child(1) {
background-image: url(/images/twitter_icon.png);
}
div:nth-child(2) {
background-image: url(/images/github_icon.png);
}
div:nth-child(3) {
background-image: url(/images/slack_icon.png);
}
div:nth-child(4) {
background-image: url(/images/stackoverflow_icon.png);
}
div + div {
margin-top: 20px;
margin-left: 0;
}
a {
display: inline-block;
color: $blue;
font-size: 24px;
font-weight: 400;
text-decoration: none;
margin-bottom: 15px;
}
a,
p {
text-align: center;
width: 100%;
}
}
}
.td-home {
#talkToUs {
.main-section {
padding: 30px 0;
}
h5 {
font-size: 20px;
}
}
#caseStudiesWrapper {
position: relative;
text-align: center;
margin-bottom: 30px;
img {
padding-bottom: 1rem;
}
div {
position: relative;
display: inline-block;
vertical-align: top;
width: 100%;
min-height: 230px;
margin-bottom: 60px;
padding-right: 1rem;
background-position: top center;
}
p {
font-size: 20px;
}
a {
position: absolute;
bottom: -30px;
left: 50%;
transform: translateX(-50%);
color: $blue;
font-weight: 400;
}
}
}
// Docs specific
#editPageButton {
position: absolute;
top: 50px;
right: 25px;
width: 50px;
height: 50px;
line-height: 50px;
border-radius: 50%;
white-space: nowrap;
text-indent: 50px;
overflow: hidden;
background: $blue url(/images/icon-pencil.svg) no-repeat;
background-position: 12px 10px;
background-size: 29px 29px;
}
.feedback--response__hidden {
display: none;
}
// GitHub info/edit buttons
#pre-footer {
margin-top: 2rem;
.button {
font-size: 1.1rem;
&:first-of-type {
margin-right: 0.75rem;
}
}
.lastedit {
margin-top: 1rem;
font-size: 1rem;
}
}
/* DOCUMENTATION */
body.td-documentation {
header > .header-filler {
height: $hero-padding-top;
background-color: black;
}
/* Special case for if an announcement is active */
header section#announcement ~ .header-filler {
display: none;
}
}
-143
View File
@@ -1,143 +0,0 @@
// SASS for Case Studies pages go here:
hr {
background-color: #999999;
margin-top: 0;
}
h2 {
margin-bottom: 15px !important;
}
.subhead {
padding-bottom: 2% !important;
padding-top: 0.75em !important;
}
.details {
margin-left: 1.9%;
padding-right: 5%;
font-size: 16px !important;
padding-bottom: 2% !important;
}
.section1 {
margin-bottom: 3%;
.cols {
width: 80% !important;
margin-left: 6.8%;
padding-top: 1.5%;
.col1 {
width: 52% !important;
font-weight: 300 !important;
}
.col2 {
width: 46% !important;
}
}
}
.banner2text {
width: 63%;
padding-top: 10%;
padding-left: 0% !important;
float: initial !important;
text-align: center;
margin: 0 auto;
position: relative;
}
.banner3text,
.banner4text,
.banner5text {
width: 63%;
padding-left: 0% !important;
float: initial !important;
text-align: center;
margin: 0 auto;
position: relative;
}
.fullcol {
float: initial !important;
}
body footer {
background-color: #585858 !important;
}
.section1 {
float: left !important;
}
.banner1 {
padding-left: 11.9% !important;
}
.banner2 {
float: initial !important;
padding-bottom: 2% !important;
}
footer {
padding: 0% 7%;
}
.banner4,
.banner3,
.banner5 {
float: initial !important;
}
@media screen and (max-width: 910px) {
.banner2text {
width: 47%;
padding-top: 45%;
}
.details {
margin-left: 0%;
margin-bottom: 3%;
}
.subhead {
padding-bottom: 0% !important;
padding-top: 0% !important;
}
.banner3 {
width: 100% !important;
}
}
@media screen and (max-width: 780px) {
.section1 .cols {
width: 100% !important;
margin-left: 0%;
padding-top: 5%;
.col1,
.col2 {
width: 100% !important;
margin-left: 0% !important;
.fullcol {
width: 90% !important;
margin-left: 5% !important;
.banner1 {
padding-left: 10% !important;
margin-bottom: 6% !important;
.banner2text {
padding-top: 60% !important;
padding-bottom: 2% !important;
}
}
}
}
}
}
-564
View File
@@ -1,564 +0,0 @@
$announcement-size-adjustment: 8px;
/* GLOBAL */
.td-main {
.row {
margin: 0;
}
main {
img {
max-width: 100%;
}
@media only screen and (min-width: 768px) {
padding-top: 2rem !important;
}
}
.ui-widget {
font-family: inherit;
font-size: inherit;
}
.ui-widget-content a {
color: $blue;
}
}
section {
.main-section {
@media only screen and (min-width: 1024px) {
max-width: 1200px;
}
}
}
.td-outer {
padding: 0 !important;
}
/* Emphasize first paragraph of running text on site front page */
body.td-home main[role="main"] > section:first-of-type .content p:first-child {
line-height: 1.3em;
font-size: 1.4em;
margin-bottom: 1.5em;
}
#desktopShowVideoButton {
border: none
}
#videoPlayer {
#closeButton {
background: transparent;
}
}
body.td-404 main .error-details {
max-width: 1100px;
margin-left: auto;
margin-right: auto;
margin-top: 4em;
margin-bottom: 0;
}
/* Global - Mermaid.js diagrams */
.mermaid {
overflow-x: auto;
max-width: 80%;
border: 1px solid rgb(222, 226, 230);
border-radius: 5px;
}
/* HEADER */
.td-navbar {
position: fixed !important;
width: 100%;
padding-bottom: 1rem !important;
background: transparent !important;
transition: 0.3s;
.navbar-brand {
position: absolute;
width: 45px;
height: 44px;
background-repeat: no-repeat;
background-size: contain;
background-image: url("/images/favicon.png");
}
#hamburger {
&:focus {
outline: none;
}
}
@media only screen and (min-width: 768px) {
.navbar-brand {
background-image: url("/images/nav_logo.svg");
top: 1.5rem;
width: 180px;
margin-left: 1rem;
}
}
}
.td-navbar-nav-scroll {
overflow: visible !important;
display: none;
.navbar-nav {
overflow: visible !important;
position: relative;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
.nav-item {
position: relative;
height: 10%;
.active::after {
position: absolute;
width: 100%;
height: 2px;
content: "";
bottom: -4px;
left: 0;
background: #fff;
}
}
}
@media only screen and (min-width: 768px) {
display: block;
margin-top: 3.5rem !important;
}
@media only screen and (min-width: 1075px) {
margin-top: 1rem !important;
}
}
// Flip-Nav
.flip-nav .td-navbar {
background-color: white !important;
box-shadow: 0 1px 2px $medium-grey;
.navbar-nav {
.nav-item {
&.show .nav-link,
.nav-link {
color: $dark-grey;
&:hover {
color: $medium-grey;
}
}
.dropdown {
&:hover {
color: $medium-grey;
}
}
}
}
.navbar-nav .nav-item .active {
color: $dark-grey;
&::after {
background: $dark-grey;
}
}
#hamburger:hover {
div,
&:before,
&:after {
background-color: $dark-grey;
}
}
@media only screen and (min-width: 768px) {
.navbar-brand {
background-image: url("/images/nav_logo2.svg");
}
}
}
/* FOOTER */
footer {
background-color: #303030;
background-image: url("/images/texture.png");
padding: 1rem !important;
min-height: initial !important;
.footer__links {
width: 100%;
margin: auto;
padding-bottom: 1rem;
nav a {
display: block;
text-align: center;
}
@media only screen and (min-width: 768px) {
nav {
display: flex;
flex-direction: row;
justify-content: space-around;
}
}
}
small {
color: $light-grey;
font-size: 0.64rem;
a {
text-decoration: inherit;
color: inherit;
&:hover {
color: inherit;
}
}
}
}
/* SIDE-DRAWER MENU */
.pi-pushmenu .sled {
.content ul {
padding: 0;
li {
&:first-child {
display: none;
}
a.nav-link {
padding: 0;
}
}
}
.push-menu-close-button {
background: transparent;
border: none;
&:focus {
outline: none;
}
}
}
/* DOCS */
.launch-cards {
button {
cursor: pointer;
box-sizing: border-box;
background: none;
margin: 0;
border: 0;
}
ul,
li {
list-style: none;
padding-left: 0;
}
}
// table of contents
.td-toc {
padding-top: 1.5rem !important;
top: 5rem !important;
#TableOfContents {
padding-top: 1rem;
}
}
main {
.td-content table code,
.td-content>table td {
word-break: break-word;
}
}
// blockquotes and callouts
.td-content, body {
blockquote.callout {
padding: 0.4rem 0.4rem 0.4rem 1rem;
border: 1px solid #eee;
border-left-width: 0.5em;
background: #fff;
color: #000;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
blockquote.callout {
border-radius: calc(1em/3);
}
.callout.caution {
border-left-color: #f0ad4e;
}
.callout.note {
border-left-color: #428bca;
}
.callout.warning {
border-left-color: #d9534f;
}
h1:first-of-type + blockquote.callout {
margin-top: 1.5em;
}
}
.deprecation-warning {
padding: 20px;
margin: 20px 0;
background-color: #faf5b6;
color: #000;
}
body.td-home .deprecation-warning, body.td-blog .deprecation-warning, body.td-documentation .deprecation-warning {
border-radius: 3px;
}
body.td-home #deprecation-warning {
max-width: 1000px;
margin-top: 2.5rem;
margin-left: auto;
margin-right: auto;
}
#caseStudies body > #deprecation-warning, body.cid-casestudies > #deprecation-warning, body.cid-community > #deprecation-warning {
display: inline-block;
vertical-align: top;
position: relative;
background-color: #326ce5; // Kubernetes blue
color: #fff;
padding: 0;
margin: 0;
width: 100vw;
}
#caseStudies body > #deprecation-warning, body.cid-casestudies > #deprecation-warning {
padding-top: 32px;
}
body.cid-partners > #deprecation-warning {
padding: 0;
margin-right: 0;
margin-left: 0;
margin-top: 0;
width: 100vw;
}
body.cid-partners > #deprecation-warning > .content {
width: 100%;
max-width: initial;
margin-right: 0;
margin-left: 0;
margin-top: 0;
padding-left: 5vw;
padding-right: 5vw;
padding-top: 2rem;
padding-bottom: 2rem;
}
body.cid-community > #deprecation-warning > .deprecation-warning {
margin-left: 20px;
margin-right: 20px;
color: #faf5b6;
background-color: inherit;
}
body.cid-community > #deprecation-warning > .deprecation-warning > * {
color: inherit;
background-color: inherit;
}
#caseStudies body > #deprecation-warning > .deprecation-warning, body.cid-casestudies > #deprecation-warning > .deprecation-warning {
color: inherit;
background: inherit;
width: 80%;
margin: 0;
margin-top: 120px;
margin-left: auto;
margin-right: auto;
border-radius: initial;
}
#deprecation-warning > .deprecation-warning a {
background: transparent;
color: inherit;
text-decoration: underline;
}
// search & sidebar
.td-sidebar {
@media only screen and (min-width: 768px) {
padding-top: 1.5rem !important;
.td-sidebar__inner {
top: 8.5rem;
@media only screen and (min-width: 1075px) {
top: 6.5rem;
}
}
}
}
.td-sidebar-nav {
& > .td-sidebar-nav__section {
padding-top: .5rem;
padding-left: 1.5rem;
}
}
.td-sidebar__inner {
form.td-sidebar__search {
button.td-sidebar__toggle {
&:hover {
color: #000000;
}
color: $blue;
margin: 1rem;
}
}
}
.no-underline {
text-decoration: none !important;
}
.hide {
display: none !important;
}
.td-sidebar-link__page {
&#m-docs-search {
display: none;
}
&#m-docs-test {
display: none;
}
}
//Tutorials
main.content {
position: inherit;
}
/* BLOG */
.td-blog {
.td-sidebar-nav {
max-height: calc(100vh - 8rem);
}
.widget-link {
margin-bottom: 1rem;
.svg-inline--fa {
width: 25px;
}
span {
margin-left: 0.5rem;
}
}
}
/* COMMUNITY */
.newcommunitywrapper {
.news {
margin-left: 0;
@media screen and (min-width: 768px) {
margin-left: 10%;
}
}
}
/* CASE-STUDIES */
// Many of the case studies have small variations in markup and styles;
// some issues cannot be addressed due to inlined !important rules.
#caseStudies {
section .cols {
margin-left: 11%;
div {
width: initial !important;
h2 {
margin-top: 1rem;
}
}
}
}
/* ANNOUNCEMENTS */
section#fp-announcement ~ .header-hero {
padding: $announcement-size-adjustment 0;
> div {
margin-top: $announcement-size-adjustment;
margin-bottom: $announcement-size-adjustment;
}
h1, h2, h3, h4, h5 {
margin: $announcement-size-adjustment 0;
}
}
section#announcement ~ .header-hero {
padding: #{$announcement-size-adjustment / 2} 0;
> div {
margin-top: #{$announcement-size-adjustment / 2};
margin-bottom: #{$announcement-size-adjustment / 2};
padding-bottom: #{$announcement-size-adjustment / 2};
}
h1, h2, h3, h4, h5 {
margin: #{$announcement-size-adjustment / 2} 0;
}
}
/* DOCUMENTATION */
/* Don't show lead text */
body.td-documentation {
main {
@media only screen {
> * {
> .lead:first-of-type {
display: none;
}
}
}
}
}
/* glossary tooltip */
.glossary-tooltip {
display: inline-block;
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
color: black;
text-decoration: none !important;
}
-99
View File
@@ -1,99 +0,0 @@
$main-max-width: 1200px;
$vendor-strip-height: 44px;
$video-section-height: 550px;
@media screen and (min-width: 1024px) {
.td-home {
.header-hero {
#vendorStrip {
display: block;
}
}
}
.td-home {
section,
header,
footer {
.main-section {
max-width: 1000px;
}
}
}
#oceanNodes {
.main-section {
position: relative;
&:nth-child(1) {
max-width: 1000px;
padding-right: 475px;
h3,
p {
text-align: left
}
.image-wrapper {
position: absolute;
max-width: 48%;
transform: translateY(-50%);
}
img {
width: 425px;
}
}
}
}
#video {
height: $video-section-height;
position: relative;
background-position: center center;
background-size: cover;
&>.light-text {
margin-right: 10%;
}
}
#talkToUs {
h4 {
br {
display: block;
}
}
#bigSocial {
div {
width: calc(25% - 18px);
}
div+div {
margin-left: 20px;
}
}
.td-home #bigSocial {
div {
width: calc(33% - 15px);
}
div:nth-child(3) {
margin-top: inherit;
}
}
}
.td-home #caseStudiesWrapper {
div {
width: 24%;
min-height: 260px;
}
}
}
-49
View File
@@ -1,49 +0,0 @@
// CONVENIENCE
.clear {
display: block;
clear: both;
}
.light-text {
color: white;
}
.right {
float: right;
}
.left {
float: left;
}
.center {
text-align: center;
}
//mixins
@mixin fullScreen {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
@mixin pureCenter($left: 50%, $top: 50%) {
position: absolute;
top: $top;
left: $left;
transform: translate(-50%, -50%);
}
@mixin maintain-aspect-ratio(
$width-factor: 16,
$height-factor: 9,
$target-width: 80vw,
$target-height: 80vh
) {
width: $target-width;
height: $target-width * ($height-factor / $width-factor);
max-width: $target-height * ($width-factor / $height-factor);
max-height: $target-height;
}
-20
View File
@@ -1,20 +0,0 @@
section,
#vendorStrip {
padding-left: $full-width-paddingX;
padding-right: $full-width-paddingX;
}
#hamburger {
width: $hamburger-size;
height: $hamburger-size;
}
.header-hero {
padding-top: $hero-padding-top;
}
#vendorStrip {
height: $vendor-strip-height;
line-height: $vendor-strip-height;
font-size: $vendor-strip-font-size;
}
-5
View File
@@ -1,5 +0,0 @@
$blue: #3371e3;
$light-grey: #f7f7f7;
$dark-grey: #303030;
$medium-grey: #4c4c4c;
$white: #ffffff;
-214
View File
@@ -1,214 +0,0 @@
// header
$full-width-paddingX: 20px;
$main-width: 100%;
$main-max-width: 100%;
$header-height: 80px;
$logo-width: 180px;
$nav-buttons-margin-left: 30px;
$hamburger-size: 50px;
// main nav
$main-nav-padding: 140px 0 30px;
$main-nav-h5-margin-bottom: 1em;
$main-nav-h3-margin-bottom: 0.6em;
$nav-box-width: 20%;
$nav-box-sibling-margin-left: calc(20% / 3);
$main-nav-main-sibling-margin-top: 60px;
$main-nav-left-button-size: 50px;
$main-nav-left-button-font-size: 18px;
// hero
$hero-padding-top: 116px;
$headline-wrapper-margin-bottom: 40px;
$quickstart-button-padding: 0 50px;
$vendor-strip-font-size: 16px;
//video
$video-section-height: 400px;
//features
$features-h3-margin-bottom: 40px;
$feature-box-margin-bottom: 60px;
$feature-box-div-margin-bottom: 0;
$feature-box-div-width: 45%;
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
@media screen and (min-width: 768px) {
@import "size";
#hamburger {
display: none;
}
.td-home {
#viewDocs,
#tryKubernetes {
display: inline-block;
}
}
#vendorStrip {
display: block;
text-align: center;
img {
max-height: 24px;
vertical-align: middle;
margin: 0 30px;
}
}
#oceanNodes {
h3 {
text-align: left;
margin-bottom: 18px;
}
main,
.main-section {
position: relative;
clear: both;
display: table;
height: 160px;
.content {
display: table-cell;
position: relative;
vertical-align: middle;
}
.image-wrapper {
position: absolute;
top: 50%;
max-width: 25%;
max-height: 100%;
transform: translateY(-50%);
width: 100%;
}
&:nth-child(odd) {
padding-right: 210px;
.image-wrapper {
right: 0;
text-align: right;
}
}
&:nth-child(even) {
padding-left: 210px;
.image-wrapper {
left: 0;
text-align: left;
}
}
&:nth-child(1) {
padding-right: 0;
h3,
p {
text-align: center;
}
.image-wrapper {
position: relative;
display: block;
float: none;
max-width: 100%;
transform: none;
}
.content {
display: block;
}
}
img {
width: 100%;
}
}
}
#video {
height: $video-section-height;
display: block;
height: 500px;
& > .light-text {
display: block;
float: right;
text-align: left;
margin-right: 5%;
}
}
#mobileShowVideoButton {
display: none;
}
#features {
padding-bottom: 60px;
.feature-box {
margin-bottom: 30px;
&:last-child {
margin-bottom: 0;
}
}
h3 {
margin-bottom: $features-h3-margin-bottom;
}
.feature-box {
& > div {
width: $feature-box-div-width;
margin-bottom: $feature-box-div-margin-bottom;
}
}
}
#talkToUs {
#bigSocial {
div {
width: calc(50% - 15px);
}
div + div {
margin-top: 0;
}
div:nth-child(2) {
margin-left: 20px;
}
div:nth-child(4) {
margin-left: 20px;
}
a {
display: inline-block;
color: $blue;
font-weight: 400;
text-decoration: none;
}
}
}
.td-home #caseStudiesWrapper {
div {
width: 48%;
}
}
}
-27
View File
@@ -1,27 +0,0 @@
/* This file is provided by Docsy as an entry point to styling.
Add styles or override variables from the theme here. */
@import "reset";
@import "skin";
//K8S-Docsy integration
@import "custom";
//Media queries
@import "base";
@import "tablet";
@import "desktop";
$primary: #3371e3;
// tooltip
$tooltip-bg: #555;
$tooltip-arrow-color: $tooltip-bg !default;
$tooltip-arrow-width: 10px !default;
$tooltip-opacity: 1 !default;
$tooltip-color: #fff !default;
$tooltip-max-width: 300px !default;
$tooltip-font-size: 1rem;
$tooltip-padding: 5px 8px;
$tooltip-border-radius: 6px;
$tooltip-font-weight: 400;
+43 -375
View File
@@ -1,28 +1,21 @@
baseURL = "https://kubernetes.io"
title = "Kubernetes"
# Hugo allows theme composition (and inheritance). The precedence is from left to right.
theme = ["docsy"]
# Language settings
contentDir = "content/en"
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = false
enableRobotsTXT = true
disableBrowserError = true
disableKinds = ["taxonomy", "taxonomyTerm"]
ignoreFiles = [ "^OWNERS$", "README[-]+[a-z]*\\.md", "^node_modules$", "content/en/docs/doc-contributor-tools" ]
contentDir = "content/en"
timeout = 3000
# Highlighting config.
pygmentsCodeFences = true
pygmentsUseClasses = false
# Use the new Chroma Go highlighter in Hugo.
pygmentsUseClassic = false
#pygmentsOptions = "linenos=table"
# See https://help.farbox.com/pygments.html
pygmentsStyle = "emacs"
@@ -30,52 +23,11 @@ pygmentsStyle = "emacs"
enableGitInfo = true
# Norwegian ("no") is sometimes but not currently used for testing.
# Hindi is disabled because it's currently in development.
disableLanguages = ["hi", "no"]
disableLanguages = ["no"]
[caches]
[caches.assets]
dir = ":cacheDir/_gen"
maxAge = -1
[caches.getcsv]
dir = ":cacheDir/:project"
maxAge = "60s"
[caches.getjson]
dir = ":cacheDir/:project"
maxAge = "60s"
[caches.images]
dir = ":cacheDir/_images"
maxAge = -1
[caches.modules]
dir = ":cacheDir/modules"
maxAge = -1
[markup]
[markup.goldmark]
[markup.goldmark.extensions]
definitionList = true
table = true
typographer = false
[markup.goldmark.parser]
attribute = true
autoHeadingID = true
autoHeadingIDType = "blackfriday"
[markup.goldmark.renderer]
unsafe = true
[markup.highlight]
codeFences = true
guessSyntax = false
hl_Lines = ""
lineNoStart = 1
lineNos = false
lineNumbersInTable = true
noClasses = true
style = "emacs"
tabWidth = 4
[markup.tableOfContents]
endLevel = 3
ordered = false
startLevel = 2
[blackfriday]
hrefTargetBlank = true
fractions = false
[frontmatter]
date = ["date", ":filename", "publishDate", "lastmod"]
@@ -83,10 +35,6 @@ date = ["date", ":filename", "publishDate", "lastmod"]
[permalinks]
blog = "/:section/:year/:month/:day/:slug/"
[sitemap]
filename = "sitemap.xml"
priority = 0.75
# Be explicit about the output formats. We (currently) only want an RSS feed for the home page.
[outputs]
home = [ "HTML", "RSS", "HEADERS" ]
@@ -109,188 +57,69 @@ baseName = "_headers"
isPlainText = true
notAlternative = true
# Image processing configuration.
[imaging]
resampleFilter = "CatmullRom"
quality = 75
anchor = "smart"
[services]
[services.googleAnalytics]
# Comment out the next line to disable GA tracking. Also disables the feature described in [params.ui.feedback].
id = "UA-00000000-0"
[params]
copyright_k8s = "The Kubernetes Authors"
copyright_linux = "Copyright © 2020 The Linux Foundation ®."
# privacy_policy = "https://policies.google.com/privacy"
# First one is picked as the Twitter card image if not set on page.
# images = ["images/project-illustration.png"]
# Menu title if your navbar has a versions selector to access old versions of your site.
# This menu appears only if you have at least one [params.versions] set.
version_menu = "Versions"
time_format_blog = "Monday, January 02, 2006"
time_format_default = "January 02, 2006 at 3:04 PM PST"
description = "Production-Grade Container Orchestration"
showedit = true
latest = "v1.19"
latest = "v1.14"
fullversion = "v1.19.0"
version = "v1.19"
githubbranch = "master"
docsbranch = "master"
deprecated = false
fullversion = "v1.10.13"
version = "v1.10"
githubbranch = "v1.10.13"
docsbranch = "release-1.10"
deprecated = true
currentUrl = "https://kubernetes.io/docs/home/"
nextUrl = "https://kubernetes-io-vnext-staging.netlify.com/"
# See codenew shortcode
githubWebsiteRepo = "github.com/kubernetes/website"
githubWebsiteRaw = "raw.githubusercontent.com/kubernetes/website"
# GitHub repository link for editing a page and opening issues.
github_repo = "https://github.com/kubernetes/website"
# param for displaying an announcement block on every page.
# See /i18n/en.toml for message text and title.
announcement = true
announcement_bg = "#3f0374" # choose a dark color text is white
#Searching
k8s_search = true
#The following search parameters are specific to Docsy's implementation. Kubernetes implementes its own search-related partials and scripts.
# Google Custom Search Engine ID. Remove or comment out to disable search.
#gcs_engine_id = "011737558837375720776:fsdu1nryfng"
# Enable Algolia DocSearch
algolia_docsearch = false
# Enable Lunr.js offline search
offlineSearch = false
[params.pushAssets]
css = [
"callouts",
"styles"
"styles",
"custom-jekyll/tags"
]
js = [
"custom-jekyll/tags",
"script"
]
[[params.versions]]
fullversion = "v1.19.0"
version = "v1.19"
githubbranch = "v1.19.0"
docsbranch = "master"
fullversion = "v1.14.0"
version = "v1.14"
githubbranch = "v1.14.0"
docsbranch = "release-1.14"
url = "https://kubernetes.io"
[[params.versions]]
fullversion = "v1.18.8"
version = "v1.18"
githubbranch = "v1.18.8"
docsbranch = "release-1.18"
url = "https://v1-18.docs.kubernetes.io"
fullversion = "v1.13.4"
version = "v1.13"
githubbranch = "v1.13.4"
docsbranch = "release-1.13"
url = "https://v1-13.docs.kubernetes.io"
[[params.versions]]
fullversion = "v1.17.11"
version = "v1.17"
githubbranch = "v1.17.11"
docsbranch = "release-1.17"
url = "https://v1-17.docs.kubernetes.io"
fullversion = "v1.12.6"
version = "v1.12"
githubbranch = "v1.12.6"
docsbranch = "release-1.12"
url = "https://v1-12.docs.kubernetes.io"
[[params.versions]]
fullversion = "v1.16.14"
version = "v1.16"
githubbranch = "v1.16.14"
docsbranch = "release-1.16"
url = "https://v1-16.docs.kubernetes.io"
fullversion = "v1.11.8"
version = "v1.11"
githubbranch = "v1.11.8"
docsbranch = "release-1.11"
url = "https://v1-11.docs.kubernetes.io"
[[params.versions]]
fullversion = "v1.15.12"
version = "v1.15"
githubbranch = "v1.15.12"
docsbranch = "release-1.15"
url = "https://v1-15.docs.kubernetes.io"
# User interface configuration
[params.ui]
# Enable to show the side bar menu in its compact state.
sidebar_menu_compact = false
# Set to true to disable breadcrumb navigation.
breadcrumb_disable = false
# Set to true to hide the sidebar search box (the top nav search box will still be displayed if search is enabled)
sidebar_search_disable = false
# Set to false if you don't want to display a logo (/assets/icons/logo.svg) in the top nav bar
navbar_logo = true
# Set to true to disable the About link in the site footer
footer_about_disable = false
# Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events.
# This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set.
# If you want this feature, but occasionally need to remove the "Feedback" section from a single page,
# add "hide_feedback: true" to the page's front matter.
[params.ui.feedback]
enable = true
# The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful).
yes = 'Glad to hear it! Please <a href="https://github.com/USERNAME/REPOSITORY/issues/new">tell us how we can improve</a>.'
no = 'Sorry to hear that. Please <a href="https://github.com/USERNAME/REPOSITORY/issues/new">tell us how we can improve</a>.'
[params.links]
# End user relevant links. These will show up on left side of footer and in the community page if you have one.
[[params.links.user]]
name = "User mailing list"
url = "https://discuss.kubernetes.io"
icon = "fa fa-envelope"
desc = "Discussion and help from your fellow users"
[[params.links.user]]
name = "Twitter"
url = "https://twitter.com/kubernetesio"
icon = "fab fa-twitter"
desc = "Follow us on Twitter to get the latest news!"
[[params.links.user]]
name = "Calendar"
url = "https://calendar.google.com/calendar/embed?src=calendar%40kubernetes.io"
icon = "fas fa-calendar-alt"
desc = "Google Calendar for Kubernetes"
[[params.links.user]]
name = "Youtube"
url = "https://youtube.com/kubernetescommunity"
icon = "fab fa-youtube"
desc = "Youtube community videos"
# Developer relevant links. These will show up on right side of footer and in the community page if you have one.
[[params.links.developer]]
name = "GitHub"
url = "https://github.com/kubernetes/kubernetes"
icon = "fab fa-github"
desc = "Development takes place here!"
[[params.links.developer]]
name = "Slack"
url = "https://slack.k8s.io"
icon = "fab fa-slack"
desc = "Chat with other project developers"
[[params.links.developer]]
name = "Contribute"
url = "https://git.k8s.io/community/contributors/guide"
icon = "fas fa-edit"
desc = "Contribute to the Kubernetes website"
[[params.links.developer]]
name = "Stack Overflow"
url = "https://stackoverflow.com/questions/tagged/kubernetes"
icon = "fab fa-stack-overflow"
desc = "Practical questions and curated answers"
fullversion = "v1.10.13"
version = "v1.10"
githubbranch = "v1.10.13"
docsbranch = "release-1.10"
url = "https://v1-10.docs.kubernetes.io"
# Language definitions.
@@ -301,190 +130,29 @@ description = "Production-Grade Container Orchestration"
languageName ="English"
# Weight used for sorting.
weight = 1
languagedirection = "ltr"
[languages.zh]
title = "Kubernetes"
description = "生产级别的容器编排系统"
description = "Production-Grade Container Orchestration"
languageName = "中文 Chinese"
weight = 2
contentDir = "content/zh"
languagedirection = "ltr"
[languages.zh.params]
time_format_blog = "2006.01.02"
language_alternatives = ["en"]
[languages.ko]
title = "Kubernetes"
description = "운영 수준의 컨테이너 오케스트레이션"
description = "Production-Grade Container Orchestration"
languageName = "한국어 Korean"
weight = 3
contentDir = "content/ko"
languagedirection = "ltr"
[languages.ko.params]
time_format_blog = "2006.01.02"
language_alternatives = ["en"]
[languages.ja]
title = "Kubernetes"
description = "プロダクショングレードのコンテナ管理基盤"
languageName = "日本語 Japanese"
weight = 4
contentDir = "content/ja"
languagedirection = "ltr"
[languages.ja.params]
time_format_blog = "2006.01.02"
language_alternatives = ["en"]
[languages.fr]
title = "Kubernetes"
description = "Solution professionnelle dorchestration de conteneurs"
languageName ="Français"
weight = 5
contentDir = "content/fr"
languagedirection = "ltr"
[languages.fr.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.it]
title = "Kubernetes"
description = "Orchestrazione di Container in produzione"
languageName = "Italiano"
weight = 6
contentDir = "content/it"
languagedirection = "ltr"
[languages.it.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.no]
title = "Kubernetes"
description = "Production-Grade Container Orchestration"
languageName ="Norsk"
weight = 7
weight = 4
contentDir = "content/no"
languagedirection = "ltr"
[languages.no.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.de]
title = "Kubernetes"
description = "Produktionsreife Container-Orchestrierung"
languageName ="Deutsch"
weight = 8
contentDir = "content/de"
languagedirection = "ltr"
[languages.de.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.es]
title = "Kubernetes"
description = "Orquestación de contenedores para producción"
languageName ="Español"
weight = 9
contentDir = "content/es"
languagedirection = "ltr"
[languages.es.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.pt]
title = "Kubernetes"
description = "Orquestração de contêineres em nível de produção"
languageName ="Português"
weight = 9
contentDir = "content/pt"
languagedirection = "ltr"
[languages.pt.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.id]
title = "Kubernetes"
description = "Orkestrasi Kontainer dengan Skala Produksi"
languageName ="Bahasa Indonesia"
weight = 10
contentDir = "content/id"
languagedirection = "ltr"
[languages.id.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.hi]
title = "Kubernetes"
description = "Production-Grade Container Orchestration"
languageName = "Hindi"
weight = 11
contentDir = "content/hi"
languagedirection = "ltr"
[languages.hi.params]
time_format_blog = "01.02.2006"
language_alternatives = ["en"]
[languages.vi]
title = "Kubernetes"
description = "Giải pháp điều phối container trong môi trường production"
languageName = "Tiếng Việt"
contentDir = "content/vi"
weight = 12
languagedirection = "ltr"
[languages.ru]
title = "Kubernetes"
description = "Первоклассная оркестрация контейнеров"
languageName = "Русский"
weight = 12
contentDir = "content/ru"
languagedirection = "ltr"
[languages.ru.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.pl]
title = "Kubernetes"
description = "Produkcyjny system zarządzania kontenerami"
languageName = "Polski"
weight = 13
contentDir = "content/pl"
languagedirection = "ltr"
[languages.pl.params]
time_format_blog = "01.02.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
[languages.uk]
title = "Kubernetes"
description = "Довершена система оркестрації контейнерів"
languageName = "Українська"
weight = 14
contentDir = "content/uk"
languagedirection = "ltr"
[languages.uk.params]
time_format_blog = "02.01.2006"
# A list of language codes to look for untranslated content, ordered from left to right.
language_alternatives = ["en"]
+153
View File
@@ -0,0 +1,153 @@
---
title: "生产级别的容器编排系统"
abstract: "自动化的容器部署、扩展和管理"
cid: "home"
---
<section id="oceanNodes">
<main>
<div class="image-wrapper"><img src="/images/flower.png"></div>
<div class="content">
<h3><a href="/docs/concepts/overview/what-is-kubernetes/">Kubernetes</a> 是用于自动部署,扩展和管理容器化应用程序的开源系统。</h3>
<p>它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现,Kubernetes 构建在 <a href="http://queue.acm.org/detail.cfm?id=2898444"> Google 15 年生产环境经验</a>基础之上,并结合来自社区的最佳创意和实践。</p>
</div>
</main>
<main>
<div class="image-wrapper"><img src="/images/scalable.png"></div>
<div class="content">
<h4>星际尺度</h4>
<p>根据同样的原则设计,允许 Google 每周运行数十亿个容器,Kubernetes 可以在不增加您的 ops 团队的情况下进行弹性扩展。</p>
</div>
</main>
<main>
<div class="image-wrapper"><img src="/images/blocks.png"></div>
<div class="content">
<h4>永不过时</h4>
<p>无论您应用运行在本地还是运行于全球任何地域,Kubernetes 的灵活性都可以随着您的需求复杂度不断增加,还可以持续、轻松地对外提供服务。</p>
</div>
</main>
<main>
<div class="image-wrapper"><img src="/images/suitcase.png"></div>
<div class="content">
<h4>随处运行</h4>
<p>Kubernetes 是开源的,可以让您自由地部署在企业内部,私有云、混合云或公有云基础架构,使您轻松将应用迁移至任何位置。</p>
</div>
</main>
</section>
<section id="video">
<div class="light-text">
<h2>Kubernetes: 最后&hellip; 它是真正的云平台</h2>
<p>Box 的联合创始人和服务架构师 Sam Ghods 发表了热情洋溢的演讲,随着使用 Kubernetes,我们首次有一个通用接口,可以建立真正的部署工具。</p>
<button id="desktopShowVideoButton" onclick="kub.showVideo()">观看视频</button>
</div>
<button id="mobileShowVideoButton" onclick="kub.showVideo()"></button>
</section>
<section id="features">
<main>
<h3 class="center">Kubernetes 特性</h3>
<div class="feature-box">
<div>
<h4><a href="/docs/concepts/configuration/manage-compute-resources-container/">自动包装</a></h4>
<p>根据资源需求和其他约束自动放置容器,同时不会牺牲可用性,混合关键和最大努力的工作负载,以提高资源利用率并节省更多资源。</p>
</div>
<div>
<h4><a href="/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller">自我修复</a></h4>
<p>重新启动失败的容器,在节点不可用时,替换和重新编排节点上的容器,终止不对用户定义的健康检查做出响应的容器,并且不会在客户端准备投放之前将其通告给客户端。</p>
</div>
</div>
<div class="feature-box">
<div>
<h4><a href="/docs/tasks/run-application/horizontal-pod-autoscale/">横向缩放</a></h4>
<p>使用简单的命令或 UI,或者根据 CPU 的使用情况自动调整应用程序副本数。</p>
</div>
<div>
<h4><a href="/docs/concepts/services-networking/service/">服务发现和负载均衡</a></h4>
<p>不需要修改您的应用程序来使用不熟悉的服务发现机制,Kubernetes 为容器提供了自己的 IP 地址和一组容器的单个 DNS 名称,并可以在它们之间进行负载均衡。</p>
</div>
</div>
<div class="feature-box">
<div>
<h4><a href="/docs/concepts/workloads/controllers/deployment/#what-is-a-deployment">自动部署和回滚</a></h4>
<p>Kubernetes 逐渐部署对应用程序或其配置的更改,同时监视应用程序运行状况,以确保它不会同时终止所有实例。 如果出现问题,Kubernetes会为您恢复更改,利用日益增长的部署解决方案的生态系统。</p>
</div>
<div>
<h4><a href="/docs/concepts/configuration/secret/">密钥</a><a href="/docs/tasks/configure-pod-container/configure-pod-configmap/">配置</a> 管理</h4>
<p>部署和更新密钥和应用程序配置,不会重新编译您的镜像,不会在堆栈配置中暴露密钥(secrets)。</p>
</div>
</div>
<div class="feature-box">
<div>
<h4><a href="/docs/concepts/storage/persistent-volumes/">存储编排</a></h4>
<p>自动安装您所选择的存储系统,无论是本地存储,如公有云提供商 <a href="https://cloud.google.com/storage/">GCP</a><a href="https://aws.amazon.com/products/storage/">AWS</a>, 还是网络存储系统 NFS, iSCSI,
Gluster, Ceph, Cinder, 或 Flocker。</p>
</div>
<div>
<h4><a href="/docs/concepts/workloads/controllers/jobs-run-to-completion/">批处理</a></h4>
<p>除了服务之外,Kubernetes还可以管理您的批处理和 CI 工作负载,如果需要,替换出现故障的容器。</p>
</div>
</div>
</main>
</section>
<section id="talkToUs">
<main>
<h3>实例探究</h3>
<div id="caseStudiesWrapper">
<div>
<p>使用Kubernetes来重塑世界上最大的教育公司</p>
<a href="/case-studies/pearson/">阅读更多</a>
</div>
<div>
<p>Kubernetes at Box: 微服务的最大优势</p>
<a href="https://blog.box.com/blog/kubernetes-box-microservices-maximum-velocity/">阅读更多</a>
</div>
<div>
<p>在 eBay 内部转移到 OpenStack 上的 Kubernetes 和容器</p>
<a href="https://www.nextplatform.com/2015/11/12/inside-ebays-shift-to-kubernetes-and-containers-atop-openstack/">阅读更多</a>
</div>
<div>
<p>将本地的集群迁移至 Kubernetes</p>
<a href="https://www.youtube.com/watch?v=6XGUTu3WhBw">观看视频</a>
</div>
</div>
<h5 style="text-align: center"><a href="/case-studies/" style="color: #3371E3; font-weight: 400">探究所有的案例</a></h5>
</main>
</section>
<div id="videoPlayer">
<iframe data-url="https://www.youtube.com/embed/of45hYbkIZs?autoplay=1" frameborder="0" allowfullscreen></iframe>
<button id="closeButton"></button>
</div>
View File
+4
View File
@@ -0,0 +1,4 @@
---
title: Home
weight: 5
---
+135
View File
@@ -0,0 +1,135 @@
---
approvers:
- bgrant0607
- erictune
- lavalamp
title: Kubernetes API访问控制
---
用户通过 `kubectl`、客户端库或者通过发送REST请求[访问API](/docs/user-guide/accessing-the-cluster)。 用户(自然人)和[Kubernetes服务账户](/docs/tasks/configure-pod-container/configure-service-account/) 都可以被授权进行API访问。
请求到达API服务器后会经过几个阶段,具体说明如图:
![Diagram of request handling steps for Kubernetes API request](/images/docs/admin/access-control-overview.svg)
## 传输层安全
在典型的Kubernetes集群中,API通过443端口提供服务。
API服务器会提供一份证书。 该证书一般是自签名的, 所以用户机器上的 `$USER/.kube/config` 目录通常
包含该API服务器证书的根证书,用来代替系统默认根证书。 当用户使用 `kube-up.sh` 创建集群时,该证书通常会被自动写入用户的`$USER/.kube/config`。 如果集群中存在多个用户,则创建者需要与其他用户共享证书。
## 认证
一旦 TLS 连接建立,HTTP请求就进入到了认证的步骤。即图中的步骤 **1**
集群创建脚本或集群管理员会为API服务器配置一个或多个认证模块。
更具体的认证相关的描述详见 [这里](/docs/admin/authentication/)。
认证步骤的输入是整个HTTP请求,但这里通常只是检查请求头和/或客户端证书。
认证模块支持客户端证书,密码和Plain Tokens
Bootstrap Tokens,以及JWT Tokens (用于服务账户)。
(管理员)可以同时设置多种认证模块,在设置了多个认证模块的情况下,每个模块会依次尝试认证,
直到其中一个认证成功。
在 GCE 平台中,客户端证书,密码和Plain TokensBootstrap Tokens,以及JWT Tokens同时被启用。
如果请求认证失败,则请求被拒绝,返回401状态码。
如果认证成功,则被认证为具体的 `username`,该用户名可供随后的步骤中使用。一些认证模块还提供了用户的组成员关系,另一些则没有。
尽管Kubernetes使用 "用户名" 来进行访问控制和请求记录,但它实际上并没有 `user` 对象,也不存储用户名称或其他相关信息。
## 授权
当请求被认证为来自某个特定的用户后,该请求需要被授权。 即图中的步骤 **2** 。
请求须包含请求者的用户名,请求动作,以及该动作影响的对象。 如果存在相应策略,声明该用户具有进行相应操作的权限,则该请求会被授权。
例如,如果Bob有如下策略,那么他只能够读取`projectCaribou`命名空间下的pod资源:
```json
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "bob",
"namespace": "projectCaribou",
"resource": "pods",
"readonly": true
}
}
```
如果Bob发起以下请求,那么请求能够通过授权,因为Bob被允许访问 `projectCaribou` 命名空间下的对象:
```json
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "projectCaribou",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
}
}
}
```
如果Bob对 `projectCaribou` 命名空间下的对象发起一个写(`create` 或者 `update`)请求,那么它的授权会被拒绝。 如果Bob请求读取(`get`) 其他命名空间,例如 `projectFish`下的对象,其授权也会被拒绝。
Kubernetes的授权要求使用通用的REST属性与现有的组织或云服务提供商的访问控制系统进行交互。 采用REST格式是必要的,因为除Kubernetes外,这些访问控制系统还可能与其他的API进行交互。
Kubernetes 支持多种授权模块,例如ABAC模式,RBAC模式和 Webhook模式。 管理员创建集群时,会配置API服务器应用的授权模块。 如果多种授权模式同时被启用,Kubernetes将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP状态码403)。
要了解更多的Kubernetes授权相关信息,包括使用授权模块创建策略的具体说明等,可参考[授权概述](/docs/admin/authorization)。
## 准入控制
准入控制模块是能够修改或拒绝请求的软件模块。
作为授权模块的补充,准入控制模块会访问被创建或更新的对象的内容。
它们作用于对象的创建,删除,更新和连接 (proxy)阶段,但不包括对象的读取。
可以同时配置多个准入控制器,它们会按顺序依次被调用。
即图中的步骤 **3** 。
与认证和授权模块不同的是,如果任一个准入控制器拒绝请求,那么整个请求会立即被拒绝。
除了拒绝请求外,准入控制器还可以为对象设置复杂的默认值。
可用的准入控制模块描述 [如下](/docs/admin/admission-controllers/)。
一旦请求通过所有准入控制器,将使用对应API对象的验证流程对其进行验证,然后写入对象存储 (如步骤 **4**)。
## API的端口和IP
上述讨论适用于发送请求到API服务器的安全端口(典型情况)。
实际上API服务器可以通过两个端口提供服务:
默认情况下,API服务器在2个端口上提供HTTP服务:
1. `Localhost Port`:
- 用于测试和启动,以及管理节点的其他组件
(scheduler, controller-manager)与API的交互
- 没有TLS
- 默认值为8080,可以通过 `--insecure-port` 标记来修改。
- 默认的IP地址为localhost, 可以通过 `--insecure-bind-address`标记来修改。
- 请求会 **绕过** 认证和鉴权模块。
- 请求会被准入控制模块处理。
- 其访问需要主机访问的权限。
2. `Secure Port`:
- 尽可能使用该端口访问
- 应用 TLS。 可以通过 `--tls-cert-file` 设置证书, 通过 `--tls-private-key-file` 设置私钥。
- 默认值为6443,可以通过 `--secure-port` 标记来修改。
- 默认IP是首个非本地的网络接口地址,可以通过 `--bind-address` 标记来修改。
- 请求会经过认证和鉴权模块处理。
- 请求会被准入控制模块处理。
- 要求认证和授权模块正常运行。
通过 `kube-up.sh`创建集群时, 对 Google Compute Engine (GCE)
和一些其他的云供应商来说, API通过443端口提供服务。 对
GCE而言,项目上配置了防火墙规则,允许外部的HTTPS请求访问API,其他(厂商的)集群设置方法各不相同。
@@ -0,0 +1,156 @@
---
approvers:
- erictune
- lavalamp
- deads2k
- liggitt
title: 概述
content_template: templates/concept
---
{{% capture overview %}}
学习有关 Kubernetes 授权的更多信息,包括有关使用支持的授权模块创建策略的详细信息。
{{% /capture %}}
{{% capture body %}}
在 Kubernetes 里,您必须经过身份验证(登录),才能授权您的请求(授予访问权限).。有关认证的信息,请参阅[访问控制概述](/docs/admin/access-the-api/)。
Kubernetes 提供通用的 REST API 请求。这意味着 Kubernetes 授权可以与现有的组织或云提供商的访问控制系统一起使用,该系统可以处理除 Kubernetes API 之外的其他 API。
## 确定请求是允许还是被拒绝
Kubernetes 使用 API 服务器授权 API 请求。它根据所有策略评估所有请求属性,并允许或拒绝请求。某些策略必须允许 API 请求的所有部分继续进行,这意味着默认情况下是拒绝权限。
(虽然 Kubernetes 使用 API ​​服务器,访问控制和依赖特定类型对象的特定领域策略由 Admission 控制器处理。)
当配置多个授权模块时,按顺序检查每个模块,如果有任何模块授权请求,则可以继续执行该请求。如果所有模块拒绝请求,则拒绝该请求(HTTP状态代码403)。
## 查看您的请求属性
Kubernetes 仅查看以下API请求属性:
* **user** - 验证期间提供的 `user` 字符串
* **group** - 认证用户所属的组名列表
* **“extra"** - 由认证层提供的任意字符串键到字符串值的映射
* **API** - 指示请求是否用于API资源
* **Request path** - 诸如`/api``/healthz`的其他非资源端点的路径(请参阅[kubectl](#kubectl)).
* **API request verb** - API 动词 `get``list``create``update``patch``watch``proxy``redirect``delete``deletecollection`用于资源请求。要确定资源 API 端点的请求动词,请参阅**确定下面的请求动词**.
* **HTTP request verb** - HTTP动词`get``post``put``delete`用于非资源请求
* **Resource** - 正在访问的资源的ID或名称(仅适用于资源请求)
--* 对于使用`get`, `update`, `patch`, 和 `delete`动词的资源请求,您必须提供资源名称。
* **Subresource** - 正在访问的子资源(仅用于资源请求)
* **Namespace** - 正在被访问的对象的命名空间(仅针对命名空间的资源请求)
* **API group** - 正在访问的API组(仅用于资源请求). 一个空字符串指定[核心 API 组](/docs/api/).
## 确定请求动词
要确定资源 API 端点的请求动词,请查看所使用的HTTP动词以及请求是否对单个资源或资源集合进行操作:
HTTP动词| 请求动词
---------- | ---------------
POST | 创建
GETHEAD | 获取(个人资源),列表(集合)
PUT | 更新
PATCH | 补丁
DELETE| 删除(个人资源),删除(收藏)
Kubernetes 有时会使用专门的动词检查授权以获得额外的权限。例如:
* [PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/)在`extensions` API组中的`podsecuritypolicies`资源上检查`use`动词的授权。
* [RBAC](/docs/admin/authorization/rbac/#privilege-escalation-prevention-and-bootstrapping) 在`rbac.authorization.k8s.io` API组中的`roles``clusterroles`资源上检查`bind`动词的授权。
* [认证](/docs/admin/authentication/) 在核心API组中的`users``groups``serviceaccounts`上的`impersonate`动词的授权以及`authentication.k8s.io` API组中的`userextras`进行层次检查。
## 授权模块
* **ABAC模式** - 基于属性的访问控制(ABAC)定义了访问控制范例,通过使用将属性组合在一起的策略来授予用户访问权限。策略可以使用任何类型的属性(用户属性,资源属性,对象,环境属性等)。要了解有关使用ABAC模式的更多信息,请参阅[ABAC模式](/docs/admin/authorization/abac/)
* **RBAC模式** - 基于角色的访问控制(RBAC)是一种根据企业内个人用户的角色来调整对计算机或网络资源的访问的方法。在这种情况下,访问是单个用户执行特定任务(例如查看,创建或修改文件)的能力。要了解有关使用RBAC模式的更多信息,请参阅[RBAC模式](/docs/admin/authorization/rbac/)
*当指定 "RBAC"(基于角色的访问控制)使用 "rbac.authorization.k8s.io" API组来驱动授权决定时,允许管理员通过Kubernetes API动态配置权限策略.
.. *截至1.6 RBAC模式是测试版.
.. *要启用RBAC,请使用 `--authorization-mode=RBAC` 启动 apiserver.
* **Webhook模式** - WebHook 是HTTP回调:发生事件时发生的HTTP POST; 通过HTTP POST简单的事件通知. 实施 WebHooks 的 Web 应用程序将在某些事情发生时向URL发送消息. 要了解有关使用Webhook模式的更多信息,请参阅[Webhook模式](/docs/admin/authorization/webhook/)
* **自定义模块** - 您可以创建使用Kubernetes的自定义模块. 要了解更多信息,请参阅下面的**自定义模块**。
### 自定义模块
可以相当容易地开发其他实现,APIserver 调用 Authorizer 接口:
```go
type Authorizer interface {
Authorize(a Attributes) error
}
```
以确定是否允许每个API操作.
授权插件是实现此接口的模块.授权插件代码位于 `pkg/auth/authorizer/$MODULENAME` 中。
授权模块可以完全实现,也可以拨出远程授权服务。 授权模块可以实现自己的缓存,以减少具有相同或相似参数的重复授权调用的成本。 开发人员应该考虑缓存和撤销权限之间的交互。
#### 检查API访问
Kubernetes 将 `subjectaccessreviews.v1.authorization.k8s.io` 资源公开为允许外部访问API授权者决策的普通资源。 无论您选择使用哪个授权器,您都可以使用`SubjectAccessReview`发出一个`POST`,就像webhook授权器的`apis/authorization.k8s.io/v1/subjectaccessreviews` 端点一样,并回复一个响应。 例如:
```bash
kubectl create --v=8 -f - << __EOF__
{
"apiVersion": "authorization.k8s.io/v1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "kittensandponies",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
},
"user": "jane",
"group": [
"group1",
"group2"
],
"extra": {
"scopes": [
"openid",
"profile"
]
}
}
}
__EOF__
--- snip lots of output ---
I0913 08:12:31.362873 27425 request.go:908] Response Body: {"kind":"SubjectAccessReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{"resourceAttributes":{"namespace":"kittensandponies","verb":"GET","group":"unicorn.example.org","resource":"pods"},"user":"jane","group":["group1","group2"],"extra":{"scopes":["openid","profile"]}},"status":{"allowed":true}}
subjectaccessreview "" created
```
这对于调试访问问题非常有用,因为您可以使用此资源来确定授权者授予哪些访问权限。
## 为您的授权模块使用标志
您的策略中必须包含一个标志,以指出您的策略包含哪个授权模块:
可以使用以下标志:
- `--authorization-mode=ABAC` 基于属性的访问控制(ABAC)模式允许您使用本地文件配置策略。
- `--authorization-mode=RBAC` 基于角色的访问控制(RBAC)模式允许您使用Kubernetes API创建和存储策略.
- `--authorization-mode=Webhook` WebHook是一种HTTP回调模式,允许您使用远程REST管理授权。
- `--authorization-mode=AlwaysDeny` 此标志阻止所有请求. 仅使用此标志进行测试。
- `--authorization-mode=AlwaysAllow` 此标志允许所有请求. 只有在您不需要API请求授权的情况下才能使用此标志。
您可以选择多个授权模块. 如果其中一种模式为 `AlwaysAllow`,则覆盖其他模式,并允许所有API请求。
## 版本控制
对于版本 1.2,配置了 kube-up.sh 创建的集群,以便任何请求都不需要授权。
从版本 1.3 开始,配置由 kube-up.sh 创建的集群,使得 ABAC 授权模块处于启用状态。但是,其输入文件最初设置为允许所有用户执行所有操作,集群管理员需要编辑该文件,或者配置不同的授权器来限制用户可以执行的操作。
{{% /capture %}}
{{% capture whatsnext %}}
* 要学习有关身份验证的更多信息,请参阅**身份验证**[控制访问 Kubernetes API](docs/admin/access-the-api/)。
* 要了解有关入学管理的更多信息,请参阅[使用 Admission 控制器](docs/admin/admission-controllers/)。
*
{{% /capture %}}
+142
View File
@@ -0,0 +1,142 @@
---
approvers:
- erictune
- lavalamp
- deads2k
- liggitt
title: ABAC 模式
content_template: templates/concept
---
{{% capture overview %}}
基于属性的访问控制(Attribute-based access control - ABAC)定义了访问控制范例,其中通过使用将属性组合在一起的策略来向用户授予访问权限。
{{% /capture %}}
{{% capture body %}}
## 策略文件格式
基于 `ABAC` 模式,可以这样指定策略文件 `--authorization-policy-file=SOME_FILENAME`
此文件是 JSON 格式[每行都是一个JSON对象](http://jsonlines.org/),不应存在封闭的列表或映射,每行只有一个映射。
每一行都是一个 "策略对象",策略对象是具有以下映射的属性:
- 版本控制属性:
- `apiVersion`,字符串类型: 有效值为"abac.authorization.kubernetes.io/v1beta1",允许版本控制和转换策略格式。
- `kind`,字符串类型: 有效值为 "Policy",允许版本控制和转换策略格式。
- `spec` 配置为具有以下映射的属性:
- 匹配属性:
- `user`,字符串类型; 来自 `--token-auth-file` 的用户字符串,如果你指定`user`,它必须与验证用户的用户名匹配。
- `group`,字符串类型; 如果指定`group`,它必须与经过身份验证的用户的一个组匹配,`system:authenticated`匹配所有经过身份验证的请求。`system:unauthenticated`匹配所有未经过身份验证的请求。
- 资源匹配属性:
- `apiGroup`,字符串类型; 一个 API 组。
- 例: `extensions`
- 通配符: `*`匹配所有 API 组。
- `namespace`,字符串类型; 一个命名空间。
- 例如: `kube-system`
- 通配符: `*` 匹配所有资源请求。
- `resource`,字符串类型; 资源类型。
- 例:`pods`
- 通配符: `*`匹配所有资源请求。
- 非资源匹配属性:
- `nonResourcePath`,字符串类型; 非资源请求路径。
- 例如:`/version``/apis`
- 通配符:
- `*` 匹配所有非资源请求。
- `/foo/*` 匹配`/foo/`的所有子路径。
- `readonly`,键入 boolean,如果为 true,则表示该策略仅适用于 getlist 和 watch 操作。
**注意:** 未设置的属性与类型设置为零值的属性相同(例如空字符串,0、false),然而未知的应该可读性优先。
在将来,策略可能以 JSON 格式表示,并通过 REST 界面进行管理。
## 授权算法
请求具有与策略对象的属性对应的属性。
当接收到请求时,确定属性。 未知属性设置为其类型的零值(例如: 空字符串,0,false)。
设置为`“*"`的属性将匹配相应属性的任何值。
检查属性的元组,以匹配策略文件中的每个策略。 如果至少有一行匹配请求属性,则请求被授权(但可能会在稍后验证失败)。
要允许任何经过身份验证的用户执行某些操作,请将策略组属性设置为 `"system:authenticated“`
要允许任何未经身份验证的用户执行某些操作,请将策略组属性设置为`"system:authentication“`
要允许用户执行任何操作,请使用 apiGroup,命名空间,
资源和 nonResourcePath 属性设置为 `“*"`的策略.
要允许用户执行任何操作,请使用设置为`“*”` 的 apiGroupnamespaceresource 和 nonResourcePath 属性编写策略。
## Kubectl
Kubectl 使用 api-server 的 `/api``/apis` 端点进行协商客户端/服务器版本。 通过创建/更新来验证发送到API的对象操作,kubectl 查询某些 swagger 资源。 对于API版本"v1", 那就是`/swaggerapi/api/v1` `/swaggerapi/ experimental/v1`
当使用 ABAC 授权时,这些特殊资源必须明确通过策略中的 `nonResourcePath` 属性暴露出来(参见下面的[例子](#examples)):
* `/api``/api/*``/apis``/apis/*` 用于 API 版本协商.
* `/version` 通过 `kubectl version` 检索服务器版本.
* `/swaggerapi/*` 用于创建/更新操作.
要检查涉及到特定kubectl操作的HTTP调用,您可以调整详细程度:
kubectl --v=8 version
## 例子
1. Alice 可以对所有资源做任何事情:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
```
2. Kubelet 可以读取任何pod:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}
```
3. Kubelet 可以读写事件:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
```
4. Bob 可以在命名空间“projectCaribou"中读取 pod:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}
```
5. 任何人都可以对所有非资源路径进行只读请求:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:unauthenticated", "readonly": true, "nonResourcePath": "*"}}
```
[完整文件示例](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/auth/authorizer/abac/example_policy_file.jsonl)
## 服务帐户的快速说明
服务帐户自动生成用户。 用户名是根据命名约定生成的:
```shell
system:serviceaccount:<namespace>:<serviceaccountname>
```
创建新的命名空间也会导致创建一个新的服务帐户:
```shell
system:serviceaccount:<namespace>:default
```
例如,如果要将 API 的 kube-system 完整权限中的默认服务帐户授予,则可以将此行添加到策略文件中:
```json
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
```
需要重新启动 apiserver 以获取新的策略行.
{{% /capture %}}
@@ -0,0 +1,143 @@
---
approvers:
- erictune
- lavalamp
- deads2k
- liggitt
title: Webhook Mode
content_template: templates/concept
---
{{% capture overview %}}
WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL 。
{{% /capture %}}
{{% 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).
{{% /capture %}}
@@ -9,14 +9,14 @@ title: 使用启动引导令牌(Bootstrap Tokens)认证
## 概述
启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群或者在现有集群中添加新节点时使用的。
它被设计成能够支持 [`kubeadm`](/zh/docs/reference/setup-tools/kubeadm/),但是也可以被用在其他的案例中以便用户在
它被设计成能够支持 [`kubeadm`](/docs/admin/kubeadm/),但是也可以被用在其他的案例中以便用户在
不使用 `kubeadm` 的情况下启动集群。它也被设计成可以通过 RBAC 策略,结合 [Kubelet TLS
Bootstrapping](/zh/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) 系统进行工作。
Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。
启动引导令牌被定义成一个特定类型的 secrets(`bootstrap.kubernetes.io/token`),并存在于
`kube-system` 命名空间中。然后这些 secrets 会被 API 服务器上的启动引导的认证器读取。
控制器管理器中的控制器 TokenCleaner 能够删除过期的令牌。在节点发现的过程中 Kubernetes 会使用特殊的 ConfigMap 对象。
控制器管理器中的 BootstrapSigner 控制器也会使用启动引导令牌为这类对象生成签名信息。
控制器管理器中的控制器TokenCleaner能够删除过期的令牌。在节点发现的过程中Kubernetes会使用特殊的ConfigMap对象。
控制器管理器中的BootstrapSigner控制器也会使用启动引导令牌为这类对象生成签名信息。
目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性变化。
@@ -26,13 +26,13 @@ Bootstrapping](/zh/docs/reference/command-line-tools-reference/kubelet-tls-boots
更加规范地说,它们必须符合正则表达式 `[a-z0-9]{6}\.[a-z0-9]{16}`
令牌的第一部分是 "Token ID" ,它是公共信息。用于引用某个令牌,并确保不会泄露认证所使用的秘密信息。
第二部分是令牌秘密(Token Secret,它应该被共享给收信的第三方。
第二部分是 "令牌秘密(Token Secret",它应该被共享给收信的第三方。
## 启用启动引导令牌
所有与启动引导令牌相关的特性在 Kubernetes v1.6 版本中默认都是禁用的。
你可以在 API 服务器上通过 `--enable-bootstrap-token-auth` 参数启用启动引导令牌。
你可以在 API 服务器上通过 `--experimental-bootstrap-token-auth` 参数启用启动引导令牌。
你可以设置控制管理器的 `--controllers` 参数来启用启动引导令牌相关的控制器,例如 `--controllers=*,tokencleaner,bootstrapsigner`
在使用 `kubeadm` 时,这是自动完成的。
@@ -82,19 +82,19 @@ TokenCleaner 控制器会删除过期的令牌。
## 使用 `kubeadm` 管理令牌
你可以使用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群`/etc/kubernetes/admin.conf`
你可以使用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群(`/etc/kubernetes/admin.conf`)
自动抓取默认管理员密码。你可以通过参数 `--kubeconfig` 对下面命令指定一个另外的 kubeconfig 文件抓取密码。
* `kubeadm token list` 列举了令牌,同时显示了它们的过期时间和用途。
* `kubeadm token create` 创建一个新令牌。
* `--description` 设置新令牌的描述。
* `--ttl duration` 设置令牌从“现在”起到过期时间的差值。
* `--ttl duration` 设置令牌从 "现在" 起到过期时间的差值。
默认是 0 ,也就是不过期。
* `--usages` 设置令牌被使用的方式。默认是 `signing,authentication`。用途在上面已经描述。
* `kubeadm token delete <token id>|<token id>.<token secret>` 删除令牌。
令牌可以只用 ID 来确认,也可以用整个令牌的值。如果只用 ID 的情况下,密文不匹配的令牌也会被删除。
### ConfigMap 签名
### ConfigMap签名
除了认证之外,令牌可以用于签名 ConfigMap。这在集群启动过程的早期,在客户端信任 API 服务器之前被使用。
被签名的 ConfigMap 可以通过共享令牌被认证。
@@ -131,6 +131,6 @@ ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件
这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。
签名是一个 JWS 签名,使用了 "detached" 模式。为了检验签名,用户应该按照 JWS 规则
base64 编码而忽略结尾的 `=``kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间
(base64 编码而忽略结尾的 `=`)`kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间
,用于形成一个完整的 JWS。可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥,
通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 用户 _必须_ 确保使用了 HS256。
+122
View File
@@ -0,0 +1,122 @@
---
approvers:
- davidopp
- lavalamp
title: 创建大规模集群
---
## 支持规格
在 {{< param "version" >}}Kubernetes支持最多5000节点规模的集群。 更具体地说,我们支持满足以下 *所有* 标准的配置:
* 不超过5000节点
* 总共不超过15000个pod
* 总共不超过300000个容器
* 每个节点不超过100个pod
<br>
* TOC
{{< toc >}}
## 创建
集群是一组运行Kubernetes代理组件的节点(物理或虚拟机),它们被 "master" (集群管理平面)所管理。
一般来说,集群的节点数量通过平台相关的 `config-default.sh` 文件中的 `NUM_NODES` 值来控制,(例如,详见 [GCE's `config-default.sh`](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/gce/config-default.sh))。
对很多云提供商来说,单纯地修改`NUM_NODES` 为一个非常大的值,可能会导致集群的创建脚本失败。 例如,在GCE中部署时,会因配额不足,导致集群启动失败。
当建立一个大型的Kubernetes集群,以下几个问题必须考虑。
### 配额问题
为了避免出现配额问题,当创建包含大量节点的集群时,考虑:
* 提高相关配额,如CPUIP等。
* 如,在 [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/{{< param "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: k8s.gcr.io/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/{{< param "githubbranch" >}}/cluster/addons/cluster-monitoring/influxdb/influxdb-grafana-controller.yaml)
* [kubedns, dnsmasq, 和 sidecar](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kubedns-controller.yaml.in)
* [Kibana](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-elasticsearch/kibana-controller.yaml)
* 当扩大集群规模时,如果涉及,相应扩大以下插件副本数 (每个组件有多个副本,因此增加副本将有助于处理增加的负载,但是,由于每个副本的负载也略有增加,也应考虑提高CPU /内存上限):
* [elasticsearch](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-elasticsearch/es-controller.yaml)
* 当扩大集群规模时,如果涉及,略微扩大以下插件的内存和CPU限制 (每个节点一个副本, 但是CPU/内存使用随集群的大小/负载增长变化不明显):
* [FluentD with ElasticSearch Plugin](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml)
* [FluentD with GCP Plugin](http://releases.k8s.io/{{< param "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`
+18
View File
@@ -0,0 +1,18 @@
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: prometheus-node-exporter
spec:
template:
metadata:
name: prometheus-node-exporter
labels:
daemon: prom-node-exp
spec:
containers:
- name: c
image: prom/prometheus
ports:
- containerPort: 9090
hostPort: 9090
name: serverport
@@ -0,0 +1,214 @@
---
title: 构建高可用集群
---
## 简介
本文描述了如何构建一个高可用(high-availability, HA)的Kubernetes集群。这是一个非常高级的主题。
对于仅希望使用Kubernetes进行试验的用户,推荐使用更简单的配置工具进行搭建,例如:
[Minikube](/docs/getting-started-guides/minikube/),或者尝试使用[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) 来运行Kubernetes。
此外,当前在我们的端到端(e2e)测试环境中,没有对Kubernetes高可用的支持进行连续测试。我们将会增加这个连续测试项,但当前对单节点master的安装测试得更加严格。
{{< toc >}}
## 概览
搭建一个正真可靠,高度可用的分布式系统需要若干步骤。这类似于穿上内衣,裤子,皮带,背带,另一套内衣和另一套裤子。我们会详细介绍每一个步骤,但先在这里给出一个总结来帮助指导用户。
相关步骤如下:
* [创建可靠的组成节点,共同形成我们的高可用主节点实现。](#可靠的节点)
* [使用etcd集群,搭建一个冗余的,可靠的存储层。](#建立一个冗余的,可靠的存储层)
* [启动具有备份和负载均衡能力的Kubernetes API 服务](#复制的API服务)
* [搭建运行master选举的Kubernetes scheduler和controller-manager守护程序](#进行master选举的组件)
系统完成时看起来应该像这样:
![High availability Kubernetes diagram](/images/docs/ha.svg)
## 初始配置
本文假设你正在搭建一个3节点的主节点集群,每个节点上都运行者某种Linux系统。
指南中的示例使用Debian发行版,但它们应该可以被轻松移植到其他发行版上。
同样的,不管在公有云还是私有云亦或是裸机上,这个配置都应该可以运行。
从一个现成的单主节点集群开始是实现一个高可用Kubernetes集群的最简单的方法。这篇指导 [https://get.k8s.io](https://get.k8s.io) 描述了在多种平台上方便的安装一个单主节点集群的方法。
## 可靠的节点
我们在每个主节点上都将运行数个实现Kubernetes API的进程。使他们可靠的第一步是保证在发生故障时,每一个进程都可以自动重启。为了实现这个目标,我们需要安装一个进程监视器。我们选择了在每个工作者节点上都会运行的`kubelet`进程。这会带来便利性,因为我们使用了容器来分发我们的二进制文件,所以我们能够为每一个守护程序建立资源限制并省查它们的资源消耗。当然,我们也需要一些手段来监控kubelete本身(在此监测监控者本身是一个有趣的话题)。对于Debian系统我们选择了monit,但也有许多可替代的工具。例如在基于systemd的系统上(如RHEL, CentOS),你可以运行 'systemctl enable kubelet'。
如果你是从标准的Kubernetes安装扩展而来,那么`kubelet`二进制文件应该已经存在于你的系统中。你可以运行`which kubelet`来判断是否确实安装了这个二进制文件。如果没有安装的话,你应该手动安装 [kubelet binary](https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubelet),
[kubelet init file](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/saltbase/salt/kubelet/initd) 和 [default-kubelet](/docs/admin/high-availability/default-kubelet)脚本。
如果使用monit,你还需要安装monit守护程序(`apt-get install monit`)以及[monit-kubelet](/docs/admin/high-availability/monit-kubelet) 和
[monit-docker](/docs/admin/high-availability/monit-docker) 配置。
在使用systemd的系统上,你可以执行 `systemctl enable kubelet``systemctl enable docker`
## 建立一个冗余的,可靠的存储层
高可用方案的中心基础是一个冗余的,可靠的存储层。高可用的头条规则是保护数据。不管发生了什么,不管什么着了火,只要还有数据,你就可以重建。如果丢掉了数据,你就完了。
集群化的etcd已经把你存储的数据复制到了你集群中的所有主节点实例上。这意味着如果要想丢失数据,三个节点的物理(或虚拟)硬盘需要全部同时故障。这种情况发生的概率是比较低的,所以对于许多人来说,运行一个复制的etcd集群可能已经足够的可靠了。你可以将集群数量从3个增大到5个来增加集群的可靠性。如果那样还不够,你可以添加[更多的可靠性到你的存储层](#更加可靠的存储)。
### 集群化etcd
集群化etcd的完整细节超出了本文范围,你可以在[etcd clustering page](https://github.com/coreos/etcd/blob/master/Documentation/op-guide/clustering.md)找到许多详细内容。这个例子仅走查一个简单的集群建立过程,使用etcd内置的发现功能来构建我们的集群。
首先,调用etcd发现服务来创建一个新令牌:
```shell
curl https://discovery.etcd.io/new?size=3
```
在每个节点上,拷贝 [etcd.yaml](/docs/admin/high-availability/etcd.yaml) 文件到`/etc/kubernetes/manifests/etcd.yaml`
每个节点上的kubelet会动态的监控这个文件夹的内容,并且会按照`etcd.yaml`里对pod的定义创建一个`etcd`服务的实例。
请注意,你应该使用上文中获取的令牌URL替换全部三个节点上`etcd.yaml`中的`${DISCOVERY_TOKEN}`项。同时还应该将每个节点上的 `${NODE_NAME}`替换为一个不同的名字(例如:`node-1`),并将 `${NODE_IP}`替换为正确的IP地址。
#### 验证你的集群
如果已经将这个文件拷贝到所有三个节点,你应该已经搭建起了一个集群化的etcd。你可以在主节点上进行验证:
```shell
kubectl exec < pod_name > etcdctl member list
```
```shell
kubectl exec < pod_name > etcdctl cluster-health
```
你也可以在一个节点上运行 `etcdctl set foo bar`,在另一个节点上运行`etcdctl get foo`来验证集群是否工作正常。
### 更加可靠的存储
当然,如果你对增加数据的可靠性感兴趣,这里还有一些更深入的选项可以使etcd把它的数据存放在比常规硬盘更可靠的地方(裤带和背带,ftw!)。
如果你使用云服务,那么你的提供商通常会为你提供这个特性,例如Google Cloud Platform上的 [Persistent Disk](https://cloud.google.com/compute/docs/disks/persistent-disks) 。它们是可以挂载到你的虚拟机中的块设备持久化存储。其他的云服务提供商提供了类似的解决方案。
如果运行于物理机之上,你仍然可以使用iSCSI或者NFS接口通过网络来连接冗余存储。
此外,你还可以运行一个集群文件系统,比如Gluster或者Ceph。最后,你还可以在你的每个物理机器上运行RAID矩阵。
不管你选择如何实现,如果已经选择了使用其中的一个选项,那么你应该保证你的存储被挂载到了每一台机器上。如果你的存储在集群中的三个主节点之间共享,那么你应该在存储上为每一个节点创建一个不同的文件夹。对于所有的这些指导,我们都假设这个存储被挂载到你机器上的`/var/etcd/data`路径。
## 复制的API服务
在正确搭建复制的etcd之后,我们还需要使用kubelet安装apiserver。
首先,你需要创建初始的日志文件,这样Docker才会挂载一个文件而不是一个文件夹:
```shell
touch /var/log/kube-apiserver.log
```
接下来,你需要在每个节点上创建一个`/srv/kubernetes/`文件夹。这个文件夹包含:
* basic_auth.csv - 基本认证的用户名和密码
* ca.crt - CA证书
* known_tokens.csv - 实体(例如kubelet)用来和apiserver通信的令牌
* kubecfg.crt - 客户端证书,公钥
* kubecfg.key - 客户端证书,私钥
* server.cert - 服务端证书,公钥
* server.key - 服务端证书,私钥
创建这个文件夹最简单的方法可以是从一个工作正常的集群的主节点拷贝,或者你也可以手动生成它们。
### 启动API服务
一旦这些文件已经存在了,拷贝 [kube-apiserver.yaml](/docs/admin/high-availability/kube-apiserver.yaml) 到每个主节点的 `/etc/kubernetes/manifests/`文件夹。
kubelet会监控这个文件夹,并且会按照文件里对pod的定义创建一个`kube-apiserver`容器。
### 负载均衡
现在,你应该有3个全部正常工作的apiserver了。如果搭建了网络负载均衡器,你应该能够通过那个负载均衡器访问你的集群,并且看到负载在apiserver实例间分发。设置负载均衡器依赖于你的平台的实际情况,例如对于Google Cloud Platform的指导可以在[这里](https://cloud.google.com/compute/docs/load-balancing/)找到。
请注意,如果使用了身份认证,你可能需要重新生成你的证书,除每个节点的IP地址外额外包含负载均衡器的IP地址。
对于部署在集群中的pods `kubernetes`服务/dns名称应该自动的为主节点提供了负载均衡的endpoint。
对于使用API的外部用户(如命令行运行的`kubectl`,持续集成管道或其他客户端)你会希望将他们配置成为访问外部负载均衡器的地址。
## 进行Master选举的组件
到目前为止,我们已经搭建了状态存储,也搭建好了API服务,但我们还没有运行任何真正改变集群状态的服务,比如controller manager和scheduler。为了可靠的实现这个目标,我们希望在同一时间只有一个参与者在修改集群状态。但是我们希望复制这些参与者的实例以防某个机器宕机。要做到这一点,我们打算在API中使用一个lease-lock来执行master选举。我们会对每一个scheduler和controller-manager使用`--leader-elect`标志,从而在API中使用一个租约来保证同一时间只有一个scheduler和controller-manager的实例正在运行。
scheduler和controller-manager可以配置为只和位于它们相同节点(即127.0.0.1)上的API服务通信,也可以配置为使用API服务的负载均衡器的IP地址。不管它们如何配置,当使用`--leader-elect` 时scheduler和controller-manager都将完成上文提到的leader选举过程。
为了防止访问API服务失败,选举出的leader不能通过更新租约来选举一个新的leader。当scheduler和controller-manager通过127.0.0.1访问API服务,而相同节点上的API服务不可用时,这一点相当重要。
### 安装配置文件
首先,在每个节点上创建空白日志文件,这样Docker就会挂载这些文件而不是创建一个新文件夹:
```shell
touch /var/log/kube-scheduler.log
touch /var/log/kube-controller-manager.log
```
接下来,在每个节点上配置scheduler和controller manager pods的描述文件。拷贝 [kube-scheduler.yaml](/docs/admin/high-availability/kube-scheduler.yaml) 和 [kube-controller-manager.yaml](/docs/admin/high-availability/kube-controller-manager.yaml) 到`/etc/kubernetes/manifests/` 文件夹。
## 结尾
此时,你已经完成了master组件的配置(耶!),但你还需要添加工作者节点(噗!)。
如果你有一个现成的集群,你只需要在每个节点上简单的重新配置你的kubeletes连接到负载均衡的endpoint并重启它们。
如果你搭建的是一个全新的集群,你将需要在每个工作节点上安装kubelet和kube-proxy,并设置 `--apiserver`指向复制的endpoint。
+229
View File
@@ -0,0 +1,229 @@
---
title: kube-apiserver
notitle: true
---
## kube-apiserver
### 概要
Kubernetes API server 为 api 对象验证并配置数据,包括 pods、 services、 replicationcontrollers和其它 api 对象。API Server 提供 REST 操作和到集群共享状态的前端,所有其他组件通过它进行交互。
```
kube-apiserver
```
### 选项
```
--admission-control stringSlice 控制资源进入集群的准入控制插件的顺序列表。逗号分隔的NamespaceLifecycle列表。(默认值[AlwaysAdmit])
--admission-control-config-file string 包含准入控制配置的文件。
--advertise-address ip 向集群成员通知apiserver消息的IP地址。这个地址必须能够被集群中其他成员访问。如果IP地址为空,将会使用--bind-address,如果未指定--bind-address,将会使用主机的默认接口地址。
--allow-privileged 如果为true, 将允许特权容器.
--anonymous-auth 启用到API server的安全端口的匿名请求。未被其他认证方法拒绝的请求被当做匿名请求。匿名请求的用户名为system:anonymous,用户组名为system:unauthenticated。(默认值true
--apiserver-count int 集群中运行的apiserver数量,必须为正数。(默认值1)
--audit-log-maxage int 基于文件名中的时间戳,旧审计日志文件的最长保留天数。
--audit-log-maxbackup int 旧审计日志文件的最大保留个数.
--audit-log-maxsize int 审计日志被轮转前的最大兆字节数。
--audit-log-path string 如果设置该值,所有到apiserver的请求都将会被记录到这个文件。'-'表示记录到标准输出。
--audit-policy-file string 定义审计策略配置的文件的路径。需要打开'AdvancedAuditing'特性开关。AdvancedAuditing需要一个配置来启用审计功能。
--audit-webhook-config-file string 一个具有kubeconfig格式文件的路径,该文件定义了审计的webhook配置。需要打开'AdvancedAuditing'特性开关。
--audit-webhook-mode string 发送审计事件的策略。 Blocking模式表示正在发送事件时应该阻塞服务器的响应。 Batch模式使webhook异步缓存和发送事件。 Known模式为batch,blocking。 (默认值"batch")
--authentication-token-webhook-cache-ttl duration 从webhook令牌认证者获取的响应的缓存时长。(默认值2m0s)
--authentication-token-webhook-config-file string 包含webhook配置的文件,用于令牌认证,具有kubeconfig格式。API server将查询远程服务来决定对bearer令牌的认证。
--authorization-mode string 在安全端口上进行权限验证的插件的顺序列表。以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值"AlwaysAllow"
--authorization-policy-file string 包含权限验证策略的csv文件,和--authorization-mode=ABAC一起使用,作用在安全端口上。
--authorization-webhook-cache-authorized-ttl duration 从webhook授权者获得的'authorized'响应的缓存时长。(默认值5m0s)
--authorization-webhook-cache-unauthorized-ttl duration 从webhook授权者获得的'unauthorized'响应的缓存时长。(默认值30s)
--authorization-webhook-config-file string 包含webhook配置的kubeconfig格式文件,和--authorization-mode=Webhook一起使用。API server将查询远程服务来决定对API server安全端口的访问。
--azure-container-registry-config string 包含Azure容器注册表配置信息的文件的路径。
--basic-auth-file string 如果设置该值,这个文件将会被用于准许通过http基本认证到API server安全端口的请求。
--bind-address ip 监听--seure-port的IP地址。被关联的接口必须能够被集群其它节点和CLI/web客户端访问。如果为空,则将使用所有接口(0.0.0.0)。(默认值0.0.0.0
--cert-dir string 存放TLS证书的目录。如果提供了--tls-cert-file和--tls-private-key-file选项,该标志将被忽略。(默认值 "/var/run/kubernetes"
--client-ca-file string 如果设置此标志,对于任何请求,如果存包含client-ca-file中的authorities签名的客户端证书,将会使用客户端证书中的CommonName对应的身份进行认证。
--cloud-config string 云服务提供商配置文件路径。空字符串表示无配置文件.
--cloud-provider string 云服务提供商,空字符串表示无提供商。
--contention-profiling 如果已经启用profiling,则启用锁竞争profiling。
--cors-allowed-origins stringSlice CORS的域列表,以逗号分隔。合法的域可以是一个匹配子域名的正则表达式。如果这个列表为空则不会启用CORS.
--delete-collection-workers int 用于DeleteCollection调用的工作者数量。这被用于加速namespace的清理。(默认值1)
--deserialization-cache-size int 在内存中缓存的反序列化json对象的数量。
--enable-aggregator-routing 打开到endpoints IP的aggregator路由请求,替换cluster IP。
--enable-garbage-collector 启用通用垃圾回收器. 必须与kube-controller-manager对应的标志保持同步。 (默认值true)
--enable-logs-handler 如果为true,则为apiserver日志功能安装一个/logs处理器。(默认值true)
--enable-swagger-ui 在apiserver的/swagger-ui路径启用swagger ui。
--etcd-cafile string 用于保护etcd通信的SSL CA文件。
--etcd-certfile string 用于保护etcd通信的的SSL证书文件。
--etcd-keyfile string 用于保护etcd通信的SSL密钥文件.
--etcd-prefix string 附加到所有etcd中资源路径的前缀。 (默认值"/registry"
--etcd-quorum-read 如果为true, 启用quorum读。
--etcd-servers stringSlice 连接的etcd服务器列表,形式为(scheme://ip:port),使用逗号分隔。
--etcd-servers-overrides stringSlice 针对单个资源的etcd服务器覆盖配置, 以逗号分隔。 单个配置覆盖格式为: group/resource#servers, 其中servers形式为http://ip:port, 以分号分隔。
--event-ttl duration 事件驻留时间。(默认值1h0m0s)
--experimental-bootstrap-token-auth 启用此选项以允许'kube-system'命名空间中的'bootstrap.kubernetes.io/token'类型密钥可以被用于TLS的启动认证。
--experimental-encryption-provider-config string 包含加密提供程序的配置的文件,该加密提供程序被用于在etcd中保存密钥。
--external-hostname string 为此master生成外部URL时使用的主机名(例如Swagger API文档)。
--feature-gates mapStringBool 一个描述alpha/experimental特性开关的键值对列表。 选项包括:
Accelerators=true|false (ALPHA - default=false)
AdvancedAuditing=true|false (ALPHA - default=false)
AffinityInAnnotations=true|false (ALPHA - default=false)
AllAlpha=true|false (ALPHA - default=false)
AllowExtTrafficLocalEndpoints=true|false (default=true)
AppArmor=true|false (BETA - default=true)
DynamicKubeletConfig=true|false (ALPHA - default=false)
DynamicVolumeProvisioning=true|false (ALPHA - default=true)
ExperimentalCriticalPodAnnotation=true|false (ALPHA - default=false)
ExperimentalHostUserNamespaceDefaulting=true|false (BETA - default=false)
LocalStorageCapacityIsolation=true|false (ALPHA - default=false)
PersistentLocalVolumes=true|false (ALPHA - default=false)
RotateKubeletClientCertificate=true|false (ALPHA - default=false)
RotateKubeletServerCertificate=true|false (ALPHA - default=false)
StreamingProxyRedirects=true|false (BETA - default=true)
TaintBasedEvictions=true|false (ALPHA - default=false)
--google-json-key string 用于认证的Google Cloud Platform服务账号的JSON密钥。
--insecure-allow-any-token username/group1,group2 如果设置该值, 你的服务将处于非安全状态。任何令牌都将会被允许,并将从令牌中把用户信息解析成为username/group1,group2。
--insecure-bind-address ip 用于监听--insecure-port的IP地址 (设置成0.0.0.0表示监听所有接口)。(默认值127.0.0.1)
--insecure-port int 用于监听不安全和为认证访问的端口。这个配置假设你已经设置了防火墙规则,使得这个端口不能从集群外访问。对集群的公共地址的443端口的访问将被代理到这个端口。默认设置中使用nginx实现。(默认值8080)
--kubelet-certificate-authority string 证书authority的文件路径。
--kubelet-client-certificate string 用于TLS的客户端证书文件路径。
--kubelet-client-key string 用于TLS的客户端证书密钥文件路径.
--kubelet-https 为kubelet启用https。 (默认值true
--kubelet-preferred-address-types stringSlice 用于kubelet连接的首选NodeAddressTypes列表。 (默认值[Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP])
--kubelet-read-only-port uint 已废弃: kubelet端口. (默认值10255
--kubelet-timeout duration kubelet操作超时时间。(默认值
5s
--kubernetes-service-node-port int 如果不为0Kubernetes master服务(用于创建/管理apiserver)将会使用NodePort类型,并将这个值作为端口号。如果为0,Kubernetes master服务将会使用ClusterIP类型。
--master-service-namespace string 已废弃: 注入到pod中的kubernetes master服务的命名空间。(默认值"default"
--max-connection-bytes-per-sec int 如果不为0,每个用户连接将会被限速为该值(bytes/sec)。当前只应用于长时间运行的请求。
--max-mutating-requests-inflight int 在给定时间内进行中可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值200)
--max-requests-inflight int 在给定时间内进行中不可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值400)
--min-request-timeout int 一个可选字段,表示一个handler在一个请求超时前,必须保持它处于打开状态的最小秒数。当前只对监听请求handler有效,它基于这个值选择一个随机数作为连接超时值,以达到分散负载的目的(默认值1800)。
--oidc-ca-file string 如果设置该值,将会使用oidc-ca-file中的任意一个authority对OpenID服务的证书进行验证,否则将会使用主机的根CA对其进行验证。
--oidc-client-id string 使用OpenID连接的客户端的ID,如果设置了oidc-issuer-url,则必须设置这个值。
--oidc-groups-claim string 如果提供该值,这个自定义OpenID连接名将指定给特定的用户组。该声明值需要是一个字符串或字符串数组。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。
--oidc-issuer-url string OpenID颁发者URL,只接受HTTPS方案。如果设置该值,它将被用于验证OIDC JSON Web Token(JWT)。
--oidc-username-claim string 用作用户名的OpenID声明值。注意,不保证除默认 ('sub')外的其他声明值的唯一性和不变性。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。
--profiling 在web接口host:port/debug/pprof/上启用profiling。(默认值true
--proxy-client-cert-file string 当必须调用外部程序时,用于证明aggregator或者kube-apiserver的身份的客户端证书。包括代理到用户api-server的请求和调用webhook准入控制插件的请求。它期望这个证书包含一个来自于CA中的--requestheader-client-ca-file标记的签名。该CA在kube-system命名空间的'extension-apiserver-authentication' configmap中发布。从Kube-aggregator收到调用的组件应该使用该CA进行他们部分的双向TLS验证。
--proxy-client-key-file string 当必须调用外部程序时,用于证明aggregator或者kube-apiserver的身份的客户端证书密钥。包括代理到用户api-server的请求和调用webhook准入控制插件的请求。
--repair-malformed-updates 如果为true,服务将会尽力修复更新请求以通过验证,例如:将更新请求UID的当前值设置为空。在我们修复了所有发送错误格式请求的客户端后,可以关闭这个标志。
--requestheader-allowed-names stringSlice 使用--requestheader-username-headers指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过--requestheader-client-ca-file中authorities验证的客户端证书都是被允许的。
--requestheader-client-ca-file string 在信任请求头中以--requestheader-username-headers指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。
--requestheader-extra-headers-prefix stringSlice 用于检查的请求头的前缀列表。建议使用X-Remote-Extra-。
--requestheader-group-headers stringSlice 用于检查群组的请求头列表。建议使用X-Remote-Group.
--requestheader-username-headers stringSlice 用于检查用户名的请求头列表。建议使用X-Remote-User。
--runtime-config mapStringString 传递给apiserver用于描述运行时配置的键值对集合。 apis/<groupVersion>键可以被用来打开/关闭特定的api版本。apis/<groupVersion>/<resource>键被用来打开/关闭特定的资源. api/all和api/legacy键分别用于控制所有的和遗留的api版本.
--secure-port int 用于监听具有认证授权功能的HTTPS协议的端口。如果为0,则不会监听HTTPS协议。 (默认值6443)
--service-account-key-file stringArray 包含PEM加密的x509 RSA或ECDSA私钥或公钥的文件,用于验证ServiceAccount令牌。如果设置该值,--tls-private-key-file将会被使用。指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用。
--service-cluster-ip-range ipNet CIDR表示的IP范围,服务的cluster ip将从中分配。 一定不要和分配给nodes和pods的IP范围产生重叠。
--ssh-keyfile string 如果不为空,在使用安全的SSH代理访问节点时,将这个文件作为用户密钥文件。
--storage-backend string 持久化存储后端。 选项为: 'etcd3' (默认), 'etcd2'.
--storage-media-type string 在存储中保存对象的媒体类型。某些资源或者存储后端可能仅支持特定的媒体类型,并且忽略该配置项。(默认值 "application/vnd.kubernetes.protobuf")
--storage-versions string 按组划分资源存储的版本。 以"group1/version1,group2/version2,..."的格式指定。当对象从一组移动到另一组时, 你可以指定"group1=group2/v1beta1,group3/v1beta1,..."的格式。你只需要传入你希望从结果中改变的组的列表。默认为从KUBE_API_VERSIONS环境变量集成而来,所有注册组的首选版本列表。 (默认值"admission.k8s.io/v1alpha1,admissionregistration.k8s.io/v1alpha1,apps/v1beta1,authentication.k8s.io/v1,authorization.k8s.io/v1,autoscaling/v1,batch/v1,certificates.k8s.io/v1beta1,componentconfig/v1alpha1,extensions/v1beta1,federation/v1beta1,imagepolicy.k8s.io/v1alpha1,networking.k8s.io/v1,policy/v1beta1,rbac.authorization.k8s.io/v1beta1,settings.k8s.io/v1alpha1,storage.k8s.io/v1,v1")
--target-ram-mb int apiserver内存限制,单位为MB(用于配置缓存大小等)。
--tls-ca-file string 如果设置该值,这个证书authority将会被用于从Admission Controllers过来的安全访问。它必须是一个PEM加密的合法CA捆绑包。此外, 该证书authority可以被添加到以--tls-cert-file提供的证书文件中.
--tls-cert-file string 包含用于HTTPS的默认x509证书的文件。(如果有CA证书,则附加于server证书之后)。如果启用了HTTPS服务,并且没有提供--tls-cert-file和--tls-private-key-file,则将为公共地址生成一个自签名的证书和密钥并保存于/var/run/kubernetes目录。
--tls-private-key-file string 包含匹配--tls-cert-file的x509证书私钥的文件。
--tls-sni-cert-key namedCertKey 一对x509证书和私钥的文件路径, 可以使用符合正式域名的域形式作为后缀。 如果没有提供域形式后缀, 则将提取证书名。 非通配符版本优先于通配符版本, 显示的域形式优先于证书中提取的名字。 对于多个密钥/证书对, 请多次使用--tls-sni-cert-key。例如: "example.crt,example.key" or "foo.crt,foo.key:*.foo.com,foo.com". (默认值[])
--token-auth-file string 如果设置该值,这个文件将被用于通过令牌认证来保护API服务的安全端口。
--version version[=true] 打印版本信息并退出。
--watch-cache 启用apiserver的监视缓存。(默认值true)
--watch-cache-sizes stringSlice 每种资源(pods, nodes等)的监视缓存大小列表,以逗号分隔。每个缓存配置的形式为:resource#sizesize是一个数字。在watch-cache启用时生效。
```
###### Auto generated by spf13/cobra on 11-Jul-2017
@@ -27,7 +27,7 @@ While any authentication strategy can be used for the kubelet's initial bootstra
1. [Bootstrap Tokens](/docs/admin/bootstrap-tokens/) - __alpha__
2. [Token authentication file](###token-authentication-file)
Using bootstrap tokens is currently __alpha__ and will simplify the management of bootstrap token management especially in a HA scenario.
Using bootstrap tokens is currently __alpha__ and will simplify the management of bootstrap token management especially in a HA scenario.
### Token authentication file
Tokens are arbitrary but should represent at least 128 bits of entropy derived from a secure random number
@@ -186,13 +186,11 @@ kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --ku
When starting the kubelet, if the file specified by `--kubeconfig` does not exist, the bootstrap kubeconfig is used to request a client certificate from the API server. On approval of the certificate request and receipt back by the kubelet, a kubeconfig file referencing the generated key and obtained certificate is written to the path specified by `--kubeconfig`. The certificate and key file will be placed in the directory specified by `--cert-dir`.
{{< note >}}
The following flags are required to enable this bootstrapping when starting the kubelet:
**Note:** The following flags are required to enable this bootstrapping when starting the kubelet:
```
--bootstrap-kubeconfig="/path/to/bootstrap/kubeconfig"
```
{{< /note >}}
Additionally, in 1.7 the kubelet implements __alpha__ features for enabling rotation of both its client and/or serving certs.
These can be enabled through the respective `RotateKubeletClientCertificate` and `RotateKubeletServerCertificate` feature
+291
View File
@@ -0,0 +1,291 @@
---
approvers:
- jlowdermilk
- justinsb
- quinton-hoole
title: 多区域运行
---
## 介绍
Kubernetes 从v1.2开始支持将集群运行在多个故障域中。
(GCE 中称其为 "区(Zones" AWS 中称其为 "可用区(Availability Zones",这里我们也称其为 "区")。
它是广泛意义上的集群联邦特性的轻量级版本 (之前被称为 ["Ubernetes"](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/multicluster/federation.md))。
完整的集群联邦能够将多个分别运行在不同区或云供应商(或本地数据中心)的集群集中管理。
然而,很多用户只是希望通过将单一云供应商上的Kubernetes集群运行在多个区域,来提高集群的可用性,
这就是1.2版本中提供的对多区域的支持。
(之前被称为 "Ubernetes Lite")。
多区域的支持是有明确限制的: Kubernetes集群能够运行在多个区,但必须在同一个地域内 (云供应商也须一致)。
目前只有GCE和AWS自动支持 (尽管在其他云甚至裸机上,也很容易通过为节点和卷添加合适的标签来实现类似的支持)。
{{< toc >}}
## 功能
节点启动时,Kubelet自动为其添加区信息的标签。
在单一区域的集群中,Kubernetes 会自动将副本管理器或服务的pod分布到各节点上 (以减轻单实例故障的影响)。
在多区域的集群中,这种分布的行为扩展到了区域级别
(以减少区域故障对整体的影响)。 (通过 `SelectorSpreadPriority` 来实现)。
这种分发是尽力而为(best-effort)的,所以如果集群在各个区之间是异构的
(比如,各区间的节点数量不同、节点类型不同、pod的资源需求不同等)可能导致pod无法完全均匀地分布。
如果需要的话,用户可以使用同质的区(节点数量和节点类型相同)来减少区域之间分配不均匀的可能。
当卷被创建时, `PersistentVolumeLabel`准入控制器会自动为其添加区域的标签。
调度器 (通过 `VolumeZonePredicate` 断言) 会确申领该卷的pod被调度到该卷对应的区域,
因为卷是不支持跨区挂载的。
## 限制
对多区的支持有一些重要的限制:
* 我们假设不同的区域间在网络上离得很近,所以我们不做任何的区域感知路由。 特别是,通过服务的网络访问可能跨区域 (即使该服务后端pod的其中一些运行在与客户端相同的区域中),这可能导致额外的延迟和损耗。
* 卷的区域亲和性只对 `PersistentVolume`有效。 例如,如果你在pod的spec中直接指定一个EBS的卷,则不会生效。
* 集群不支持跨云平台或地域 (这些功能需要完整的集群联邦特性支持)。
* 尽管节点位于多区域,目前默认情况下 kube-up 创建的管理节点是单实例的。 所以尽管服务是高可用的,并且能够容忍跨区域的性能损耗,管理平面还是单区域的。 需要高可用的管理平面的用户可以按照 [高可用](/docs/admin/high-availability) 指导来操作。
* 目前StatefulSet的卷动态创建时的跨区域分配,与pod的亲和性/反亲和性不兼容。
* StatefulSet的名称包含破折号 ("-")时,可能影响到卷在区域间的均匀分布。
* 为deployment或pod指定多个PVC时,要求其StorageClass处于同一区域内,否则,相应的PV卷需要在一个区域中静态配置。 另一种方式是使用StatefulSet,这可以确保同一副本所挂载的卷位于同一区内。
## 演练
接下来我们将介绍如何同时在 GCE 和 AWS 上创建和使用多区域的集群。 为此,你需要创建一个完整的集群
(指定 `MULTIZONE=true`),然后再次执行 `kube-up`(指定 `KUBE_USE_EXISTING_MASTER=true`)来添加其他区域的节点。
### 创建集群
按正常方式创建集群,但是传入 MULTIZONE 来通知集群对多区域进行管理。 在 us-central1-a 区域创建节点。
GCE:
```shell
curl -sS https://get.k8s.io | MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a NUM_NODES=3 bash
```
AWS:
```shell
curl -sS https://get.k8s.io | MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a NUM_NODES=3 bash
```
该步骤按正常方式创建了集群,仍然运行在单个区域中。
`MULTIZONE=true` 已经开启了多区域的能力。
### 标记节点
查看节点,你可以发现节点上打了区域信息的标签。
节点位于 `us-central1-a` (GCE) 或者 `us-west-2a` (AWS)。 标签 `failure-domain.beta.kubernetes.io/region` 用于区分地域,
标签 `failure-domain.beta.kubernetes.io/zone` 用于区分区域。
```shell
> kubectl get nodes --show-labels
NAME STATUS AGE VERSION LABELS
kubernetes-master Ready,SchedulingDisabled 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-87j9 Ready 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
```
### 添加其它区中的节点
接下来我们复用已有的管理节点,添加运行于其它区域 (us-central1-b或us-west-2b)中的节点。
再次执行 kube-up 通过指定 `KUBE_USE_EXISTING_MASTER=true`
kube-up 不会创建新的管理节点,而是会复用之前创建的。
GCE:
```shell
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-b NUM_NODES=3 kubernetes/cluster/kube-up.sh
```
在 AWS 中我们还需要为新增的子网指定网络CIDR,还有管理节点的内部IP地址。
```shell
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2b NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.1.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
```
再次查看节点,3个新增的节点已经启动,并被标记为us-central1-b
```shell
> kubectl get nodes --show-labels
NAME STATUS AGE VERSION LABELS
kubernetes-master Ready,SchedulingDisabled 16m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-281d Ready 2m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-87j9 Ready 16m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready 16m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready 17m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
kubernetes-minion-pp2f Ready 2m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f
kubernetes-minion-wf8i Ready 2m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i
```
### 卷的亲和性
使用动态创建卷的功能创建一个卷 (只有PV持久卷才支持区域亲和性):
```json
kubectl create -f - <<EOF
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "claim1",
"annotations": {
"volume.alpha.kubernetes.io/storage-class": "foo"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "5Gi"
}
}
}
}
EOF
```
**注意:** Kubernetes 1.3以上的版本中可以将PVC分发到多个已配置的区域中,在1.2版本中, 动态卷只能创建在管理节点所在的区域内(即这里的 us-central1-a / us-west-2a);相关issue
([#23330](https://github.com/kubernetes/kubernetes/issues/23330))
在1.3后续的版本中已解决。
现在我们验证一下 Kubernetes 自动为创建的PV打上了所在地域和区域的标签。
```shell
> kubectl get pv --show-labels
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE LABELS
pv-gce-mj4gm 5Gi RWO Bound default/claim1 46s failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a
```
现在我们将创建使用这些PVC的pod。
因为 GCE 的PD存储 / AWS 的EBS 卷 不支持跨区域挂载,
这意味着相应的pod只能创建在卷所在的区域中。
```yaml
kubectl create -f - <<EOF
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: claim1
EOF
```
注意pod被自动创建在了卷所在的区域中,因为云供应商通常不支持卷的跨区域挂载(attach)。
```shell
> kubectl describe pod mypod | grep Node
Node: kubernetes-minion-9vlv/10.240.0.5
> kubectl get node kubernetes-minion-9vlv --show-labels
NAME STATUS AGE VERSION LABELS
kubernetes-minion-9vlv Ready 22m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
```
### Pod的跨区域分布
副本管理器或服务的pod被自动创建在了不同的区域。 首先,在第三个区域内启动节点:
GCE:
```shell
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-f NUM_NODES=3 kubernetes/cluster/kube-up.sh
```
AWS:
```shell
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2c NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.2.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
```
验证你现在在3个区域内拥有节点:
```shell
kubectl get nodes --show-labels
```
创建 guestbook-go 示例应用, 它包含一个副本数为3的RC,运行一个简单的网络应用:
```shell
find kubernetes/examples/guestbook-go/ -name '*.json' | xargs -I {} kubectl create -f {}
```
Pod应该分布在全部3个区域上:
```shell
> kubectl describe pod -l app=guestbook | grep Node
Node: kubernetes-minion-9vlv/10.240.0.5
Node: kubernetes-minion-281d/10.240.0.8
Node: kubernetes-minion-olsh/10.240.0.11
> kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels
NAME STATUS AGE VERSION LABELS
kubernetes-minion-9vlv Ready 34m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-281d Ready 20m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-olsh Ready 3m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh
```
负载平衡器覆盖集群中的所有区域; guestbook-go 示例包含一个
负载均衡服务的例子:
```shell
> kubectl describe service guestbook | grep LoadBalancer.Ingress
LoadBalancer Ingress: 130.211.126.21
> ip=130.211.126.21
> curl -s http://${ip}:3000/env | grep HOSTNAME
"HOSTNAME": "guestbook-44sep",
> (for i in `seq 20`; do curl -s http://${ip}:3000/env | grep HOSTNAME; done) | sort | uniq
"HOSTNAME": "guestbook-44sep",
"HOSTNAME": "guestbook-hum5n",
"HOSTNAME": "guestbook-ppm40",
```
负载平衡器正确指向了所有的pod,即使它们位于不同的区域内。
### 停止集群
使用完成后,进行清理:
GCE:
```shell
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-f kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-b kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a kubernetes/cluster/kube-down.sh
```
AWS:
```shell
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2c kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2b kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a kubernetes/cluster/kube-down.sh
```
+84
View File
@@ -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 \
k8s.gcr.io/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测试
k8s.gcr.io/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外的所有测试
k8s.gcr.io/node-test:0.2
```
节点合规性测试是[节点端到端测试](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/devel/e2e-node-tests.md)的一个容器化的版本。
默认情况下, 它会运行所有的合规性测试用例。
理论上,只要合理地配置容器和挂载所需的卷,就可以运行任何的节点端到端测试用例。 但是这里 **强烈建议只运行合规性测试**,因为运行非合规性测试需要很多复杂的配置。
## 注意事项
* 测试会在节点上遗留一些Docker镜像, 包括节点合规性测试本身的镜像,和功能测试相关的镜像。
* 测试会在节点上遗留一些死的容器。这些容器是在功能测试的过程中创建的。
+22
View File
@@ -0,0 +1,22 @@
---
approvers:
- thockin
title: Kubernetes OpenVSwitch GRE/VxLAN 网络
---
本文档介绍了如何使用OpenVSwitch,在跨nodes的pods之间设置网络。
隧道类型可以是GRE或者是VxLAN。如需在网络内执行大规模隔离时,最好使用VxLAN。
![OVS Networking](/images/docs/ovs-networking.png)
Kubernetes中Vagrant的设置如下:
docker网桥被brctl生成的Linux网桥(kbr0)所代替,kbr0是具有256个地址空间的子网。总的来说,node会得到10.244.x.0/24的子网,docker上配置使用的网桥会代替默认docker0的网桥。
另外,OVS网桥创建(obr0),并将其作为端口添加到kbr0的网桥中。所有OVS网桥通过GRE隧道连接所有的nodes。因此,每个node都有一个到其他nodes的出站GRE隧道。这个隧道没有必要是一个完整的网状物,但是越像网状结构越好。在网桥上开启STP(生成树)模式以防止环路的发生。
路由规则允许任何10.244.0.0/16通过与隧道相连的OVS网桥到达目标。
@@ -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" 的服务账户
@@ -0,0 +1,248 @@
title: 云控制器管理器的基本概念
## 云控制器管理器
云控制器管理器(CCM)这个概念创建的初衷是为了让特定的云服务供应商代码和Kubernetes核心相互独立演化。云控制器管理器与其他主要组件如Kubernetes控制器管理器,API服务器和调度程序同时运行。云控制器管理器也可以作为Kubernetes的插件启动,这种情况下,CCM运行在Kubernetes系统之上。
云控制器管理器基于插件机制设计,允许新的云服务供应商通过插件轻松地与Kubernetes集成。目前已经有在Kubernetes上加入新的云服务供应商计划,并为云服务供应商提供从原先的旧模式迁移到新CCM模式的方案。
本文讨论了云控制器管理器背后的概念,并提供了相关功能的详细信息。
下面这张图描述了没有云控制器管理器的Kubernetes集群架构:
![无云控制器管理器的 K8s 集群架构](/images/docs/pre-ccm-arch.png)
## 设计
在上图中,Kubernetes和云服务供应商通过几个不同的组件进行了集成,分别是:
* Kubelet
* Kubernetes 控制管理器
* Kubernetes API服务器
而CCM整合了前三个组件中的所有依赖于云的逻辑,用来创建与云的单点集成。新架构如下图所示:
![有云控制器管理器的 K8s 集群架构](/images/docs/post-ccm-arch.png)
## 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/kubernetes52371](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/v1
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的完整说明。
@@ -0,0 +1,70 @@
---
approvers:
- dchen1107
- roberthbailey
- liggitt
title: Master 节点通信
---
{{< toc >}}
## 概览
本文对 Master 节点(确切说是 apiserver)和 Kubernetes 集群之间的通信路径进行了分类。目的是为了让用户能够自定义他们的安装,对网络配置进行加固,使得集群能够在不可信的网络上(或者在一个云服务商完全公共的 IP 上)运行。
## Cluster -> Master
所有从集群到 master 的通信路径都终止于 apiserver(其它 master 组件没有被设计为可暴露远程服务)。在一个典型的部署中,apiserver 被配置为在一个安全的 HTTPS 端口(443)上监听远程连接并启用一种或多种形式的客户端[身份认证](/docs/admin/authentication/)机制。一种或多种客户端[身份认证](/docs/admin/authentication/)机制应该被启用,特别是在允许使用 [匿名请求](/docs/admin/authentication/#anonymous-requests) 或 [service account tokens](/docs/admin/authentication/#service-account-tokens) 的时候。
应该使用集群的公共根证书开通节点,如此它们就能够基于有效的客户端凭据安全的连接 apiserver。例如:在一个默认的 GCE 部署中,客户端凭据以客户端证书的形式提供给 kubelet。请查看 [kubelet TLS bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 获取如何自动提供 kubelet 客户端证书。
想要连接到 apiserver 的 Pods 可以使用一个 service account 安全的进行连接。这种情况下,当 Pods 被实例化时 Kubernetes 将自动的把公共根证书和一个有效的不记名令牌注入到 pod 里。`kubernetes` service (所有 namespaces 中)都配置了一个虚拟 IP 地址,用于转发(通过 kube-proxy)请求到 apiserver 的 HTTPS endpoint。
Master 组件通过非安全(没有加密或认证)端口和集群的 apiserver 通信。这个端口通常只在 master 节点的 localhost 接口暴露,这样,所有在相同机器上运行的 master 组件就能和集群的 apiserver 通信。一段时间以后,master 组件将变为使用带身份认证和权限验证的安全端口(查看[#13598](https://github.com/kubernetes/kubernetes/issues/13598))。
这样的结果使得从集群(在节点上运行的 nodes 和 pods)到 master 的缺省连接操作模式默认被保护,能够在不可信或公网中运行。
## Master -> Cluster
从 masterapiserver)到集群有两种主要的通信路径。第一种是从 apiserver 到集群中每个节点上运行的 kubelet 进程。第二种是从 apiserver 通过它的代理功能到任何 node、pod 或者 service。
### apiserver -> kubelet
从 apiserver 到 kubelet 的连接用于获取 pods 日志、连接(通过 kubectl)运行中的 pods,以及使用 kubele 的端口转发功能。这些连接终止于 kubelet 的 HTTPS endpoint。
默认的,apiserver 不会验证 kubelet 的服务证书,这会导致连接遭到中间人攻击,因而在不可信或公共网络上是不安全的。
为了对这个连接进行认证,请使用 `--kubelet-certificate-authority` 标记给 apiserver 提供一个根证书捆绑,用于 kubelet 的服务证书。
如果这样不可能,又要求避免在不可信的或公共的网络上进行连接,请在 apiserver 和 kubelet 之间使用 [SSH 隧道](/docs/concepts/architecture/master-node-communication/#ssh-tunnels)。
最后,应该启用[Kubelet 用户认证和/或权限认证](/docs/admin/kubelet-authentication-authorization/)来保护 kubelet API。
### apiserver -> nodes, pods, and services
从 apiserver 到 node、pod或者service 的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。他们能够通过给API URL 中的 node、pod 或 service 名称添加前缀 `https:` 来运行在安全的 HTTPS 连接上。但他们即不会认证 HTTPS endpoint 提供的证书,也不会提供客户端证书。这样虽然连接是加密的,但它不会提供任何完整性保证。这些连接**目前还不能安全的**在不可信的或公共的网络上运行。
### SSH 隧道
[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/) 使用 SSH 隧道保护 Master -> Cluster 通信路径。在这种配置下,apiserver 发起一个到集群中每个节点的 SSH 隧道(连接到在 22 端口监听的 ssh 服务)并通过这个隧道传输所有到 kubelet、node、pod 或者 service 的流量。这个隧道保证流量不会在集群运行的私有 GCE 网络之外暴露。
@@ -0,0 +1,233 @@
---
approvers:
- caesarxuchao
- dchen1107
title: Nodes
redirect_from:
- "/docs/admin/node/"
- "/docs/admin/node.html"
- "/docs/concepts/nodes/node/"
- "/docs/concepts/nodes/node.html"
---
{{< toc >}}
## Node 是什么?
`Node` 是 Kubernetes 的工作节点,以前叫做 `minion`。取决于你的集群,Node 可以是一个虚拟机或者物理机器。每个 node 都有用于运行 [pods](/docs/user-guide/pods) 的必要服务,并由 master 组件管理。Node 上的服务包括 Docker、kubelet 和 kube-proxy。请查阅架构设计文档中 [The Kubernetes Node](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node) 一节获取更多细节。
## Node 状态
一个 node 的状态包含以下信息:
* [地址](#地址)
* ~~[阶段](#阶段)~~ **已废弃**
* [条件](#条件)
* [容量](#容量)
* [信息](#信息)
下面对每个章节进行详细描述。
### 地址
这些字段组合的用法取决于你的云服务商或者裸机配置。
* HostNameHostName 和 node 内核报告的相同。可以通过 kubelet 的 `--hostname-override` 参数覆盖。
* ExternalIP:通常是可以外部路由的 node IP 地址(从集群外可访问)。
* InternalIP:通常是仅可在集群内部路由的 node IP 地址。
### 阶段
一废弃:node 阶段已经不再使用。
### 条件
`conditions` 字段描述了所有 `Running` nodes 的状态。
| Node 条件 | 描述 |
| ---------------- | ---------------------------------------- |
| `OutOfDisk` | `True` 表示 node 的空闲空间不足以用于添加新 pods, 否则为 `False` |
| `Ready` | `True` 表示 node 是健康的并已经准备好接受 pods;`False` 表示 node 不健康而且不能接受 pods;`Unknown` 表示 node 控制器在最近 40 秒内没有收到 node 的消息 |
| `MemoryPressure` | `True` 表示 node 不存在内存压力 -- 即 node 内存用量低, 否则为 `False` |
| `DiskPressure` | `True` 表示 node 不存在磁盘压力 -- 即磁盘用量低, 否则为 `False` |
Node 条件使用一个 JSON 对象表示。例如,下面的响应描述了一个健康的 node。
```json
"conditions": [
{
"kind": "Ready",
"status": "True"
}
]
```
如果 Ready 条件处于状态 "Unknown" 或者 "False" 的时间超过了 `pod-eviction-timeout`(一个传递给 [kube-controller-manager](/docs/admin/kube-controller-manager/) 的参数),node 上的所有 Pods 都会被 Node 控制器计划删除。默认的删除超时时长为**5分钟**。某些情况下,当 node 不可访问时,apiserver 不能和其上的 kubelet 通信。删除 pods 的决定不能传达给 kubelet,直到它重新建立和 apiserver 的连接为止。与此同时,被计划删除的 pods 可能会继续在分区 node 上运行。
在 1.5 版本之前的 Kubernetes 里,node 控制器会将不能访问的 pods 从 apiserver 中[强制删除](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods)。但在 1.5 或更高的版本里,在node 控制器确认这些 pods 已经在集群里停运行前不会强制删除它们。你可以看到这些处于 "Terminating" 或者 "Unknown" 状态的 pods 可能在无法访问的 node 上运行。为了防止 kubernetes 不能从底层基础设施中推断出一个 node 是否已经永久的离开了集群,集群管理员可能需要手动删除这个 node 对象。从 Kubernetes 删除 node 对象将导致 apiserver 删除 node 上所有运行的 Pod 对象并释放它们的名字。
### 容量
描述 node 上的可用资源:CPU、内存和可以调度到 node 上的 pods 的最大数量。
### 信息
关于 node 的通用信息,例如内核版本、Kubernetes 版本(kubelet 和 kube-proxy 版本)、Docker 版本 (如果使用了)和 OS 名。这些信息由 Kubelet 从 node 搜集而来。
## 管理
与 [pods](/docs/user-guide/pods) 和 [services](/docs/user-guide/services) 不同,node 并不是在 Kubernetes 内部创建的:它是被外部的云服务商创建,例如 Google Compute Engine 或者你的集群中的物理或者虚拟机。这意味着当 Kubernetes 创建一个 node 时,它其实仅仅创建了一个对象来代表这个 node。创建以后,Kubernetes 将检查这个 node 是否可用。例如,如果你尝试使用如下内容创建一个 node:
```json
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
```
Kubernetes 会在内部创一个 node 对象(象征 node),并基于 `metadata.name` 字段(我们假设 `metadata.name` 能够被解析)通过健康检查来验证 node。如果 node 可用,意即所有必要服务都已运行,它就符合了运行一个 pod 的条件;否则它将被所有的集群动作忽略直到变为可用。请注意,Kubernetes 将保存不可用 node 的对象,除非它被客户端显式的删除。Kubernetes 将持续检查 node 是否变的可用。
当前,有3个组件同 Kubernetes node 接口交互:node 控制器、kubelet 和 kubectl。
### Node 控制器
Node 控制器是一个 Kubernetes master 组件,管理 nodes 的方方面面。
Node 控制器在 node 的生命周期中扮演了多个角色。第一个是当 node 注册时为它分配一个 CIDR block(如果打开了 CIDR 分配)。
第二个是使用云服务商提供了可用节点列表保持 node 控制器内部的 nodes 列表更新。如果在云环境下运行,任何时候当一个 node 不健康时 node 控制器将询问云服务 node 的虚拟机是否可用。如果不可用,node 控制器会将这个 node 从它的 nodes 列表删除。
第三个是监控 nodes 的健康情况。Node 控制器负责在 node 不能访问时(也即是 node 控制器因为某些原因没有收到心跳,例如 node 宕机)将它的 NodeStatus 的 NodeReady 状态更新为 ConditionUnknown。后续如果 node 持续不可访问,Node 控制器将删除 node 上的所有 pods(使用优雅终止)。(默认情况下 40s 开始报告 ConditionUnknown,在那之后 5m 开始删除 pods。)Node 控制器每隔 `--node-monitor-period` 秒检查每个 node 的状态。
在 Kubernetes 1.4 中我们更新了 node 控制器逻辑以更好的处理大批量 nodes 访问 master 出问题的情况(例如 master 的网络出了问题)。从 1.4 开始,node 控制器在决定删除 pod 之前会检查集群中所有 nodes 的状态。
大部分情况下, node 控制器把删除频率限制在每秒 `--node-eviction-rate` 个(默认为 0.1)。这表示它在 10 秒钟内不会从超过一个 node 上删除 pods。
当一个 availability zone 中的 node 变为不健康时,它的删除行为将发生改变。Node 控制器会同时检查 zone 中不健康(NodeReady 状态为 ConditionUnknown 或 ConditionFalse)的 nodes 的百分比。如果不健康 nodes 的部分超过 `--unhealthy-zone-threshold` (默认为 0.55),删除速率将会减小:如果集群较小(意即小于等于 `--large-cluster-size-threshold` 个 nodes - 默认为50),删除将会停止,否则删除速率将降为每秒 `--secondary-node-eviction-rate` 个(默认为 0.01)。在单个 availability zone 实施这些策略的原因是当一个 availability zone 可能从 master 分区时其它的仍然保持连接。如果你的集群没有跨越云服务商的多个 availability zones,那就只有一个 availability zone(整个集群)。
在多个 availability zones 分布你的 nodes 的一个关键原因是当整个 zone 故障时,工作负载可以转移到健康的 zones。因此,如果一个 zone 中的所有 nodes 都不健康时,node 控制器会以正常的速率 `--node-eviction-rate` 删除。在所有的 zones 都不健康(也即集群中没有健康 node)的极端情况下,node 控制器将假设 master 的连接出了某些问题,它将停止所有删除动作直到一些连接恢复。
从 Kubernetes 1.6 开始,NodeController 还负责删除运行在拥有 `NoExecute` taints 的 nodes 上的 pods,如果这些 pods 没有 tolerate 这些 taints。此外,作为一个默认禁用的 alpha 特性,NodeController 还负责根据 node 故障(例如 node 不可访问或没有 ready)添加 taints。请查看 [这个文档](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature)了解关于 `NoExecute` taints 和这个 alpha 特性。
### Nodes 自注册
当 kubelet 标志 `--register-node` 为 true (默认)时,它会尝试向 API 服务注册自己。这是首选模式,被绝大多数发行版选用。
对于自注册模式,kubelet 使用下列参数启动:
- `--api-servers` - apiservers 地址。
- `--kubeconfig` - 用于向 apiserver 验证自己的凭据路径。
- `--cloud-provider` - 如何从云服务商读取关于自己的元数据。
- `--register-node` - 自动向 API 服务注册。
- `--register-with-taints` - 使用 taints 列表(逗号分隔的 `<key>=<value>:<effect>`)注册 node。当 `register-node` 为 false 时无效。
- `--node-ip` - node IP 地址。
- `--node-labels` - 向集群注册时给 node 添加的 labels。
- `--node-status-update-frequency` - 指定 kubelet 向 master 发送状态的频率。
目前,任何 kubelet 都被授权可以创建/修改任意 node 资源,但通常只对自己的进行创建/修改。(未来我们计划只允许一个 kubelet 修改它自己 node 的资源。)
#### 手动 Node 管理
集群管理员可以创建及修改 node 对象。
如果管理员希望手动创建 node 对象,请设置 kubelet 标记 `--register-node=false`
管理员可以修改 node 资源(忽略 `--register-node` 设置)。修改包括在 node 上设置 labels及标记它为不可调度。
Nodes 上的 labels 可以和 pods 的 node selectors 一起使用来控制调度,例如限制一个 pod 只能在一个符合要求的 nodes 子集上运行。
标记一个 node 为不可调度的将防止新建 pods 调度到那个 node 之上,但不会影响任何已经在它之上的 pods。这是重启 node 等操作之前的一个有用的准备步骤。例如,标记一个 node 为不可调度的,执行以下命令:
```shell
kubectl cordon $NODENAME
```
请注意,被 daemonSet 控制器创建的 pods 将忽略 Kubernetes 调度器,且不会遵照 node 上不可调度的属性。这个假设基于守护程序属于节点机器,即使在准备重启而隔离应用的时候。
### Node 容量
Node 的容量(cpu 数量和内存容量)是 node 对象的一部分。通常情况下,在创建 node 对象时,它们会注册自己并报告自己的容量。如果你正在执行[手动 node 管理](#manual-node-administration),那么你需要在添加 node 时手动设置 node 容量。
Kubernetes 调度器保证一个 node 上有足够的资源供其上的所有 pods 使用。它会检查 node 上所有容器要求的总和不会超过 node 的容量。这包括所有 kubelet 启动的容器,但不包含 Docker 启动的容器和不在容器中的进程。
如果希望显式的为非 pod 进程预留资源,你可以创建一个占位 pod。使用如下模板:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: resource-reserver
spec:
containers:
- name: sleep-forever
image: k8s.gcr.io/pause:0.8.0
resources:
requests:
cpu: 100m
memory: 100Mi
```
设置 `cpu``memory` 值为你希望预留的资源量。将文件放在清单文件夹中(kubelet 的 `--config=DIR` 标志)。当你希望预留资源时,在每个 kubelet 上都这样执行。
## API 对象
Node 是 Kubernetes REST API 的顶级资源。更多关于 API 对象的细节可以在这里找到: [Node API
object](/docs/api-reference/{{< param "version" >}}/#node-v1-core).``
@@ -0,0 +1,45 @@
---
title: 安装扩展(Addons
---
## 概览
Add-ons 扩展了 Kubernetes 的功能。
本文列举了一些可用的 add-ons 以及到它们各自安装说明的链接。
每个 add-ons 按字母顺序排序 - 顺序不代表任何优先地位。
## 网络和网络策略
* [Calico](http://docs.projectcalico.org/latest/getting-started/kubernetes/installation/hosted/) 是一个安全的 L3 网络和网络策略提供者。
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install) 结合 Flannel 和 Calico, 提供网络和网络策略。
* [Cilium](https://github.com/cilium/cilium) 是一个 L3 网络和网络策略插件, 能够透明的实施 HTTP/API/L7 策略。 同时支持路由(routing)和叠加/封装( overlay/encapsulation)模式。
* [Contiv](http://contiv.github.io) 为多种用例提供可配置网络(使用 BGP 的原生 L3,使用 vxlan 的 overlay,经典 L2 和 Cisco-SDN/ACI)和丰富的策略框架。Contiv 项目完全[开源](http://github.com/contiv)。[安装工具](http://github.com/contiv/install)同时提供基于和不基于 kubeadm 的安装选项。
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kube-flannel.yml) 是一个可以用于 Kubernetes 的 overlay 网络提供者。
* [Romana](http://romana.io) 是一个 pod 网络的层 3 解决方案,并且支持 [NetworkPolicy API](/docs/concepts/services-networking/network-policies/)。Kubeadm add-on 安装细节可以在[这里](https://github.com/romana/romana/tree/master/containerize)找到。
* [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) 提供了在网络分组两端参与工作的网络和网络策略,并且不需要额外的数据库。
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) 使 Kubernetes 无缝连接到一种 CNI 插件,例如:Flannel、Calico、Canal、Romana 或者 Weave。
## 可视化管理
* [Dashboard](https://github.com/kubernetes/dashboard#kubernetes-dashboard) 是一个 Kubernetes 的 web 控制台界面。
* [Weave Scope](https://www.weave.works/documentation/scope-latest-installing/#k8s) 是一个图形化工具,用于查看你的 containers、 pods、services等。 请和一个 [Weave Cloud account](https://cloud.weave.works/) 一起使用,或者自己运行 UI。
## 遗留 Add-ons
还有一些其它 add-ons 归档在已废弃的 [cluster/addons](https://git.k8s.io/kubernetes/cluster/addons) 路径中。
维护完善的 add-ons 应该被链接到这里。欢迎提出 PRs!
@@ -0,0 +1,247 @@
---
cn-approvers:
- lichuqiang
title: 证书
---
{{< toc >}}
## 创建证书
当使用客户端证书进行认证时,用户可以使用现有部署脚本,或者通过 `easyrsa``openssl`
`cfssl` 手动生成证书。
### 使用现有部署脚本
**现有部署脚本** 位于
`cluster/saltbase/salt/generate-cert/make-ca-cert.sh`
执行该脚本时需传入两个参数。 第一个参数为 API 服务器的 IP 地址,第二个参数为对象的候补名称列表,
形如 `IP:<ip地址> 或 DNS:<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_IP>`
替换为你想使用的真实值。 注意:`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 = <country>
ST = <state>
L = <city>
O = <organization>
OU = <organization unit>
CN = <MASTER_IP>
[ 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 = <MASTER_IP>
IP.2 = <MASTER_CLUSTER_IP>
[ 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": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>",
}]
}
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",
"<MASTER_IP>",
"<MASTER_CLUSTER_IP>",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>"
}]
}
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 证书,用于认证。
@@ -0,0 +1,109 @@
---
title: 云供应商
content_template: templates/concept
---
{{% capture overview %}}
本文介绍了如何管理运行在特定云供应商上的 Kubernetes 集群。
{{% /capture %}}
{{% 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`:用于在服务中请求安全监听器,其值为合法的证书 ARNAmazon 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://<keystone_ip>/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
```
{{% /capture %}}
@@ -0,0 +1,87 @@
---
approvers:
- davidopp
- lavalamp
title: 集群管理概述
content_template: templates/concept
---
{{% capture overview %}}
集群管理概述面向任何创建和管理 Kubernetes 集群的读者人群。我们假设你对 [用户指南](/docs/user-guide/)中的概念有一些熟悉。
{{% /capture %}}
{{% capture body %}}
## 规划集群
查阅 [选择正确解决方案](/docs/setup/pick-right-solution/) 中的指导,获取如何规划、建立以及配置 Kubernetes 集群的示例。本文所列的文章称为*发行版*。
在选择一个指南前,有一些因素需要考虑:
- 你是打算在你的电脑上尝试 Kubernetes,还是要构建一个高可用的多节点集群?请选择最适合你需求的发行版。
- **如果你正在设计一个高可用集群**,请了解[在多个 zones 中配置集群](/docs/admin/multi-cluster)。
- 你的集群是在**本地**还是**云(IaaS**上?Kubernetes 不能直接支持混合集群。作为代替,你可以建立多个集群。
- **如果你在本地配置 Kubernetes**,需要考虑哪种[网络模型](/docs/admin/networking)最适合。一种自定义网络的选项是 [*OpenVSwitch GRE/VxLAN 网络*](/docs/admin/ovs-networking/),它使用 OpenVSwitch 在跨 Kubernetes 节点的 pods 之间建立起网络。
- 你的 Kubernetes 在 **裸金属硬件** 还是 **虚拟机(VMs)**上运行?
- 你**只想运行一个集群**,还是打算**活动开发 Kubernetes 项目代码**?如果是后者,请选择一个活动开发的发行版。某些发行版只提供二进制发布版,但提供更多的选择。
- 让你自己熟悉运行一个集群所需的[组件](/docs/admin/cluster-components) 。
请注意:不是所有的发行版都被积极维护着。请选择测试过最近版本的 Kubernetes 的发行版。
如果你正在使用和 Salt 有关的指南,请查阅 [使用 Salt 配置 Kubernetes](/docs/admin/salt)。
## 管理集群
[管理集群](/docs/concepts/cluster-administration/cluster-management/)叙述了和集群生命周期相关的几个主题:创建一个新集群、升级集群的 master 和 worker 节点、执行节点维护(例如内核升级)以及升级活动集群的 Kubernetes API 版本。
## 保护集群
* [Kubernetes 容器环境](/docs/concepts/containers/container-environment-variables/) 描述了 Kubernetes 节点上由 Kubelet 管理的容器的环境。
* [控制到 Kubernetes API 的访问](/docs/admin/accessing-the-api) 描述了如何为用户和 service accounts 建立权限许可.
* [用户认证](/docs/admin/authentication) 阐述了 Kubernetes 中的认证功能,包括许多认证选项。
* [授权](/docs/admin/authorization)从认证中分离出来,用于控制如何处理 HTTP 请求。
* [使用 Admission Controllers](/docs/admin/admission-controllers) 阐述了在认证和授权之后拦截到 Kubernetes API 服务的请求的插件。
* [在 Kubernetes Cluster 中使用 Sysctls](/docs/concepts/cluster-administration/sysctl-cluster/) 描述了管理员如何使用 `sysctl` 命令行工具来设置内核参数。
* [审计](/docs/tasks/debug-application-cluster/audit/) 描述了如何与 Kubernetes 的审计日志交互。
### 保护 kubelet
* [Master 节点通信](/docs/concepts/cluster-administration/master-node-communication/)
* [TLS 引导](/docs/admin/kubelet-tls-bootstrapping/)
* [Kubelet 认证/授权](/docs/admin/kubelet-authentication-authorization/)
## 可选集群服务
* [DNS 与 SkyDNS 集成](/docs/concepts/services-networking/dns-pod-service/)描述了如何将一个 DNS 名解析到一个Kubernetes service。
* [记录和监控集群活动](/docs/concepts/cluster-administration/logging/) 阐述了Kubernetes 的日志如何工作以及怎样实现。
{{% /capture %}}
@@ -0,0 +1,97 @@
---
approvers:
title: 设备插件
description: 使用 Kubernetes 设备插件框架来为 GPUs、 NICs、 FPGAs、 InfiniBand 和其他类似的需要供应商特别设置的资源开发插件。
content_template: templates/concept
---
{{< feature-state state="alpha" >}}
{{% 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
和其他类似的可能需要供应商特定的初始化和设置的计算资源。
{{% /capture %}}
{{% 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/{{< param "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 disappears, 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/{{< param "version" >}}/#podspec-v1-core) 中以 [Volume](/docs/api-reference/{{< param "version" >}}/#volume-v1-core) 的形式挂载。
## 示例
设备插件实现的示例,参考
[基于 COS 操作系统的 nvidia GPU 设备插件](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu)。
{{% /capture %}}
@@ -0,0 +1,117 @@
---
title: 联邦
content_template: templates/concept
---
{{% capture overview %}}
本页面阐明了为何以及如何使用联邦创建Kubernetes集群。
{{% /capture %}}
{{% capture body %}}
## 为何使用联邦
联邦可以使多个集群的管理简单化。它提供了两个主要构件模块:
* 跨集群同步资源:联邦能够让资源在多个集群中同步。例如,你可以确保在多个集群中存在同样的部署。
* 跨集群发现:联邦能够在所有集群的后端自动配置DNS服务和负载均衡。例如,通过多个集群的后端,你可以确保全局的VIP或DNS记录可用。
联邦技术的其他应用场景:
* 高可用性:通过跨集群分摊负载,自动配置DNS服务和负载均衡,联邦将集群失败所带来的影响降到最低。
* 避免供应商锁定:跨集群使迁移应用程序变得更容易,联邦服务避免了供应商锁定。
只有在多个集群的场景下联邦服务才是有帮助的。这里列出了一些你会使用多个集群的原因:
* 降低延迟:在多个区域含有集群,可使用离用户最近的集群来服务用户,从而最大限度降低延迟。
* 故障隔离:对于故障隔离,也许有多个小的集群比有一个大的集群要更好一些(例如:一个云供应商的不同可用域里有多个集群)。详细信息请参阅[多集群指南](/docs/admin/multi-cluster)。
* 可伸缩性:对于单个kubernetes集群是有伸缩性限制的(但对于大多数用户来说并非如此。更多细节参考[Kubernetes扩展和性能目标](https://git.k8s.io/community/sig-scalability/goals.md))。
* [混合云](#混合云的能力):可以有多个集群,它们分别拥有不同的云供应商或者本地数据中心。
### 注意事项
虽然联邦有很多吸引人的场景,但这里还是有一些需要关注的事项:
* 增加网络的带宽和损耗:联邦控制面会监控所有的集群,来确保集群的当前状态与预期一致。那么当这些集群运行在一个或者多个云提供者的不同区域中,则会带来重大的网络损耗。
* 降低集群的隔离:当联邦控制面中存在一个故障时,会影响所有的集群。把联邦控制面的逻辑降到最小可以缓解这个问题。 无论何时,它都是kubernetes集群里控制面的代表。设计和实现也使其变得更安全,避免多集群运行中断。
* 完整性:联邦项目相对较新,还不是很成熟。不是所有资源都可用,且很多资源才刚刚开始。[Issue 38893](https://github.com/kubernetes/kubernetes/issues/38893) 列举了一些团队正忙于解决的系统已知问题。
### 混合云的能力
Kubernetes集群里的联邦包括运行在不同云供应商上的集群(例如,谷歌云、亚马逊),和本地部署的集群(例如,OpenStack)。只需在适当的云供应商和/或位置创建所需的所有集群,并将每个集群的API endpoint和凭据注册到您的联邦API服务中(详情参考[联邦管理指南](/docs/admin/federation/))。
在此之后,您的[API资源](#api资源)就可以跨越不同的集群和云供应商。
## 建立联邦
若要能联合多个集群,首先需要建立一个联邦控制面。参照[安装指南](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) 建立联邦控制面。
## API资源
控制面建立完成后,就可以开始创建联邦API资源了。
以下指南详细介绍了一些资源:
* [Cluster](/docs/tasks/administer-federation/cluster/)
* [ConfigMap](/docs/tasks/administer-federation/configmap/)
* [DaemonSets](/docs/tasks/administer-federation/daemonset/)
* [Deployment](/docs/tasks/administer-federation/deployment/)
* [Events](/docs/tasks/administer-federation/events/)
* [Ingress](/docs/tasks/administer-federation/ingress/)
* [Namespaces](/docs/tasks/administer-federation/namespaces/)
* [ReplicaSets](/docs/tasks/administer-federation/replicaset/)
* [Secrets](/docs/tasks/administer-federation/secret/)
* [Services](/docs/concepts/cluster-administration/federation-service-discovery/)
[API参考文档](/docs/reference/federation/)列举了联邦API服务支持的所有资源。
## 级联删除
Kubernetes1.6版本支持联邦资源级联删除。使用级联删除,即当删除联邦控制面的一个资源时,也删除了所有底层集群中的相应资源。
当使用REST API时,级联删除功能不是默认开启的。若使用REST API从联邦控制面删除一个资源时,要开启级联删除功能,即需配置选项 `DeleteOptions.orphanDependents=false`。使用`kubectl delete`使级联删除功能默认开启。使用`kubectl delete --cascade=false`禁用级联删除功能。
注意:Kubernetes1.5版本开始支持联邦资源子集的级联删除。
## 单个集群的范围
对于IaaS供应商如谷歌计算引擎或亚马逊网络服务,一个虚拟机存在于一个[](https://cloud.google.com/compute/docs/zones)或[可用域](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html)中。
我们建议一个Kubernetes集群里的所有虚机应该在相同的可用域里,因为:
- 与单一的全局Kubernetes集群对比,该方式有较少的单点故障。
- 与跨可用域的集群对比,该方式更容易推断单区域集群的可用性属性。
- 当Kubernetes开发者设计一个系统(例如,对延迟、带宽或相关故障进行假设),他们也会假设所有的机器都在一个单一的数据中心,或者以其他方式紧密相连。
每个可用区域里包含多个集群当然是可以的,但是总的来说我们认为集群数越少越好。
偏爱较少集群数的原因是:
- 在某些情况下,在一个集群里有更多的节点,可以改进Pods的装箱问题(更少的资源碎片)。
- 减少操作开销(尽管随着OPS工具和流程的成熟而降低了这块的优势)。
- 为每个集群的固定资源花费降低开销,例如,使用apiserver的虚拟机(但是在全体集群开销中,中小型集群的开销占比要小的多)。
多集群的原因包括:
- 严格的安全性策略要求隔离一类工作与另一类工作(但是,请参见下面的集群分割)。
- 测试集群或其他集群软件直至最优的新Kubernetes版本发布。
## 选择合适的集群数
Kubernetes集群数量选择也许是一个相对静止的选择,因为对其重新审核的情况很少。相比之下,一个集群中的节点数和一个服务中的pods数可能会根据负载和增长频繁变化。
选择集群的数量,首先,需要决定哪些区域对于将要运行在Kubernetes上的服务,可以有足够的时间到达所有的终端用户(如果使用内容分发网络,则不需要考虑CDN-hosted内容的延迟需求)。法律问题也可能影响这一点。例如,拥有全球客户群的公司可能会对于在美国、欧盟、亚太和南非地区拥有集群起到决定权。使用`R`代表区域的数量。
其次,决定有多少集群在同一时间不可用,而一些仍然可用。使用`U`代表不可用的数量。如果不确定,最好选择1。
如果允许负载均衡在集群故障发生时将通信引导到任何区域,那么至少需要较大的`R``U + 1`集群。若非如此(例如,若要在集群故障发生时确保所有用户的低延迟),则需要`R * (U + 1)`集群(在每一个`R`区域里都有`U + 1`)。在任何情况下,尝试将每个集群放在不同的区域中。
最后,如果你的集群需求超过一个Kubernetes集群推荐的最大节点数,那么你可能需要更多的集群。Kubernetes1.3版本支持多达1000个节点的集群规模。
{{% /capture %}}
{{% capture whatsnext %}}
* 进一步学习[联邦提案](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/multicluster/federation.md)。
* 集群联邦参考该[配置指导](/docs/tutorials/federation/set-up-cluster-federation-kubefed/)。
* 查看[Kubecon2016浅谈联邦](https://www.youtube.com/watch?v=pq9lbkmxpS8)
{{% /capture %}}
@@ -0,0 +1,64 @@
---
title: Kubernetes 中的代理
content_template: templates/concept
---
{{% capture overview %}}
本文讲述了 Kubernetes 中所使用的代理。
{{% /capture %}}
{{% 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 用户通常只需要关心前两种类型的代理,集群管理员通常需要确保后面几种类型的代理设置正确。
## 请求重定向
代理已经取代重定向功能,重定向已被弃用。
{{% /capture %}}
@@ -0,0 +1,100 @@
---
approvers:
- sttts
title: Kubernetes集群中使用Sysctls
---
{{< toc >}}
这篇文章描述了如何在Kubernetes集群中使用Sysctls。
## 什么是Sysctl
在Linux中,Sysctl接口允许管理员在内核运行时修改内核参数。这些可用参数都存在于虚拟进程文件系统中的`/proc/sys/`目录。这些内核参数作用于各种子系统中,例如:
- 内核 (通用前缀:`kernel.`)
- 网络 (通用前缀:`net.`)
- 虚拟内存 (通用前缀:`vm.`)
- 设备专用 (通用前缀:`dev.`)
- 更多子系统描述见 [Kernel docs](https://www.kernel.org/doc/Documentation/sysctl/README).
获取所有参数列表,可运行
```
$ sudo sysctl -a
```
## 命名空间级vs.节点级Sysctls
在今天的Linux内核系统中有一些Sysctls是 _命名空间级_ 的。这意味着他们在同节点的不同pod间是可配置成独立的。在kubernetes里,命名空间级是Sysctls的一个必要条件,以使其在一个pod语境里易于理解。
以下列出了Sysctls中已知的 _命名空间级_
- `kernel.shm*`(内核中共享内存相关参数),
- `kernel.msg*`(内核中SystemV消息队列相关参数),
- `kernel.sem`(内核中信号量参数),
- `fs.mqueue.*`(内核中POSIX消息队列相关参数),
- `net.*`(内核中网络配置项相关参数)。
Sysctls中非命名空间级的被称为 _节点级_ ,其必须由集群管理员手动设置,要么通过节点的底层Linux分布方式(例如,通过 `/etc/sysctls.conf`),亦或在特权容器中使用Daemonset。
**注意**: 这是很好的做法,考虑在一个集群里给有特殊sysctl的节点设置为 _污点_ ,并且给他们安排仅需要这些sysctl设置的pods。 建议采用Kubernetes [_污点和容点_
特征](/docs/user-guide/kubectl/{{< param "version" >}}/#taint) 来实现。
## 安全的 vs. 不安全的 Sysctls
Sysctls被分为 _安全的__不安全的_ sysctls。同一节点上的pods间除了适当命名空间命名一个 _安全的_ sysctl,还必须适当的 _隔离_ 。 这意味着给一个pod设置一个 _安全的_ sysctl
- 不能对相同节点上其他pod产生任何影响
- 不能对节点的健康造成损害
- 不能在pod资源限制以外获取更多的CPU和内存资源
目前看来,大多数的 _命名空间级_ sysctls 不一定被认为是 _安全的_
在Kubernetes 1.4版本中,以下sysctls提供了 _安全的_ 配置:
- `kernel.shm_rmid_forced`,
- `net.ipv4.ip_local_port_range`,
- `net.ipv4.tcp_syncookies`.
该列表在未来的Kubernetes版本里还会继续扩充,当kubelet提供更好的隔离机制时。
所有 _安全的_ sysctls 都是默认启用的。
所有 _不安全的_ sysctls 默认是关闭的,且必须通过每个节点基础上的集群管理手动开启。禁用不安全的sysctls的Pods将会被计划,但不会启动。
**警告**: 由于他们的本质是 _不安全的_ ,使用 _不安全的_ sysctls是自担风险的,并且会导致严重的问题,例如容器的错误行为,资源短缺或者是一个节点的完全破损。
## 使能不安全的Sysctls
牢记上面的警告, 在非常特殊的情况下,例如高性能指标或是实时应用程序优化,集群管理员可以允许 _不安全的_
sysctls。 _不安全的_ sysctls 会打上kubelet标识,在逐节点的基础上被启用,例如:
```shell
$ kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,net.ipv4.route.min_pmtu' ...
```
只有 _命名空间级_ sysctls 可以使用该方法启用。
## 给Pod配置Sysctls
在Kubernetes 1.4版本中,sysctl特性是一个alpha API。因此,sysctls被设置为在pods上使用注释。它们适用于同一个pod上的所有容器。
这里列举了一个例子, _安全的__不安全的_ sysctls使用不同的注释:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
annotations:
security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1
security.alpha.kubernetes.io/unsafe-sysctls: net.ipv4.route.min_pmtu=1000,kernel.msgmax=1 2 3
spec:
...
```
**注意**: 包含以上规定的 _不安全的_ sysctls的一个Pod, 将无法启动任何不能使这两个 _不安全的_ sysctls明确的节点。 推荐
_节点级_ sysctls使用 [_容点和污点_
特征](/docs/user-guide/kubectl/v1.6/#taint) or [taints on nodes](/docs/concepts/configuration/taint-and-toleration/)
来将这些pods分配到正确的nodes上。
@@ -0,0 +1,299 @@
---
title: Managing Compute Resources for Containers
content_template: templates/concept
---
{{% capture overview %}}
当您定义 [Pod](/docs/user-guide/pods) 的时候可以选择为每个容器指定需要的 CPU 和内存(RAM)大小。当为容器指定了资源请求后,调度器就能够更好的判断出将容器调度到哪个节点上。如果您还为容器指定了资源限制,节点上的资源就可以按照指定的方式做竞争。关于资源请求和限制的不同点和更多资料请参考 [Resource QoS](https://git.k8s.io/community/contributors/design-proposals/resource-qos.md)。
{{% /capture %}}
{{% 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 和 64MiB2<sup>26</sup> 字节)内存,每个容器的限制为 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/{{< param "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/{{< param "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 "k8s.gcr.io/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
[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]]
```
您可以看到容器因为 `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
```
```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/{{< param "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 资源的定义,以便在不同的提供商和平台之间保持一致。
{{% /capture %}}
{{% capture whatsnext %}}
- 获取将 [CPU 和内存资源分配给容器](/docs/tasks/configure-pod-container/assign-cpu-ram-container/) 的实践经验
- [容器](/docs/api-reference/{{< param "version" >}}/#container-v1-core)
- [ResourceRequirements](/docs/resources-reference/{{< param "version" >}}/#resourcerequirements-v1-core)
{{% /capture %}}
- [容器](/docs/api-reference/{{< param "version" >}}/#container-v1-core)
- [ResourceRequirements](/docs/resources-reference/{{< param "version" >}}/#resourcerequirements-v1-core)
{{% /capture %}}
@@ -0,0 +1,29 @@
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: kubernetes.io/hostname
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0
@@ -0,0 +1,586 @@
---
approvers:
- mikedanese
title: Secret
---
`Secret` 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。将这些信息放在 `secret` 中比放在 `pod` 的定义或者 docker 镜像中来说更加安全和灵活。参阅 [Secret 设计文档](https://git.k8s.io/community/contributors/design-proposals/secrets.md) 获取更多详细信息。
{{< toc >}}
## Secret 概览
Secret 是一种包含少量敏感信息例如密码、token 或 key 的对象。这样的信息可能会被放在 Pod spec 中或者镜像中;将其放在一个 secret 对象中可以更好地控制它的用途,并降低意外暴露的风险。
用户可以创建 secret,同时系统也创建了一些 secret。
要使用 secretpod 需要引用 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: <none>
Annotations: <none>
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: k8s.gcr.io/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 签署一些消息。因为它具有复杂的应用程序逻辑,所以在服务器中可能会出现一个未被注意的远程文件读取漏洞,这可能会将私钥暴露给攻击者。
这可以在两个容器中分为两个进程:前端容器,用于处理用户交互和业务逻辑,但无法看到私钥;以及可以看到私钥的签名者容器,并且响应来自前端的简单签名请求(例如通过本地主机网络)。
使用这种分割方法,攻击者现在必须欺骗应用程序服务器才能进行任意的操作,这可能比使其读取文件更难。
<!-- TODO: explain how to do this while still using automation. -->
## 最佳实践
### 客户端使用 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 才能限制单个节点的根漏洞的影响,该功能还在计划中。
@@ -0,0 +1,62 @@
---
approvers:
- mikedanese
- thockin
title: 容器环境变量
content_template: templates/concept
---
{{% capture overview %}}
本文介绍容器环境中对容器可用的资源。
{{% /capture %}}
{{< 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/{{< param "githubbranch" >}}/cluster/addons/dns/),还可以在容器中通过 DNS 进行访问。
{{% /capture %}}
{{% capture whatsnext %}}
* 查看[容器生命周期挂钩(hooks](/docs/concepts/containers/container-lifecycle-hooks/)了解更多。
* 获取[为容器生命周期事件附加处理程序](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/)的实践经验。
{{% /capture %}}
@@ -0,0 +1,297 @@
---
approvers:
- erictune
- thockin
title: 镜像
content_template: templates/concept
---
{{% capture overview %}}
在Kubernetes pod中引用镜像前,请创建Docker镜像,并将之推送到镜像仓库中。
容器的“image”属性支持和Docker命令行相同的语法,包括私有仓库和标签。
{{% /capture %}}
{{< toc >}}
{{% capture body %}}
## 升级镜像
默认的镜像拉取策略是“IfNotPresent”,在镜像已经存在的情况下,kubelet将不在去拉取镜像。
如果总是想要拉取镜像,必须设置拉取策略为“Always”或者设置镜像标签为“:latest”。
如果没有指定镜像的标签,它会被假定为“:latest”,同时拉取策略为“Always”。
注意应避免使用“:latest”标签,参见 [Best Practices for Configuration](/docs/concepts/configuration/overview/#container-images) 获取更多信息。
## 使用私有仓库
从私有仓库读取镜像时可能需要密钥。
凭证可以用以下方式提供:
- 使用Google Container Registry
- 每个集群分别配置
- 在Google Compute Engine 或者 Google Kubernetes Engine上自动配置
- 所有的pod都能读取项目的私有仓库
- 使用 AWS EC2 Container Registry (ECR)
- 使用IAM角色和策略来控制对ECR仓库的访问
- 自动刷新ECR的登录凭证
- 使用 Azure Container Registry (ACR)
- 配置节点对私有仓库认证
- 所有的pod都可以读取已配置的私有仓库
- 需要集群管理员提供node的配置
- 提前拉取镜像
- 所有的pod都可以使用node上缓存的镜像
- 需要以root进入node操作
- pod上指定 ImagePullSecrets
- 只有提供了密钥的pod才能接入私有仓库
下面将详细描述每一项
### 使用 Google Container Registry
Kuberetes运行在Google Compute Engine (GCE)时原生支持[Google ContainerRegistry (GCR)]
(https://cloud.google.com/tools/container-registry/)。如果kubernetes集群运行在GCE
或者Google Kubernetes Engine 上,使用镜像全名(e.g. gcr.io/my_project/image:tag)即可。
集群中的所有pod都会有读取这个仓库中镜像的权限。
Kubelet将使用实例的Google service account向GCR认证。实例的service account拥有
`https://www.googleapis.com/auth/devstorage.read_only`,所以它可以从项目的GCR拉取,但不能推送。
### 使用 AWS EC2 Container Registry
当Node是AWS EC2实例时,Kubernetes原生支持[AWS EC2 ContainerRegistry](https://aws.amazon.com/ecr/)。
在pod定义中,使用镜像全名即可 (例如 `ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag`)
集群中可以创建pod的用户都可以使用ECR中的任意镜像运行pod。
Kubelet会获取并且定期刷新ECR的凭证。它需要以下权限
- `ecr:GetAuthorizationToken`
- `ecr:BatchCheckLayerAvailability`
- `ecr:GetDownloadUrlForLayer`
- `ecr:GetRepositoryPolicy`
- `ecr:DescribeRepositories`
- `ecr:ListImages`
- `ecr:BatchGetImage`
要求:
- 必须使用kubelet 1.2.0及以上版本
- 如果node在区域A,而镜像仓库在另一个区域B,需要1.3.0及以上版本
- 区域中必须提供ECR
诊断
- 验证是否满足以上要求
- 获取工作站的$REGION (例如 `us-west-2`)凭证,使用凭证SSH到主机手动运行docker,检查是否运行
- 验证kublet是否使用参数`--cloud-provider=aws`运行
- 检查kubelet日志(例如 `journalctl -u kubelet`),是否有类似的行
- `plugins.go:56] Registering credential provider: aws-ecr-key`
- `provider.go:91] Refreshing cache for provider: *aws_credentials.ecrProvider`
### 使用 Azure Container Registry (ACR)
当使用[Azure Container Registry](https://azure.microsoft.com/en-us/services/container-registry/)时,可以使用admin user或者service principal认证。
任何一种情况,认证都通过标准的Dokcer authentication完成。本指南假设使用[azure-cli](https://github.com/azure/azure-cli)
命令行工具。
首先,需要创建仓库并获取凭证,完整的文档请参考
[Azure container registry documentation](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-azure-cli)。
创建好容器仓库后,可以使用以下凭证登录:
* `DOCKER_USER` : service principal, or admin username
* `DOCKER_PASSWORD`: service principal password, or admin user password
* `DOCKER_REGISTRY_SERVER`: `${some-registry-name}.azurecr.io`
* `DOCKER_EMAIL`: `${some-email-address}`
填写以上变量后,就可以
[configure a Kubernetes Secret and use it to deploy a Pod](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod)。
### 配置Nodes对私有仓库认证
**注意:** 如果在Google Kubernetes Engine 上运行集群,每个节点上都会有`.dockercfg`文件,它包含对Google Container Registry的凭证。
不需要使用以下方法。
**注意:** 如果在AWS EC2上运行集群且准备使用EC2 Container Registry (ECR),每个node上的kubelet会管理和更新ECR的登录凭证。不需要使用以下方法。
**注意:** 该方法适用于能够对节点进行配置的情况。该方法在GCE及在其它能自动配置节点的云平台上并不适合。
Docker将私有仓库的密钥存放在`$HOME/.dockercfg``$HOME/.docker/config.json`文件中。Kubelet上,docker会使用root用户`$HOME`路径下的密钥。
推荐如下步骤来为node配置私有仓库。以下示例在PC或笔记本电脑中操作
1.对于想要使用的每一种凭证,运行 `docker login [server]`,它会更新`$HOME/.docker/config.json`
1.使用编辑器查看`$HOME/.docker/config.json`,保证文件中包含了想要使用的凭证
1.获取node列表,例如
- 如果使用node名称,`nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')`
- 如果使用node IP `nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')`
1.将本地的`.docker/config.json`拷贝到每个节点root用户目录下
- 例如: `for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done`
创建使用私有仓库的pod来验证,例如:
```yaml
$ cat <<EOF > /tmp/private-image-test-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: private-image-test-1
spec:
containers:
- name: uses-private-image
image: $PRIVATE_IMAGE_NAME
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
EOF
$ kubectl create -f /tmp/private-image-test-1.yaml
pod "private-image-test-1" created
$
```
如果一切正常,一段时间后,可以看到:
```shell
$ kubectl logs private-image-test-1
SUCCESS
```
如果失败,则可以看到:
```shell
$ kubectl describe pods/private-image-test-1 | grep "Failed"
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
```
必须保证集群中所有的节点都有相同的`.docker/config.json`文件。否则,pod会在一些节点上正常运行而在另一些节点上无法启动
例如,如果使用node自动弹缩,那么每个实例模板都需要包含`.docker/config.json`,或者挂载一个包含这个文件的驱动器。
`.docker/config.json`中配置了私有仓库密钥后,所有pod都会能读取私有仓库中的镜像。
**该方法已在6月26日的docker私有仓库和kubernetes v0.19.3上测试通过,其他私有仓库,如quay.io应该也可以运行,但未测试过。**
### 提前拉取镜像
**注意:** 如果在Google Kubernetes Engine 上运行集群,每个节点上都会有`.dockercfg`文件,它包含对Google Container Registry的凭证。
不需要使用以下方法。
**注意:** 该方法适用于能够对节点进行配置的情况。该方法在GCE及在其它能自动配置节点的云平台上并不适合。
默认情况下,kubelet会尝试从指定的仓库拉取每一个镜像
但是,如果容器属性`imagePullPolicy`设置为`IfNotPresent`或者`Never`
则会使用本地镜像(优先、唯一、分别)。
如果依赖提前拉取镜像代替仓库认证,
必须保证集群所有的节点提前拉取的镜像是相同的。
可以用于提前载入指定的镜像以提高速度,或者作为私有仓库认证的一种替代方案
所有的pod都可以使用node上缓存的镜像
### 在pod上指定ImagePullSecrets
**注意:** Google Kubernetes Engine,GCE及其他自动创建node的云平台上,推荐使用本方法。
Kubernetes支持在pod中指定仓库密钥。
#### 使用Docker Config创建Secret
运行以下命令,将大写字母代替为合适的值
```shell
$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret "myregistrykey" created.
```
如果需要接入多个仓库,可以为每个仓库创建一个secret。
当为pod拉取镜像时,kubelet会将`imagePullSecrets`合入一个独立虚拟的`.docker/config.json`
Pod只能引用和它相同namespace的ImagePullSecrets
所以需要为每一个namespace做配置
#### 通过kubectl创建secret
由于某种原因在一个`.docker/config.json`中需要多个项或者需要非上述命令给出的secret,可以[create a secret using
json or yaml](/docs/user-guide/secrets/#creating-a-secret-manually)。
请保证:
- 设置data项的名称为`.dockerconfigjson`
- 使用base64对docker文件编码,并将字符准确黏贴到`data[".dockerconfigjson"]`
- 设置`type``kubernetes.io/dockerconfigjson`
示例:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
namespace: awesomeapps
data:
.dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson
```
如果收到错误消息`error: no objects passed to create`,可能是 base64 编码后的字符串非法。
如果收到错误消息类似`Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...`,
说明数据已经解码成功,但是不满足`.docker/config.json`文件的语法。
#### 在pod中引用imagePullSecrets
现在,在创建pod时,可以在pod定义中增加`imagePullSecrets`小节来引用secret
```yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
```
对每一个使用私有仓库的pod,都需要做以上操作。
也可以在[serviceAccount](/docs/user-guide/service-accounts) 资源中设置imagePullSecrets自动设置`imagePullSecrets`
`imagePullSecrets`可以和每个node上的`.docker/config.json`一起使用,他们将共同生效。本方法在Google Kubernetes Engine
也能正常工作。
### 使用场景
配置私有仓库有多种方案,以下是一些常用场景和建议的解决方案。
1. 集群运行非专有(例如 开源镜像)镜像。镜像不需要隐藏。
- 使用Docker hub上的公有镜像
- 无需配置
- 在GCE/GKE上会自动使用高稳定性和高速的Docker hub的本地mirror
1. 集群运行一些专有镜像,这些镜像对外部公司需要隐藏,对集群用户可见
- 使用自主的私有[Docker registry](https://docs.docker.com/registry/).
- 可以放置在[Docker Hub](https://hub.docker.com/account/signup/),或者其他地方。
- 按照上面的描述,在每个节点手动配置.docker/config.json
- 或者,在防火墙内运行一个内置的私有仓库,并开放读取权限
- 不需要配置Kubenretes
- 或者,在GCE/GKE上时,使用项目的Google Container Registry
- 使用集群自动伸缩比手动配置node工作的更好
- 或者,在更改集群node配置不方便时,使用`imagePullSecrets`
1. 使用专有镜像的集群,有更严格的访问控制
- 保证[AlwaysPullImages admission controller](/docs/admin/admission-controllers/#alwayspullimages)开启。否则,所有的pod都可以使用镜像
- 将敏感数据存储在"Secret"资源中,而不是打包在镜像里
1. 多租户集群下,每个租户需要自己的私有仓库
- 保证[AlwaysPullImages admission controller](/docs/admin/admission-controllers/#alwayspullimages)开启。否则,所有租户的所有的pod都可以使用镜像
- 私有仓库开启认证
- 为每个租户获取仓库凭证,放置在secret中,并发布到每个租户的namespace下
- 租户将secret增加到每个namespace下的imagePullSecrets中
{{% /capture %}}
@@ -0,0 +1,37 @@
---
title: 概念模板示例
approvers:
- chenopis
content_template: templates/concept
---
{{% capture overview %}}
**注意:** 注意为新文档 [create an entry in the table of contents](/docs/home/contribute/write-new-topic/#creating-an-entry-in-the-table-of-contents) 。
本页解释了 ...
{{% /capture %}}
{{% capture body %}}
## 了解 ...
Kubernetes 提供 ...
## 使用 ...
使用 ...
{{% /capture %}}
{{% capture whatsnext %}}
**[可选章节]**
* 了解更多 [Writing a New Topic](/docs/home/contribute/write-new-topic/)。
* 查看 [Using Page Templates - Concept template](/docs/home/contribute/page-templates/#concept_template) 了解如何使用本模板。
{{% /capture %}}
@@ -0,0 +1,125 @@
---
approvers:
- lavalamp
title: Kubernetes 组件
redirect_from:
- "/docs/admin/cluster-components/"
- "/docs/admin/cluster-components.html"
content_template: templates/concept
---
{{% capture overview %}}
本文档概述了 Kubernetes 所需的各种二进制组件, 用于提供齐全的功能。
{{% /capture %}}
{{% capture body %}}
## Master 组件
Master 组件提供的集群控制。Master 组件对集群做出全局性决策(例如:调度),以及检测和响应集群事件(副本控制器的`replicas`字段不满足时,启动新的副本)。
Master 组件可以在集群中的任何节点上运行。然而,为了简单起见,设置脚本通常会启动同一个虚拟机上所有 Master 组件,并且不会在此虚拟机上运行用户容器。请参阅[构建高可用性群集](/docs/admin/high-availability)示例对于多主机 VM 的设置。
### API服务器
[kube-apiserver](/docs/admin/kube-apiserver)对外暴露了Kubernetes API。它是的 Kubernetes 前端控制层。它被设计为水平扩展,即通过部署更多实例来缩放。请参阅[构建高可用性群集](/docs/admin/high-availability).
### etcd
[etcd](/docs/admin/etcd) 用于 Kubernetes 的后端存储。所有集群数据都存储在此处,始终为您的 Kubernetes 集群的 etcd 数据提供备份计划。
### kube-controller-manager
[kube-controller-manager](/docs/admin/kube-controller-manager)运行控制器,它们是处理集群中常规任务的后台线程。逻辑上,每个控制器是一个单独的进程,但为了降低复杂性,它们都被编译成独立的可执行文件,并在单个进程中运行。
这些控制器包括:
* 节点控制器: 当节点移除时,负责注意和响应。
* 副本控制器: 负责维护系统中每个副本控制器对象正确数量的 Pod。
* 端点控制器: 填充 端点(Endpoints) 对象(即连接 Services & Pods)。
* 服务帐户和令牌控制器: 为新的命名空间创建默认帐户和 API 访问令牌.
### 云控制器管理器-(cloud-controller-manager)
cloud-controller-manager 是用于与底层云提供商交互的控制器。云控制器管理器可执行组件是 Kubernetes v1.6 版本中引入的 Alpha 功能。
cloud-controller-manager 仅运行云提供商特定的控制器循环。您必须在 kube-controller-manager 中禁用这些控制器循环,您可以通过在启动 kube-controller-manager 时将 `--cloud-provider` 标志设置为`external`来禁用控制器循环。
cloud-controller-manager 允许云供应商代码和 Kubernetes 核心彼此独立发展,在以前的版本中,Kubernetes 核心代码依赖于云提供商特定的功能代码。在未来的版本中,云供应商的特定代码应由云供应商自己维护,并与运行 Kubernetes 的云控制器管理器相关联。
以下控制器具有云提供商依赖关系:
* 节点控制器: 用于检查云提供商以确定节点是否在云中停止响应后被删除
* 路由控制器: 用于在底层云基础架构中设置路由
* 服务控制器: 用于创建,更新和删除云提供商负载平衡器
* 数据卷控制器: 用于创建,附加和装载卷,并与云提供商进行交互以协调卷
### 调度器 - (kube-scheduler)
[kube-scheduler](/docs/admin/kube-scheduler)监视没有分配节点的新创建的 Pod,选择一个节点供他们运行。
### 插件(addons)
插件是实现集群功能的 Pod 和 Service。 Pods 可以通过 DeploymentsReplicationControllers 管理。插件对象本身是受命名空间限制的,被创建于 `kube-system` 命名空间。
Addon 管理器用于创建和维护附加资源. 有关详细信息,请参阅[here](http://releases.k8s.io/HEAD/cluster/addons).
#### DNS
虽然其他插件并不是必需的,但所有 Kubernetes 集群都应该具有[Cluster DNS](/docs/concepts/services-networking/dns-pod-service/),许多示例依赖于它。
Cluster DNS 是一个 DNS 服务器,和您部署环境中的其他 DNS 服务器一起工作,为 Kubernetes 服务提供DNS记录。
Kubernetes 启动的容器自动将 DNS 服务器包含在 DNS 搜索中。
#### 用户界面
dashboard 提供了集群状态的只读概述。有关更多信息,请参阅[使用HTTP代理访问 Kubernetes API](/docs/tasks/access-kubernetes-api/http-proxy-access-api/)
#### 容器资源监控
[容器资源监控](/docs/user-guide/monitoring)将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。
#### 集群层面日志
[集群层面日志](/docs/user-guide/logging/overview) 机制负责将容器的日志数据保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。
## 节点组件
节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行时环境。
### kubelet
[kubelet](/docs/admin/kubelet)是主要的节点代理,它监测已分配给其节点的 Pod(通过 apiserver 或通过本地配置文件),提供如下功能:
* 挂载 Pod 所需要的数据卷(Volume)。
* 下载 Pod 的 secrets。
* 通过 Docker 运行(或通过 rkt)运行 Pod 的容器。
* 周期性的对容器生命周期进行探测。
* 如果需要,通过创建 *镜像 PodMirror Pod* 将 Pod 的状态报告回系统的其余部分。
* 将节点的状态报告回系统的其余部分。
### kube-proxy
[kube-proxy](/docs/admin/kube-proxy)通过维护主机上的网络规则并执行连接转发,实现了Kubernetes服务抽象。
### docker
Docker 用于运行容器。
### rkt
支持 rkt 运行容器作为 Docker 的试验性替代方案。
### supervisord
supervisord 是一个轻量级的进程监控系统,可以用来保证 kubelet 和 docker 运行。
### fluentd
fluentd 是一个守护进程,它有助于提供[集群层面日志](#cluster-level-logging) 集群层面的日志。
{{% /capture %}}
@@ -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`** 并使用 **`apiVersionv1`**。
1. 指定的组位于REST路径 **`/apis/$GROUP_NAME/$VERSION`**,并使用 **`apiVersion$GROUP_NAME/$VERSION`**(例如 **`apiVersionbatch/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`** 更改生效。
## 启用组中资源
DaemonSetsDeploymentsHorizontalPodAutoscalersIngressJobs和ReplicaSets是默认启用的。 其他扩展资源可以通过在apiserver上设置 **`--runtime-config`** 来启用。**`--runtime-config`** 接受逗号分隔的值。
例如:要禁用 Deployment 和 Ingress,请设置 **`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/ingress=false`**
@@ -0,0 +1,118 @@
---
approvers:
- k8s-merge-robot
title: 认识 Kubernetes?
---
Kubernetes 是一个跨主机集群的 [开源的容器调度平台,它可以自动化应用容器的部署、扩展和操作](http://www.slideshare.net/BrianGrant11/wso2con-us-2015-kubernetes-a-platform-for-automating-deployment-scaling-and-operations) , 提供以容器为中心的基础架构。
使用 Kubernetes, 您可以快速高效地响应客户需求:
- 快速、可预测地部署您的应用程序
- 拥有即时扩展应用程序的能力
- 不影响现有业务的情况下,无缝地发布新功能
- 优化硬件资源,降低成本
我们的目标是构建一个软件和工具的生态系统,以减轻您在公共云或私有云运行应用程序的负担。
#### Kubernetes 具有如下特点:
* **便携性**: 无论公有云、私有云、混合云还是多云架构都全面支持
* **可扩展**: 它是模块化、可插拔、可挂载、可组合的,支持各种形式的扩展
* **自修复**: 它可以自保持应用状态、可自重启、自复制、自缩放的,通过声明式语法提供了强大的自修复能力
Kubernetes 项目由 Google 公司在 2014 年启动。Kubernetes 建立在 [Google 公司超过十余年的运维经验基础之上,Google 所有的应用都运行在容器上](https://research.google.com/pubs/pub43438.html), 再与社区中最好的想法和实践相结合,也许它是最受欢迎的容器平台。
##### 准备好 [开始](/docs/getting-started-guides/)?
## 为什么是容器?
查看此文,可以了解为什么您要使用容器 [容器](http://aucouranton.com/2014/06/13/linux-containers-parallels-lxc-openvz-docker-and-more/)?
![为什么是容器?](/images/docs/why_containers.svg)
*传统* 部署应用程序的方式,一般是使用操作系统自带的包管理器在主机上安装应用依赖,之后再安装应用程序。这无疑将应用程序的可执行文件、应用的配置、应用依赖库和应用的生命周期与宿主机操作系统进行了紧耦合。在此情境下,可以通过构建不可改变的虚拟机镜像版本,通过镜像版本实现可预测的发布和回滚,但是虚拟机实在是太重量级了,且镜像体积太庞大,便捷性差。
*新方式* 是基于操作系统级虚拟化而不是硬件级虚拟化方法来部署容器。容器之间彼此隔离并与主机隔离:它们具有自己的文件系统,不能看到彼此的进程,并且它们所使用的计算资源是可以被限制的。它们比虚拟机更容易构建,并且因为它们与底层基础架构和主机文件系统隔离,所以它们可以跨云和操作系统快速分发。
由于容器体积小且启动快,因此可以在每个容器镜像中打包一个应用程序。这种一对一的应用镜像关系拥有很多好处。使用容器,不需要与外部的基础架构环境绑定, 因为每一个应用程序都不需要外部依赖,更不需要与外部的基础架构环境依赖。完美解决了从开发到生产环境的一致性问题。
容器同样比虚拟机更加透明,这有助于监测和管理。尤其是容器进程的生命周期由基础设施管理,而不是由容器内的进程对外隐藏时更是如此。最后,每个应用程序用容器封装,管理容器部署就等同于管理应用程序部署。
容器优点摘要:
* **敏捷的应用程序创建和部署**:
与虚拟机镜像相比,容器镜像更容易创建,提升了硬件的使用效率。
* **持续开发、集成和部署**:
提供可靠与频繁的容器镜像构建和部署,可以很方便及快速的回滚 (由于镜像不可变性).
* **关注开发与运维的分离**:
在构建/发布时创建应用程序容器镜像,从而将应用程序与基础架构分离。
* **开发、测试和生产环境的一致性**:
在笔记本电脑上运行与云中一样。
* **云和操作系统的可移植性**:
可运行在 Ubuntu, RHEL, CoreOS, 内部部署, Google 容器引擎和其他任何地方。
* **以应用为中心的管理**:
提升了操作系统的抽象级别,以便在使用逻辑资源的操作系统上运行应用程序。
* **松耦合、分布式、弹性伸缩 [微服务](http://martinfowler.com/articles/microservices.html)**:
应用程序被分成更小,更独立的部分,可以动态部署和管理 - 而不是巨型单体应用运行在专用的大型机上。
* **资源隔离**:
通过对应用进行资源隔离,可以很容易的预测应用程序性能。
* **资源利用**:
高效率和高密度。
#### 为什么我们需要 Kubernetes,它能做什么?
最基础的,Kubernetes 可以在物理或虚拟机集群上调度和运行应用程序容器。然而,Kubernetes 还允许开发人员从物理和虚拟机'脱离',从以**主机为中心**的基础架构转移到以**容器为中心**的基础架构,这样可以提供容器固有的全部优点和益处。Kubernetes 提供了基础设施来构建一个真正以**容器为中心**的开发环境。
Kubernetes 满足了生产中运行应用程序的许多常见的需求,例如:
* [Pod](/docs/user-guide/pods/) 提供复合应用并保留一个应用一个容器的容器模型,
* [挂载外部存储](/docs/user-guide/volumes/),
* [Secret管理](/docs/user-guide/secrets/),
* [应用健康检查](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),
* [副本应用实例](/docs/user-guide/replication-controller/),
* [横向自动扩缩容](/docs/user-guide/horizontal-pod-autoscaling/),
* [服务发现](/docs/user-guide/connecting-applications/),
* [负载均衡](/docs/user-guide/services/),
* [滚动更新](/docs/user-guide/update-demo/),
* [资源监测](/docs/user-guide/monitoring/),
* [日志采集和存储](/docs/user-guide/logging/overview/),
* [支持自检和调试](/docs/user-guide/introspection-and-debugging/),
* [认证和鉴权](/docs/admin/authorization/).
这提供了平台即服务 (PAAS) 的简单性以及基础架构即服务 (IAAS) 的灵活性,并促进跨基础设施供应商的可移植性。
有关详细信息,请参阅 [用户指南](/docs/user-guide/).
#### 为什么 Kubernetes 是一个平台?
Kubernetes 提供了很多的功能,总会有新的场景受益于新特性。它可以简化应用程序的工作流,加快开发速度。被大家认可的应用编排通常需要有较强的自动化能力。这就是为什么 Kubernetes 被设计作为构建组件和工具的生态系统平台,以便更轻松地部署、扩展和管理应用程序。
[Label](/docs/user-guide/labels/) 允许用户按照自己的方式组织管理对应的资源。 [注解](/docs/user-guide/annotations/) 使用户能够以自定义的描述信息来修饰资源,以适用于自己的工作流,并为管理工具提供检查点状态的简单方法。
此外,[Kubernetes 控制面 (Control Plane)](/docs/admin/cluster-components) 是构建在相同的 [APIs](/docs/api/) 上面,开发人员和用户都可以用。用户可以编写自己的控制器, [调度器](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/docs/devel/scheduler.md)等等,如果这么做,根据新加的[自定义 API](https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/docs/design/extending-api.md) ,可以扩展当前的通用 [CLI 命令行工具](/docs/user-guide/kubectl-overview/)。
这种 [设计](https://git.k8s.io/community/contributors/design-proposals/architecture/principles.md) 使得许多其他系统可以构建在 Kubernetes 之上。
#### Kubernetes 不是什么:
Kubernetes 不是一个传统意义上,包罗万象的 PaaS (平台即服务) 系统。我们保留用户选择的自由,这非常重要。
* Kubernetes 不限制支持的应用程序类型。 它不插手应用程序框架 (例如 [Wildfly](http://wildfly.org/)), 不限制支持的语言运行时 (例如 Java, Python, Ruby),只迎合符合 [12种因素的应用程序](http://12factor.net/),也不区分"应用程序"与"服务"。Kubernetes 旨在支持极其多样化的工作负载,包括无状态、有状态和数据处理工作负载。如果应用可以在容器中运行,它就可以在 Kubernetes 上运行。
* Kubernetes 不提供作为内置服务的中间件 (例如 消息中间件)、数据处理框架 (例如 Spark)、数据库 (例如 mysql)或集群存储系统 (例如 Ceph)。这些应用可以运行在 Kubernetes 上。
* Kubernetes 没有提供点击即部署的服务市场
* Kubernetes 从源代码到镜像都是非垄断的。 它不部署源代码且不构建您的应用程序。 持续集成 (CI) 工作流是一个不同用户和项目都有自己需求和偏好的领域。 所以我们支持在 Kubernetes 分层的 CI 工作流,但不指定它应该如何工作。
* Kubernetes 允许用户选择其他的日志记录,监控和告警系统 (虽然我们提供一些集成作为概念验证)
* Kubernetes 不提供或授权一个全面的应用程序配置语言/系统 (例如 [jsonnet](https://github.com/google/jsonnet)).
* Kubernetes 不提供也不采用任何全面机器配置、保养、管理或自我修复系统
另一方面,许多 PaaS 系统*运行*在 Kubernetes 上面,例如 [Openshift](https://github.com/openshift/origin), [Deis](http://deis.io/), and [Eldarion](http://eldarion.cloud/)。 您也可以自定义您自己的 PaaS, 与您选择的 CI 系统集成,或与 Kubernetes 一起使用: 将您的容器镜像部署到 Kubernetes。
由于 Kubernetes 在应用级别而不仅仅在硬件级别上运行,因此它提供 PaaS 产品通用的一些功能,例如部署、扩展、负载均衡、日志记录、监控等。但是,Kubernetes 不是单一的,默认解决方案是可选和可插拔的。
此处,Kubernetes 不仅仅是一个 "编排系统";它消除了编排的需要。 "编排"技术定义的是工作流的执行: 从 A 到 B,然后到 C。相反,Kubernetes 是包括一套独立、可组合的控制过程,通过声明式语法使其连续地朝着期望状态驱动当前状态。 不需要告诉它具体从 A 到 C 的过程,只要告诉到 C 的状态即可。 也不需要集中控制;该方法更类似于"编舞"。这使得系统更容易使用并且更强大、更可靠、更具弹性和可扩展性。
#### *Kubernetes* 是什么意思? K8s?
名称 **Kubernetes** 源于希腊语,意为 "舵手" 或 "飞行员" 且是英文 "governor" 和 ["cybernetic"](http://www.etymonline.com/index.php?term=cybernetics)的词根。 **K8s** 是通过将 8 个字母 "ubernete" 替换为 8 而导出的缩写。另外,在中文里,k8s 的发音与 Kubernetes 的发音比较接近。
@@ -0,0 +1,99 @@
---
title: 理解 Kubernetes 对象
redirect_from:
- "/docs/concepts/abstractions/overview/"
- "/docs/concepts/abstractions/overview.html"
content_template: templates/concept
---
{{% capture overview %}}
本页说明了 Kubernetes 对象在 Kubernetes API 中是如何表示的,以及如何在 `.yaml` 格式的文件中表示。
{{% /capture %}}
{{% capture body %}}
## 理解 Kubernetes 对象
在 Kubernetes 系统中,*Kubernetes 对象* 是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态。特别地,它们描述了如下信息:
* 哪些容器化应用在运行(以及在哪个 Node 上)
* 可以被应用使用的资源
* 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略
Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,本质上是在告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的 **期望状态(Desired State**
操作 Kubernetes 对象 —— 是否创建、修改,或者删除 —— 需要使用 [Kubernetes API](https://git.k8s.io/community/contributors/devel/api-conventions.md)。比如,当使用 `kubectl` 命令行接口时,CLI 会执行必要的 Kubernetes API 调用,也可以在程序中直接调用 Kubernetes API。为了实现该目标,Kubernetes 当前提供了一个 `golang` [客户端库](https://github.com/kubernetes/client-go)
,其它语言库(例如[Python](https://github.com/kubernetes-incubator/client-python))也正在开发中。
### 对象规约(Spec)与状态(Status)
每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 *spec* 和 对象 *status*
*spec* 是必需的,它描述了对象的 *期望状态(Desired State* —— 希望对象所具有的特征。
*status* 描述了对象的 *实际状态(Actual State*,它是由 Kubernetes 系统提供和更新的。在任何时刻,Kubernetes 控制面一直努力地管理着对象的实际状态以与期望状态相匹配。
例如,Kubernetes Deployment 对象能够表示运行在集群中的应用。
当创建 Deployment 时,可能需要设置 Deployment 的规约,以指定该应用需要有 3 个副本在运行。
Kubernetes 系统读取 Deployment 规约,并启动我们所期望的该应用的 3 个实例 —— 更新状态以与规约相匹配。
如果那些实例中有失败的(一种状态变更),Kubernetes 系统通过修正来响应规约和状态之间的不一致 —— 这种情况,会启动一个新的实例来替换。
关于对象 spec、status 和 metadata 的更多信息,查看 [Kubernetes API 约定](https://git.k8s.io/community/contributors/devel/api-conventions.md)。
### 描述 Kubernetes 对象
当创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。
当使用 Kubernetes API 创建对象时(或者直接创建,或者基于`kubectl`),API 请求必须在请求体中包含 JSON 格式的信息。
**大多数情况下,需要在 .yaml 文件中为 `kubectl` 提供这些信息**
`kubectl` 在发起 API 请求时,将这些信息转换成 JSON 格式。
这里有一个 `.yaml` 示例文件,展示了 Kubernetes Deployment 的必需字段和对象规约:
{{< code file="nginx-deployment.yaml" >}}
使用类似于上面的 `.yaml` 文件来创建 Deployment,一种方式是使用 `kubectl` 命令行接口(CLI)中的 [`kubectl create`](/docs/user-guide/kubectl/v1.7/#create) 命令,将 `.yaml` 文件作为参数。下面是一个示例:
```shell
$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record
```
输出类似如下这样:
```shell
deployment "nginx-deployment" created
```
### 必需字段
在想要创建的 Kubernetes 对象对应的 `.yaml` 文件中,需要配置如下的字段:
* `apiVersion` - 创建该对象所使用的 Kubernetes API 的版本
* `kind` - 想要创建的对象的类型
* `metadata` - 帮助识别对象唯一性的数据,包括一个 `name` 字符串、UID 和可选的 `namespace`
也需要提供对象的 `spec` 字段。对象 `spec` 的精确格式对每个 Kubernetes 对象来说是不同的,包含了特定于该对象的嵌套字段。[Kubernetes API 参考](/docs/api/)能够帮助我们找到任何我们想创建的对象的 spec 格式。
{{% /capture %}}
{{% capture whatsnext %}}
* 了解最重要的基本 Kubernetes 对象,例如 [Pod](/docs/concepts/abstractions/pod/)。
{{% /capture %}}
@@ -0,0 +1,16 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
@@ -0,0 +1,219 @@
---
approvers:
- pweil-
title: Pod 安全策略
redirect_from:
- "/docs/user-guide/pod-security-policy/"
- "/docs/user-guide/pod-security-policy/index.html"
---
`PodSecurityPolicy` 类型的对象能够控制,是否可以向 Pod 发送请求,该 Pod 能够影响被应用到 Pod 和容器的 `SecurityContext`
查看 [Pod 安全策略建议](https://git.k8s.io/community/contributors/design-proposals/security-context-constraints.md) 获取更多信息。
{{< toc >}}
## 什么是 Pod 安全策略?
_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。
`PodSecurityPolicy` 对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行。
它们允许管理员控制如下方面:
| 控制面 | 字段名称 |
| ------------------------------------------------------------- | --------------------------------- |
| 已授权容器的运行 | `privileged` |
| 为容器添加默认的一组能力 | `defaultAddCapabilities` |
| 为容器去掉某些能力 | `requiredDropCapabilities` |
| 容器能够请求添加某些能力 | `allowedCapabilities` |
| 控制卷类型的使用 | [`volumes`](#controlling-volumes) |
| 主机网络的使用 | [`hostNetwork`](#host-network) |
| 主机端口的使用 | `hostPorts` |
| 主机 PID namespace 的使用 | `hostPID` |
| 主机 IPC namespace 的使用 | `hostIPC` |
| 主机路径的使用 | [`allowedHostPaths`](#allowed-host-paths) |
| 容器的 SELinux 上下文 | [`seLinux`](#selinux) |
| 用户 ID | [`runAsUser`](#runasuser) |
| 配置允许的补充组 | [`supplementalGroups`](#supplementalgroups) |
| 分配拥有 Pod 数据卷的 FSGroup | [`fsGroup`](#fsgroup) |
| 必须使用一个只读的 root 文件系统 | `readOnlyRootFilesystem` |
_Pod 安全策略_ 由设置和策略组成,它们能够控制 Pod 访问的安全特征。这些设置分为如下三类:
- *基于布尔值控制*:这种类型的字段默认为最严格限制的值。
- *基于被允许的值集合控制*:这种类型的字段会与这组值进行对比,以确认值被允许。
- *基于策略控制*:设置项通过一种策略提供的机制来生成该值,这种机制能够确保指定的值落在被允许的这组值中。
### RunAsUser
- *MustRunAs* - 必须配置一个 `range`。使用该范围内的第一个值作为默认值。验证是否不在配置的该范围内。
- *MustRunAsNonRoot* - 要求提交的 Pod 具有非零 `runAsUser` 值,或在镜像中定义了 `USER` 环境变量。不提供默认值。
- *RunAsAny* - 没有提供默认值。允许指定任何 `runAsUser`
### SELinux
- *MustRunAs* - 如果没有使用预分配的值,必须配置 `seLinuxOptions`。默认使用 `seLinuxOptions`。验证 `seLinuxOptions`
- *RunAsAny* - 没有提供默认值。允许任意指定的 `seLinuxOptions` ID。
### SupplementalGroups
- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证所有范围的值。
- *RunAsAny* - 没有提供默认值。允许任意指定的 `supplementalGroups` ID。
### FSGroup
- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证在第一个范围内的第一个 ID。
- *RunAsAny* - 没有提供默认值。允许任意指定的 `fsGroup` ID。
### 控制卷
通过设置 PSP 卷字段,能够控制具体卷类型的使用。当创建一个卷的时候,与该字段相关的已定义卷可以允许设置如下值:
1. azureFile
1. azureDisk
1. flocker
1. flexVolume
1. hostPath
1. emptyDir
1. gcePersistentDisk
1. awsElasticBlockStore
1. gitRepo
1. secret
1. nfs
1. iscsi
1. glusterfs
1. persistentVolumeClaim
1. rbd
1. cinder
1. cephFS
1. downwardAPI
1. fc
1. configMap
1. vsphereVolume
1. quobyte
1. projected
1. portworxVolume
1. scaleIO
1. storageos
1. \* (allow all volumes)
对新的 PSP,推荐允许的卷的最小集合包括:configMap、downwardAPI、emptyDir、persistentVolumeClaim、secret 和 projected。
### 主机网络
- *HostPorts* 默认为 `empty``HostPortRange` 列表通过 `min`(包含) and `max`(包含) 来定义,指定了被允许的主机端口。
### 允许的主机路径
- *AllowedHostPaths* 是一个被允许的主机路径前缀的白名单。空值表示所有的主机路径都可以使用。
## 许可
包含 `PodSecurityPolicy`_许可控制_,允许控制集群资源的创建和修改,基于这些资源在集群范围内被许可的能力。
许可使用如下的方式为 Pod 创建最终的安全上下文:
1. 检索所有可用的 PSP。
1. 生成在请求中没有指定的安全上下文设置的字段值。
1. 基于可用的策略,验证最终的设置。
如果某个策略能够匹配上,该 Pod 就被接受。如果请求与 PSP 不匹配,则 Pod 被拒绝。
Pod 必须基于 PSP 验证每个字段。
## 创建 Pod 安全策略
下面是一个 Pod 安全策略的例子,所有字段的设置都被允许:
{{< code file="psp.yaml" >}}
下载示例文件可以创建该策略,然后执行如下命令:
```shell
$ kubectl create -f ./psp.yaml
podsecuritypolicy "permissive" created
```
## 获取 Pod 安全策略列表
获取已存在策略列表,使用 `kubectl get`
```shell
$ kubectl get psp
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
permissive false [] RunAsAny RunAsAny RunAsAny RunAsAny false [*]
privileged true [] RunAsAny RunAsAny RunAsAny RunAsAny false [*]
restricted false [] RunAsAny MustRunAsNonRoot RunAsAny RunAsAny false [emptyDir secret downwardAPI configMap persistentVolumeClaim projected]
```
## 修改 Pod 安全策略
通过交互方式修改策略,使用 `kubectl edit`
```shell
$ kubectl edit psp permissive
```
该命令将打开一个默认文本编辑器,在这里能够修改策略。
## 删除 Pod 安全策略
一旦不再需要一个策略,很容易通过 `kubectl` 删除它:
```shell
$ kubectl delete psp permissive
podsecuritypolicy "permissive" deleted
```
## 启用 Pod 安全策略
为了能够在集群中使用 Pod 安全策略,必须确保满足如下条件:
1. 已经启用 API 类型 `extensions/v1beta1/podsecuritypolicy`(仅对 1.6 之前的版本)
1. 已经启用许可控制器 `PodSecurityPolicy`
1. 已经定义了自己的策略
## 使用 RBAC
在 Kubernetes 1.5 或更新版本,可以使用 PodSecurityPolicy 来控制,对基于用户角色和组的已授权容器的访问。访问不同的 PodSecurityPolicy 对象,可以基于认证来控制。基于 Deployment、ReplicaSet 等创建的 Pod,限制访问 PodSecurityPolicy 对象,[Controller Manager](/docs/admin/kube-controller-manager/) 必须基于安全 API 端口运行,并且不能够具有超级用户权限。
PodSecurityPolicy 认证使用所有可用的策略,包括创建 Pod 的用户,Pod 上指定的服务账户(Service Acount)。当 Pod 基于 Deployment、ReplicaSet 创建时,它是创建 Pod 的 Controller Manager,所以如果基于非安全 API 端口运行,允许所有的 PodSecurityPolicy 对象,并且不能够有效地实现细分权限。用户访问给定的 PSP 策略有效,仅当是直接部署 Pod 的情况。更多详情,查看 [PodSecurityPolicy RBAC 示例](https://git.k8s.io/kubernetes/examples/podsecuritypolicy/rbac/README.md),当直接部署 Pod 时,应用 PodSecurityPolicy 控制基于角色和组的已授权容器的访问 。
+18
View File
@@ -0,0 +1,18 @@
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: permissive
spec:
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
hostPorts:
- min: 8000
max: 8080
volumes:
- '*'
@@ -0,0 +1,220 @@
---
approvers:
- derekwaynecarr
title: 资源配额
---
当多个用户或团队共享具有固定数目节点的集群时,人们会担心有人使用的资源超出应有的份额。
资源配额是帮助管理员解决这一问题的工具。
资源配额, 通过 `ResourceQuota` 对象来定义, 对每个namespace的资源消耗总量提供限制。 它可以按类型限制namespace下可以创建的对象的数量,也可以限制可被该项目以资源形式消耗的计算资源的总量。
资源配额的工作方式如下:
- 不同的团队在不同的namespace下工作。 目前这是自愿的, 但计划通过ACL (Access Control List 访问控制列表)
使其变为强制性的。
- 管理员为每个namespace创建一个或多个资源配额对象。
- 用户在namespace下创建资源 (pods、 services等),同时配额系统会跟踪使用情况,来确保其不超过
资源配额中定义的硬性资源限额。
- 如果资源的创建或更新违反了配额约束,则请求会失败,并返回 HTTP状态码 `403 FORBIDDEN` ,以及说明违反配额
约束的信息。
- 如果namespace下的计算资源 (如 `cpu``memory`)的配额被启用,则用户必须为这些资源设定请求值(request)
和约束值(limit),否则配额系统将拒绝Pod的创建。
提示: 可使用 LimitRange 准入控制器来为没有设置计算资源需求的Pod设置默认值。
作为示例,请参考 [演练](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/) 来避免这个问题。
下面是使用namespace和配额构建策略的示例:
- 在具有 32 GiB 内存 和 16 核CPU资源的集群中, 允许A团队使用 20 GiB 内存 和 10 核的CPU资源,
允许B团队使用 10GiB 内存和 4 核的CPU资源, 并且预留 2GiB 内存和 2 核的CPU资源供将来分配。
- 限制 "testing" namespace使用 1 核CPU资源和 1GiB 内存。 允许 "production" namespace使用任意数量。
在集群容量小于各namespace配额总和的情况下,可能存在资源竞争。 Kubernetes采用先到先服务的方式处理这类问题。
无论是资源竞争还是配额的变更都不会影响已经创建的资源。
## 启用资源配额
资源配额的支持在很多Kubernetes版本中是默认开启的。 当 apiserver 的
`--admission-control=` 参数中包含 `ResourceQuota` 时,资源配额会被启用。
当namespace中存在一个 `ResourceQuota` 对象时,该namespace即开始实施资源配额管理。
一个namespace中最多只应存在一个 `ResourceQuota` 对象
## 计算资源配额
用户可以对给定namespace下的 [计算资源](/docs/user-guide/compute-resources) 总量进行限制。
配额机制所支持的资源类型:
| 资源名称 | 描述 |
| --------------------- | ----------------------------------------------------------- |
| `cpu` | 所有非终止状态的Pod中,其CPU需求总量不能超过该值。 |
| `limits.cpu` | 所有非终止状态的Pod中,其CPU限额总量不能超过该值。 |
| `limits.memory` | 所有非终止状态的Pod中,其内存限额总量不能超过该值。 |
| `memory` | 所有非终止状态的Pod中,其内存需求总量不能超过该值。 |
| `requests.cpu` | 所有非终止状态的Pod中,其CPU需求总量不能超过该值。 |
| `requests.memory` | 所有非终止状态的Pod中,其内存需求总量不能超过该值。 |
## 存储资源配额
用户可以对给定namespace下的 [存储资源](/docs/user-guide/persistent-volumes) 总量进行限制。
此外,还可以根据相关的存储类(Storage Class)来限制存储资源的消耗。
| 资源名称 | 描述 |
| --------------------- | ----------------------------------------------------------- |
| `requests.storage` | 所有的PVC中,存储资源的需求不能超过该值。 |
| `persistentvolumeclaims` | namespace中所允许的 [PVC](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) 总量。 |
| `<storage-class-name>.storageclass.storage.k8s.io/requests.storage` | 所有该storage-class-name相关的PVC中, 存储资源的需求不能超过该值。 |
| `<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims` | namespace中所允许的该storage-class-name相关的[PVC](/docs/user-guide/persistent-volumes/#persistentvolumeclaims)的总量。 |
例如,如果一个操作人员针对 "黄金" 存储类型与 "铜" 存储类型设置配额,操作员可以
定义配额如下:
* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi`
* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi`
## 对象数量配额
给定类型的对象数量可以被限制。 支持以下类型:
| 资源名称 | 描述 |
| ------------------------------- | ------------------------------------------------- |
| `configmaps` | namespace下允许存在的configmap的数量。 |
| `persistentvolumeclaims` | namespace下允许存在的[PVC](/docs/user-guide/persistent-volumes/#persistentvolumeclaims)的数量。 |
| `pods` | namespace下允许存在的非终止状态的pod数量。 如果pod 的 `status.phase 为 Failed 或 Succeeded` 那么其处于终止状态。 |
| `replicationcontrollers` | namespace下允许存在的replication controllers的数量。 |
| `resourcequotas` | namespace下允许存在的 [resource quotas](/docs/admin/admission-controllers/#resourcequota) 的数量。 |
| `services` | namespace下允许存在的service的数量。 |
| `services.loadbalancers` | namespace下允许存在的load balancer类型的service的数量。 |
| `services.nodeports` | namespace下允许存在的node port类型的service的数量。 |
| `secrets` | namespace下允许存在的secret的数量。 |
例如 `pods` 配额统计并保证单个namespace下创建 `pods` 的最大数量。
用户可能希望在namespace中为pod设置配额,来避免有用户创建很多小的pod,从而耗尽集群提供的pod IP地址。
## 配额作用域
每个配额都有一组相关的作用域(scope),配额只会对作用域内的资源生效。
当一个作用域被添加到配额中后,它会对作用域相关的资源数量作限制。
如配额中指定了允许(作用域)集合之外的资源,会导致验证错误。
| 范围 | 描述 |
| ----- | ----------- |
| `Terminating` | 匹配 `spec.activeDeadlineSeconds >= 0` 的pod。 |
| `NotTerminating` | 匹配 `spec.activeDeadlineSeconds is nil` 的pod。 |
| `BestEffort` | 匹配"尽力而为(best effort)"服务类型的pod。 |
| `NotBestEffort` | 匹配非"尽力而为(best effort)"服务类型的pod。 |
`BestEffort` 作用域限制配额跟踪以下资源: `pods`
`Terminating``NotTerminating``NotBestEffort` 限制配额跟踪以下资源:
* `cpu`
* `limits.cpu`
* `limits.memory`
* `memory`
* `pods`
* `requests.cpu`
* `requests.memory`
## 请求/约束
分配计算资源时,每个容器可以为CPU或内存指定请求和约束。
也可以设置两者中的任何一个。
如果配额中指定了 `requests.cpu``requests.memory` 的值,那么它要求每个进来的容器针对这些资源有明确的请求。 如果配额中指定了 `limits.cpu``limits.memory`的值,那么它要求每个进来的容器针对这些资源指定明确的约束。
## 查看和设置配额
Kubectl 支持创建、更新和查看配额:
```shell
$ kubectl create namespace myspace
$ cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
pods: "4"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
EOF
$ kubectl create -f ./compute-resources.yaml --namespace=myspace
$ cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
EOF
$ kubectl create -f ./object-counts.yaml --namespace=myspace
$ kubectl get quota --namespace=myspace
NAME AGE
compute-resources 30s
object-counts 32s
$ kubectl describe quota compute-resources --namespace=myspace
Name: compute-resources
Namespace: myspace
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
pods 0 4
requests.cpu 0 1
requests.memory 0 1Gi
$ kubectl describe quota object-counts --namespace=myspace
Name: object-counts
Namespace: myspace
Resource Used Hard
-------- ---- ----
configmaps 0 10
persistentvolumeclaims 0 4
replicationcontrollers 0 20
secrets 1 10
services 0 10
services.loadbalancers 0 2
```
## 配额和集群容量
配额对象是独立于集群容量的。它们通过绝对的单位来表示。 所以,为集群添加节点, *不会*
自动赋予每个namespace消耗更多资源的能力。
有时可能需要更复杂的策略,比如:
- 在几个团队中按比例划分总的集群资源。
- 允许每个租户根据需要增加资源使用量,但要有足够的限制以防止意外资源耗尽。
- 在namespace中添加节点、提高配额的额外需求。
这些策略可以基于 ResourceQuota,通过编写一个检测配额使用,并根据其他信号调整各namespace下的配额硬性限制的 "控制器" 来实现。
注意:资源配额对集群资源总体进行划分,但它对节点没有限制:来自多个namespace的Pod可能在同一节点上运行。
## 示例
查看 [如何使用资源配额的详细示例](/docs/tasks/administer-cluster/quota-api-object/)。
## 更多信息
查看 [资源配额设计文档](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md) 了解更多信息。
@@ -0,0 +1,75 @@
---
approvers:
- rickypai
- thockin
title: 使用 HostAliases 向 Pod /etc/hosts 文件添加条目
redirect_from:
- "/docs/user-guide/add-entries-to-pod-etc-hosts-with-host-aliases/"
- "/docs/user-guide/add-entries-to-pod-etc-hosts-with-host-aliases.md"
---
{{< toc >}}
当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts 文件中添加条目,可以在 Pod 级别覆盖对主机名的解析。在 1.7 版本,用户可以通过 PodSpec 的 HostAliases 字段来添加这些自定义的条目。
建议通过使用 HostAliases 来进行修改,因为该文件由 Kubelet 管理,并且可以在 Pod 创建/重启过程中被重写。
## 默认 hosts 文件内容
让我们从一个 Nginx Pod 开始,给该 Pod 分配一个 IP:
```
$ kubectl get pods --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
```
默认,hosts 文件只包含 ipv4 和 ipv6 的样板内容,像 `localhost` 和主机名称。
## 通过 HostAliases 增加额外的条目
除了默认的样板内容,我们可以向 hosts 文件添加额外的条目,将 `foo.local``bar.local` 解析为`127.0.0.1`,将 `foo.remote``bar.remote` 解析为 `10.1.2.3`,我们可以在 `.spec.hostAliases` 下为 Pod 添加 HostAliases。
{{< code file="hostaliases-pod.yaml" >}}
hosts 文件的内容看起来类似如下这样:
```
$ kubectl logs hostaliases-pod
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.200.0.4 hostaliases-pod
127.0.0.1 foo.local
127.0.0.1 bar.local
10.1.2.3 foo.remote
10.1.2.3 bar.remote
```
在最下面额外添加了一些条目。
## 限制
在 1.7 版本,如果 Pod 启用 hostNetwork,那么将不能使用这个特性,因为 kubelet 只管理非 hostNetwork 类型 Pod 的 hosts 文件。目前正在讨论要改变这个情况。
## 为什么 Kubelet 管理 hosts文件?
kubelet [管理](https://github.com/kubernetes/kubernetes/issues/14633) Pod 中每个容器的 hosts 文件,避免 Docker 在容器已经启动之后去 [修改](https://github.com/moby/moby/issues/17190) 该文件。
因为该文件是托管性质的文件,无论容器重启或 Pod 重新调度,用户修改该 hosts 文件的任何内容,都会在 Kubelet 重新安装后被覆盖。因此,不建议修改该文件的内容。
@@ -0,0 +1,371 @@
---
approvers:
- caesarxuchao
- lavalamp
- thockin
title: 应用连接到 Service
---
{{< toc >}}
## Kubernetes 连接容器模型
既然有了一个持续运行、可复制的应用,我们就能够将它暴露到网络上。
在讨论 Kubernetes 网络连接的方式之前,非常值得与 Docker 中 “正常” 方式的网络进行对比。
默认情况下,Docker 使用私有主机网络连接,只能与同在一台机器上的容器进行通信。
为了实现容器的跨节点通信,必须在机器自己的 IP 上为这些容器分配端口,为容器进行端口转发或者代理。
多个开发人员之间协调端口的使用很难做到规模化,那些难以控制的集群级别的问题,都会交由用户自己去处理。
Kubernetes 假设 Pod 可与其它 Pod 通信,不管它们在哪个主机上。
我们给 Pod 分配属于自己的集群私有 IP 地址,所以没必要在 Pod 或映射到的容器的端口和主机端口之间显式地创建连接。
这表明了在 Pod 内的容器都能够连接到本地的每个端口,集群中的所有 Pod 不需要通过 NAT 转换就能够互相看到。
文档的剩余部分将详述如何在一个网络模型之上运行可靠的服务。
该指南使用一个简单的 Nginx server 来演示并证明谈到的概念。同样的原则也体现在一个更加完整的 [Jenkins CI 应用](http://blog.kubernetes.io/2015/07/strong-simple-ssl-for-kubernetes.html) 中。
## 在集群中暴露 Pod
我们在之前的示例中已经做过,然而再让我重试一次,这次聚焦在网络连接的视角。
创建一个 Nginx Pod,指示它具有一个容器端口的说明:
{{< code file="run-my-nginx.yaml" >}}
这使得可以从集群中任何一个节点来访问它。检查节点,该 Pod 正在运行:
```shell
$ kubectl create -f ./run-my-nginx.yaml
$ kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd
```
检查 Pod 的 IP 地址:
```shell
$ kubectl get pods -l run=my-nginx -o yaml | grep podIP
podIP: 10.244.3.4
podIP: 10.244.2.5
```
应该能够通过 ssh 登录到集群中的任何一个节点上,使用 curl 也能调通所有 IP 地址。
需要注意的是,容器不会使用该节点上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。
这意味着可以在同一个节点上运行多个 Pod,使用相同的容器端口,并且可以从集群中任何其他的 Pod 或节点上使用 IP 的方式访问到它们。
像 Docker 一样,端口能够被发布到主机节点的接口上,但是出于网络模型的原因应该从根本上减少这种用法。
如果对此好奇,可以获取更多关于 [如何实现网络模型](/docs/concepts/cluster-administration/networking/#how-to-achieve-this) 的内容。
## 创建 Service
我们有 Pod 在一个扁平的、集群范围的地址空间中运行 Nginx 服务,可以直接连接到这些 Pod,但如果某个节点死掉了会发生什么呢?
Pod 会终止,Deployment 将创建新的 Pod,且使用不同的 IP。这正是 Service 要解决的问题。
Kubernetes Service 从逻辑上定义了运行在集群中的一组 Pod,这些 Pod 提供了相同的功能。
当每个 Service 创建时,会被分配一个唯一的 IP 地址(也称为 clusterIP)。
这个 IP 地址与一个 Service 的生命周期绑定在一起,当 Service 存在的时候它也不会改变。
可以配置 Pod 使它与 Service 进行通信,Pod 知道与 Service 通信将被自动地负载均衡到该 Service 中的某些 Pod 上。
可以使用 `kubectl expose` 命令为 2个 Nginx 副本创建一个 Service
```shell
$ kubectl expose deployment/my-nginx
service "my-nginx" exposed
```
这等价于使用 `kubectl create -f` 命令创建,对应如下的 yaml 文件:
{{< code file="nginx-svc.yaml" >}}
上述规约将创建一个 Service,对应具有标签 `run: my-nginx` 的 Pod,目标 TCP 端口 80,并且在一个抽象的 Service 端口(`targetPort`:容器接收流量的端口;`port`:抽象的 Service 端口,可以使任何其它 Pod 访问该 Service 的端口)上暴露。
查看 [Service API 对象](/docs/api-reference/{{< param "version" >}}/#service-v1-core) 了解 Service 定义支持的字段列表。
```shell
$ kubectl get svc my-nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx 10.0.162.149 <none> 80/TCP 21s
```
正如前面所提到的,一个 Service 由一组 backend Pod 组成。这些 Pod 通过 `endpoints` 暴露出来。
Service Selector 将持续评估,结果被 POST 到一个名称为 `my-nginx` 的 Endpoint 对象上。
当 Pod 终止后,它会自动从 Endpoint 中移除,新的能够匹配上 Service Selector 的 Pod 将自动地被添加到 Endpoint 中。
检查该 Endpoint,注意到 IP 地址与在第一步创建的 Pod 是相同的。
```shell
$ kubectl describe svc my-nginx
Name: my-nginx
Namespace: default
Labels: run=my-nginx
Selector: run=my-nginx
Type: ClusterIP
IP: 10.0.162.149
Port: <unset> 80/TCP
Endpoints: 10.244.2.5:80,10.244.3.4:80
Session Affinity: None
No events.
$ kubectl get ep my-nginx
NAME ENDPOINTS AGE
my-nginx 10.244.2.5:80,10.244.3.4:80 1m
```
现在,能够从集群中任意节点上使用 curl 命令请求 Nginx Service `<CLUSTER-IP>:<PORT>`
注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇,可以阅读更多关于 [服务代理](/docs/user-guide/services/#virtual-ips-and-service-proxies) 的内容。
## 访问 Service
Kubernetes 支持两种主要的服务发现模式 —— 环境变量和 DNS。前者在单个节点上可用使用,然而后者必须使用 [kube-dns 集群插件](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md)。
### 环境变量
当 Pod 在 Node 上运行时,kubelet 会为每个活跃的 Service 添加一组环境变量。这会有一个顺序的问题。想了解为何,检查正在运行的 Nginx Pod 的环境变量(Pod 名称将不会相同):
```shell
$ kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
```
注意,还没有谈及到 Service。这是因为创建副本先于 Service。
这样做的另一个缺点是,调度器可能在同一个机器上放置所有 Pod,如果该机器宕机则所有的 Service 都会挂掉。
正确的做法是,我们杀掉 2 个 Pod,等待 Deployment 去创建它们。
这次 Service 会 *先于* 副本存在。这将实现调度器级别的 Service,能够使 Pod 分散创建(假定所有的 Node 都具有同样的容量),以及正确的环境变量:
```shell
$ kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
$ kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd
my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m
```
可能注意到,Pod 具有不同的名称,因为它们被杀掉后并被重新创建。
```shell
$ kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.0.162.149
KUBERNETES_SERVICE_HOST=10.0.0.1
MY_NGINX_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
```
### DNS
Kubernetes 提供了一个 DNS 插件 Service,它使用 skydns 自动为其它 Service 指派 DNS 名字。
如果它在集群中处于运行状态,可以通过如下命令来检查:
```shell
$ kubectl get services kube-dns --namespace=kube-system
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 8m
```
如果没有在运行,可以 [启用它](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md#how-do-i-configure-it)。
本段剩余的内容,将假设已经有一个 Service,它具有一个长久存在的 IP(my-nginx),一个为该 IP 指派名称的 DNS 服务器(kube-dns 集群插件),所以可以通过标准做法,使在集群中的任何 Pod 都能与该 Service 通信(例如:gethostbyname)。
让我们运行另一个 curl 应用来进行测试:
```shell
$ kubectl run curl --image=radial/busyboxplus:curl -i --tty
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
Hit enter for command prompt
```
然后,按回车并执行命令 `nslookup my-nginx`
```shell
[ root@curl-131556218-9fnch:/ ]$ nslookup my-nginx
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: my-nginx
Address 1: 10.0.162.149
```
## Service 安全
到现在为止,我们只在集群内部访问了 Nginx server。在将 Service 暴露到 Internet 之前,我们希望确保通信信道是安全的。对于这可能需要:
* https 自签名证书(除非已经有了一个识别身份的证书)
* 使用证书配置的 Nginx server
* 使证书可以访问 Pod 的[秘钥](/docs/user-guide/secrets)
可以从 [Nginx https 示例](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/examples/https-nginx/) 获取所有上述内容,简明示例如下:
```shell
$ make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json
$ kubectl create -f /tmp/secret.json
secret "nginxsecret" created
$ kubectl get secrets
NAME TYPE DATA AGE
default-token-il9rc kubernetes.io/service-account-token 1 1d
nginxsecret Opaque 2 1m
```
现在修改 Nginx 副本,启动一个使用在秘钥中的证书的 https 服务器和 Servcie,都暴露端口(80 和 443):
{{< code file="nginx-secure-app.yaml" >}}
关于 nginx-secure-app manifest 值得注意的点如下:
- 它在相同的文件中包含了 Deployment 和 Service 的规格
- [Nginx server](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/examples/https-nginx/default.conf) 处理 80 端口上的 http 流量,以及 443 端口上的 https 流量,Nginx Service 暴露了这两个端口。
- 每个容器访问挂载在 /etc/nginx/ssl 卷上的秘钥。这需要在 Nginx server 启动之前安装好。
```shell
$ kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
```
这时可以从任何节点访问到 Nginx server。
```shell
$ kubectl get pods -o yaml | grep -i podip
podIP: 10.244.3.5
node $ curl -k https://10.244.3.5
...
<h1>Welcome to nginx!</h1>
```
注意最后一步我们是如何提供 `-k` 参数执行 curl命令的,这是因为在证书生成时,我们不知道任何关于运行 Nginx 的 Pod 的信息,所以不得不在执行 curl 命令时忽略 CName 不匹配的情况。
通过创建 Service,我们连接了在证书中的 CName 与在 Service 查询时被 Pod使用的实际 DNS 名字。
让我们从一个 Pod 来测试(为了简化使用同一个秘钥,Pod 仅需要使用 nginx.crt 去访问 Service):
{{< code file="curlpod.yaml" >}}
```shell
$ kubectl create -f ./curlpod.yaml
$ kubectl get pods -l app=curlpod
NAME READY STATUS RESTARTS AGE
curl-deployment-1515033274-1410r 1/1 Running 0 1m
$ kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt
...
<title>Welcome to nginx!</title>
...
```
## 暴露 Service
对我们应用的某些部分,可能希望将 Service 暴露在一个外部 IP 地址上。
Kubernetes 支持两种实现方式:NodePort 和 LoadBalancer。
在上一段创建的 Service 使用了 `NodePort`,因此 Nginx https 副本已经就绪,如果使用一个公网 IP,能够处理 Internet 上的流量。
```shell
$ kubectl get svc my-nginx -o yaml | grep nodePort -C 5
uid: 07191fb3-f61a-11e5-8ae5-42010af00002
spec:
clusterIP: 10.0.162.149
ports:
- name: http
nodePort: 31704
port: 8080
protocol: TCP
targetPort: 80
- name: https
nodePort: 32453
port: 443
protocol: TCP
targetPort: 443
selector:
run: my-nginx
$ kubectl get nodes -o yaml | grep ExternalIP -C 1
- address: 104.197.41.11
type: ExternalIP
allocatable:
--
- address: 23.251.152.56
type: ExternalIP
allocatable:
...
$ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
...
<h1>Welcome to nginx!</h1>
```
让我们重新创建一个 Service,使用一个云负载均衡器,只需要将 `my-nginx` Service 的 `Type``NodePort` 改成 `LoadBalancer`
```shell
$ kubectl edit svc my-nginx
$ kubectl get svc my-nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx 10.0.162.149 162.222.184.144 80/TCP,81/TCP,82/TCP 21s
$ curl https://<EXTERNAL-IP> -k
...
<title>Welcome to nginx!</title>
```
`EXTERNAL-IP` 列指定的 IP 地址是在公网上可用的。`CLUSTER-IP` 只在集群/私有云网络中可用。
注意,在 AWS 上类型 `LoadBalancer` 创建一个 ELB,它使用主机名(比较长),而不是 IP。
它太长以至于不能适配标准 `kubectl get svc` 的输出,事实上需要通过执行 `kubectl describe service my-nginx` 命令来查看它。
可以看到类似如下内容:
```shell
$ kubectl describe service my-nginx
...
LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com
...
```
## 进一步阅读
Kubernetes 也支持联合 Service,能够跨多个集群和云提供商,为 Service 提供逐步增强的可用性、更优的容错、更好的可伸缩性。
查看 [联合 Service 用户指南](/docs/concepts/cluster-administration/federation-service-discovery/) 获取更进一步信息。
@@ -0,0 +1,25 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: curl-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: curlpod
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
containers:
- name: curlpod
command:
- sh
- -c
- while true; do sleep 1; done
image: radial/busyboxplus:curl
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
@@ -0,0 +1,419 @@
---
approvers:
- davidopp
- thockin
title: DNS Pod 与 Service
redirect_from:
- "/docs/admin/dns/"
- "/docs/admin/dns.html"
---
## 介绍
Kubernetes 从 1.3 版本起, DNS 是内置的服务,通过插件管理器 [集群插件](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/README.md) 自动被启动。
Kubernetes DNS 在集群中调度 DNS Pod 和 Service ,配置 kubelet 以通知个别容器使用 DNS Service 的 IP 解析 DNS 名字。
## 怎样获取 DNS 名字?
在集群中定义的每个 Service(包括 DNS 服务器自身)都会被指派一个 DNS 名称。
默认,一个客户端 Pod 的 DNS 搜索列表将包含该 Pod 自己的 Namespace 和集群默认域。
通过如下示例可以很好地说明:
假设在 Kubernetes 集群的 Namespace `bar` 中,定义了一个Service `foo`
运行在Namespace `bar` 中的一个 Pod,可以简单地通过 DNS 查询 `foo` 来找到该 Service。
运行在 Namespace `quux` 中的一个 Pod 可以通过 DNS 查询 `foo.bar` 找到该 Service。
## 支持的 DNS 模式
下面各段详细说明支持的记录类型和布局。
如果任何其它的布局、名称或查询,碰巧也能够使用,这就需要研究下它们的实现细节,以免后续修改它们又不能使用了。
### Service
#### A 记录
“正常” Service(除了 Headless Service)会以 `my-svc.my-namespace.svc.cluster.local` 这种名字的形式被指派一个 DNS A 记录。这会解析成该 Service 的 Cluster IP。
“Headless” Service(没有Cluster IP)也会以 `my-svc.my-namespace.svc.cluster.local` 这种名字的形式被指派一个 DNS A 记录。
不像正常 Service,它会解析成该 Service 选择的一组 Pod 的 IP。
希望客户端能够使用这一组 IP,否则就使用标准的 round-robin 策略从这一组 IP 中进行选择。
#### SRV 记录
命名端口需要创建 SRV 记录,这些端口是正常 Service或 [Headless
Services](/docs/concepts/services-networking/service/#headless-services) 的一部分。
对每个命名端口,SRV 记录具有 `_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local` 这种形式。
对普通 Service,这会被解析成端口号和 CNAME:`my-svc.my-namespace.svc.cluster.local`
对 Headless Service,这会被解析成多个结果,Service 对应的每个 backend Pod 各一个,包含 `auto-generated-name.my-svc.my-namespace.svc.cluster.local` 这种形式 Pod 的端口号和 CNAME。
#### 后向兼容性
上一版本的 kube-dns 使用 `my-svc.my-namespace.cluster.local` 这种形式的名字(后续会增加 'svc' 这一级),以后这将不再被支持。
### Pod
#### A 记录
如果启用,Pod 会以 `pod-ip-address.my-namespace.pod.cluster.local` 这种形式被指派一个 DNS A 记录。
例如,`default` Namespace 具有 DNS 名字 `cluster.local`,在该 Namespace 中一个 IP 为 `1.2.3.4` 的 Pod 将具有一个条目:`1-2-3-4.default.pod.cluster.local`
#### 基于 Pod hostname、subdomain 字段的 A 记录和主机名
当前,创建 Pod 后,它的主机名是该 Pod 的 `metadata.name` 值。
在 v1.2 版本中,用户可以配置 Pod annotation 通过 `pod.beta.kubernetes.io/hostname` 来设置 Pod 的主机名。
如果为 Pod 配置了 annotation,会优先使用 Pod 的名称作为主机名。
例如,给定一个 Pod,它具有 annotation `pod.beta.kubernetes.io/hostname: my-pod-name`,该 Pod 的主机名被设置为 “my-pod-name”。
在 v1.3 版本中,PodSpec 具有 `hostname` 字段,可以用来指定 Pod 的主机名。这个字段的值优先于 annotation `pod.beta.kubernetes.io/hostname`
在 v1.2 版本中引入了 beta 特性,用户可以为 Pod 指定 annotation,其中 `pod.beta.kubernetes.io/subdomain` 指定了 Pod 的子域名。
最终的域名将是 “<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>”。
举个例子,Pod 的主机名 annotation 设置为 “foo”,子域名 annotation 设置为 “bar”,在 Namespace “my-namespace” 中对应的 FQDN 为 “foo.bar.my-namespace.svc.cluster.local”。
在 v1.3 版本中,PodSpec 具有 `subdomain` 字段,可以用来指定 Pod 的子域名。
这个字段的值优先于 annotation `pod.beta.kubernetes.io/subdomain` 的值。
```yaml
apiVersion: v1
kind: Service
metadata:
name: default-subdomain
spec:
selector:
name: busybox
clusterIP: None
ports:
- name: foo # Actually, no port is needed.
port: 1234
targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: default-subdomain
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox
---
apiVersion: v1
kind: Pod
metadata:
name: busybox2
labels:
name: busybox
spec:
hostname: busybox-2
subdomain: default-subdomain
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox
```
如果 Headless Service 与 Pod 在同一个 Namespace 中,它们具有相同的子域名,集群的 KubeDNS 服务器也会为该 Pod 的完整合法主机名返回 A 记录。
在同一个 Namespace 中,给定一个主机名为 “busybox-1” 的 Pod,子域名设置为 “default-subdomain”,名称为 “default-subdomain” 的 Headless Service Pod 将看到自己的 FQDN 为 “busybox-1.default-subdomain.my-namespace.svc.cluster.local”。
DNS 会为那个名字提供一个 A 记录,指向该 Pod 的 IP。
“busybox1” 和 “busybox2” 这两个 Pod 分别具有它们自己的 A 记录。
在Kubernetes v1.2 版本中,`Endpoints` 对象也具有 annotation `endpoints.beta.kubernetes.io/hostnames-map`
它的值是 map[string(IP)][endpoints.HostRecord] 的 JSON 格式,例如: '{"10.245.1.6":{HostName: "my-webserver"}}'。
如果是 Headless Service 的 `Endpoints`,会以 <hostname>.<service name>.<pod namespace>.svc.<cluster domain> 的格式创建 A 记录。
对示例中的 JSON 字符串,如果 `Endpoints` 是为名称为 “bar” 的 Headless Service 而创建的,其中一个 `Endpoints` 的 IP 是 “10.245.1.6”,则会创建一个名称为 “my-webserver.bar.my-namespace.svc.cluster.local” 的 A 记录,该 A 记录查询将返回 “10.245.1.6”。
`Endpoints` annotation 通常没必要由最终用户指定,但可以被内部的 Service Controller 用来提供上述功能。
在 v1.3 版本中,`Endpoints` 对象可以为任何 endpoint 指定 `hostname` 和 IP。
`hostname` 字段优先于通过 `endpoints.beta.kubernetes.io/hostnames-map` annotation 指定的主机名。
在 v1.3 版本中,下面的 annotation 是过时的:`pod.beta.kubernetes.io/hostname``pod.beta.kubernetes.io/subdomain``endpoints.beta.kubernetes.io/hostnames-map`
## 如何测试它是否可以使用?
### 创建一个简单的 Pod 作为测试环境
创建 `busybox.yaml` 文件,内容如下:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
```
然后,用该文件创建一个 Pod
```
kubectl create -f busybox.yaml
```
### 等待这个 Pod 变成运行状态
获取它的状态,执行如下命令:
```
kubectl get pods busybox
```
可以看到如下内容:
```
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 <some-time>
```
### 验证 DNS 已经生效
一旦 Pod 处于运行中状态,可以在测试环境中执行如下 nslookup 查询:
```
kubectl exec -ti busybox -- nslookup kubernetes.default
```
可以看到类似如下的内容:
```
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: kubernetes.default
Address 1: 10.0.0.1
```
如果看到了,说明 DNS 已经可以正确工作了。
### 问题排查技巧
如果执行 nslookup 命令失败,检查如下内容:
#### 先检查本地 DNS 配置
查看配置文件 resolv.conf。(关于更多信息,参考下面的 “从 Node 继承 DNS” 和 “已知问题”。)
```
kubectl exec busybox cat /etc/resolv.conf
```
按照如下方法(注意搜索路径可能会因为云提供商不同而变化)验证搜索路径和 Name Server 的建立:
```
search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5
```
#### 快速诊断
出现类似如下指示的错误,说明 kube-dns 插件或相关 Service 存在问题:
```
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10
nslookup: can't resolve 'kubernetes.default'
```
或者
```
$ kubectl exec -ti busybox -- nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
nslookup: can't resolve 'kubernetes.default'
```
#### 检查是否 DNS Pod 正在运行
使用 `kubectl get pods` 命令验证 DNS Pod 正在运行:
```
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
```
应该能够看到类似如下信息:
```
NAME READY STATUS RESTARTS AGE
...
kube-dns-v19-ezo1y 3/3 Running 0 1h
...
```
如果看到没有 Pod 运行,或 Pod 失败/结束,DNS 插件不能默认部署到当前的环境,必须手动部署。
#### 检查 DNS Pod 中的错误信息
使用 `kubectl logs` 命令查看 DNS 后台进程的日志:
```
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz
```
查看是否有任何可疑的日志。在行开头的字母 W、E、F 分别表示 警告、错误、失败。请搜索具有这些日志级别的日志行,通过 [Kubernetes 问题](https://github.com/kubernetes/kubernetes/issues) 报告意外的错误。
#### DNS 服务是否运行?
通过使用 `kubectl get service` 命令,验证 DNS 服务是否运行:
```
kubectl get svc --namespace=kube-system
```
应该能够看到:
```
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 1h
...
```
如果服务已经创建,或在这个例子中默认被创建,但是并没有看到,可以查看 [调试 Service 页面](/docs/tasks/debug-application-cluster/debug-service/) 获取更多信息。
```
kubectl get ep kube-dns --namespace=kube-system
```
应该能够看到类似如下信息:
```
NAME ENDPOINTS AGE
kube-dns 10.180.3.17:53,10.180.3.17:53 1h
```
如果没有看到 Endpoint,查看 [调试 Service 文档](/docs/tasks/debug-application-cluster/debug-service/) 中的 Endpoint 段内容。
关于更多 Kubernetes DNS 的示例,参考 Kubernetes GitHub 仓库中 [集群 DNS 示例](https://git.k8s.io/kubernetes/examples/cluster-dns)。
## Kubernetes Federation(多 Zone 支持)
在1.3 发行版本中,为多站点 Kubernetes 安装引入了集群 Federation 支持。这需要对 Kubernetes 集群 DNS 服务器处理 DNS 查询的方式,做出一些微小(后向兼容)改变,从而便利了对联合 Service 的查询(跨多个 Kubernetes 集群)。参考 [集群 Federation 管理员指南](/docs/concepts/cluster-administration/federation/) 获取更多关于集群 Federation 和多站点支持的细节。
## 工作原理
运行的 Kubernetes DNS Pod 包含 3 个容器 —— kubedns、dnsmasq 和负责健康检查的 healthz。
kubedns 进程监视 Kubernetes master 对 Service 和 Endpoint 操作的变更,并维护一个内存查询结构去处理 DNS 请求。dnsmasq 容器增加了一个 DNS 缓存来改善性能。为执行对 dnsmasq 和 kubedns 的健康检查,healthz 容器提供了一个单独的健康检查 Endpoint。
DNS Pod 通过一个静态 IP 暴露为一个 Service。一旦 IP 被分配,kubelet 会通过 `--cluster-dns=10.0.0.10` 标志将配置的 DNS 传递给每一个容器。
DNS 名字也需要域名,本地域名是可配置的,在 kubelet 中使用 `--cluster-domain=<default local domain>` 标志。
Kubernetes 集群 DNS 服务器(根据 [SkyDNS](https://github.com/skynetservices/skydns) 库)支持正向查询(A 记录),Service 查询(SRV 记录)和反向 IP 地址查询(PTR 记录)。
## 从 Node 继承 DNS
当运行 Pod 时,kubelet 将集群 DNS 服务器和搜索路径追加到 Node 自己的 DNS 设置中。如果 Node 能够在大型环境中解析 DNS 名字,Pod 也应该没问题。参考下面 "已知问题” 中给出的更多说明。
如果不想这样,或者希望 Pod 有一个不同的 DNS 配置,可以使用 kubelet 的 `--resolv-conf` 标志。设置为 "" 表示 Pod 将不继承自 DNS。设置为一个合法的文件路径,表示 kubelet 将使用这个文件而不是 `/etc/resolv.conf`
## 已知问题
Kubernetes 安装但并不配置 Node 的 resolv.conf 文件,而是默认使用集群 DNS的,因为那个过程本质上就是和特定的发行版本相关的。最终应该会被实现。
Linux libc 在限制为3个 DNS `nameserver` 记录和3个 DNS `search` 记录是不可能卡住的([查看 2005 年的一个 Bug](https://bugzilla.redhat.com/show_bug.cgi?id=168253))。Kubernetes 需要使用1个 `nameserver` 记录和3个 `search` 记录。这意味着如果本地安装已经使用了3个 `nameserver` 或使用了3个以上 `search`,那些设置将会丢失。作为部分解决方法, Node 可以运行 `dnsmasq` ,它能提供更多 `nameserver` 条目,但不能运行更多 `search` 条目。可以使用 kubelet 的 `--resolv-conf` 标志。
如果使用 3.3 版本的 Alpine 或更早版本作为 base 镜像,由于 Alpine 的一个已知问题,DNS 可能不会正确工作。查看 [这里](https://github.com/kubernetes/kubernetes/issues/30215) 获取更多信息。
## 参考
- [DNS 集群插件文档](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/README.md)
## 下一步
- [集群中 DNS Service 自动伸缩](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)

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