From 1d3b7c42289f6b0af041c69a037fe45bf2affc18 Mon Sep 17 00:00:00 2001 From: Krishna m-Kumar Date: Wed, 6 Sep 2017 07:27:36 +0530 Subject: [PATCH 001/102] updated Readme with several links missing 5 missing links updated Added Review Issues Tab and Link from the same folder's file. --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 264822b1df..280a4ceb40 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,12 @@ You can click the **Fork** button in the upper-right area of the screen to creat For more information about contributing to the Kubernetes documentation, see: * [Contributing to the Kubernetes Documentation](http://kubernetes.io/editdocs/) -* [Creating a Documentation Pull Request](http://kubernetes.io/docs/contribute/create-pull-request/) -* [Writing a New Topic](http://kubernetes.io/docs/contribute/write-new-topic/) -* [Staging Your Documentation Changes](http://kubernetes.io/docs/contribute/stage-documentation-changes/) -* [Using Page Templates](http://kubernetes.io/docs/contribute/page-templates/) -* [Documentation Style Guide](http://kubernetes.io/docs/contribute/style-guide/) +* [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/) ## Thank you! From 11161b63515dc20f310044f347e171684f9ce56e Mon Sep 17 00:00:00 2001 From: Ryan McGinnis Date: Thu, 7 Sep 2017 17:09:24 -0700 Subject: [PATCH 002/102] Edits deployment.md - Fixes an inaccuracy: `template: metadata: labels:` labels the Pod template rather than the containers - Elaborates some more on the explanation of the manifest --- docs/concepts/workloads/controllers/deployment.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/concepts/workloads/controllers/deployment.md b/docs/concepts/workloads/controllers/deployment.md index 0312a6390f..70dfe589fe 100644 --- a/docs/concepts/workloads/controllers/deployment.md +++ b/docs/concepts/workloads/controllers/deployment.md @@ -41,15 +41,18 @@ The following is an example of a Deployment. It creates a ReplicaSet to bring up In this example: -* A Deployment named `nginx` is created. -* The `nginx` Deployment creates three replicated Pods. -* The Pods are created from the `template` field. +* A Deployment named `nginx` is created, indicated by the `metadata: name` field. +* The Deployment creates three replicated Pods, indicated by the `replicas` field. +* The Pod template's specification, or `template: spec` field, indicates that + the Pods run one container, `nginx`, which runs the `nginx` + [Docker Hub](https://hub.docker.com/) image at version 1.7.9. +* The Deployment opens port 80 for use by the Pods. The `template` field contains the following instructions: -* Create one container in each Pod. -* Label the container `app: nginx`. -* Run the [Docker Hub](https://hub.docker.com) image `nginx` at version `1.7.9`. +* The Pod template is labelled `app: nginx` +* Create one container and name it `nginx`. +* Run the `nginx` image at version `1.7.9`. * Open port `80` so that the container can send and accept traffic. To create this Deployment, run the following command: From 02155b7b964932e082dce26291b6815001ca4157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iago=20L=C3=B3pez=20Galeiras?= Date: Fri, 8 Sep 2017 13:14:21 +0200 Subject: [PATCH 003/102] Add quotes to JSONPATH bash variable The command was failing with error: error parsing jsonpath {range, unclosed action We need to quote `$JSONPATH` so the full contents of the variable are passed to `-o jsonpath=`. Fixes #4258 --- docs/user-guide/kubectl-cheatsheet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/kubectl-cheatsheet.md b/docs/user-guide/kubectl-cheatsheet.md index ddba577c75..db16eed44b 100644 --- a/docs/user-guide/kubectl-cheatsheet.md +++ b/docs/user-guide/kubectl-cheatsheet.md @@ -128,7 +128,7 @@ $ echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.na # Check which nodes are ready $ JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \ - && kubectl get nodes -o jsonpath=$JSONPATH | grep "Ready=True" + && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True" # List all Secrets currently in use by a pod $ kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq From 0347e50b82b0628b100fd5ce90a4a08fbe8eb29d Mon Sep 17 00:00:00 2001 From: Ryan McGinnis Date: Fri, 8 Sep 2017 07:32:40 -0700 Subject: [PATCH 004/102] Update deployment.md --- docs/concepts/workloads/controllers/deployment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/workloads/controllers/deployment.md b/docs/concepts/workloads/controllers/deployment.md index 70dfe589fe..3b011d9585 100644 --- a/docs/concepts/workloads/controllers/deployment.md +++ b/docs/concepts/workloads/controllers/deployment.md @@ -50,7 +50,7 @@ In this example: The `template` field contains the following instructions: -* The Pod template is labelled `app: nginx` +* The Pods are labeled `app: nginx` * Create one container and name it `nginx`. * Run the `nginx` image at version `1.7.9`. * Open port `80` so that the container can send and accept traffic. From 93133cca2f6c34bb91304e234af113fea53d0f32 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Sat, 9 Sep 2017 00:04:16 +0800 Subject: [PATCH 005/102] duplicate not (#5347) --- docs/tasks/run-application/scale-stateful-set.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/run-application/scale-stateful-set.md b/docs/tasks/run-application/scale-stateful-set.md index ca73a3997e..0ee87d9b20 100644 --- a/docs/tasks/run-application/scale-stateful-set.md +++ b/docs/tasks/run-application/scale-stateful-set.md @@ -70,7 +70,7 @@ kubectl patch statefulsets -p '{"spec":{"replicas": Date: Sat, 9 Sep 2017 00:09:48 +0800 Subject: [PATCH 006/102] Update kube-proxy.md (#5344) there lost a blank character. --- docs/admin/kube-proxy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/admin/kube-proxy.md b/docs/admin/kube-proxy.md index 167b9f3d6c..6e6551af65 100644 --- a/docs/admin/kube-proxy.md +++ b/docs/admin/kube-proxy.md @@ -11,7 +11,7 @@ notitle: true The Kubernetes network proxy runs on each node. This reflects services as defined in the Kubernetes API on each node and can do simple -TCP,UDP stream forwarding or round robin TCP,UDP forwarding across a set of backends. +TCP, UDP stream forwarding or round robin TCP, UDP forwarding across a set of backends. Service cluster IPs and ports are currently found through Docker-links-compatible environment variables specifying ports opened by the service proxy. There is an optional addon that provides cluster DNS for these cluster IPs. The user must create a service From 108a4051fe66415d28ea8153f515457c3b87395b Mon Sep 17 00:00:00 2001 From: Ahmet Kizilay Date: Fri, 8 Sep 2017 12:10:24 -0400 Subject: [PATCH 007/102] updated kops download link to latest version (#5345) * 1.6.1 -> 1.7.0 --- docs/getting-started-guides/kops.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/kops.md b/docs/getting-started-guides/kops.md index a8720aa46e..e4a030584e 100644 --- a/docs/getting-started-guides/kops.md +++ b/docs/getting-started-guides/kops.md @@ -34,7 +34,7 @@ Download kops from the [releases page](https://github.com/kubernetes/kops/releas On MacOS: ``` -wget https://github.com/kubernetes/kops/releases/download/1.6.1/kops-darwin-amd64 +wget https://github.com/kubernetes/kops/releases/download/1.7.0/kops-darwin-amd64 chmod +x kops-darwin-amd64 mv kops-darwin-amd64 /usr/local/bin/kops # you can also install using Homebrew @@ -44,7 +44,7 @@ brew update && brew install kops On Linux: ``` -wget https://github.com/kubernetes/kops/releases/download/1.6.1/kops-linux-amd64 +wget https://github.com/kubernetes/kops/releases/download/1.7.0/kops-linux-amd64 chmod +x kops-linux-amd64 mv kops-linux-amd64 /usr/local/bin/kops ``` From c3209bb6803229e295801946c94d5c56dd03867e Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Fri, 8 Sep 2017 17:25:33 +0800 Subject: [PATCH 008/102] fix the command output fix the command output --- docs/tasks/administer-cluster/static-pod.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/administer-cluster/static-pod.md b/docs/tasks/administer-cluster/static-pod.md index 1c21a6f178..f2f439470a 100644 --- a/docs/tasks/administer-cluster/static-pod.md +++ b/docs/tasks/administer-cluster/static-pod.md @@ -92,7 +92,7 @@ Notice we cannot delete the pod with the API server (e.g. via [`kubectl`](/docs/ ```shell [joe@my-master ~] $ kubectl delete pod static-web-my-node1 -pods/static-web-my-node1 +pod "static-web-my-node1" deleted [joe@my-master ~] $ kubectl get pods NAME READY STATUS RESTARTS AGE static-web-my-node1 1/1 Running 0 12s From e0cb103488e1cc3c097e731c5c3c36c9abd1073c Mon Sep 17 00:00:00 2001 From: John Belamaric Date: Fri, 8 Sep 2017 16:17:08 -0400 Subject: [PATCH 009/102] Add coredns to add-on list (#5358) * Add CoreDNS addon * Update text --- docs/concepts/cluster-administration/addons.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/concepts/cluster-administration/addons.md b/docs/concepts/cluster-administration/addons.md index 53b94997dc..eb62a0795e 100644 --- a/docs/concepts/cluster-administration/addons.md +++ b/docs/concepts/cluster-administration/addons.md @@ -21,6 +21,10 @@ Add-ons in each section are sorted alphabetically - the ordering does not imply * [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) provides networking and network policy, will carry on working on both sides of a network partition, and does not require an external database. * [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) enables Kubernetes to seamlessly connect to a choice of CNI plugins, such as Flannel, Calico, Canal, Romana, or Weave. +## Service Discovery + +* [CoreDNS](https://coredns.io) is a flexible, extensible DNS server which can be [installed](https://github.com/coredns/deployment/tree/master/kubernetes) as the in-cluster DNS for pods. + ## Visualization & Control * [Dashboard](https://github.com/kubernetes/dashboard#kubernetes-dashboard) is a dashboard web interface for Kubernetes. From ef24a54abd0ed3b4ef3b9795af3923579c12c157 Mon Sep 17 00:00:00 2001 From: Cliff Burdick <30670611+cliffburdick@users.noreply.github.com> Date: Fri, 8 Sep 2017 17:37:19 -0700 Subject: [PATCH 010/102] Update downward-api-volume-expose-pod-information.md (#5309) Keeping the capitalization uniform. --- .../downward-api-volume-expose-pod-information.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md b/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md index 9caad6cdff..e6962e2389 100644 --- a/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md +++ b/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information.md @@ -188,15 +188,15 @@ You can use similar commands to view the `cpu_request`, `mem_limit` and The following information is available to Containers through environment variables and DownwardAPIVolumeFiles: -* The node’s name -* The node's IP +* The Node’s name +* The Node's IP * The Pod’s name * The Pod’s namespace * The Pod’s IP address * The Pod’s service account name * The Pod’s UID * A Container’s CPU limit -* A container’s CPU request +* A Container’s CPU request * A Container’s memory limit * A Container’s memory request From 9981d7e6c9ee25370986d74371e8e552c4784833 Mon Sep 17 00:00:00 2001 From: Kyle Bai Date: Sat, 9 Sep 2017 08:44:41 +0800 Subject: [PATCH 011/102] Remove unknown flag for apiserver (#5312) --- docs/getting-started-guides/scratch.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/getting-started-guides/scratch.md b/docs/getting-started-guides/scratch.md index de475a07bb..eebdebb78b 100644 --- a/docs/getting-started-guides/scratch.md +++ b/docs/getting-started-guides/scratch.md @@ -68,20 +68,20 @@ another pod using the IP of the second pod. This connectivity can be accomplished in two ways: - **Using an overlay network** - - An overlay network obscures the underlying network architecture from the + - An overlay network obscures the underlying network architecture from the pod network through traffic encapsulation (e.g. vxlan). - Encapsulation reduces performance, though exactly how much depends on your solution. - **Without an overlay network** - Configure the underlying network fabric (switches, routers, etc.) to be aware of pod IP addresses. - - This does not require the encapsulation provided by an overlay, and so can achieve + - This does not require the encapsulation provided by an overlay, and so can achieve better performance. -Which method you choose depends on your environment and requirements. There are various ways -to implement one of the above options: +Which method you choose depends on your environment and requirements. There are various ways +to implement one of the above options: - **Use a network plugin which is called by Kubernetes** - Kubernetes supports the [CNI](https://github.com/containernetworking/cni) network plugin interface. - - There are a number of solutions which provide plugins for Kubernetes (listed alphabetically): + - There are a number of solutions which provide plugins for Kubernetes (listed alphabetically): - [Calico](http://docs.projectcalico.org/) - [Flannel](https://github.com/coreos/flannel) - [Open vSwitch (OVS)](http://openvswitch.org/) @@ -628,7 +628,6 @@ Here are some apiserver flags you may need to set: - `--cloud-provider=` see [cloud providers](#cloud-providers) - `--cloud-config=` see [cloud providers](#cloud-providers) - `--address=${MASTER_IP}` *or* `--bind-address=127.0.0.1` and `--address=127.0.0.1` if you want to run a proxy on the master node. -- `--cluster-name=$CLUSTER_NAME` - `--service-cluster-ip-range=$SERVICE_CLUSTER_IP_RANGE` - `--etcd-servers=http://127.0.0.1:4001` - `--tls-cert-file=/srv/kubernetes/server.cert` @@ -792,7 +791,6 @@ Template for controller manager pod: Flags to consider using with controller manager: - - `--cluster-name=$CLUSTER_NAME` - `--cluster-cidr=`, the CIDR range for pods in cluster. - `--allocate-node-cidrs=`, if you are using `--cloud-provider=`, allocate and set the CIDRs for pods on the cloud provider. - `--cloud-provider=` and `--cloud-config` as described in apiserver section. From bc0eae1b341a04a5945868f48fc18d1185c44029 Mon Sep 17 00:00:00 2001 From: Evgeny Shmarnev Date: Sat, 9 Sep 2017 02:45:40 +0200 Subject: [PATCH 012/102] Update persistent-volumes.md (#5314) Add necessary line breaks so vSphere yaml examples will be shown correctly. --- docs/concepts/storage/persistent-volumes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/concepts/storage/persistent-volumes.md b/docs/concepts/storage/persistent-volumes.md index f20004aff7..ef67f78e8b 100644 --- a/docs/concepts/storage/persistent-volumes.md +++ b/docs/concepts/storage/persistent-volumes.md @@ -574,6 +574,7 @@ parameters: #### vSphere 1. Create a persistent volume with a user specified disk format. + ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1 @@ -587,6 +588,7 @@ parameters: - `diskformat`: `thin`, `zeroedthick` and `eagerzeroedthick`. Default: `"thin"`. 2. Create a persistent volume with a disk format on a user specified datastore. + ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1beta1 @@ -602,6 +604,7 @@ parameters: - `datastore`: The user can also specify the datastore in the Storageclass. The volume will be created on the datastore specified in the storage class which in this case is `VSANDatastore`. This field is optional. If not specified as in previous YAML description, the volume will be created on the datastore specified in the vsphere config file used to initialize the vSphere Cloud Provider. 3. Create a persistent volume with user specified VSAN storage capabilities. + ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1beta1 From 728598298f4e7f3d728fa3bfda1f4eca5e77f72f Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Sat, 9 Sep 2017 08:46:32 +0800 Subject: [PATCH 013/102] fix the command output (#5315) fix the command output --- .../run-single-instance-stateful-application.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/tasks/run-application/run-single-instance-stateful-application.md b/docs/tasks/run-application/run-single-instance-stateful-application.md index ca0bb66775..6a1c305fa9 100644 --- a/docs/tasks/run-application/run-single-instance-stateful-application.md +++ b/docs/tasks/run-application/run-single-instance-stateful-application.md @@ -140,6 +140,8 @@ for a secure solution. Name: mysql-pv Labels: + Annotations: pv.kubernetes.io/bound-by-controller=yes + StorageClass: Status: Bound Claim: default/mysql-pv-claim Reclaim Policy: Retain @@ -152,7 +154,7 @@ for a secure solution. FSType: ext4 Partition: 0 ReadOnly: false - No events. + Events: 1. Inspect the PersistentVolumeClaim: @@ -160,12 +162,15 @@ for a secure solution. Name: mysql-pv-claim Namespace: default + StorageClass: Status: Bound Volume: mysql-pv Labels: + Annotations: pv.kubernetes.io/bind-completed=yes + pv.kubernetes.io/bound-by-controller=yes Capacity: 20Gi Access Modes: RWO - No events. + Events: ## Accessing the MySQL instance From 162e042d427ef4ee96f6d6fec11714a2c7333f0f Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Sat, 9 Sep 2017 08:47:46 +0800 Subject: [PATCH 014/102] fix the command output (#5316) fix the command output --- .../index.md | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/docs/tasks/job/coarse-parallel-processing-work-queue/index.md b/docs/tasks/job/coarse-parallel-processing-work-queue/index.md index 6ffd1fe1ae..e40bb2d238 100644 --- a/docs/tasks/job/coarse-parallel-processing-work-queue/index.md +++ b/docs/tasks/job/coarse-parallel-processing-work-queue/index.md @@ -225,24 +225,37 @@ Now wait a bit, then check on the job. $ kubectl describe jobs/job-wq-1 Name: job-wq-1 Namespace: default -Image(s): gcr.io/causal-jigsaw-637/job-wq-1 -Selector: app in (job-wq-1) +Selector: controller-uid=41d75705-92df-11e7-b85e-fa163ee3c11f +Labels: controller-uid=41d75705-92df-11e7-b85e-fa163ee3c11f + job-name=job-wq-1 +Annotations: Parallelism: 2 Completions: 8 -Labels: app=job-wq-1 +Start Time: Wed, 06 Sep 2017 16:42:02 +0800 Pods Statuses: 0 Running / 8 Succeeded / 0 Failed -No volumes. +Pod Template: + Labels: controller-uid=41d75705-92df-11e7-b85e-fa163ee3c11f + job-name=job-wq-1 + Containers: + c: + Image: gcr.io/causal-jigsaw-637/job-wq-1 + Port: + Environment: + BROKER_URL: amqp://guest:guest@rabbitmq-service:5672 + QUEUE: job1 + Mounts: + Volumes: Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - ───────── ──────── ───── ──── ───────────── ────── ─────── - 27s 27s 1 {job } SuccessfulCreate Created pod: job-wq-1-hcobb - 27s 27s 1 {job } SuccessfulCreate Created pod: job-wq-1-weytj - 27s 27s 1 {job } SuccessfulCreate Created pod: job-wq-1-qaam5 - 27s 27s 1 {job } SuccessfulCreate Created pod: job-wq-1-b67sr - 26s 26s 1 {job } SuccessfulCreate Created pod: job-wq-1-xe5hj - 15s 15s 1 {job } SuccessfulCreate Created pod: job-wq-1-w2zqe - 14s 14s 1 {job } SuccessfulCreate Created pod: job-wq-1-d6ppa - 14s 14s 1 {job } SuccessfulCreate Created pod: job-wq-1-p17e0 + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + ───────── ──────── ───── ──── ───────────── ────── ────── ─────── + 27s 27s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-hcobb + 27s 27s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-weytj + 27s 27s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-qaam5 + 27s 27s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-b67sr + 26s 26s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-xe5hj + 15s 15s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-w2zqe + 14s 14s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-d6ppa + 14s 14s 1 {job } Normal SuccessfulCreate Created pod: job-wq-1-p17e0 ``` All our pods succeeded. Yay. From 7a7718378a6db53be389b857f311cfd35f12dd92 Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Sat, 9 Sep 2017 08:48:15 +0800 Subject: [PATCH 015/102] fix the command output (#5317) fix the command output --- .../index.md | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/tasks/job/fine-parallel-processing-work-queue/index.md b/docs/tasks/job/fine-parallel-processing-work-queue/index.md index 887f5e6dd2..9d19895039 100644 --- a/docs/tasks/job/fine-parallel-processing-work-queue/index.md +++ b/docs/tasks/job/fine-parallel-processing-work-queue/index.md @@ -178,14 +178,24 @@ Now wait a bit, then check on the job. $ kubectl describe jobs/job-wq-2 Name: job-wq-2 Namespace: default -Image(s): gcr.io/exampleproject/job-wq-2 -Selector: app in (job-wq-2) +Selector: controller-uid=b1c7e4e3-92e1-11e7-b85e-fa163ee3c11f +Labels: controller-uid=b1c7e4e3-92e1-11e7-b85e-fa163ee3c11f + job-name=job-wq-2 +Annotations: Parallelism: 2 -Completions: Unset +Completions: Start Time: Mon, 11 Jan 2016 17:07:59 -0800 -Labels: app=job-wq-2 Pods Statuses: 1 Running / 0 Succeeded / 0 Failed -No volumes. +Pod Template: + Labels: controller-uid=b1c7e4e3-92e1-11e7-b85e-fa163ee3c11f + job-name=job-wq-2 + Containers: + c: + Image: gcr.io/exampleproject/job-wq-2 + Port: + Environment: + Mounts: + Volumes: Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- From f179452a9a12f15e0e28a1bf7529e5ce84b87aaf Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sat, 9 Sep 2017 08:49:56 +0800 Subject: [PATCH 016/102] Update create-cluster-kubeadm.md (#5318) Fix leading spaces in commands. --- docs/setup/independent/create-cluster-kubeadm.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/setup/independent/create-cluster-kubeadm.md b/docs/setup/independent/create-cluster-kubeadm.md index 9ca5dd13a0..65a05b634d 100644 --- a/docs/setup/independent/create-cluster-kubeadm.md +++ b/docs/setup/independent/create-cluster-kubeadm.md @@ -468,9 +468,9 @@ control of your Kubernetes cluster. ## Feedback * kubeadm support Slack Channel: - [#kubeadm](https://kubernetes.slack.com/messages/kubeadm/) + [kubeadm](https://kubernetes.slack.com/messages/kubeadm/) * General SIG Cluster Lifecycle Development Slack Channel: - [#sig-cluster-lifecycle](https://kubernetes.slack.com/messages/sig-cluster-lifecycle/) + [sig-cluster-lifecycle](https://kubernetes.slack.com/messages/sig-cluster-lifecycle/) * Mailing List: [kubernetes-sig-cluster-lifecycle](https://groups.google.com/forum/#!forum/kubernetes-sig-cluster-lifecycle) * [GitHub Issues in the kubeadm @@ -561,10 +561,10 @@ Verify that the `$HOME/.kube/config` file contains a valid certificate, and rege Another workaround is to overwrite the default `kubeconfig` for the "admin" user: ``` - mv $HOME/.kube $HOME/.kube.bak - mkdir -p $HOME/.kube - sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config - sudo chown $(id -u):$(id -g) $HOME/.kube/config +mv $HOME/.kube $HOME/.kube.bak +mkdir -p $HOME/.kube +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config ``` 1. If you are using CentOS and encounter difficulty while setting up the master node, From 1e4399ee8908140496b22fd04f983d05f3cc4c20 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Sat, 9 Sep 2017 03:50:44 +0300 Subject: [PATCH 017/102] Mailing list moved to kubernetes-users group (#5320) --- docs/tasks/debug-application-cluster/debug-service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/debug-application-cluster/debug-service.md b/docs/tasks/debug-application-cluster/debug-service.md index 6ca474efc9..b2ee1307d3 100644 --- a/docs/tasks/debug-application-cluster/debug-service.md +++ b/docs/tasks/debug-application-cluster/debug-service.md @@ -627,7 +627,7 @@ us know, so we can help investigate! Contact us on [Slack](/docs/troubleshooting/#slack) or -[email](https://groups.google.com/forum/#!forum/google-containers) or +[email](https://groups.google.com/forum/#!forum/kubernetes-users) or [GitHub](https://github.com/kubernetes/kubernetes). ## More information From 6a4fde54b21098670339b7e9937dbb1571883d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pab=C3=B3n?= Date: Fri, 8 Sep 2017 20:51:21 -0400 Subject: [PATCH 018/102] Update link in AWS documentation (#5325) --- docs/concepts/cluster-administration/cloud-providers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/cluster-administration/cloud-providers.md b/docs/concepts/cluster-administration/cloud-providers.md index e0b60896dd..4c0034efb9 100644 --- a/docs/concepts/cluster-administration/cloud-providers.md +++ b/docs/concepts/cluster-administration/cloud-providers.md @@ -44,7 +44,7 @@ Different settings can be applied to a load balancer service in AWS using _annot * `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix`: Used to specify access log s3 bucket prefix. * `service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags`: Used on the service to specify a comma-separated list of key-value pairs which will be recorded as additional tags in the ELB. For example: `"Key1=Val1,Key2=Val2,KeyNoVal1=,KeyNoVal2"`. * `service.beta.kubernetes.io/aws-load-balancer-backend-protocol`: Used on the service to specify the protocol spoken by the backend (pod) behind a listener. If `http` (default) or `https`, an HTTPS listener that terminates the connection and parses headers is created. If set to `ssl` or `tcp`, a "raw" SSL listener is used. If set to `http` and `aws-load-balancer-ssl-cert` is not used then a HTTP listener is used. -* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`: Used on the service to request a secure listener. Value is a valid certificate ARN. For more, see http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html CertARN is an IAM or CM certificate ARN, e.g. `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`. +* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`: Used on the service to request a secure listener. Value is a valid certificate ARN. For more, see [ELB Listener Config](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-listener-config.html) CertARN is an IAM or CM certificate ARN, e.g. `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`. * `service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled`: Used on the service to enable or disable connection draining. * `service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout`: Used on the service to specify a connection draining timeout. * `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout`: Used on the service to specify the idle connection timeout. From de452f864ed7d541004f5e1b598b6685471b5f93 Mon Sep 17 00:00:00 2001 From: Joel Roggeman Date: Fri, 8 Sep 2017 20:43:23 -0700 Subject: [PATCH 019/102] Fix MD formatting issue in docs (#5326) --- docs/getting-started-guides/windows/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index ad5c1b9329..96e3c49216 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -32,7 +32,8 @@ The following diagram illustrates the Windows Server networking setup for Kubern ![Windows Setup](windows-setup.png) ## Setting up Windows Server Containers on Kubernetes -To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and setup Routes for Pod communication on different nodes +To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and setup Routes for Pod communication on different nodes. + ### Host Setup **Windows Host Setup** From 8c37e43a183837015edce11b20716c50ccd26016 Mon Sep 17 00:00:00 2001 From: Weihua Meng Date: Fri, 8 Sep 2017 23:05:36 -0500 Subject: [PATCH 020/102] Update opaque-integer-resource.md (#5331) remove irrelevant words --- docs/tasks/configure-pod-container/opaque-integer-resource.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/configure-pod-container/opaque-integer-resource.md b/docs/tasks/configure-pod-container/opaque-integer-resource.md index fff8f55703..fafe753792 100644 --- a/docs/tasks/configure-pod-container/opaque-integer-resource.md +++ b/docs/tasks/configure-pod-container/opaque-integer-resource.md @@ -53,7 +53,7 @@ Describe the Pod: kubectl describe pod oir-demo ``` -The output shows the memory, CPU, and dongle requests: +The output shows dongle requests: ```yaml Requests: From d19e83c3c1ad1a073191a6a145c445f7151dd9e7 Mon Sep 17 00:00:00 2001 From: XsWack Date: Sat, 9 Sep 2017 12:08:09 +0800 Subject: [PATCH 021/102] add Node Condition Type (#5334) add Node Condition Type --- docs/concepts/architecture/nodes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/concepts/architecture/nodes.md b/docs/concepts/architecture/nodes.md index 1d361db045..43c5d722c0 100644 --- a/docs/concepts/architecture/nodes.md +++ b/docs/concepts/architecture/nodes.md @@ -51,6 +51,7 @@ The `conditions` field describes the status of all `Running` nodes. | `Ready` | `True` if the node is healthy and ready to accept pods, `False` if the node is not healthy and is not accepting pods, and `Unknown` if the node controller has not heard from the node in the last 40 seconds | | `MemoryPressure` | `True` if pressure exists on the node memory -- that is, if the node memory is low; otherwise `False` | | `DiskPressure` | `True` if pressure exists on the disk size -- that is, if the disk capacity is low; otherwise `False` | +| `NetworkUnavailable` | `True` if the network for the node is not correctly configured, otherwise `False` | The node condition is represented as a JSON object. For example, the following response describes a healthy node. From 511402d8e2d5bbf6feeff2d35fe5dd4e4c1691ed Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Sat, 9 Sep 2017 12:15:45 +0800 Subject: [PATCH 022/102] fix the command output (#5350) fix the command output --- .../debug-application-introspection.md | 69 ++++++++++++------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/docs/tasks/debug-application-cluster/debug-application-introspection.md b/docs/tasks/debug-application-cluster/debug-application-introspection.md index ac936adf74..55c4c24c7f 100644 --- a/docs/tasks/debug-application-cluster/debug-application-introspection.md +++ b/docs/tasks/debug-application-cluster/debug-application-introspection.md @@ -280,34 +280,55 @@ kubernetes-node-unaj Ready 1h v1.6.0+fff5156 $ kubectl describe node kubernetes-node-861h Name: kubernetes-node-861h -Labels: kubernetes.io/hostname=kubernetes-node-861h -CreationTimestamp: Fri, 10 Jul 2015 14:32:29 -0700 +Role +Labels: beta.kubernetes.io/arch=amd64 + beta.kubernetes.io/os=linux + kubernetes.io/hostname=kubernetes-node-861h +Annotations: node.alpha.kubernetes.io/ttl=0 + volumes.kubernetes.io/controller-managed-attach-detach=true +Taints: +CreationTimestamp: Mon, 04 Sep 2017 17:13:23 +0800 +Phase: Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message - Ready Unknown Fri, 10 Jul 2015 14:34:32 -0700 Fri, 10 Jul 2015 14:35:15 -0700 Kubelet stopped posting node status. + ---- ------ ----------------- ------------------ ------ ------- + OutOfDisk Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status. + MemoryPressure Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status. + DiskPressure Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status. + Ready Unknown Fri, 08 Sep 2017 16:04:28 +0800 Fri, 08 Sep 2017 16:20:58 +0800 NodeStatusUnknown Kubelet stopped posting node status. Addresses: 10.240.115.55,104.197.0.26 Capacity: - cpu: 1 - memory: 3800808Ki - pods: 100 -Version: - Kernel Version: 3.16.0-0.bpo.4-amd64 - OS Image: Debian GNU/Linux 7 (wheezy) - Container Runtime Version: docker://Unknown - Kubelet Version: v0.21.1-185-gffc5a86098dc01 - Kube-Proxy Version: v0.21.1-185-gffc5a86098dc01 -PodCIDR: 10.244.0.0/24 -ExternalID: 15233045891481496305 -Pods: (0 in total) - Namespace Name -Events: - FirstSeen LastSeen Count From SubobjectPath Reason Message - Fri, 10 Jul 2015 14:32:28 -0700 Fri, 10 Jul 2015 14:32:28 -0700 1 {kubelet kubernetes-node-861h} NodeNotReady Node kubernetes-node-861h status is now: NodeNotReady - Fri, 10 Jul 2015 14:32:30 -0700 Fri, 10 Jul 2015 14:32:30 -0700 1 {kubelet kubernetes-node-861h} NodeNotReady Node kubernetes-node-861h status is now: NodeNotReady - Fri, 10 Jul 2015 14:33:00 -0700 Fri, 10 Jul 2015 14:33:00 -0700 1 {kubelet kubernetes-node-861h} starting Starting kubelet. - Fri, 10 Jul 2015 14:33:02 -0700 Fri, 10 Jul 2015 14:33:02 -0700 1 {kubelet kubernetes-node-861h} NodeReady Node kubernetes-node-861h status is now: NodeReady - Fri, 10 Jul 2015 14:35:15 -0700 Fri, 10 Jul 2015 14:35:15 -0700 1 {controllermanager } NodeNotReady Node kubernetes-node-861h status is now: NodeNotReady - + cpu: 2 + hugePages: 0 + memory: 4046788Ki + pods: 110 +Allocatable: + cpu: 1500m + hugePages: 0 + memory: 1479263Ki + pods: 110 +System Info: + Machine ID: 8e025a21a4254e11b028584d9d8b12c4 + System UUID: 349075D1-D169-4F25-9F2A-E886850C47E3 + Boot ID: 5cd18b37-c5bd-4658-94e0-e436d3f110e0 + Kernel Version: 4.4.0-31-generic + OS Image: Debian GNU/Linux 8 (jessie) + Operating System: linux + Architecture: amd64 + Container Runtime Version: docker://1.12.5 + Kubelet Version: v1.6.9+a3d1dfa6f4335 + Kube-Proxy Version: v1.6.9+a3d1dfa6f4335 +ExternalID: 15233045891481496305 +Non-terminated Pods: (9 in total) + Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits + --------- ---- ------------ ---------- --------------- ------------- +...... +Allocated resources: + (Total limits may be over 100 percent, i.e., overcommitted.) + CPU Requests CPU Limits Memory Requests Memory Limits + ------------ ---------- --------------- ------------- + 900m (60%) 2200m (146%) 1009286400 (66%) 5681286400 (375%) +Events: $ kubectl get node kubernetes-node-861h -o yaml apiVersion: v1 From c4fde406f0f90e00485ba1a401469db15f9da62d Mon Sep 17 00:00:00 2001 From: Joseph Heck Date: Fri, 8 Sep 2017 21:20:29 -0700 Subject: [PATCH 023/102] fixing broken note annotation, and cleaning blank line endings (#5360) * fixing broken note annotation, and cleaning blank line endings * fixing caution annotation typo --- docs/getting-started-guides/kubespray.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/getting-started-guides/kubespray.md b/docs/getting-started-guides/kubespray.md index eee97f6a2a..9ceb1b5af9 100644 --- a/docs/getting-started-guides/kubespray.md +++ b/docs/getting-started-guides/kubespray.md @@ -21,15 +21,15 @@ To choose a tool which best fits your use case, read [this comparison](https://g Provision servers with the following requirements: -* `Ansible v2.3` (or newer) -* `Jinja 2.9` (or newer) +* `Ansible v2.3` (or newer) +* `Jinja 2.9` (or newer) * `python-netaddr` installed on the machine that running Ansible commands * Target servers must have access to the Internet in order to pull docker images * Target servers are configured to allow IPv4 forwarding * Target servers have SSH connectivity ( tcp/22 ) directly to your nodes or through a bastion host/ssh jump box * Target servers have a privileged user * Your SSH key must be copied to all the servers that are part of your inventory -* Firewall rules configured properly to allow Ansible and Kubernetes components to communicate +* Firewall rules configured properly to allow Ansible and Kubernetes components to communicate * If using a cloud provider, you must have the appropriate credentials available and exported as environment variables Kubespray provides the following utilities to help provision your environment: @@ -44,7 +44,7 @@ Kubespray provides the following utilities to help provision your environment: ### (2/5) Compose an inventory file -After you provision your servers, create an [inventory file for Ansible](http://docs.ansible.com/ansible/intro_inventory.html). You can do this manually or via a dynamic inventory script. For more information, see "[Building your own inventory](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md#building-your-own-inventory)". +After you provision your servers, create an [inventory file for Ansible](http://docs.ansible.com/ansible/intro_inventory.html). You can do this manually or via a dynamic inventory script. For more information, see "[Building your own inventory](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md#building-your-own-inventory)". ### (3/5) Plan your cluster deployment @@ -65,10 +65,10 @@ Kubespray customizations can be made to a [variable file](http://docs.ansible.co Next, deploy your cluster with one of two methods: * [ansible-playbook](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md#starting-custom-deployment). -* [kubespray-cli tool](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md) +* [kubespray-cli tool](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md) **Note:** kubespray-cli is no longer actively maintained. -{. :note} +{: .note} Both methods run the default [cluster definition file](https://github.com/kubernetes-incubator/kubespray/blob/master/cluster.yml). @@ -84,11 +84,11 @@ Kubespray provides additional playbooks to manage your cluster: _scale_ and _upg ### Scale your cluster -You can scale your cluster by running the scale playbook. For more information, see "[Adding nodes](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md#Adding-nodes)". +You can scale your cluster by running the scale playbook. For more information, see "[Adding nodes](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md#Adding-nodes)". ### Upgrade your cluster -You can upgrade your cluster by running the upgrade-cluster playbook. For more information, see "[Upgrades](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/upgrades.md)". +You can upgrade your cluster by running the upgrade-cluster playbook. For more information, see "[Upgrades](https://github.com/kubernetes-incubator/kubespray/blob/master/docs/upgrades.md)". ## What's next @@ -99,7 +99,7 @@ Check out planned work on Kubespray's [roadmap](https://github.com/kubernetes-in You can reset your nodes and wipe out all components installed with Kubespray via the [reset playbook](https://github.com/kubernetes-incubator/kubespray/blob/master/reset.yml). **Caution:** When running the reset playbook, be sure not to accidentally target your production cluster! -{. :caution} +{: .caution} ## Feedback From 16e44fcc9a9746613b0c1c6f61ff824f8774cde6 Mon Sep 17 00:00:00 2001 From: Errien Date: Sat, 9 Sep 2017 07:14:12 +0200 Subject: [PATCH 024/102] Update configure-pod-configmap.md (#4017) Setting correct key for LOG_LEVEL env value From 38d3414a794cd27171d750dbef6a0247cb40257a Mon Sep 17 00:00:00 2001 From: Malepati Bala Siva Sai Akhil Date: Sat, 9 Sep 2017 11:22:39 +0530 Subject: [PATCH 025/102] Fixed Broken Link (#4798) Fixed Broken Link in Case Study of Box Signed-off-by: Malepati Bala Siva Sai Akhil --- case-studies/box.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/case-studies/box.html b/case-studies/box.html index 468a7b2e4a..6b816631bf 100644 --- a/case-studies/box.html +++ b/case-studies/box.html @@ -55,7 +55,7 @@ css: /css/style_box.css A platform that allows its more than 50 million users (including governments and big businesses like General Electric) to manage and share content in the cloud, Box was originally a PHP monolith of millions of lines of code built exclusively with bare metal inside of its own data centers. It had already begun to slowly chip away at the monolith, decomposing it into microservices. And "as we’ve been expanding into regions around the globe, and as the public cloud wars have been heating up, we’ve been focusing a lot more on figuring out how we run our workload across many different environments and many different cloud infrastructure providers," says Box Cofounder and Services Architect Sam Ghods. "It’s been a huge challenge thus far because of all these different providers, especially bare metal, have very different interfaces and ways in which you work with them."

Box’s cloud native journey accelerated that June, when Ghods attended DockerCon. The company had come to the realization that it could no longer run its applications only off bare metal, and was researching containerizing with Docker, virtualizing with OpenStack, and supporting public cloud.

At that conference, Google announced the release of its Kubernetes container management system, and Ghods was won over. "We looked at a lot of different options, but Kubernetes really stood out, especially because of the incredibly strong team of Borg veterans and the vision of having a completely infrastructure-agnostic way of being able to run cloud software," he says, referencing Google’s internal container orchestrator Borg. "The fact that on day one it was designed to run on bare metal just as well as Google Cloud meant that we could actually migrate to it inside of our data centers, and then use those same tools and concepts to run across public cloud providers as well."

- Another plus: Ghods liked that Kubernetes has a universal set of API objects like pod, service, replica set and deployment object, which created a consistent surface to build tooling against. "Even PaaS layers like OpenShift or Deis that build on top of Kubernetes still treat those objects as first-class principles," he says. "We were excited about having these abstractions shared across the entire ecosystem, which would result in a lot more momentum than we saw in other potential solutions."

+ Another plus: Ghods liked that Kubernetes has a universal set of API objects like pod, service, replica set and deployment object, which created a consistent surface to build tooling against. "Even PaaS layers like OpenShift or Deis that build on top of Kubernetes still treat those objects as first-class principles," he says. "We were excited about having these abstractions shared across the entire ecosystem, which would result in a lot more momentum than we saw in other potential solutions."

Box deployed Kubernetes in a cluster in a production data center just six months later. Kubernetes was then still pre-beta, on version 0.11. They started small: The very first thing Ghods’s team ran on Kubernetes was a Box API checker that confirms Box is up. "That was just to write and deploy some software to get the whole pipeline functioning," he says. Next came some daemons that process jobs, which was "nice and safe because if they experienced any interruptions, we wouldn’t fail synchronous incoming requests from customers." From d58b78d05898bd94a6278eb9f4ca2f438f65d71f Mon Sep 17 00:00:00 2001 From: Weihua Meng Date: Sat, 9 Sep 2017 11:18:05 -0500 Subject: [PATCH 026/102] Update opaque-integer-resource-node.md (#5330) typo correction --- docs/tasks/administer-cluster/opaque-integer-resource-node.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tasks/administer-cluster/opaque-integer-resource-node.md b/docs/tasks/administer-cluster/opaque-integer-resource-node.md index 71925c1642..026488ebe2 100644 --- a/docs/tasks/administer-cluster/opaque-integer-resource-node.md +++ b/docs/tasks/administer-cluster/opaque-integer-resource-node.md @@ -134,7 +134,7 @@ opaque-int-resource-special-storage. ```yaml Capacity: ... - pod.alpha.kubernetes.io/opaque-int-special-storage: 8 + pod.alpha.kubernetes.io/opaque-int-resource-special-storage: 8 ``` If you want to allow arbitrary requests for special storage, you @@ -144,7 +144,7 @@ could advertise special storage in chunks of size 1 byte. In that case, you woul ```yaml Capacity: ... - pod.alpha.kubernetes.io/opaque-int-special-storage: 8Gi + pod.alpha.kubernetes.io/opaque-int-resource-special-storage: 8Gi ``` Then a Container could request any number of bytes of special storage, up to 800Gi. From 7eb3fa9f2eb04c12d5396d9419697d76bee1839e Mon Sep 17 00:00:00 2001 From: Steve Perry Date: Sat, 9 Sep 2017 09:22:48 -0700 Subject: [PATCH 027/102] Update opaque-integer-resource-node.md --- docs/tasks/administer-cluster/opaque-integer-resource-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/administer-cluster/opaque-integer-resource-node.md b/docs/tasks/administer-cluster/opaque-integer-resource-node.md index 026488ebe2..cae82948be 100644 --- a/docs/tasks/administer-cluster/opaque-integer-resource-node.md +++ b/docs/tasks/administer-cluster/opaque-integer-resource-node.md @@ -144,7 +144,7 @@ could advertise special storage in chunks of size 1 byte. In that case, you woul ```yaml Capacity: ... - pod.alpha.kubernetes.io/opaque-int-resource-special-storage: 8Gi + pod.alpha.kubernetes.io/opaque-int-resource-special-storage: 800Gi ``` Then a Container could request any number of bytes of special storage, up to 800Gi. From fdbe5086a0fe268de6c3fe50638c0a194d3bfbe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=93=E9=9B=B7=E4=B8=8D=E6=80=95?= Date: Sun, 10 Sep 2017 00:45:38 +0800 Subject: [PATCH 028/102] cn-translation-from-2017-08-14-to-2017-09-03 (#5364) --- .../architecture/master-node-communication.md | 71 +++ cn/docs/concepts/architecture/nodes.md | 234 ++++++++++ .../concepts/cluster-administration/addons.md | 45 ++ .../cluster-administration-overview.md | 86 ++++ .../access-cluster-services.md | 110 +++++ .../apply-resource-quota-limit.md | 411 ++++++++++++++++++ .../change-default-storage-class.md | 94 ++++ .../change-pv-reclaim-policy.md | 80 ++++ .../administer-cluster/cluster-management.md | 227 ++++++++++ 9 files changed, 1358 insertions(+) create mode 100644 cn/docs/concepts/architecture/master-node-communication.md create mode 100644 cn/docs/concepts/architecture/nodes.md create mode 100644 cn/docs/concepts/cluster-administration/addons.md create mode 100644 cn/docs/concepts/cluster-administration/cluster-administration-overview.md create mode 100644 cn/docs/tasks/administer-cluster/access-cluster-services.md create mode 100644 cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md create mode 100644 cn/docs/tasks/administer-cluster/change-default-storage-class.md create mode 100644 cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md create mode 100644 cn/docs/tasks/administer-cluster/cluster-management.md diff --git a/cn/docs/concepts/architecture/master-node-communication.md b/cn/docs/concepts/architecture/master-node-communication.md new file mode 100644 index 0000000000..e090ed3197 --- /dev/null +++ b/cn/docs/concepts/architecture/master-node-communication.md @@ -0,0 +1,71 @@ +--- +approvers: +- dchen1107 +- roberthbailey +- liggitt + +title: Master 节点通信 +--- + +* TOC +{: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 + + +从 master(apiserver)到集群有两种主要的通信路径。第一种是从 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 Container Engine](https://cloud.google.com/container-engine/docs/) 使用 SSH 隧道保护 Master -> Cluster 通信路径。在这种配置下,apiserver 发起一个到集群中每个节点的 SSH 隧道(连接到在 22 端口监听的 ssh 服务)并通过这个隧道传输所有到 kubelet、node、pod 或者 service 的流量。这个隧道保证流量不会在集群运行的私有 GCE 网络之外暴露。 diff --git a/cn/docs/concepts/architecture/nodes.md b/cn/docs/concepts/architecture/nodes.md new file mode 100644 index 0000000000..1e611c896a --- /dev/null +++ b/cn/docs/concepts/architecture/nodes.md @@ -0,0 +1,234 @@ +--- +assignees: +- caesarxuchao +- dchen1107 + +title: Nodes +redirect_from: +- "/docs/admin/node/" +- "/docs/admin/node.html" +- "/docs/concepts/nodes/node/" +- "/docs/concepts/nodes/node.html" +--- + +* TOC +{: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.md#the-kubernetes-node) 一节获取更多细节。 + + +## Node 状态 + + + 一个 node 的状态包含以下信息: + +* [地址](#地址) +* ~~[阶段](#阶段)~~ **已废弃** +* [条件](#条件) +* [容量](#容量) +* [信息](#信息) + + +下面对每个章节进行详细描述。 + + +### 地址 + + +这些字段组合的用法取决于你的云服务商或者裸金属配置。 + +* HostName:HostName 和 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 列表(逗号分隔的 `=:`)注册 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: gcr.io/google_containers/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/{{page.version}}/#node-v1-core).`` diff --git a/cn/docs/concepts/cluster-administration/addons.md b/cn/docs/concepts/cluster-administration/addons.md new file mode 100644 index 0000000000..1ddac950f1 --- /dev/null +++ b/cn/docs/concepts/cluster-administration/addons.md @@ -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! diff --git a/cn/docs/concepts/cluster-administration/cluster-administration-overview.md b/cn/docs/concepts/cluster-administration/cluster-administration-overview.md new file mode 100644 index 0000000000..9f6fbf0f9e --- /dev/null +++ b/cn/docs/concepts/cluster-administration/cluster-administration-overview.md @@ -0,0 +1,86 @@ +--- +approvers: +- davidopp +- lavalamp + +title: 集群管理概述 +--- + +{% capture overview %} + +集群管理概述面向任何创建和管理 Kubernetes 集群的读者人群。我们假设你对 [用户指南](/docs/user-guide/)中的概念有一些熟悉。 +{% endcapture %} + +{% 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 的日志如何工作以及怎样实现。 + +{% endcapture %} + +{% include templates/concept.md %} diff --git a/cn/docs/tasks/administer-cluster/access-cluster-services.md b/cn/docs/tasks/administer-cluster/access-cluster-services.md new file mode 100644 index 0000000000..00e06266ab --- /dev/null +++ b/cn/docs/tasks/administer-cluster/access-cluster-services.md @@ -0,0 +1,110 @@ +--- + +title: 访问集群上运行的服务 +redirect_from: +- "/docs/user-guide/accessing-the-cluster/" +- "/docs/user-guide/accessing-the-cluster.html" +--- + +{% capture overview %} + +本文展示了如何连接 Kubernetes 集群上运行的服务。 +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} +{% endcapture %} + +{% capture steps %} + +## 访问集群上运行的服务 + + +在 Kubernetes 里, [nodes](/docs/admin/node)、[pods](/docs/user-guide/pods) 和 [services](/docs/user-guide/services) 都有它们自己的 IP。许多情况下,集群上的 node IP、pod IP 和某些 service IP 路由不可达,所以不能从一个集群之外的节点访问它们,例如从你自己的台式机。 + + +### 连接方式 + + +你有多种从集群外连接 nodes、pods 和 services 的选项: + + + - 通过公共 IP 访问 services。 + - 使用具有 `NodePort` 或 `LoadBalancer` 类型的 service,可以从外部访问它们。请查阅 [services](/docs/user-guide/services) 和 [kubectl expose](/docs/user-guide/kubectl/v1.6/#expose) 文档。 + - 取决于你的集群环境,你可以仅把 service 暴露在你的企业网络环境中,也可以将其暴露在因特网上。需要考虑暴露的 service 是否安全,它是否有自己的用户认证? + - 将 pods 放置于 services 背后。如果要访问一个副本集合中特定的 pod,例如用于调试目的时,请给 pod 指定一个独特的标签并创建一个新 service 选择这个标签。 + - 大部分情况下,都不需要应用开发者通过节点 IP 直接访问 nodes。 + - 通过 Proxy Verb 访问 services、nodes 或者 pods。 + - 在访问 Apiserver 远程服务之前是否经过认证和授权?如果你的服务暴露到因特网中不够安全,或者需要获取 node IP 之上的端口,又或者处于调试目的时,请使用这个特性。 + - Proxies 可能给某些应用带来麻烦。 + - 仅适用于 HTTP/HTTPS。 + - 在[这里](#manually-constructing-apiserver-proxy-urls)描述 + - 从集群中的 node 或者 pod 访问。 + - 运行一个 pod,然后使用 [kubectl exec](/docs/user-guide/kubectl/v1.6/#exec) 连接到它的一个shell。从那个 shell 连接其他的 nodes、pods 和 services。 + - 某些集群可能允许你 ssh 到集群中的节点。你可能可以从那儿访问集群服务。这是一个非标准的方式,可能在一些集群上能工作,但在另一些上却不能。浏览器和其他工具可能安装或可能不会安装。集群 DNS 可能不会正常工作。 + + +### 发现内置服务 + + +典型情况下,kube-system 会启动集群中的几个服务。使用 `kubectl cluster-info` 命令获取它们的列表: + +```shell +$ kubectl cluster-info + + Kubernetes master is running at https://104.197.5.247 + elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy + kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy + kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy + grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy + heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy +``` + +这显示了用于访问每个服务的 proxy-verb URL。例如,这个集群启用了(使用 Elasticsearch)集群层面的日志,如果提供合适的凭据可以通过 `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/` 访问,或通过一个 kubectl 代理地址访问,如:`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`。(请查看 [上文](#accessing-the-cluster-api) 关于如何传递凭据或者使用 kubectl 代理的说明。) + + +#### 手动构建 apiserver 代理 URLs + + +如同上面所提到的,你可以使用 `kubectl cluster-info` 命令取得 service 的代理 URL。为了创建包含 service endpoints、suffixes 和 parameters 的代理 URLs,你可以简单的在 service 的代理 URL中 添加: +`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*`/proxy` + + +如果还没有为你的端口指定名称,你可以不用在 URL 中指定 *port_name*。 + + +##### 示例 + + + * 你可以通过 `http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy` 访问 Elasticsearch service endpoint `_search?q=user:kimchy`。 + * 你可以通过 `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true` 访问 Elasticsearch 集群健康信息 endpoint `_cluster/health?pretty=true`。 + +```json + { + "cluster_name" : "kubernetes_logging", + "status" : "yellow", + "timed_out" : false, + "number_of_nodes" : 1, + "number_of_data_nodes" : 1, + "active_primary_shards" : 5, + "active_shards" : 5, + "relocating_shards" : 0, + "initializing_shards" : 0, + "unassigned_shards" : 5 + } +``` + + +#### 通过 web 浏览器访问集群中运行的服务 + + +你或许能够将 apiserver 代理的 url 放入浏览器的地址栏,然而: + + + - Web 服务器不总是能够传递令牌,所以你可能需要使用基本(密码)认证。 Apiserver 可以配置为接受基本认证,但你的集群可能并没有这样配置。 + - 某些 web 应用可能不能工作,特别是那些使用客户端侧 javascript 的应用,它们构造 url 的方式可能不能理解代理路径前缀。 + +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md b/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md new file mode 100644 index 0000000000..5ffd280425 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/apply-resource-quota-limit.md @@ -0,0 +1,411 @@ +--- +assignees: +- derekwaynecarr +- janetkuo + +title: 应用资源配额和限额 +redirect_from: +- "/docs/admin/resourcequota/walkthrough/" +- "/docs/admin/resourcequota/walkthrough.html" +- "/docs/tasks/configure-pod-container/apply-resource-quota-limit/" +- "/docs/tasks/configure-pod-container/apply-resource-quota-limit.html" +--- + +{% capture overview %} + + +本示例展示了在一个 namespace 中控制资源用量的典型设置。 + + +本文展示了以下资源的使用: [Namespace](/docs/admin/namespaces), [ResourceQuota](/docs/concepts/policy/resource-quotas/) 和 [LimitRange](/docs/tasks/configure-pod-container/limit-range/)。 + +{% endcapture %} + +{% capture prerequisites %} + +* {% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture steps %} + +## 场景 + + +集群管理员正在操作一个代表用户群体的集群,他希望控制一个特定 namespace 中可以被使用的资源总量,以达到促进对集群的公平共享及控制成本的目的。 + + +集群管理员有以下目标: + + +* 限制运行中 pods 使用的计算资源数量 +* 限制 persistent volume claims 数量以控制对存储的访问 +* 限制 load balancers 数量以控制成本 +* 防止使用 node ports 以保留稀缺资源 +* 提供默认计算资源请求以实现更好的调度决策 + + +## 创建 namespace + + +本示例将在一个自定义的 namespace 中运行,以展示相关概念。 + + +让我们创建一个叫做 quota-example 的新 namespace: + +```shell +$ kubectl create namespace quota-example +namespace "quota-example" created +$ kubectl get namespaces +NAME STATUS AGE +default Active 2m +kube-system Active 2m +quota-example Active 39s +``` + + +## 应用 object-count 配额到 namespace + + +集群管理员想要控制下列资源: + +* persistent volume claims +* load balancers +* node ports + + +我们来创建一个简单的配额,用于控制这个 namespace 中那些资源类型的对象数量。 + +```shell +$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/rq-object-counts.yaml --namespace=quota-example +resourcequota "object-counts" created +``` + + +配额系统将察觉到有一个配额被创建,并且会计算 namespace 中的资源消耗量作为响应。这应该会很快发生。 + + +让我们显示一下配额来观察这个 namespace 中当前被消耗的资源: + +```shell +$ kubectl describe quota object-counts --namespace=quota-example +Name: object-counts +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +persistentvolumeclaims 0 2 +services.loadbalancers 0 2 +services.nodeports 0 0 +``` + + +配额系统现在将阻止用户创建比各个资源指定数量更多的资源。 + + + +## 应用计算资源配额到 namespace + + +为了限制这个 namespace 可以被使用的计算资源数量,让我们创建一个跟踪计算资源的配额。 + +```shell +$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/rq-compute-resources.yaml --namespace=quota-example +resourcequota "compute-resources" created +``` + + +让我们显示一下配额来观察这个 namespace 中当前被消耗的资源: + +```shell +$ kubectl describe quota compute-resources --namespace=quota-example +Name: compute-resources +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +limits.cpu 0 2 +limits.memory 0 2Gi +pods 0 4 +requests.cpu 0 1 +requests.memory 0 1Gi +``` + + +配额系统现在会防止 namespace 拥有超过 4 个没有终止的 pods。此外它还将强制 pod 中的每个容器配置一个 `request` 并为 `cpu` 和 `memory` 定义 `limit`。 + + +## 应用默认资源请求和限制 + + +Pod 的作者很少为它们的 pods 指定资源请求和限制。 + + +既然我们对项目应用了配额,我们来看一下当终端用户通过创建一个没有 cpu 和 内存限制的 pod 时会发生什么。这通过在 pod 里创建一个 nginx 容器实现。 + + +作为演示,让我们来创建一个运行 nginx 的 deployment: + +```shell +$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example +deployment "nginx" created +``` + + +现在我们来看一下创建的 pods。 + +```shell +$ kubectl get pods --namespace=quota-example +``` + + +发生了什么?我一个 pods 都没有!让我们 describe 这个 deployment 来看看发生了什么。 + +```shell +$ kubectl describe deployment nginx --namespace=quota-example +Name: nginx +Namespace: quota-example +CreationTimestamp: Mon, 06 Jun 2016 16:11:37 -0400 +Labels: run=nginx +Selector: run=nginx +Replicas: 0 updated | 1 total | 0 available | 1 unavailable +StrategyType: RollingUpdate +MinReadySeconds: 0 +RollingUpdateStrategy: 1 max unavailable, 1 max surge +OldReplicaSets: +NewReplicaSet: nginx-3137573019 (0/1 replicas created) +... +``` + + +Deployment 创建了一个对应的 replica set 并尝试按照大小来创建一个 pod。 + + +让我们看看 replica set 的更多细节。 + +```shell +$ kubectl describe rs nginx-3137573019 --namespace=quota-example +Name: nginx-3137573019 +Namespace: quota-example +Image(s): nginx +Selector: pod-template-hash=3137573019,run=nginx +Labels: pod-template-hash=3137573019 + run=nginx +Replicas: 0 current / 1 desired +Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed +No volumes. +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 4m 7s 11 {replicaset-controller } Warning FailedCreate Error creating: pods "nginx-3137573019-" is forbidden: Failed quota: compute-resources: must specify limits.cpu,limits.memory,requests.cpu,requests.memory +``` + + +Kubernetes API server 拒绝了 replica set 创建一个 pod 的请求,因为我们的 pods 没有为 `cpu` 和 `memory` 指定 `requests` 或 `limits`。 + + +因此,我们来为 pod 指定它可以使用的 `cpu` 和 `memory` 默认数量。 + +```shell +$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/rq-limits.yaml --namespace=quota-example +limitrange "limits" created +$ kubectl describe limits limits --namespace=quota-example +Name: limits +Namespace: quota-example +Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio +---- -------- --- --- --------------- ------------- ----------------------- +Container memory - - 256Mi 512Mi - +Container cpu - - 100m 200m - +``` + + +如果 Kubernetes API server 发现一个 namespace 中有一个创建 pod 的请求,并且 pod 中的容器没有设置任何计算资源请求时,作为准入控制的一部分,一个默认的 request 和 limit 将会被应用。 + + +在本例中,创建的每个 pod 都将拥有如下的计算资源限制: + +```shell +$ kubectl run nginx \ + --image=nginx \ + --replicas=1 \ + --requests=cpu=100m,memory=256Mi \ + --limits=cpu=200m,memory=512Mi \ + --namespace=quota-example +``` + + +由于已经为我们的 namespace 申请了默认的计算资源,我们的 replica set 应该能够创建它的 pods 了。 + +```shell +$ kubectl get pods --namespace=quota-example +NAME READY STATUS RESTARTS AGE +nginx-3137573019-fvrig 1/1 Running 0 6m +``` + + +而且如果打印出我们在这个 namespace 中的配额使用情况: + +```shell +$ kubectl describe quota --namespace=quota-example +Name: compute-resources +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +limits.cpu 200m 2 +limits.memory 512Mi 2Gi +pods 1 4 +requests.cpu 100m 1 +requests.memory 256Mi 1Gi + + +Name: object-counts +Namespace: quota-example +Resource Used Hard +-------- ---- ---- +persistentvolumeclaims 0 2 +services.loadbalancers 0 2 +services.nodeports 0 0 +``` + + +就像你看到的,创建的 pod 消耗了明确的计算资源量,并且正被 Kubernetes 正确的追踪着。 + + +## 高级配额 scopes + + +让我们想象一下如果你不希望为你的 namespace 指定默认计算资源使用量。 + + +作为替换,你希望用户在它们的 namespace 中运行指定数量的 `BestEffort` pods,以从宽松的计算资源中获得好处。然后要求用户为需要更高质量服务的 pods 配置一个显式的资源请求。 + + +让我们新建一个拥有两个配额的 namespace 来演示这种行为: + +```shell +$ kubectl create namespace quota-scopes +namespace "quota-scopes" created +$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/rq-best-effort.yaml --namespace=quota-scopes +resourcequota "best-effort" created +$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/rq-not-best-effort.yaml --namespace=quota-scopes +resourcequota "not-best-effort" created +$ kubectl describe quota --namespace=quota-scopes +Name: best-effort +Namespace: quota-scopes +Scopes: BestEffort + * Matches all pods that have best effort quality of service. +Resource Used Hard +-------- ---- ---- +pods 0 10 + + +Name: not-best-effort +Namespace: quota-scopes +Scopes: NotBestEffort + * Matches all pods that do not have best effort quality of service. +Resource Used Hard +-------- ---- ---- +limits.cpu 0 2 +limits.memory 0 2Gi +pods 0 4 +requests.cpu 0 1 +requests.memory 0 1Gi +``` + + +在这种场景下,一个没有配置计算资源请求的 pod 将会被 `best-effort` 配额跟踪。 + + +而配置了计算资源请求的则会被 `not-best-effort` 配额追踪。 + + +让我们创建两个 deployments 作为演示: + +```shell +$ kubectl run best-effort-nginx --image=nginx --replicas=8 --namespace=quota-scopes +deployment "best-effort-nginx" created +$ kubectl run not-best-effort-nginx \ + --image=nginx \ + --replicas=2 \ + --requests=cpu=100m,memory=256Mi \ + --limits=cpu=200m,memory=512Mi \ + --namespace=quota-scopes +deployment "not-best-effort-nginx" created +``` + + +虽然没有指定默认的 limits,`best-effort-nginx` deployment 还是会创建 8 个 pods。这是由于它被 `best-effort` 配额追踪,而 `not-best-effort` 配额将忽略它。`not-best-effort` 配额将追踪 `not-best-effort-nginx` deployment,因为它创建的 pods 具有 `Burstable` 服务质量。 + + +让我们列出 namespace 中的 pods: + +```shell +$ kubectl get pods --namespace=quota-scopes +NAME READY STATUS RESTARTS AGE +best-effort-nginx-3488455095-2qb41 1/1 Running 0 51s +best-effort-nginx-3488455095-3go7n 1/1 Running 0 51s +best-effort-nginx-3488455095-9o2xg 1/1 Running 0 51s +best-effort-nginx-3488455095-eyg40 1/1 Running 0 51s +best-effort-nginx-3488455095-gcs3v 1/1 Running 0 51s +best-effort-nginx-3488455095-rq8p1 1/1 Running 0 51s +best-effort-nginx-3488455095-udhhd 1/1 Running 0 51s +best-effort-nginx-3488455095-zmk12 1/1 Running 0 51s +not-best-effort-nginx-2204666826-7sl61 1/1 Running 0 23s +not-best-effort-nginx-2204666826-ke746 1/1 Running 0 23s +``` + + +如你看到的,所有 10 个 pods 都已经被准许创建。 + + +让我们 describe 这个 namespace 当前的配额使用情况: + +```shell +$ kubectl describe quota --namespace=quota-scopes +Name: best-effort +Namespace: quota-scopes +Scopes: BestEffort + * Matches all pods that have best effort quality of service. +Resource Used Hard +-------- ---- ---- +pods 8 10 + + +Name: not-best-effort +Namespace: quota-scopes +Scopes: NotBestEffort + * Matches all pods that do not have best effort quality of service. +Resource Used Hard +-------- ---- ---- +limits.cpu 400m 2 +limits.memory 1Gi 2Gi +pods 2 4 +requests.cpu 200m 1 +requests.memory 512Mi 1Gi +``` + + +如你看到的,`best-effort` 配额追踪了我们在 `best-effort-nginx` deployment 中创建的 8 个 pods 的资源用量,而 `not-best-effort` 配额追踪了我们在 `not-best-effort-nginx` deployment 中创的两个 pods 的用量。 + + +Scopes 提供了一种来对任何配额文档追踪的资源集合进行细分的机制,给操作人员部署和追踪资源消耗带来更大的灵活性。 + + +除 `BestEffort` 和 `NotBestEffort` scopes 之外,还有用于限制长时间运行和有时限 pods 的scopes。`Terminating` scope 将匹配任何 `spec.activeDeadlineSeconds` 不为 `nil` 的 pod。`NotTerminating` scope 将匹配任何 `spec.activeDeadlineSeconds` 为 `nil` 的 pod。这些 scopes 允许你基于 pods 在你集群中 node 上的预期持久程度来为它们指定配额。 + +{% endcapture %} + +{% capture discussion %} + +## 总结 + + +消耗节点 cpu 和 memory 资源的动作受到 namespace 配额定义的硬性配额限制的管制。 + + +任意消耗那些资源的动作能够被调整,或者获得一个 namespace 级别的默认值以符合你最终的目标。 + + +可以基于服务质量或者在你集群中节点上的预期持久程度来分配配额。 + +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/change-default-storage-class.md b/cn/docs/tasks/administer-cluster/change-default-storage-class.md new file mode 100644 index 0000000000..b1ba51a064 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/change-default-storage-class.md @@ -0,0 +1,94 @@ +--- + +title: 改变默认 StorageClass +--- + +{% capture overview %} + +本文展示了如何改变默认的 Storage Class,它用于为没有特殊需求的 PersistentVolumeClaims 配置 volumes。 + +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture steps %} + + +## 为什么要改变默认 storage class? + + +取决于安装模式,您的 Kubernetes 集群可能和一个被标记为默认的已有 StorageClass 一起部署。这个默认的 StorageClass 以后将被用于动态的为没有特定 storage class 需求的 PersistentVolumeClaims 配置存储。更多细节请查看 [PersistentVolumeClaim 文档](/docs/user-guide/persistent-volumes/#class-1)。 + + +预先安装的默认 StorageClass 可能不能很好的适应您期望的工作负载;例如,它配置的存储可能太过昂贵。如果是这样的话,您可以改变默认 StorageClass,或者完全禁用它以防止动态配置存储。 + + +简单的删除默认 StorageClass 可能行不通,因为它可能会被您集群中的扩展管理器自动重建。请查阅您的安装文档中关于扩展管理器的细节,以及如何禁用单个扩展。 + + +## 改变默认 StorageClass + + +1. 列出您集群中的 StorageClasses: + + kubectl get storageclass + + + 输出类似这样: + + NAME TYPE + standard (default) kubernetes.io/gce-pd + gold kubernetes.io/gce-pd + + + 默认 StorageClass 以 `(default)` 标记。 + + +2. 标记默认 StorageClass 非默认: + + + 默认 StorageClass 的注解 `storageclass.kubernetes.io/is-default-class` 设置为 `true`。注解的其它任意值或者缺省值将被解释为 `false`。 + + + 要标记一个 StorageClass 为非默认的,您需要改变它的值为 `false`: + + kubectl patch storageclass -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' + + + 这里的 `` 是您选择的 StorageClass 的名字。 + + +3. 标记一个 StorageClass 为默认的: + + + 和前面的步骤类似,您需要添加/设置注解 `storageclass.kubernetes.io/is-default-class=true`。 + + kubectl patch storageclass -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' + + + 请注意,最多只能有一个 StorageClass 能够被标记为默认。如果它们中有两个或多个被标记为默认,Kubernetes 将忽略这个注解,也就是它将表现为没有默认 StorageClass。 + + +4. 验证您选用的 StorageClass 为默认的: + + kubectl get storageclass + + + 输出类似这样: + + NAME TYPE + standard kubernetes.io/gce-pd + gold (default) kubernetes.io/gce-pd + +{% endcapture %} + +{% capture whatsnext %} + +* 了解更多关于 [StorageClasses](/docs/concepts/storage/persistent-volumes/)。 + {% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md b/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md new file mode 100644 index 0000000000..14844d903e --- /dev/null +++ b/cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md @@ -0,0 +1,80 @@ +--- +title: 更改 PersistentVolume 的回收策略 +--- + + +{% capture overview %} + +本文展示了如何更改 Kubernetes PersistentVolume 的回收策略。 +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture steps %} + + +## 为什么要更改 PersistentVolume 的回收策略 + + +`PersistentVolumes` 可以有多种回收策略,包括 "Retain"、"Recycle" 和 "Delete"。对于动态配置的 `PersistentVolumes` 来说,默认回收策略为 "Delete"。这表示当用户删除对应的 `PeristentVolumeClaim` 时,动态配置的 volume 将被自动删除。如果 volume 包含重要数据时,这种自动行为可能是不合适的。那种情况下,更适合使用 "Retain" 策略。使用 "Retain" 时,如果用户删除 `PersistentVolumeClaim`,对应的 `PersistentVolume` 不会被删除。相反,它将变为 `Released` 状态,表示所有的数据可以被手动恢复。 + + +## 更改 PersistentVolume 的回收策略 + + +1. 列出你集群中的 PersistentVolumes + + kubectl get pv + + 输出类似于这样: + + NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM REASON AGE + pvc-b6efd8da-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim1 10s + pvc-b95650f8-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim2 6s + pvc-bb3ca71d-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim3 3s + + + 这个列表同样包含了绑定到每个 volume 的 claims 名称,以便更容易的识别动态配置的 volumes。 + + +2. 选择你的 PersistentVolumes 中的一个并更改它的回收策略: + + kubectl patch pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' + + 这里的 `` 是你选择的 PersistentVolume 的名字。 + +3. 验证你选择的 PersistentVolume 拥有正确的策略: + + kubectl get pv + + 输出类似于这样: + + NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM REASON AGE + pvc-b6efd8da-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim1 40s + pvc-b95650f8-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim2 36s + pvc-bb3ca71d-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Retain Bound default/claim3 33s + + + 在前面的输出中,你可以看到绑定到 claim `default/claim3` 的 volume 拥有的回收策略为 `Retain`。当用户删除 claim `default/claim3` 时,它不会被自动删除。 + +{% endcapture %} + +{% capture whatsnext %} + +* 了解更多关于 [PersistentVolumes](/docs/concepts/storage/persistent-volumes/)的信息。 +* 了解更多关于 [PersistentVolumeClaims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) 的信息。 + + +### 参考 + +* [PersistentVolume](/docs/api-reference/{{page.version}}/#persistentvolume-v1-core) +* [PersistentVolumeClaim](/docs/api-reference/{{page.version}}/#persistentvolumeclaim-v1-core) + +* 查阅 [PersistentVolumeSpec](/docs/api-reference/{{page.version}}/#persistentvolumeclaim-v1-core) 的 `persistentVolumeReclaimPolicy` 字段。 +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/cluster-management.md b/cn/docs/tasks/administer-cluster/cluster-management.md new file mode 100644 index 0000000000..f492a2314d --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cluster-management.md @@ -0,0 +1,227 @@ +--- +approvers: +- lavalamp +- thockin +title: 集群管理 +--- + + +* TOC +{:toc} + + +本文描述了和集群生命周期相关的几个主题:创建新集群、更新集群的 master 和 worker 节点、执行节点维护(例如升级内核)以及升级运行中集群的 Kubernetes API 版本。 + + +## 创建和配置集群 + + +要在一组机器上安装 Kubernetes, 请根据您的环境,查阅现有的 [入门指南](/docs/getting-started-guides/) + + +## 升级集群 + + +集群升级当前是配套提供的,某些发布版本在升级时可能需要特殊处理。推荐管理员在升级他们的集群前,同时查阅 [发行说明](https://git.k8s.io/kubernetes/CHANGELOG.md) 和版本具体升级说明。 + + +* [升级到 1.6](/docs/admin/upgrade-1-6) + + +### 升级 Google Compute Engine 集群 + + +Google Compute Engine Open Source (GCE-OSS) 通过删除和重建 master 来支持 master 升级。通过维持相同的 Persistent Disk (PD) 以保证在升级过程中保留数据。 + + +GCE 的 Node 升级采用 [管理实例组](https://cloud.google.com/compute/docs/instance-groups/),每个节点将被顺序的删除,然后使用新软件重建。任何运行在那个节点上的 Pod 需要用 Replication Controller 控制,或者在扩容之后手动重建。 + + +开源 Google Compute Engine (GCE) 集群上的升级过程由 `cluster/gce/upgrade.sh` 脚本控制。 + + +运行 `cluster/gce/upgrade.sh -h` 获取使用说明。 + + +例如,只将 master 升级到一个指定的版本 (v1.0.2): + +```shell +cluster/gce/upgrade.sh -M v1.0.2 +``` + + +或者,将整个集群升级到最新的稳定版本: + +```shell +cluster/gce/upgrade.sh release/stable +``` + + +### 升级 Google Container Engine (GKE) 集群 + + +Google Container Engine 自动升级 master 组件(例如 `kube-apiserver`、`kube-scheduler`)至最新版本。它还负责 master 运行的操作系统和其它组件。 + + +节点升级过程由用户初始化,[GKE 文档](https://cloud.google.com/container-engine/docs/clusters/upgrade) 里有相关描述。 + + +### 在其他平台上升级集群 + + +不同的供应商和工具管理升级的过程各不相同。建议您查阅它们有关升级的主要文档。 + +* [kops](https://github.com/kubernetes/kops) +* [kubespray](https://github.com/kubernetes-incubator/kubespray) +* [CoreOS Tectonic](https://coreos.com/tectonic/docs/latest/admin/upgrade.html) +* ... + + +## 调整集群大小 + + +如果集群资源短缺,您可以轻松的添加更多的机器,如果集群正运行在[节点自注册模式](/docs/admin/node/#self-registration-of-nodes)下的话。如果正在使用的是 GCE 或者 GKE,这将通过调整管理节点的实例组的大小完成。在 [Google Cloud Console page](https://console.developers.google.com) 的 `Compute > Compute Engine > Instance groups > your group > Edit group` 下修改实例数量或使用 gcloud CLI 都可以完成这个任务。 + +```shell +gcloud compute instance-groups managed resize kubernetes-minion-group --size 42 --zone $ZONE +``` + + +实例组将负责在新机器上放置恰当的镜像并启动它们。Kubelet 将向 API server 注册它的节点以使其可以用于调度。如果您对 instance group 进行缩容,系统将会随机选取节点来终止。 + + +在其他环境上,您可能需要手动配置机器并告诉 Kubelet API server 在哪台机器上运行。 + + +### 集群自动伸缩 + + +如果正在使用 GCE 或者 GKE,您可以配置您的集群,使其能够基于 pod 需求自动重新调整大小。 + + +如 [Compute Resource](/docs/concepts/configuration/manage-compute-resources-container/) 所述,用户可以控制预留多少 CPU 和内存来分配给 pod。这个信息被 Kubernetes scheduler 用来寻找一个运行 pod 的地方。如果没有一个节点有足够的空闲容量(或者不能满足其他 pod 的需求),这个 pod 就需要等待某些 pod 结束,或者一个新的节点被添加。 + + +集群 autoscaler 查找不能被调度的 pod 并检查添加一个新节点(和集群中其它节点类似的)是否有帮助。如果是的话,它将调整集群的大小以容纳等待调度的 pod。 + + +如果发现在一段延时时间内(默认10分钟,将来有可能改变)某些节点不再需要,集群 autoscaler 也会缩小集群。 + + +集群 autoscaler 在每一个实例组(GCE)或节点池(GKE)上配置。 + + +如果您使用 GCE,那么您可以在使用 kube-up.sh 脚本创建集群的时候启用它。要想配置集群 autoscaler,您需要设置三个环境变量: + + +* `KUBE_ENABLE_CLUSTER_AUTOSCALER` - 如果设置为 true 将启用集群 autoscaler。 +* `KUBE_AUTOSCALER_MIN_NODES` - 集群的最小节点数量。 +* `KUBE_AUTOSCALER_MAX_NODES` - 集群的最大节点数量。 + + +示例: + +```shell +KUBE_ENABLE_CLUSTER_AUTOSCALER=true KUBE_AUTOSCALER_MIN_NODES=3 KUBE_AUTOSCALER_MAX_NODES=10 NUM_NODES=5 ./cluster/kube-up.sh +``` + + +在 GKE 上,您可以在创建、更新集群或创建一个特别的节点池(您希望自动伸缩的)时,通过给对应的 `gcloud` 命令传递 `--enable-autoscaling` `--min-nodes` 和 `--max-nodes` 来配置集群 autoscaler。 + + +示例: + +```shell +gcloud container clusters create mytestcluster --zone=us-central1-b --enable-autoscaling --min-nodes=3 --max-nodes=10 --num-nodes=5 +``` + +```shell +gcloud container clusters update mytestcluster --enable-autoscaling --min-nodes=1 --max-nodes=15 +``` + + +**集群 autoscaler 期望节点未被手动修改过(例如通过 kubectl 添加标签),因为那些属性可能不能被传递到相同节点组中的新节点上。** + + +## 维护节点 + + +如果需要重启节点(例如内核升级、libc 升级、硬件维修等),且停机时间很短时,当 Kubelet 重启后,它将尝试重启调度到节点上的 pod。如果重启花费较长时间(默认时间为 5 分钟,由 controller-manager 的 `--pod-eviction-timeout` 控制),节点控制器将会结束绑定到这个不可用节点上的 pod。如果存在对应的 replica set(或者 replication controller)时,则将在另一个节点上启动 pod 的新副本。所以,如果所有的 pod 都是复制而来,那么在不是所有节点都同时停机的前提下,升级可以在不需要特殊调整情况下完成。 + + +如果您希望更多的控制升级过程,可以使用下面的工作流程: + + +使用 `kubectl drain` 优雅的结束节点上的所有 pod 并同时标记节点为不可调度: + +```shell +kubectl drain $NODENAME +``` + + +在您正试图使节点离线时,这将阻止新的 pod 落到它们上面。 + + +对于有 replica set 的 pod 来说,它们将会被新的 pod 替换并且将被调度到一个新的节点。此外,如果 pod 是一个 service 的一部分,则客户端将被自动重定向到新的 pod。 + + +对于没有 replica set 的 pod,您需要手动启动 pod 的新副本,并且如果它不是 service 的一部分,您需要手动将客户端重定向到这个 pod。 + + +在节点上执行维护工作。 + + +重新使节点可调度: + +```shell +kubectl uncordon $NODENAME +``` + + +如果删除了节点的虚拟机实例并重新创建,那么一个新的可调度节点资源将被自动创建(只在您使用支持节点发现的云服务提供商时;当前只有 Google Compute Engine,不包括在 Google Compute Engine 上使用 kube-register 的 CoreOS)。相关详细信息,请查阅 [节点](/docs/admin/node)。 + + +## 高级主题 + + +### 升级到不同的 API 版本 + + +当新的 API 版本发布时,您可能需要升级集群支持新的 API 版本(例如当 'v2' 发布时从 'v1' 切换到 'v2')。 + + +这不是一个经常性的事件,但需要谨慎的处理。这里有一系列升级到新 API 版本的步骤。 + + 1. 开启新 API 版本。 + 2. 升级集群存储来使用新版本。 + 3. 升级所有配置文件。识别使用旧 API 版本 endpoint 的用户。 + 4. 运行 `cluster/update-storage-objects.sh` 升级存储中的现有对象为新版本。 + 5. 关闭旧 API 版本。 + + +### 打开或关闭集群的 API 版本 + + +可以在启动 API server 时传递 `--runtime-config=api/` 标志来打开或关闭特定的 API 版本。例如:要关闭 v1 API,请传递 `--runtime-config=api/v1=false`。运行时配置还支持两个特殊键值:api/all 和 api/legacy,分别控制全部和遗留 API。例如要关闭除 v1 外全部 API 版本,请传递 `--runtime-config=api/all=false,api/v1=true`。对于这些标志来说,_legacy_ API 指那些被显式废弃的 API(例如 `v1beta3`)。 + + +### 切换集群存储的 API 版本 + + +存储于磁盘中,用于在集群内部代表 Kubernetes 活跃资源的对象使用特定的 API 版本书写。当支撑的 API 改变时,这些对象可能需要使用更新的 API 重写。重写失败将最终导致资源不再能够被 Kubernetes API server 解析或使用。 + + +`kube-apiserver` 二进制文件的 `KUBE_API_VERSIONS` 环境变量控制了集群支持的 API 版本。列表中的第一个版本被用作集群的存储版本。因此,要设置特定的版本为存储版本,请将其放在 `KUBE_API_VERSIONS` 参数值版本列表的最前面。您需要重启 `kube-apiserver` 二进制以使这个变量的改动生效。 + + +### 切换配置文件为新 API 版本 + + +可以使用 `kubectl convert` 命令对不同 API 版本的配置文件进行转换。 + +```shell +kubectl convert -f pod.yaml --output-version v1 +``` + + +更多选项请参考 [kubectl convert](/docs/user-guide/kubectl/v1.6/#convert) 命令用法。 From eac3d83e94643d317cbcb631954fb1244b49fb3b Mon Sep 17 00:00:00 2001 From: Jesse Kinkead Date: Sat, 9 Sep 2017 09:48:50 -0700 Subject: [PATCH 029/102] Complete documentation of SSL-on-AWS. (#5357) The SSL-on-AWS documentation was missing a critical annotation, without which SSL termination doesn't work (all ports are configured to use SSL). This also fixes the indentation of the existing YAML. --- docs/concepts/services-networking/service.md | 54 ++++++++++++++++---- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/docs/concepts/services-networking/service.md b/docs/concepts/services-networking/service.md index c566b42047..1d348bd60c 100644 --- a/docs/concepts/services-networking/service.md +++ b/docs/concepts/services-networking/service.md @@ -479,25 +479,25 @@ metadata: {% include tabs.md %} #### SSL support on AWS -For partial SSL support on clusters running on AWS, starting with 1.3 two +For partial SSL support on clusters running on AWS, starting with 1.3 three annotations can be added to a `LoadBalancer` service: ``` - metadata: - name: my-service - annotations: - service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 ``` -The first specifies which certificate to use. It can be either a +The first specifies the ARN of the certificate to use. It can be either a certificate from a third party issuer that was uploaded to IAM or one created within AWS Certificate Manager. ```yaml - metadata: - name: my-service - annotations: - service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp) +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp) ``` The second annotation specifies which protocol a pod speaks. For HTTPS and @@ -512,6 +512,40 @@ ELB at the other end of its connection) when forwarding requests. TCP and SSL will select layer 4 proxying: the ELB will forward traffic without modifying the headers. +```yaml +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: (comma-separated-port-names) +``` + +The third annotation indicates which port(s) should accept SSL traffic on the ELB. If a certificate is set on the +Service, the default is to configure all ports on the ELB to use SSL. This is not typically desired for HTTP servers. + +A complete HTTP Service supporting SSL might look like: + +```yaml +kind: Service +apiVersion: v1 +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" +spec: + type: LoadBalancer + ports: + - port: 80 + name: http + targetPort: 8080 + - port: 443 + name: https + targetPort: 8080 + selector: + app: MyApp +``` + ### External IPs If there are external IPs that route to one or more cluster nodes, Kubernetes services can be exposed on those From 7f83f2be59ec78280d962eb4881ee2d63f89506d Mon Sep 17 00:00:00 2001 From: Tony-CCIE <1278146756@qq.com> Date: Sun, 10 Sep 2017 00:50:45 +0800 Subject: [PATCH 030/102] k8smeetup-admin-ovs-networking-pr-2017-07-15 (#5356) * admin-ovs-networking-pr-2017-07-15 * Update ovs-networking.md --- cn/docs/admin/ovs-networking.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 cn/docs/admin/ovs-networking.md diff --git a/cn/docs/admin/ovs-networking.md b/cn/docs/admin/ovs-networking.md new file mode 100644 index 0000000000..7153f2a7b1 --- /dev/null +++ b/cn/docs/admin/ovs-networking.md @@ -0,0 +1,22 @@ +--- +assignees: +- 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网桥到达目标。 + + + + From 4a55e281661a29c2bb37401141c47b349587087d Mon Sep 17 00:00:00 2001 From: Sylvain WITMEYER Date: Sat, 9 Sep 2017 22:41:45 -0400 Subject: [PATCH 031/102] Label can't have whitespaces (#4086) My nvidia GPU name was "GeForce GTX 1070" which isn't a correct label "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character" --- docs/tasks/manage-gpus/scheduling-gpus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/manage-gpus/scheduling-gpus.md b/docs/tasks/manage-gpus/scheduling-gpus.md index 8981bc5a31..fa701e4cfa 100644 --- a/docs/tasks/manage-gpus/scheduling-gpus.md +++ b/docs/tasks/manage-gpus/scheduling-gpus.md @@ -60,7 +60,7 @@ Following is an illustration of this workflow: As part of your Node bootstrapping, identify the GPU hardware type on your nodes and expose it as a node label. ```shell -NVIDIA_GPU_NAME=$(nvidia-smi --query-gpu=gpu_name --format=csv,noheader --id=0) +NVIDIA_GPU_NAME=$(nvidia-smi --query-gpu=gpu_name --format=csv,noheader --id=0 | sed -e 's/ /-/g') source /etc/default/kubelet KUBELET_OPTS="$KUBELET_OPTS --node-labels='alpha.kubernetes.io/nvidia-gpu-name=$NVIDIA_GPU_NAME'" echo "KUBELET_OPTS=$KUBELET_OPTS" > /etc/default/kubelet From 3e49e008ccec4c0ae144b9ae456e7edba4ad0d0c Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 10 Sep 2017 18:07:38 +0800 Subject: [PATCH 032/102] Update bare_metal_offline.md Fix format. --- .../coreos/bare_metal_offline.md | 186 ++++++++---------- 1 file changed, 83 insertions(+), 103 deletions(-) diff --git a/docs/getting-started-guides/coreos/bare_metal_offline.md b/docs/getting-started-guides/coreos/bare_metal_offline.md index a471d2db8d..0dec61168f 100644 --- a/docs/getting-started-guides/coreos/bare_metal_offline.md +++ b/docs/getting-started-guides/coreos/bare_metal_offline.md @@ -42,154 +42,134 @@ To setup CentOS PXELINUX environment there is a complete [guide here](http://doc 1. Install packages needed on CentOS -```shell -sudo yum install tftp-server dhcp syslinux -``` + sudo yum install tftp-server dhcp syslinux 2. `vi /etc/xinetd.d/tftp` to enable tftp service and change disable to 'no' -```conf -disable = no -``` + go get github.com/vmware/photon-controller-cli/photon 3. Copy over the syslinux images we will need. -```shell -su - -mkdir -p /tftpboot -cd /tftpboot -cp /usr/share/syslinux/pxelinux.0 /tftpboot -cp /usr/share/syslinux/menu.c32 /tftpboot -cp /usr/share/syslinux/memdisk /tftpboot -cp /usr/share/syslinux/mboot.c32 /tftpboot -cp /usr/share/syslinux/chain.c32 /tftpboot + su - + mkdir -p /tftpboot + cd /tftpboot + cp /usr/share/syslinux/pxelinux.0 /tftpboot + cp /usr/share/syslinux/menu.c32 /tftpboot + cp /usr/share/syslinux/memdisk /tftpboot + cp /usr/share/syslinux/mboot.c32 /tftpboot + cp /usr/share/syslinux/chain.c32 /tftpboot -/sbin/service dhcpd start -/sbin/service xinetd start -/sbin/chkconfig tftp on -``` + /sbin/service dhcpd start + /sbin/service xinetd start + /sbin/chkconfig tftp on 4. Setup default boot menu -```shell -mkdir /tftpboot/pxelinux.cfg -touch /tftpboot/pxelinux.cfg/default -``` + mkdir /tftpboot/pxelinux.cfg + touch /tftpboot/pxelinux.cfg/default 5. Edit the menu `vi /tftpboot/pxelinux.cfg/default` -```conf -default menu.c32 -prompt 0 -timeout 15 -ONTIMEOUT local -display boot.msg + default menu.c32 + prompt 0 + timeout 15 + ONTIMEOUT local + display boot.msg -MENU TITLE Main Menu + MENU TITLE Main Menu -LABEL local - MENU LABEL Boot local hard drive - LOCALBOOT 0 -``` + LABEL local + MENU LABEL Boot local hard drive + LOCALBOOT 0 Now you should have a working PXELINUX setup to image CoreOS nodes. You can verify the services by using VirtualBox locally or with bare metal servers. ## Adding CoreOS to PXE This section describes how to setup the CoreOS images to live alongside a pre-existing PXELINUX environment. - 1. Find or create the TFTP root directory that everything will be based on. - * For this document we will assume `/tftpboot/` is our root directory. -2. Once we know and have our tftp root directory we will create a new directory structure for our CoreOS images. + - For this document we will assume `/tftpboot/` is our root directory. +2. Once we know and have our tftp root directory we will create a new directory structure for our CoreOS images. 3. Download the CoreOS PXE files provided by the CoreOS team. -```shell -MY_TFTPROOT_DIR=/tftpboot -mkdir -p $MY_TFTPROOT_DIR/images/coreos/ -cd $MY_TFTPROOT_DIR/images/coreos/ -wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz -wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz.sig -wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz -wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz.sig -gpg --verify coreos_production_pxe.vmlinuz.sig -gpg --verify coreos_production_pxe_image.cpio.gz.sig -``` + MY_TFTPROOT_DIR=/tftpboot + mkdir -p $MY_TFTPROOT_DIR/images/coreos/ + cd $MY_TFTPROOT_DIR/images/coreos/ + wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz + wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz.sig + wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz + wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz.sig + gpg --verify coreos_production_pxe.vmlinuz.sig + gpg --verify coreos_production_pxe_image.cpio.gz.sig 4. Edit the menu `vi /tftpboot/pxelinux.cfg/default` again -```conf -default menu.c32 -prompt 0 -timeout 300 -ONTIMEOUT local -display boot.msg + default menu.c32 + prompt 0 + timeout 300 + ONTIMEOUT local + display boot.msg -MENU TITLE Main Menu + MENU TITLE Main Menu -LABEL local - MENU LABEL Boot local hard drive - LOCALBOOT 0 + LABEL local + MENU LABEL Boot local hard drive + LOCALBOOT 0 -MENU BEGIN CoreOS Menu + MENU BEGIN CoreOS Menu - LABEL coreos-master - MENU LABEL CoreOS Master - KERNEL images/coreos/coreos_production_pxe.vmlinuz - APPEND initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///pxe-cloud-config-single-master.yml + LABEL coreos-master + MENU LABEL CoreOS Master + KERNEL images/coreos/coreos_production_pxe.vmlinuz + APPEND initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///pxe-cloud-config-single-master.yml - LABEL coreos-slave - MENU LABEL CoreOS Slave - KERNEL images/coreos/coreos_production_pxe.vmlinuz - APPEND initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///pxe-cloud-config-slave.yml -MENU END -``` + LABEL coreos-slave + MENU LABEL CoreOS Slave + KERNEL images/coreos/coreos_production_pxe.vmlinuz + APPEND initrd=images/coreos/coreos_production_pxe_image.cpio.gz cloud-config-url=http:///pxe-cloud-config-slave.yml + MENU END This configuration file will now boot from local drive but have the option to PXE image CoreOS. ## DHCP configuration This section covers configuring the DHCP server to hand out our new images. In this case we are assuming that there are other servers that will boot alongside other images. - 1. Add the `filename` to the _host_ or _subnet_ sections. -```conf -filename "/tftpboot/pxelinux.0"; -``` + filename "/tftpboot/pxelinux.0"; 2. At this point we want to make pxelinux configuration files that will be the templates for the different CoreOS deployments. -```conf -subnet 10.20.30.0 netmask 255.255.255.0 { - next-server 10.20.30.242; - option broadcast-address 10.20.30.255; - filename ""; + subnet 10.20.30.0 netmask 255.255.255.0 { + next-server 10.20.30.242; + option broadcast-address 10.20.30.255; + filename ""; - ... - # http://www.syslinux.org/wiki/index.php/PXELINUX - host core_os_master { - hardware ethernet d0:00:67:13:0d:00; - option routers 10.20.30.1; - fixed-address 10.20.30.40; - option domain-name-servers 10.20.30.242; - filename "/pxelinux.0"; + ... + # http://www.syslinux.org/wiki/index.php/PXELINUX + host core_os_master { + hardware ethernet d0:00:67:13:0d:00; + option routers 10.20.30.1; + fixed-address 10.20.30.40; + option domain-name-servers 10.20.30.242; + filename "/pxelinux.0"; + } + host core_os_slave { + hardware ethernet d0:00:67:13:0d:01; + option routers 10.20.30.1; + fixed-address 10.20.30.41; + option domain-name-servers 10.20.30.242; + filename "/pxelinux.0"; + } + host core_os_slave2 { + hardware ethernet d0:00:67:13:0d:02; + option routers 10.20.30.1; + fixed-address 10.20.30.42; + option domain-name-servers 10.20.30.242; + filename "/pxelinux.0"; + } + ... } - host core_os_slave { - hardware ethernet d0:00:67:13:0d:01; - option routers 10.20.30.1; - fixed-address 10.20.30.41; - option domain-name-servers 10.20.30.242; - filename "/pxelinux.0"; - } - host core_os_slave2 { - hardware ethernet d0:00:67:13:0d:02; - option routers 10.20.30.1; - fixed-address 10.20.30.42; - option domain-name-servers 10.20.30.242; - filename "/pxelinux.0"; - } - ... -} -``` We will be specifying the node configuration later in the guide. From e96a9f992cbe0beedc518cbc1a03d4150beaddf1 Mon Sep 17 00:00:00 2001 From: Abdullah Al Maruf - Tuhin Date: Mon, 11 Sep 2017 03:38:49 +0600 Subject: [PATCH 033/102] Fix Typos --- docs/admin/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/admin/authentication.md b/docs/admin/authentication.md index 4a2fb19195..b0f4467527 100644 --- a/docs/admin/authentication.md +++ b/docs/admin/authentication.md @@ -549,7 +549,7 @@ checked. Keystone authentication is enabled by passing the `--experimental-keystone-url=` option to the API server during startup. The plugin is implemented in `plugin/pkg/auth/authenticator/password/keystone/keystone.go` and currently uses -basic auth to verify used by username and password. +basic auth to verify user by username and password. If you have configured self-signed certificates for the Keystone server, you may need to set the `--experimental-keystone-ca-file=SOMEFILE` option when From 94d9e2759717bd2073e6cea0b19aa9acd761bfb5 Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Mon, 11 Sep 2017 07:59:24 +0800 Subject: [PATCH 034/102] Update bare_metal_offline.md Fix copy error. --- docs/getting-started-guides/coreos/bare_metal_offline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/coreos/bare_metal_offline.md b/docs/getting-started-guides/coreos/bare_metal_offline.md index 0dec61168f..c7684f73b2 100644 --- a/docs/getting-started-guides/coreos/bare_metal_offline.md +++ b/docs/getting-started-guides/coreos/bare_metal_offline.md @@ -46,7 +46,7 @@ To setup CentOS PXELINUX environment there is a complete [guide here](http://doc 2. `vi /etc/xinetd.d/tftp` to enable tftp service and change disable to 'no' - go get github.com/vmware/photon-controller-cli/photon + -disable = no 3. Copy over the syslinux images we will need. From f9f9d60c84289127b6b15fafed8d32e21301f996 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Fri, 8 Sep 2017 14:19:14 +0800 Subject: [PATCH 035/102] run-application-scale-stateful-set-2017-09-08 --- .../run-application/scale-stateful-set.md | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 cn/docs/tasks/run-application/scale-stateful-set.md diff --git a/cn/docs/tasks/run-application/scale-stateful-set.md b/cn/docs/tasks/run-application/scale-stateful-set.md new file mode 100644 index 0000000000..94c750b25c --- /dev/null +++ b/cn/docs/tasks/run-application/scale-stateful-set.md @@ -0,0 +1,88 @@ +--- +approvers: +- bprashanth +- enisoc +- erictune +- foxish +- janetkuo +- kow3ns +- smarterclayton +title: 伸缩StatefulSet +--- + +{% capture overview %} +本文介绍如何伸缩StatefulSet. +{% endcapture %} + +{% capture prerequisites %} + +* StatefulSets仅适用于Kubernetes1.5版本或高于1.5. +* **不是所有stateful applications都适合伸缩.** 在伸缩前您必须了解您的StatefulSets应用. 如果您不确定, 请记住伸缩该StatefulSets也许不安全. +* 仅当您确定该stateful应用的集群是完全健康才可执行伸缩操作. + +{% endcapture %} + +{% capture steps %} + +## 使用 `kubectl` 伸缩StatefulSets + +伸缩前确保 `kubectl` 已升级至Kubernetes1.5版本或高于1.5. 如果不确定, 执行 `kubectl version` 命令并检查使用的 `Client Version`. + +### `kubectl 伸缩` + +首先, 找到您想要伸缩的StatefulSet. 记住, 您需先清楚是否能伸缩该应用. + +```shell +kubectl get statefulsets +``` + +改变StatefulSet副本数量: + +```shell +kubectl scale statefulsets --replicas= +``` + +### 可使用其他命令: `kubectl apply` / `kubectl edit` / `kubectl patch` + +另外, 您可以 [in-place updates](/docs/concepts/cluster-administration/manage-deployment/#in-place-updates-of-resources) StatefulSets. + +如果您的StatefulSet开始由 `kubectl apply` 或 `kubectl create --save-config`创建, +更新StatefulSet manifests中的 `.spec.replicas`, 然后执行命令 `kubectl apply`: + +```shell +kubectl apply -f +``` + +除此之外, 可以通过命令 `kubectl edit`编辑该字段: + +```shell +kubectl edit statefulsets +``` + +或使用 `kubectl patch`: + +```shell +kubectl patch statefulsets -p '{"spec":{"replicas":}}' +``` + +## 排查故障 + +### 缩容工作不正常 + +当stateful管理下的任何一个Pod不健康时您不能缩容该StatefulSet. 仅当stateful下的所有Pods都处于运行和ready状态后才可缩容. + +当一个StatefulSet的size > 1, 如果有一个不健康的Pod, 没有办法让Kubernetes知道是否是由于永久性故障还是瞬态(升级/维护/节点重启)导致. 如果该Pod不健康是由于永久性 +故障导致, 则在不纠正该故障的情况下进行缩容可能会导致一种状态, 即StatefulSet下的Pod数量低于应正常运行的副本数. 这也许会导致StatefulSet变成不可用. + +如果由于瞬态故障而导致Pod不健康,并且Pod可能再次可用,那么瞬态错误可能会干扰您对StatefulSet的扩容/缩容操作. 一些分布式数据库在节点加入和同时离开时存在问题. 在这些情况下,最好是在应用级别进行伸缩操作, 并且只有在您确保stateful应用的集群是完全健康时才执行伸缩. + + +{% endcapture %} + +{% capture whatsnext %} + +了解更多 [deleting a StatefulSet](/docs/tasks/manage-stateful-set/deleting-a-statefulset/). + +{% endcapture %} + +{% include templates/task.md %} From f482482d72d390903bf0d89199989a87b9ae25a8 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Mon, 11 Sep 2017 09:56:49 +0800 Subject: [PATCH 036/102] run-application-scale-stateful-set-pr-2017-09-11 --- .../run-application/scale-stateful-set.md | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/cn/docs/tasks/run-application/scale-stateful-set.md b/cn/docs/tasks/run-application/scale-stateful-set.md index 94c750b25c..508b484bef 100644 --- a/cn/docs/tasks/run-application/scale-stateful-set.md +++ b/cn/docs/tasks/run-application/scale-stateful-set.md @@ -7,18 +7,18 @@ approvers: - janetkuo - kow3ns - smarterclayton -title: 伸缩StatefulSet +title: 弹缩StatefulSet --- {% capture overview %} -本文介绍如何伸缩StatefulSet. +本文介绍如何弹缩StatefulSet. {% endcapture %} {% capture prerequisites %} -* StatefulSets仅适用于Kubernetes1.5版本或高于1.5. -* **不是所有stateful applications都适合伸缩.** 在伸缩前您必须了解您的StatefulSets应用. 如果您不确定, 请记住伸缩该StatefulSets也许不安全. -* 仅当您确定该stateful应用的集群是完全健康才可执行伸缩操作. +* StatefulSets仅适用于Kubernetes1.5及以上版本. +* **不是所有Stateful应用都适合弹缩.** 在弹缩前您的应用前. 您必须充分了解您的应用, 不适当的弹缩StatefulSet或许会造成应用自身功能的不稳定. +* 仅当您确定该Stateful应用的集群是完全健康才可执行弹缩操作. {% endcapture %} @@ -26,11 +26,11 @@ title: 伸缩StatefulSet ## 使用 `kubectl` 伸缩StatefulSets -伸缩前确保 `kubectl` 已升级至Kubernetes1.5版本或高于1.5. 如果不确定, 执行 `kubectl version` 命令并检查使用的 `Client Version`. +弹缩请确认 `kubectl` 已经升级到Kubernetes1.5及以上版本. 如果不确定, 执行 `kubectl version` 命令并检查使用的 `Client Version`. -### `kubectl 伸缩` +### `kubectl 弹缩` -首先, 找到您想要伸缩的StatefulSet. 记住, 您需先清楚是否能伸缩该应用. +首先, 找到您想要弹缩的StatefulSet. 记住, 您需先清楚是否能弹缩该应用. ```shell kubectl get statefulsets @@ -53,7 +53,7 @@ kubectl scale statefulsets --replicas= kubectl apply -f ``` -除此之外, 可以通过命令 `kubectl edit`编辑该字段: +除此之外, 可以通过命令 `kubectl edit` 编辑该字段: ```shell kubectl edit statefulsets @@ -69,12 +69,13 @@ kubectl patch statefulsets -p '{"spec":{"replicas": 1, 如果有一个不健康的Pod, 没有办法让Kubernetes知道是否是由于永久性故障还是瞬态(升级/维护/节点重启)导致. 如果该Pod不健康是由于永久性 -故障导致, 则在不纠正该故障的情况下进行缩容可能会导致一种状态, 即StatefulSet下的Pod数量低于应正常运行的副本数. 这也许会导致StatefulSet变成不可用. +当一个StatefulSet的size > 1, 如果有一个Pod不健康, 没有办法让Kubernetes知道是否是由于永久性故障还是瞬态(升级/维护/节点重启)导致. 如果该Pod不健康是由于永久性 +故障导致, 则在不纠正该故障的情况下进行缩容可能会导致一种状态, 即StatefulSet下的Pod数量低于应正常运行的副本数. 这也许会导致StatefulSet不可用. -如果由于瞬态故障而导致Pod不健康,并且Pod可能再次可用,那么瞬态错误可能会干扰您对StatefulSet的扩容/缩容操作. 一些分布式数据库在节点加入和同时离开时存在问题. 在这些情况下,最好是在应用级别进行伸缩操作, 并且只有在您确保stateful应用的集群是完全健康时才执行伸缩. +如果由于瞬态故障而导致Pod不健康,并且Pod可能再次可用,那么瞬态错误可能会干扰您对StatefulSet的扩容/缩容操作. 一些分布式数据库在节点加入和同时离开时存在问题. 在 +这些情况下,最好是在应用级别进行弹缩操作, 并且只有在您确保Stateful应用的集群是完全健康时才执行弹缩. {% endcapture %} From c9e835c66e9c62e1fa3f6adce1ce3cdbd27b7e38 Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Mon, 11 Sep 2017 10:33:56 +0800 Subject: [PATCH 037/102] fix typo fix typo --- docs/tasks/administer-cluster/kubeadm-upgrade-1-7.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tasks/administer-cluster/kubeadm-upgrade-1-7.md b/docs/tasks/administer-cluster/kubeadm-upgrade-1-7.md index 23049680ee..a78cc683b5 100644 --- a/docs/tasks/administer-cluster/kubeadm-upgrade-1-7.md +++ b/docs/tasks/administer-cluster/kubeadm-upgrade-1-7.md @@ -42,7 +42,7 @@ You need to have a Kubernetes cluster running version 1.6.x. 2. Restart kubelet. - sudo systemctl restart kubelet + systemctl restart kubelet 3. Delete the `kube-proxy` DaemonSet. @@ -88,7 +88,7 @@ You need to have a Kubernetes cluster running version 1.6.x. 2. Restart kubelet. - sudo systemctl restart kubelet + systemctl restart kubelet {% endcapture %} From 4165c64a8e7dc35063f6dce7031a0a69024e097d Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Mon, 11 Sep 2017 13:44:08 +0800 Subject: [PATCH 038/102] run-application-scale-stateful-set-pr-2017-09-11-13 --- cn/docs/tasks/run-application/scale-stateful-set.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cn/docs/tasks/run-application/scale-stateful-set.md b/cn/docs/tasks/run-application/scale-stateful-set.md index 508b484bef..9262faae2e 100644 --- a/cn/docs/tasks/run-application/scale-stateful-set.md +++ b/cn/docs/tasks/run-application/scale-stateful-set.md @@ -24,7 +24,7 @@ title: 弹缩StatefulSet {% capture steps %} -## 使用 `kubectl` 伸缩StatefulSets +## 使用 `kubectl` 弹缩StatefulSets 弹缩请确认 `kubectl` 已经升级到Kubernetes1.5及以上版本. 如果不确定, 执行 `kubectl version` 命令并检查使用的 `Client Version`. @@ -46,8 +46,7 @@ kubectl scale statefulsets --replicas= 另外, 您可以 [in-place updates](/docs/concepts/cluster-administration/manage-deployment/#in-place-updates-of-resources) StatefulSets. -如果您的StatefulSet开始由 `kubectl apply` 或 `kubectl create --save-config`创建, -更新StatefulSet manifests中的 `.spec.replicas`, 然后执行命令 `kubectl apply`: +如果您的StatefulSet开始由 `kubectl apply` 或 `kubectl create --save-config` 创建,更新StatefulSet manifests中的 `.spec.replicas`, 然后执行命令 `kubectl apply`: ```shell kubectl apply -f @@ -74,7 +73,8 @@ kubectl patch statefulsets -p '{"spec":{"replicas": 1, 如果有一个Pod不健康, 没有办法让Kubernetes知道是否是由于永久性故障还是瞬态(升级/维护/节点重启)导致. 如果该Pod不健康是由于永久性 故障导致, 则在不纠正该故障的情况下进行缩容可能会导致一种状态, 即StatefulSet下的Pod数量低于应正常运行的副本数. 这也许会导致StatefulSet不可用. -如果由于瞬态故障而导致Pod不健康,并且Pod可能再次可用,那么瞬态错误可能会干扰您对StatefulSet的扩容/缩容操作. 一些分布式数据库在节点加入和同时离开时存在问题. 在 +如果由于瞬态故障而导致Pod不健康,并且Pod可能再次可用,那么瞬态错误可能会干扰您对 +StatefulSet的扩容/缩容操作. 一些分布式数据库在节点加入和同时离开时存在问题. 在 这些情况下,最好是在应用级别进行弹缩操作, 并且只有在您确保Stateful应用的集群是完全健康时才执行弹缩. From 010449ee60fb2424ae4852b3af1ad4adc01d3ce1 Mon Sep 17 00:00:00 2001 From: Johannes 'fish' Ziemke Date: Mon, 11 Sep 2017 17:54:35 +0200 Subject: [PATCH 039/102] Fix configmaps resource name in rbac.md (#5389) The resource is 'configmaps', not 'configmap'. --- docs/admin/authorization/rbac.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/admin/authorization/rbac.md b/docs/admin/authorization/rbac.md index 5e7ce7de5d..5eae556f61 100644 --- a/docs/admin/authorization/rbac.md +++ b/docs/admin/authorization/rbac.md @@ -181,7 +181,7 @@ metadata: name: configmap-updater rules: - apiGroups: [""] - resources: ["configmap"] + resources: ["configmaps"] resourceNames: ["my-configmap"] verbs: ["update", "get"] ``` From be8ea1e37cbf658c1240c68da45e14da1a8e6fb2 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Mon, 11 Sep 2017 23:58:47 +0800 Subject: [PATCH 040/102] Elaborate the scheme field in httpGet (#5386) --- .../configure-liveness-readiness-probes.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md b/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md index a842c449cd..9ae8da1f1e 100644 --- a/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md +++ b/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md @@ -268,7 +268,7 @@ have additional fields that can be set on `httpGet`: * `host`: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. -* `scheme`: Scheme to use for connecting to the host. Defaults to HTTP. +* `scheme`: Scheme to use for connecting to the host (HTTP or HTTPS). Defaults to HTTP. * `path`: Path to access on the HTTP server. * `httpHeaders`: Custom headers to set in the request. HTTP allows repeated headers. * `port`: Name or number of the port to access on the container. Number must be @@ -276,12 +276,13 @@ in the range 1 to 65535. For an HTTP probe, the kubelet sends an HTTP request to the specified path and port to perform the check. The kubelet sends the probe to the container’s IP address, -unless the address is overridden by the optional `host` field in `httpGet`. -In most scenarios, you do not want to set the `host` field. Here's one scenario -where you would set it. Suppose the Container listens on 127.0.0.1 and the Pod's -`hostNetwork` field is true. Then `host`, under `httpGet`, should be set to 127.0.0.1. -If your pod relies on virtual hosts, which is probably the more common case, -you should not use `host`, but rather set the `Host` header in `httpHeaders`. +unless the address is overridden by the optional `host` field in `httpGet`. If +`scheme` field is set to `HTTPS`, the kubelet sends an HTTPS request skipping the +certificate verification. In most scenarios, you do not want to set the `host` field. +Here's one scenario where you would set it. Suppose the Container listens on 127.0.0.1 +and the Pod's `hostNetwork` field is true. Then `host`, under `httpGet`, should be set +to 127.0.0.1. If your pod relies on virtual hosts, which is probably the more common +case, you should not use `host`, but rather set the `Host` header in `httpHeaders`. {% endcapture %} From 51104cb1fc0605d1800a79303a16ddb0b04f0f90 Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Tue, 12 Sep 2017 00:00:38 +0800 Subject: [PATCH 041/102] fix the command output (#5380) fix the command output --- docs/tasks/administer-cluster/namespaces.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/tasks/administer-cluster/namespaces.md b/docs/tasks/administer-cluster/namespaces.md index eee6e75e46..c59da6b890 100644 --- a/docs/tasks/administer-cluster/namespaces.md +++ b/docs/tasks/administer-cluster/namespaces.md @@ -42,9 +42,10 @@ Or you can get detailed information with: ```shell $ kubectl describe namespaces -Name: default -Labels: -Status: Active +Name: default +Labels: +Annotations: +Status: Active No resource quota. From a9208e8a5de8cbdc6050347d6048df226c4ecede Mon Sep 17 00:00:00 2001 From: Kaitlyn Barnard Date: Mon, 11 Sep 2017 19:01:43 +0200 Subject: [PATCH 042/102] Updates to partner page design to add KCSPs (#5336) * Updates to partner page design to add KCSPs * Update index.html * Update partner-style.css * Update partner-script.js * Add files via upload * Update partner-script.js * Add files via upload * Update partner-script.js --- _includes/partner-script.js | 150 ++++++++++++++-------- _includes/partner-style.css | 72 ++++++++++- images/square-logos/accenture.png | Bin 0 -> 13997 bytes images/square-logos/applatix.png | Bin 0 -> 12404 bytes images/square-logos/biarca.png | Bin 0 -> 9809 bytes images/square-logos/bitnami.png | Bin 12870 -> 11503 bytes images/square-logos/boozallenhamilton.png | Bin 0 -> 6717 bytes images/square-logos/claranet.png | Bin 0 -> 10283 bytes images/square-logos/cloudkite.png | Bin 0 -> 9582 bytes images/square-logos/cloudops.png | Bin 0 -> 12656 bytes images/square-logos/contino.png | Bin 0 -> 5877 bytes images/square-logos/ghostcloud.png | Bin 0 -> 9854 bytes images/square-logos/heptio.png | Bin 0 -> 7554 bytes partners/index.html | 19 ++- 14 files changed, 181 insertions(+), 60 deletions(-) create mode 100644 images/square-logos/accenture.png create mode 100644 images/square-logos/applatix.png create mode 100644 images/square-logos/biarca.png create mode 100644 images/square-logos/boozallenhamilton.png create mode 100644 images/square-logos/claranet.png create mode 100644 images/square-logos/cloudkite.png create mode 100644 images/square-logos/cloudops.png create mode 100644 images/square-logos/contino.png create mode 100644 images/square-logos/ghostcloud.png create mode 100644 images/square-logos/heptio.png diff --git a/_includes/partner-script.js b/_includes/partner-script.js index cb991e19d1..c77537e522 100644 --- a/_includes/partner-script.js +++ b/_includes/partner-script.js @@ -1,21 +1,14 @@ ;(function () { var partners = [ { - type: 0, + type: 2, name: 'CoreOS', logo: 'core_os', link: 'https://tectonic.com/', blurb: 'Tectonic is the enterprise-ready Kubernetes product, by CoreOS. It adds key features to allow you to manage, update, and control clusters in production.' }, { - type: 0, - name: 'Deis', - logo: 'deis', - link: 'https://deis.com', - blurb: 'Deis the creators of Helm, Workflow, and Steward, helps developers and operators build, deploy, manage and scale their applications on top of Kubernetes.' - }, - { - type: 0, + type: 2, name: 'StackPointCloud', logo: 'stackpoint', link: 'https://stackpoint.io', @@ -49,13 +42,6 @@ link: 'https://www.cockroachlabs.com/blog/running-cockroachdb-on-kubernetes/', blurb: 'CockroachDB is a distributed SQL database whose built-in replication and survivability model pair with Kubernetes to truly make data easy.' }, - { - type: 0, - name: 'Skippbox', - logo: 'skippbox', - link: 'http://www.skippbox.com/tag/products/', - blurb: 'Creator of Cabin the first mobile application for Kubernetes, and kompose. Skippbox’s solutions distill all the power of k8s in simple easy to use interfaces.' - }, { type: 0, name: 'Weave Works', @@ -134,7 +120,7 @@ blurb: 'Deep, automated security for your containers running on Kubernetes.' }, { - type: 0, + type: 2, name: 'Canonical', logo: 'canonical', link: 'https://jujucharms.com/canonical-kubernetes/', @@ -183,14 +169,14 @@ blurb: 'Aporeto makes cloud-native applications secure by default without impacting developer velocity and works at any scale, on any cloud.' }, { - type: 0, + type: 2, name: 'Giant Swarm', logo: 'giant_swarm', link: 'https://giantswarm.io', blurb: 'Giant Swarm provides fully-managed Kubernetes Clusters in your location of choice, so you can focus on your product.' }, { - type: 0, + type: 2, name: 'Mirantis', logo: 'mirantis', link: 'https://content.mirantis.com/Containerizing-OpenStack-on-Kubernetes-Video-Landing-Page.html', @@ -218,42 +204,28 @@ blurb: 'ReactiveOps has written automation on best practices for infrastructure as code on GCP & AWS using Kubernetes, helping you build and maintain a world-class infrastructure at a fraction of the price of an internal hire.' }, { - type: 1, + type: 2, name: 'Livewyer', logo: 'livewyer', link: 'https://livewyer.io/services/kubernetes-experts/', blurb: 'Kubernetes experts that on-board applications and empower IT teams to get the most out of containerised technology.' }, { - type: 1, - name: 'Deis', - logo: 'deis', - link: 'https://deis.com/services/', - blurb: 'Deis provides professional services and 24x7 operational support for any Kubernetes cluster managed by our global cluster operations team.' - }, - { - type: 1, - name: 'StackPointCloud', - logo: 'stackpoint', - link: 'https://stackpoint.io', - blurb: 'StackPointCloud offers a wide range of support plans for managed Kubernetes clusters built through its universal control plane for Kubernetes Anywhere.' - }, - { - type: 1, + type: 2, name: 'Samsung SDS', logo: 'samsung_sds', link: 'http://www.samsungsdsa.com/cloud-infrastructure_kubernetes', blurb: 'Samsung SDS’s Cloud Native Computing Team offers expert consulting across the range of technical aspects involved in building services targeted at a Kubernetes cluster.' }, { - type: 1, + type: 2, name: 'Container Solutions', logo: 'container_solutions', link: 'http://container-solutions.com/resources/kubernetes/', blurb: 'Container Solutions is a premium software consultancy that focuses on programmable infrastructure, offering our expertise in software development, strategy and operations to help you innovate at speed and scale.' }, { - type: 1, + type: 2, name: 'Jetstack', logo: 'jetstack', link: 'https://www.jetstack.io/', @@ -288,7 +260,7 @@ blurb: 'Spotinst uses a prediction algorithm in the Amazon EC2 Spot allowing k8s clusters to increase performance and lower the infrastructure costs' }, { - type: 1, + type: 2, name: 'inwinSTACK', logo: 'inwinstack', link: 'http://www.inwinstack.com/index.php/en/solutions-en/', @@ -330,7 +302,7 @@ blurb: 'NATS is a simple, secure, and scalable cloud native messaging system.' }, { - type: 1, + type: 2, name: 'RX-M', logo: 'rxm', link: 'http://rx-m.com/training/kubernetes-training/', @@ -372,7 +344,7 @@ blurb: 'Full stack monitoring of containers and microservices orchestrated by Kubernetes. Powered by anomaly detection to find problems faster.' }, { - type: 0, + type: 2, name: 'Supergiant.io', logo: 'supergiant', link: 'https://supergiant.io/blog/supergiant-packing-algorithm-unique-save-money', @@ -418,7 +390,7 @@ name: 'Cobe', logo: 'cobe', link: 'https://cobe.io/product-page/', - blurb: 'Manage Kubernetes clusters with a live, searchable model that captures all relationships and performance data in full visualised context.' + blurb: 'Manage Kubernetes clusters with a live, searchable model that captures all relationships and performance data in full visualised context.' }, { type: 0, @@ -463,7 +435,7 @@ blurb: 'Strong DevOps and Cloud talent working with couple clients on kubernetes and helm implementations. ' }, { - type: 0, + type: 2, name: 'Bitnami', logo: 'bitnami', link: 'http://bitnami.com/kubernetes', @@ -491,7 +463,7 @@ blurb: 'Opcito is a software consultancy that uses Kubernetes to help organisations build, architect & deploy highly scalable applications.' }, { - type: 0, + type: 2, name: 'Huawei Technologies Co., Ltd.', logo: 'huawei', link: 'http://developer.huawei.com/ict/en/site-paas', @@ -533,14 +505,7 @@ blurb: 'Fluentd Enterprise brings smart, secure logging to Kubernetes, and brings integrations with backends such as Splunk, Kafka, or AWS S3.' }, { - type: 0, - name: 'IBM', - logo: 'IBM', - link: 'https://www.ibm.com/cloud-computing/bluemix/containers', - blurb: 'IBM Container Service is a managed k8s environment with built-in cluster security and isolation while leveraging services including Watson, IoT, Weather, etc.' - }, - { - type: 1, + type: 2, name: 'IBM', logo: 'IBM', link: 'https://www.ibm.com/cloud-computing/bluemix/containers', @@ -566,9 +531,80 @@ logo: 'endocode', link: 'https://endocode.com/kubernetes/', blurb: 'Endocode practices and teaches the open source way. Kernel to cluster - Dev to Ops. We offer Kubernetes trainings, services and support.' - } + }, + { + type: 2, + name: 'Accenture', + logo: 'accenture', + link: 'https://www.accenture.com/us-en/service-application-containers', + blurb: 'Architecture, implementation and operation of world-class Kubernetes solutions for cloud-native clients.' + }, + { + type: 1, + name: 'Biarca', + logo: 'biarca', + link: 'http://biarca.io/', + blurb: 'Biarca is a cloud services provider and key focus areas Key areas of focus for Biarca include Cloud Adoption Services, Infrastructure Services, DevOps Services and Application Services. Biarca leverages Kubernetes to deliver containerized solutions.' + }, + { + type: 2, + name: 'Claranet', + logo: 'claranet', + link: 'http://www.claranet.co.uk/hosting/google-cloud-platform-consulting-managed-services', + blurb: 'Claranet helps people migrate to the cloud and take full advantage of the new world it offers. We consult, design, build and proactively manage the right infrastructure and automation tooling for clients to achieve this.' + }, + { + type: 1, + name: 'CloudKite', + logo: 'cloudkite', + link: 'https://cloudkite.io/', + blurb: 'CloudKite.io helps companies build and maintain highly automated, resilient, and impressively performing software on Kubernetes.' + }, + { + type: 1, + name: 'CloudOps', + logo: 'CloudOps', + link: 'https://www.cloudops.com/services/docker-and-kubernetes-workshops/', + blurb: 'CloudOps gets you hands-on with the K8s ecosystem via workshop/lab. Get prod ready K8s in cloud(s) of your choice with our managed services.' + }, + { + type: 2, + name: 'Ghostcloud', + logo: 'ghostcloud', + link: 'https://www.ghostcloud.cn/ecos-kubernetes', + blurb: 'EcOS is an enterprise-grade PaaS / CaaS based on Docker and Kubernetes, which makes it easier to configure, deploy and manage containerized applications.' + }, + { + type: 2, + name: 'Contino', + logo: 'contino', + link: 'https://www.contino.io/', + blurb: 'We help enterprise organizations adopt DevOps, containers and cloud computing. Contino is a global consultancy that enables regulated organizations to accelerate innovation through the adoption of modern approaches to software delivery.' + }, + { + type: 2, + name: 'Heptio', + logo: 'heptio', + link: 'http://heptio.com', + blurb: 'Heptio helps businesses of all sizes get closer to the vibrant Kubernetes community.' + }, + { + type: 2, + name: 'Booz Allen Hamilton', + logo: 'boozallenhamilton', + link: 'https://www.boozallen.com/', + blurb: 'Booz Allen partners with public and private sector clients to solve their most difficult challenges through a combination of consulting, analytics, mission operations, technology, systems delivery, cybersecurity, engineering, and innovation expertise.' + }, + { + type: 0, + name: 'Applatix', + logo: 'applatix', + link: 'https://applatix.com/applatix-product/', + blurb: 'Applatix helps build and run containerized apps on public cloud using Docker and Kubernetes.' + } ] + var kcspContainer = document.getElementById('kcspContainer') var isvContainer = document.getElementById('isvContainer') var servContainer = document.getElementById('servContainer') @@ -601,7 +637,15 @@ box.appendChild(img) box.appendChild(div) - var container = obj.type ? servContainer : isvContainer + var container; + if (obj.type === 0) { + container = isvContainer; + } else if (obj.type === 1) { + container = servContainer; + } else if (obj.type === 2) { + container = kcspContainer; + } + container.appendChild(box) }) })(); diff --git a/_includes/partner-style.css b/_includes/partner-style.css index a8cc125992..191d6b340b 100644 --- a/_includes/partner-style.css +++ b/_includes/partner-style.css @@ -1,5 +1,65 @@ +/* SECTIONS */ +.section { + clear: both; + padding: 0px; + margin-bottom: 2em; +} + +/* COLUMN SETUP */ +.col { + display: block; + float:left; + margin: 1% 0 1% 1.6%; + background-color: #f9f9f9; +} +.col:first-child { margin-left: 0; } + + +/* GROUPING */ +.group:before, +.group:after { + content:""; + display:table; +} +.group:after { + clear:both; +} +.group { + zoom:1; /* For IE 6/7 */ +} + +/* GRID OF THREE */ +.span_3_of_3 { + width: 32.2%; + background-color: #f9f9f9; + padding: 20px; +} +.span_2_of_3 { + width: 32.2%; + background-color: #f9f9f9; + padding: 20px; +} +.span_1_of_3 { + width: 32.2%; + background-color: #f9f9f9; + padding: 20px; +} + +/* GO FULL WIDTH AT LESS THAN 480 PIXELS */ + +@media only screen and (max-width: 480px) { + .col { margin: 1% 0 1% 0%;} + .span_3_of_3, .span_2_of_3, .span_1_of_3 { width: 100%; } +} + +.button{ + max-width: 100%; + line-height: 14px; + padding: 15px; + } + h5 { - font-size: 18px; + font-size: 16px; line-height: 1.5em; margin-bottom: 2em; } @@ -9,7 +69,7 @@ h5 { background-color: #f9f9f9; } -#isvContainer, #servContainer { +#kcspContainer, #isvContainer, #servContainer { position: relative; width: 100%; display: flex; @@ -21,6 +81,10 @@ h5 { margin-bottom: 80px; } +#kcspContainer { + margin-bottom: 80px; +} + .partner-box { position: relative; width: 47%; @@ -58,7 +122,7 @@ h5 { } @media screen and (max-width: 568px) { - #isvContainer, #servContainer { + #kcspContainer, #isvContainer, #servContainer { justify-content: center; } @@ -76,7 +140,7 @@ h5 { } @media screen and (max-width: 568px) { - #isvContainer, #servContainer { + #kcspContainer, #isvContainer, #servContainer { justify-content: center; } diff --git a/images/square-logos/accenture.png b/images/square-logos/accenture.png new file mode 100644 index 0000000000000000000000000000000000000000..473e6afd7ec1b1f580e8f846e3924cc8de35971a GIT binary patch literal 13997 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 literal 0 HcmV?d00001 diff --git a/images/square-logos/applatix.png b/images/square-logos/applatix.png new file mode 100644 index 0000000000000000000000000000000000000000..15a30708cad437672ff9c56bc7c65c6573d17697 GIT binary patch literal 12404 zcmaKT19WA}x^8TC*s*PA#kOtRwmVkGwmKc#w%xHhSur|x^0Lo8``r8Pc>Ap})~Y$b z@#Cwie~dY+>RXYD@)C$}IB*~!Ac#_uqRO9b$>%o}2I}*-XGn7Ov-#>Ors=BUVD9Q+ zBDrK;(wDJKgsaj;`B`pbsF)6VhJ8w7+` zz|+yl#Kz2($k@!n%ASwpvZIHD$jX$DM1x(9NzPHk%+gBI+u2OTTVB<~+s1_3lth4^ zh}RSF8NklW)riQ`&eq-q;K@hwuegBE>%U+|5~6>ZxZ3cM{1+)rIYlB72WK-Pb_Nc5 z6J}N}B2I1wW_E5a7B)H}7A9s6Mka1XW;S{zW&jg6fQgyt-yf3CY|f_U0A*3}f9LwV z<0G+jb#(+VGJ1G;FnF*sI5=A{GIMitGcvI-vary9TF|?A*}EEf(%ZX`{vAQo%*Djn z%F)%z!Jg=^h(^W^ZmxVJpG^O&3wDnG32X22?_v5JFh)-!M@D7_roX!Mx1pTe|KHTk z?myNpuF7Wr&G-Kq*hSUL(Tq{q%*DaY+2nKL%t`-B

aQHZyW{a8`A2u>E@!6)hcH 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%0AxxyZkQC^Ys;#jsp0o3Kc7HD`aE`( zHm(^sZ)-H#-B^xdO=9q;X>w@(F$OGA|M4sqs%0<)s^$w^YZ~Kd(YP7CbdN{=b~oxC(ok2czVH*Mbl9;a$X07s$HUm)e8(HfXg#VBQCe;bKk<--AU=7 z!6CQ3*ZV6L)?x4z!6?C}zNI-0c@!1M*|<1h)|N3-Ny`}gxw0^1vn(KC1b>A#wT45g zGb{rRi8gmT8)SI>IeBX z@`b_uwoYSIkv5xz=mhd zKi}kK91{6USqnGcAS<-|58RSzX~$k*|ezcES=!%qe_v* zEGTh#EW0>Q^D{O$RikdhlNm5e$eFQDdqInA=0z5EL@{5amOttqAY4Q$v6OO4tVkAB zA{lIFt{Skr#$g8O+z9}Tn`z63AERo}87Wu3wun4!RFv18&lh)3=I5=jZWl>qLVT+z zx6O*^mr)>lw{LSN^*-=(FkY$7`1r`Sd`aE}y&}iO)yD*sz48Yp<-dExL}v@cHT;mF-offE+k$q=@X4x0 zNk+*R`?~;rHI_mudyx(f(~+pBId0$zs8{YZtv&QYHG=u`DP8W*AB$x@ z(p(ovn<1j2raH!FZD?6Z1)AwI#|lba`X?3k6nPj1N4W#K*3`Lc@(;Rge))QMIpsPu ze=tRQ(+Sv~fpB)|5;5OPC-tAYw!P>wIFMAWOUW`JZPgm@p5kInzlD%ZXxRQKvXh!q zVlr=VF@41l+qsCE_&7>N`IiXyAGEapLxlUc;`ZNK+P`$U{|owGD&K#W*Z#8>_-`8j tLmvD$^lvTj-#PymGk(1%1yCrEWy*G%2n6N7{!;)VB_=OgEo>P4e*hlDfO`M{ literal 0 HcmV?d00001 diff --git a/images/square-logos/biarca.png b/images/square-logos/biarca.png new file mode 100644 index 0000000000000000000000000000000000000000..d99a06d245aa95a8ce9e6457624a8f98f81d83b7 GIT binary patch literal 9809 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

7?4pM&*S9NGgj5rb=MWsaV&;aQ&kmjQ-%$1 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 ZB4iLQS|O>H_xp#AhKi1I5!5#LzW{QjaXbJ3 literal 0 HcmV?d00001 diff --git a/images/square-logos/claranet.png b/images/square-logos/claranet.png new file mode 100644 index 0000000000000000000000000000000000000000..63e208eb5b3f60dd450082964902ce4e0ec5575a GIT binary patch literal 10283 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 PzkpJZQI)O&m<0YGAHDm% literal 0 HcmV?d00001 diff --git a/images/square-logos/cloudops.png b/images/square-logos/cloudops.png new file mode 100644 index 0000000000000000000000000000000000000000..731a0c11af16353c954b67ac320c165b06048178 GIT binary patch literal 12656 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 F{{R7}DZu~$ literal 0 HcmV?d00001 diff --git a/images/square-logos/contino.png b/images/square-logos/contino.png new file mode 100644 index 0000000000000000000000000000000000000000..f2d42c95b069adbf80a3d22c52a25905387cd476 GIT binary patch literal 5877 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 g+wc=!PK`RFtlvVSu4ixs&y(3+#E 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 JTOw`f|34_?GpYap literal 0 HcmV?d00001 diff --git a/partners/index.html b/partners/index.html index c4b58d73da..f19649cf77 100644 --- a/partners/index.html +++ b/partners/index.html @@ -13,10 +13,23 @@ cid: partners

-
We are working with a broad group of partners who contribute to the Kubernetes core codebase, making it stronger and richer. These partners create a vibrant Kubernetes ecosystem supporting a spectrum of complementing platforms, from open source solutions to market-leading technologies. Partners can get their services and offerings added to this page by completing and submitting the partner request form.
-

Technology Partners

+
Kubernetes works with partners to create a strong, vibrant codebase that supports a spectrum of complementary platforms.
+
+
Kubernetes Certified Service Providers
Vetted service providers with deep experience helping enterprises successfully adopt Kubernetes.

+
Technology Partners
Integrations and plugins that add features to Kubernetes applications.


+
Service Providers
Consulting or management services to help companies implement Kubernetes in commercial applications.

+
+

Kubernetes Certified Service Providers (KCSP)

+

The KCSP program is a vetted tier of service providers who have deep experience helping enterprises successfully adopt Kubernetes. KCSP partners offer Kubernetes support, consulting, professional services and training for organizations embarking on their Kubernetes journey.

+

Interested in becoming a KCSP? Learn more.

+
+

Technology Partners

+

Technology partners offer integrations and plugins that add features to Kubernetes applications.

+

Interested in becoming a Technology Partner? Please fill out this form.

-

Services Partners

+

Services Partners

+

Service Providers offer consulting or management services to help companies implement and use Kubernetes in commercial applications.

+

Interested in becoming a Service Provider? Please fill out this form

From 87bf3696ca75fc314e779fa1334bb28ebe27ade4 Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 10 Sep 2017 18:13:03 +0800 Subject: [PATCH 043/102] Update photon-controller.md Fix leading spaces in commands. --- docs/getting-started-guides/photon-controller.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/photon-controller.md b/docs/getting-started-guides/photon-controller.md index 45e4251565..ecdaf13f82 100644 --- a/docs/getting-started-guides/photon-controller.md +++ b/docs/getting-started-guides/photon-controller.md @@ -22,13 +22,13 @@ setup: the actual creation of the cluster can be done by anyone.) needs to be installed on the machine on which you'll be running kube-up. If you have go installed, this can be easily installed with: - go get github.com/vmware/photon-controller-cli/photon + go get github.com/vmware/photon-controller-cli/photon 3. `mkisofs` needs to be installed. The installation process creates a CD-ROM ISO image to bootstrap the VMs with cloud-init. If you are on a Mac, you can install this with [brew](http://brew.sh/): - brew install cdrtools + brew install cdrtools 4. Several common tools need to be installed: `ssh`, `scp`, `openssl` From 9a472c4fbba416a4d19e5628181610ae69d344d8 Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Mon, 11 Sep 2017 14:44:06 +0800 Subject: [PATCH 044/102] fix typo fix typo --- .../configure-multiple-schedulers.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/tasks/administer-cluster/configure-multiple-schedulers.md b/docs/tasks/administer-cluster/configure-multiple-schedulers.md index 00c1f1c597..157fa4b7e7 100644 --- a/docs/tasks/administer-cluster/configure-multiple-schedulers.md +++ b/docs/tasks/administer-cluster/configure-multiple-schedulers.md @@ -138,9 +138,9 @@ scheduler in that pod spec. Let's look at three examples. Save this file as `pod1.yaml` and submit it to the Kubernetes cluster. - ```shell - kubectl create -f pod1.yaml - ``` +```shell +kubectl create -f pod1.yaml +``` - Pod spec with `default-scheduler` @@ -151,9 +151,9 @@ scheduler in that pod spec. Let's look at three examples. Save this file as `pod2.yaml` and submit it to the Kubernetes cluster. - ```shell - kubectl create -f pod2.yaml - ``` +```shell +kubectl create -f pod2.yaml +``` - Pod spec with `my-scheduler` From 496b1758c7961df419fa4a769c436a917018c06b Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 10 Sep 2017 19:12:18 +0800 Subject: [PATCH 045/102] Update libvirt-coreos.md Add som urls. --- docs/getting-started-guides/libvirt-coreos.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/libvirt-coreos.md b/docs/getting-started-guides/libvirt-coreos.md index 7bcb341e73..4c067f8d65 100644 --- a/docs/getting-started-guides/libvirt-coreos.md +++ b/docs/getting-started-guides/libvirt-coreos.md @@ -59,7 +59,7 @@ You can test it with the following command: virsh -c qemu:///system pool-list ``` -If you have access error messages, please read https://libvirt.org/acl.html and https://libvirt.org/aclpolkit.html . +If you have access error messages, please read [https://libvirt.org/acl.html](https://libvirt.org/acl.html) and [https://libvirt.org/aclpolkit.html](https://libvirt.org/aclpolkit.html). In short, if your libvirt has been compiled with Polkit support (ex: Arch, Fedora 21), you can create `/etc/polkit-1/rules.d/50-org.libvirt.unix.manage.rules` as follows to grant full access to libvirt to `$USER` @@ -125,7 +125,7 @@ There is both an automated way and a manual, customizable way of setting up libv #### Automated setup -There is an automated setup script on https://get.k8s.io that will download the tarball for Kubernetes and spawn a Kubernetes cluster on a local CoreOS instances that the script creates. To run this script, use wget or curl with the KUBERNETES_PROVIDER environment variable set to libvirt-coreos: +There is an automated setup script on [https://get.k8s.io]( https://get.k8s.io ) that will download the tarball for Kubernetes and spawn a Kubernetes cluster on a local CoreOS instances that the script creates. To run this script, use wget or curl with the KUBERNETES_PROVIDER environment variable set to libvirt-coreos: ```shell export KUBERNETES_PROVIDER=libvirt-coreos; wget -q -O - https://get.k8s.io | bash From ac3c40c91d54afb19d3224f927dfebf5ddedb4ee Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Tue, 12 Sep 2017 11:07:16 +0800 Subject: [PATCH 046/102] fix the command output fix the command output --- .../stateless-application/expose-external-ip-address.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/stateless-application/expose-external-ip-address.md b/docs/tutorials/stateless-application/expose-external-ip-address.md index 39b7bfaa0c..6d4b0a39bc 100644 --- a/docs/tutorials/stateless-application/expose-external-ip-address.md +++ b/docs/tutorials/stateless-application/expose-external-ip-address.md @@ -85,6 +85,7 @@ external IP address. Name: my-service Namespace: default Labels: run=load-balancer-example + Annotations: Selector: run=load-balancer-example Type: LoadBalancer IP: 10.3.245.137 @@ -93,7 +94,7 @@ external IP address. NodePort: 32377/TCP Endpoints: 10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 more... Session Affinity: None - Events: + Events: Make a note of the external IP address exposed by your service. In this example, the external IP address is 104.198.205.71. Also note From 6dabd96cd67b211b359facae0422d976122ead79 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Tue, 12 Sep 2017 16:21:46 +0800 Subject: [PATCH 047/102] fix typo of configure-volume-storage --- docs/tasks/configure-pod-container/configure-volume-storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/configure-pod-container/configure-volume-storage.md b/docs/tasks/configure-pod-container/configure-volume-storage.md index d2f945097b..56b839619e 100644 --- a/docs/tasks/configure-pod-container/configure-volume-storage.md +++ b/docs/tasks/configure-pod-container/configure-volume-storage.md @@ -40,7 +40,7 @@ restarts. Here is the configuration file for the Pod: 1. Verify that the Pod's Container is running, and then watch for changes to the Pod: - kubectl get --watch pod redis + kubectl get pod redis --watch The output looks like this: From 48714d5c9d5fe9c20c75fb5af526f0b4fda3e919 Mon Sep 17 00:00:00 2001 From: kairen Date: Mon, 11 Sep 2017 01:21:20 +0800 Subject: [PATCH 048/102] Remove manual deploy on Ubuntu --- _data/setup.yml | 1 - docs/getting-started-guides/ubuntu/manual.md | 308 ------------------- docs/setup/pick-right-solution.md | 1 - 3 files changed, 310 deletions(-) delete mode 100644 docs/getting-started-guides/ubuntu/manual.md diff --git a/_data/setup.yml b/_data/setup.yml index 576fe257c0..86d591f46d 100644 --- a/_data/setup.yml +++ b/_data/setup.yml @@ -94,7 +94,6 @@ toc: - docs/getting-started-guides/ubuntu/glossary.md - docs/getting-started-guides/ubuntu/local.md - docs/getting-started-guides/ubuntu/logging.md - - docs/getting-started-guides/ubuntu/manual.md - docs/getting-started-guides/windows/index.md diff --git a/docs/getting-started-guides/ubuntu/manual.md b/docs/getting-started-guides/ubuntu/manual.md deleted file mode 100644 index 7957e10bef..0000000000 --- a/docs/getting-started-guides/ubuntu/manual.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -approvers: -- thockin -title: Manually Deploying Kubernetes on Ubuntu Nodes ---- - -{% capture overview %} -This document describes how to deploy Kubernetes on ubuntu nodes, 1 master and 3 nodes involved -in the given examples. You can scale to **any number of nodes** by changing some settings with ease. -The original idea was heavily inspired by @jainvipin 's ubuntu single node -work, which has been merge into this document. -{% endcapture %} - -The scripting referenced here can be used to deploy Kubernetes with -networking based either on Flannel or on a CNI plugin that you supply. -This document is focused on the Flannel case. See -`kubernetes/cluster/ubuntu/config-default.sh` for remarks on how to -use a CNI plugin instead. - -[Cloud team from Zhejiang University](https://github.com/ZJU-SEL) will maintain this work. - -{% capture prerequisites %} -## Prerequisites - -1. The nodes have installed docker version 1.2+ and bridge-utils to manipulate linux bridge. -2. All machines can communicate with each other. Master node needs to be connected to the -Internet to download the necessary files, while worker nodes do not. -3. These guide is tested OK on Ubuntu 14.04 LTS 64bit server, but it can not work with -Ubuntu 15 which uses systemd instead of upstart. -4. Dependencies of this guide: etcd-2.2.1, flannel-0.5.5, k8s-1.2.0, may work with higher versions. -5. All the remote servers can be ssh logged in without a password by using key authentication. -6. The remote user on all machines is using /bin/bash as its login shell, and has sudo access. -{% endcapture %} - -{% capture steps %} -## Starting a Cluster - -### Set up working directory - -Clone the Kubernetes github repo locally - -```shell -$ git clone --depth 1 https://github.com/kubernetes/kubernetes.git -``` - -#### Configure and start the Kubernetes cluster - -The startup process will first download all the required binaries automatically. -By default etcd version is 2.2.1, flannel version is 0.5.5 and k8s version is 1.2.0. -You can customize your etcd version, flannel version, k8s version by changing corresponding variables -`ETCD_VERSION` , `FLANNEL_VERSION` and `KUBE_VERSION` like following. - -```shell -$ export KUBE_VERSION=1.2.0 -$ export FLANNEL_VERSION=0.5.0 -$ export ETCD_VERSION=2.2.0 -``` - -**Note** - -For users who want to bring up a cluster with k8s version v1.1.1, `controller manager` may fail to start -due to [a known issue](https://github.com/kubernetes/kubernetes/issues/17109). You could raise it -up manually by using following command on the remote master server. Note that -you should do this only after `api-server` is up. Moreover, this issue is fixed in v1.1.2 and later. - -```shell -$ sudo service kube-controller-manager start -``` - -Note that we use flannel here to set up overlay network, yet it's optional. Actually you can build up k8s -cluster natively, or use flannel, Open vSwitch or any other SDN tool you like. - -An example cluster is listed below: - -```shell -| IP Address | Role | -|-------------|----------| -|10.10.103.223| node | -|10.10.103.162| node | -|10.10.103.250| both master and node| -``` - -First configure the cluster information in cluster/ubuntu/config-default.sh, following is a simple sample. - -```shell -export nodes="vcap@10.10.103.250 vcap@10.10.103.162 vcap@10.10.103.223" - -export roles="ai i i" - -export NUM_NODES=${NUM_NODES:-3} - -export SERVICE_CLUSTER_IP_RANGE=192.168.3.0/24 - -export FLANNEL_NET=172.16.0.0/16 -``` - -The first variable `nodes` defines all your cluster nodes, master node comes first and -separated with blank space like ` ` - -Then the `roles` variable defines the roles of above machine in the same order, "ai" stands for machine -acts as both master and node, "a" stands for master, "i" stands for node. - -The `NUM_NODES` variable defines the total number of nodes. - -The `SERVICE_CLUSTER_IP_RANGE` variable defines the Kubernetes service IP range. Please make sure -that you do have a valid private ip range defined here, because some IaaS provider may reserve private ips. -You can use below three private network range according to rfc1918. Besides you'd better not choose the one -that conflicts with your own private network range. - -```shell -10.0.0.0 - 10.255.255.255 (10/8 prefix) - -172.16.0.0 - 172.31.255.255 (172.16/12 prefix) - -192.168.0.0 - 192.168.255.255 (192.168/16 prefix) -``` - -The `FLANNEL_NET` variable defines the IP range used for flannel overlay network, -should not conflict with above `SERVICE_CLUSTER_IP_RANGE`. -You can optionally provide additional Flannel network configuration -through `FLANNEL_BACKEND` and `FLANNEL_OTHER_NET_CONFIG`, as explained in `cluster/ubuntu/config-default.sh`. - -The default setting for `ADMISSION_CONTROL` is right for the latest -release of Kubernetes, but if you choose an earlier release then you -might want a different setting. See -[the admission control doc](/docs/admin/admission-controllers/#is-there-a-recommended-set-of-plug-ins-to-use) -for the recommended settings for various releases. - -**Note:** When deploying, master needs to be connected to the Internet to download the necessary files. -If your machines are located in a private network that need proxy setting to connect the Internet, -you can set the config `PROXY_SETTING` in cluster/ubuntu/config-default.sh such as: - - PROXY_SETTING="http_proxy=http://server:port https_proxy=https://server:port" - -After all the above variables being set correctly, we can use following command in `cluster/` directory to -bring up the whole cluster. - -```shell -$ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh -``` - -The scripts automatically copy binaries and config files to all the machines via `scp` and start Kubernetes -service on them. The only thing you need to do is to type the sudo password when promoted. - -```shell -Deploying node on machine 10.10.103.223 -... -[sudo] password to start node: -``` - -If everything works correctly, you will see the following message from console indicating the k8s cluster is up. - -```shell -Cluster validation succeeded -``` - -### Test it out - -You can use `kubectl` command to check if the newly created cluster is working correctly. -The `kubectl` binary is under the `cluster/ubuntu/binaries` directory. -You can make it available via PATH, then you can use the below command smoothly. - -For example, use `$ kubectl get nodes` to see if all of your nodes are ready. - -```shell -$ kubectl get nodes -NAME STATUS AGE VERSION -10.10.103.162 Ready 3d v1.6.0+fff5156 -10.10.103.223 Ready 3d v1.6.0+fff5156 -10.10.103.250 Ready 3d v1.6.0+fff5156 -``` - -Also you can run Kubernetes [guest-example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) to build a redis backend cluster. - - -### Deploy addons - -Assuming you have a starting cluster now, this section will tell you how to deploy addons like DNS -and UI onto the existing cluster. - -The configuration of DNS is configured in cluster/ubuntu/config-default.sh. - -```shell -ENABLE_CLUSTER_DNS="${KUBE_ENABLE_CLUSTER_DNS:-true}" - -DNS_SERVER_IP="192.168.3.10" - -DNS_DOMAIN="cluster.local" - -DNS_REPLICAS=1 -``` - -The `DNS_SERVER_IP` is defining the ip of dns server which must be in the `SERVICE_CLUSTER_IP_RANGE`. -The `DNS_REPLICAS` describes how many dns pod running in the cluster. - -By default, we also take care of kube-ui addon. - -```shell -ENABLE_CLUSTER_UI="${KUBE_ENABLE_CLUSTER_UI:-true}" -``` - -After all the above variables have been set, just type the following command. - -```shell -$ cd cluster/ubuntu -$ KUBERNETES_PROVIDER=ubuntu ./deployAddons.sh -``` - -After some time, you can use `$ kubectl get pods --namespace=kube-system` to see the DNS and UI pods are running in the cluster. - -### On going - -We are working on these features which we'd like to let everybody know: - -1. Run Kubernetes binaries in Docker using [kube-in-docker](https://github.com/ZJU-SEL/kube-in-docker/tree/baremetal-kube), -to eliminate OS-distro differences. -2. Tearing Down scripts: clear and re-create the whole stack by one click. - -### Troubleshooting - -Generally, what this approach does is quite simple: - -1. Download and copy binaries and configuration files to proper directories on every node. -2. Configure `etcd` for master node using IPs based on input from user. -3. Create and start flannel network for worker nodes. - -So if you encounter a problem, check etcd configuration of master node first. - -1. Check `/var/log/upstart/etcd.log` for suspicious etcd log -2. You may find following commands useful, the former one to bring down the cluster, while the latter one could start it again. - -```shell -$ KUBERNETES_PROVIDER=ubuntu ./kube-down.sh -$ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh -``` - -3. You can also customize your own settings in `/etc/default/{component_name}` and restart it via -`$ sudo service {component_name} restart`. - - -## Upgrading a Cluster - -If you already have a Kubernetes cluster, and want to upgrade to a new version, -you can use following command in `cluster/` directory to update the whole cluster -or a specified node to a new version. - -```shell -$ KUBERNETES_PROVIDER=ubuntu ./kube-push.sh [-m|-n ] -``` - -It can be done for all components (by default), master(`-m`) or specified node(`-n`). -Upgrading a single node is currently experimental. -If the version is not specified, the script will try to use local binaries. You should ensure all -the binaries are well prepared in the expected directory path cluster/ubuntu/binaries. - -```shell -$ tree cluster/ubuntu/binaries -binaries/ -├── kubectl -├── master -│   ├── etcd -│   ├── etcdctl -│   ├── flanneld -│   ├── kube-apiserver -│   ├── kube-controller-manager -│   └── kube-scheduler -└── minion - ├── flanneld - ├── kubelet - └── kube-proxy -``` - -You can use following command to get a help. - -```shell -$ KUBERNETES_PROVIDER=ubuntu ./kube-push.sh -h -``` - -Here are some examples: - -* upgrade master to version 1.0.5: `$ KUBERNETES_PROVIDER=ubuntu ./kube-push.sh -m 1.0.5` -* upgrade node `vcap@10.10.103.223` to version 1.0.5 : `$ KUBERNETES_PROVIDER=ubuntu ./kube-push.sh -n 10.10.103.223 1.0.5` -* upgrade master and all nodes to version 1.0.5: `$ KUBERNETES_PROVIDER=ubuntu ./kube-push.sh 1.0.5` - -The script will not delete any resources of your cluster, it just replaces the binaries. - -### Test it out - -You can use the `kubectl` command to check if the newly upgraded Kubernetes cluster is working correctly. - -To make sure the version of the upgraded cluster is what you expect, you will find these commands helpful. - -* upgrade all components or master: `$ kubectl version`. Check the *Server Version*. -* upgrade node `vcap@10.10.102.223`: `$ ssh -t vcap@10.10.102.223 'cd /opt/bin && sudo ./kubelet --version'`* -{% endcapture %} - - -## Support Level - - -IaaS Provider | Config. Mgmt | OS | Networking | Docs | Conforms | Support Level --------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ---------------------------- -Bare-metal | custom | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu) | | Community ([@resouer](https://github.com/resouer), [@WIZARD-CXY](https://github.com/WIZARD-CXY)) - - -For support level information on all solutions, see the [Table of solutions](/docs/getting-started-guides/#table-of-solutions) chart. - -{% include templates/task.md %} diff --git a/docs/setup/pick-right-solution.md b/docs/setup/pick-right-solution.md index 2b05534ff4..5c65f1a38c 100644 --- a/docs/setup/pick-right-solution.md +++ b/docs/setup/pick-right-solution.md @@ -120,7 +120,6 @@ These solutions are combinations of cloud providers and operating systems not co * [Fedora (Multi Node)](/docs/getting-started-guides/fedora/flannel_multi_node_cluster) * [CentOS](/docs/getting-started-guides/centos/centos_manual_config) * [Kubernetes on Ubuntu](/docs/getting-started-guides/ubuntu/) -* [Manually Deploying Kubernetes on Ubuntu Nodes](/docs/getting-started-guides/ubuntu/manual) * [CoreOS on AWS or GCE](/docs/getting-started-guides/coreos) ## Integrations From 97f089ed881ffd60423cd271eb0b78252be3094d Mon Sep 17 00:00:00 2001 From: Kyle Bai Date: Wed, 13 Sep 2017 03:21:34 +0800 Subject: [PATCH 049/102] Unified use of YAML for Secret example (#5418) * Unified use of YAML for Secret example * Fix dotfiles in secret volume yaml --- docs/concepts/configuration/secret.md | 482 ++++++++++---------------- 1 file changed, 187 insertions(+), 295 deletions(-) diff --git a/docs/concepts/configuration/secret.md b/docs/concepts/configuration/secret.md index 23a1dc1401..102eee8648 100644 --- a/docs/concepts/configuration/secret.md +++ b/docs/concepts/configuration/secret.md @@ -182,32 +182,23 @@ To consume a Secret in a volume in a Pod: This is an example of a pod that mounts a secret in a volume: -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "mypod", - "namespace": "myns" - }, - "spec": { - "containers": [{ - "name": "mypod", - "image": "redis", - "volumeMounts": [{ - "name": "foo", - "mountPath": "/etc/foo", - "readOnly": true - }] - }], - "volumes": [{ - "name": "foo", - "secret": { - "secretName": "mysecret" - } - }] - } -} +```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 ``` Each secret you want to use needs to be referred to in `spec.volumes`. @@ -222,36 +213,26 @@ You can package many files into one secret, or use many secrets, whichever is co We can also control the paths within the volume where Secret keys are projected. You can use `spec.volumes[].secret.items` field to change target path of each key: -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "mypod", - "namespace": "myns" - }, - "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" - }] - } - }] - } -} +```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 ``` What will happen: @@ -271,32 +252,23 @@ mode for the whole secret volume and override per key if needed. For example, you can specify a default mode like this: -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "mypod", - "namespace": "myns" - }, - "spec": { - "containers": [{ - "name": "mypod", - "image": "redis", - "volumeMounts": [{ - "name": "foo", - "mountPath": "/etc/foo" - }] - }], - "volumes": [{ - "name": "foo", - "secret": { - "secretName": "mysecret", - "defaultMode": 256 - } - }] - } -} +```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 ``` Then, the secret will be mounted on `/etc/foo` and all the files created by the @@ -309,36 +281,26 @@ notation to specify permissions in a more natural way. You can also use mapping, as in the previous example, and specify different permission for different files like this: -```json -{ - "apiVersion": "v1", - "kind": "Pod", - "metadata": { - "name": "mypod", - "namespace": "myns" - }, - "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 - }] - } - }] - } -} +```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 ``` In this case, the file resulting in `/etc/foo/my-group/my-username` will have @@ -393,19 +355,19 @@ 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 + - 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 ``` @@ -515,40 +477,25 @@ $ kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/ Now we can create a pod which references the secret with the ssh key and consumes it in a volume: -```json -{ - "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" - } - ] - } - ] - } -} +```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" ``` When the container's command runs, the pieces of the key will be available in: @@ -577,78 +524,46 @@ secret "test-db-secret" created Now make the pods: -```json -{ - "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" - } - ] - } - ] - } - }] -} +```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" ``` Both containers will have the following files present on their filesystems with the values for each container's environment: @@ -665,26 +580,18 @@ You could further simplify the base pod specification by using two Service Accou one called, say, `prod-user` with the `prod-db-secret`, and one called, say, `test-user` with the `test-db-secret`. Then, the pod spec can be shortened to, for example: -```json -{ - "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" - } - ] - } -} +```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 ``` ### Use-case: Dotfiles in secret volume @@ -692,49 +599,34 @@ one called, say, `prod-user` with the `prod-db-secret`, and one called, say, In order to make piece of data 'hidden' (i.e., in a file whose name begins with a dot character), simply make that key begin with a dot. For example, when the following secret is mounted into a volume: -```json -{ - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "dotfile-secret" - }, - "data": { - ".secret-file": "dmFsdWUtMg0KDQo=" - } -} - -{ - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "secret-dotfiles-pod" - }, - "spec": { - "volumes": [ - { - "name": "secret-volume", - "secret": { - "secretName": "dotfile-secret" - } - } - ], - "containers": [ - { - "name": "dotfile-test-container", - "image": "gcr.io/google_containers/busybox", - "command": [ "ls", "-l", "/etc/secret-volume" ], - "volumeMounts": [ - { - "name": "secret-volume", - "readOnly": true, - "mountPath": "/etc/secret-volume" - } - ] - } - ] - } -} +```yaml +kind: Secret +apiVersion: v1 +metadata: + name: dotfile-secret +data: + .secret-file: dmFsdWUtMg0KDQo= +--- +kind: Pod +apiVersion: v1 +metadata: + name: secret-dotfiles-pod +spec: + volumes: + - name: secret-volume + secret: + secretName: dotfile-secret + containers: + - name: dotfile-test-container + image: gcr.io/google_containers/busybox + command: + - ls + - "-l" + - "/etc/secret-volume" + volumeMounts: + - name: secret-volume + readOnly: true + mountPath: "/etc/secret-volume" ``` @@ -798,7 +690,7 @@ reference a secret then `watch` the resource, re-requesting the secret when the reference changes. Additionally, a ["bulk watch" API]( https://github.com/kubernetes/community/blob/master/contributors/design-proposals/bulk_watch.md) to let clients `watch` individual resources has also been proposed, and will likely -be available in future releases of Kubernetes. +be available in future releases of Kubernetes. ## Security Properties From 6fe16ae8d03f03269c0d2209685c9a6c203465b2 Mon Sep 17 00:00:00 2001 From: Max Prettyjohns Date: Wed, 13 Sep 2017 10:16:42 +0100 Subject: [PATCH 050/102] Fix typo in deployment documentation --- docs/concepts/workloads/controllers/deployment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/workloads/controllers/deployment.md b/docs/concepts/workloads/controllers/deployment.md index 51b395fd62..71379da9fa 100644 --- a/docs/concepts/workloads/controllers/deployment.md +++ b/docs/concepts/workloads/controllers/deployment.md @@ -115,7 +115,7 @@ NAME DESIRED CURRENT READY AGE nginx-deployment-2035384211 3 3 3 18s ``` -Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]`. The hash value is automatically generated when the Deployemnt is created. +Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]`. The hash value is automatically generated when the Deployment is created. To see the labels automatically generated for each pod, run `kubectl get pods --show-labels`. The following output is returned: From b935664c81d49ec2b398767759f46ed03a86d860 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Wed, 13 Sep 2017 17:29:58 +0800 Subject: [PATCH 051/102] fix typo of basic-stateful-set --- docs/tutorials/stateful-application/basic-stateful-set.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/stateful-application/basic-stateful-set.md b/docs/tutorials/stateful-application/basic-stateful-set.md index 557e8488bd..a8098b1713 100644 --- a/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/docs/tutorials/stateful-application/basic-stateful-set.md @@ -399,7 +399,7 @@ three replicas. ```shell kubectl patch sts web -p '{"spec":{"replicas":3}}' -"web" patched +statefulset "web" patched ``` Wait for `web-4` and `web-3` to transition to Terminating. From eb443b0b7dbd913755e6bad64bf998d9e0278cab Mon Sep 17 00:00:00 2001 From: lemon-tree Date: Wed, 13 Sep 2017 19:34:15 +0800 Subject: [PATCH 052/102] Update install-kubeadm.md Added the lost period, and modified the layout in some lines. --- docs/setup/independent/install-kubeadm.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/setup/independent/install-kubeadm.md b/docs/setup/independent/install-kubeadm.md index 2de5fb7552..69a1d682a5 100644 --- a/docs/setup/independent/install-kubeadm.md +++ b/docs/setup/independent/install-kubeadm.md @@ -79,7 +79,7 @@ You will install these packages on all of your machines: **Note:** If you already have kubeadm installed, you should do a `apt-get update && apt-get upgrade` or `yum update` to get the latest version of kubeadm. See the kubeadm release notes if you want to read about the different [kubeadm -releases](https://github.com/kubernetes/kubeadm/blob/master/CHANGELOG.md) +releases](https://github.com/kubernetes/kubeadm/blob/master/CHANGELOG.md). For each machine: @@ -116,12 +116,12 @@ For each machine: systemctl enable kubelet && systemctl start kubelet ``` - The kubelet is now restarting every few seconds, as it waits in a crashloop for - kubeadm to tell it what to do. +The kubelet is now restarting every few seconds, as it waits in a crashloop for +kubeadm to tell it what to do. - Note: Disabling SELinux by running `setenforce 0` is required to allow - containers to access the host filesystem, which is required by pod networks for - example. You have to do this until SELinux support is improved in the kubelet. +**Note:** Disabling SELinux by running `setenforce 0` is required to allow +containers to access the host filesystem, which is required by pod networks for +example. You have to do this until SELinux support is improved in the kubelet. {% endcapture %} From 9e198467064133e8c291a97bb0178f67cce89349 Mon Sep 17 00:00:00 2001 From: kairen Date: Wed, 13 Sep 2017 20:41:01 +0800 Subject: [PATCH 053/102] Fix typo and examples --- docs/concepts/storage/persistent-volumes.md | 72 +++++++++++---------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/docs/concepts/storage/persistent-volumes.md b/docs/concepts/storage/persistent-volumes.md index ef67f78e8b..c708ef0181 100644 --- a/docs/concepts/storage/persistent-volumes.md +++ b/docs/concepts/storage/persistent-volumes.md @@ -86,7 +86,7 @@ However, an administrator can configure a custom recycler pod template using the apiVersion: v1 kind: Pod metadata: - name: pv-recycler- + name: pv-recycler namespace: default spec: restartPolicy: Never @@ -128,7 +128,7 @@ For volume plugins that support the Delete reclaim policy, deletion removes both * Glusterfs * VsphereVolume * Quobyte Volumes -* HostPath (single node testing only -- local storage is not supported in any way and WILL NOT WORK in a multi-node cluster) +* HostPath (Single node testing only -- local storage is not supported in any way and WILL NOT WORK in a multi-node cluster) * VMware Photon * Portworx Volumes * ScaleIO Volumes @@ -139,20 +139,20 @@ For volume plugins that support the Delete reclaim policy, deletion removes both Each PV contains a spec and status, which is the specification and status of the volume. ```yaml - apiVersion: v1 - kind: PersistentVolume - metadata: - name: pv0003 - spec: - capacity: - storage: 5Gi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Recycle - storageClassName: slow - nfs: - path: /tmp - server: 172.17.0.2 +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv0003 +spec: + capacity: + storage: 5Gi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Recycle + storageClassName: slow + nfs: + path: /tmp + server: 172.17.0.2 ``` ### Capacity @@ -220,7 +220,7 @@ it will become fully deprecated in a future Kubernetes release. Current reclaim policies are: * Retain -- manual reclamation -* Recycle -- basic scrub ("rm -rf /thevolume/*") +* Recycle -- basic scrub (`rm -rf /thevolume/*`) * Delete -- associated storage asset such as AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder volume is deleted Currently, only NFS and HostPath support recycling. AWS EBS, GCE PD, Azure Disk, and Cinder volumes support deletion. @@ -591,7 +591,7 @@ parameters: ```yaml kind: StorageClass -apiVersion: storage.k8s.io/v1beta1 +apiVersion: storage.k8s.io/v1 metadata: name: fast provisioner: kubernetes.io/vsphere-volume @@ -607,7 +607,7 @@ parameters: ```yaml kind: StorageClass -apiVersion: storage.k8s.io/v1beta1 +apiVersion: storage.k8s.io/v1 metadata: name: vsan-policy-fast provisioner: kubernetes.io/vsphere-volume @@ -639,22 +639,22 @@ You can see [vSphere example](https://github.com/kubernetes/examples/tree/master #### Ceph RBD ```yaml - apiVersion: storage.k8s.io/v1 - kind: StorageClass - metadata: - name: fast - provisioner: kubernetes.io/rbd - parameters: - monitors: 10.16.153.105:6789 - adminId: kube - adminSecretName: ceph-secret - adminSecretNamespace: kube-system - pool: kube - userId: kube - userSecretName: ceph-secret-user - fsType: ext4 - imageFormat: "2" - imageFeatures: "layering" +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast +provisioner: kubernetes.io/rbd +parameters: + monitors: 10.16.153.105:6789 + adminId: kube + adminSecretName: ceph-secret + adminSecretNamespace: kube-system + pool: kube + userId: kube + userSecretName: ceph-secret-user + fsType: ext4 + imageFormat: "2" + imageFeatures: "layering" ``` * `monitors`: Ceph monitors, comma delimited. This parameter is required. @@ -785,6 +785,7 @@ parameters: * `ephemeral`: specifies whether the volume should be cleaned-up after unmount or should be persistent. `emptyDir` use case can set this value to true and `persistent volumes` use case such as for databases like Cassandra should set to false, [true/false] (default `false`). A string is expected here i.e. `"true"` and not `true`. #### ScaleIO + ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1 @@ -821,6 +822,7 @@ $> kubectl create secret generic sio-secret --type="kubernetes.io/scaleio" --fro ``` #### StorageOS + ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1 From d13227afa4a6f0fce9ad97a6ce877edd27c7e4b3 Mon Sep 17 00:00:00 2001 From: Samuel Giles Date: Wed, 13 Sep 2017 15:33:58 +0100 Subject: [PATCH 054/102] Typo in environment variable `KUBECONGIG` -> `KUBECONFIG` --- .../configuration/organize-cluster-access-kubeconfig.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/configuration/organize-cluster-access-kubeconfig.md b/docs/concepts/configuration/organize-cluster-access-kubeconfig.md index 3fd78f0ac4..78a63da117 100644 --- a/docs/concepts/configuration/organize-cluster-access-kubeconfig.md +++ b/docs/concepts/configuration/organize-cluster-access-kubeconfig.md @@ -50,7 +50,7 @@ credentials of the user listed in the current context. ## The KUBECONFIG environment variable -The `KUBECONGIG` environment variable holds a list of kubeconfig files. +The `KUBECONFIG` environment variable holds a list of kubeconfig files. For Linux and Mac, the list is colon-delimited. For Windows, the list is semicolon-delimited. The `KUBECONFIG` environment variable is not required. If the `KUBECONFIG` environment variable doesn't exist, From 34d2a2e7f25d8075a86fab21a03f606b73d92ab2 Mon Sep 17 00:00:00 2001 From: Weibin Lin Date: Thu, 14 Sep 2017 06:40:32 +0800 Subject: [PATCH 055/102] fix typos in /admin/authorization/rbac.md (#5427) --- docs/admin/authorization/rbac.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/admin/authorization/rbac.md b/docs/admin/authorization/rbac.md index 5eae556f61..23d36f7185 100644 --- a/docs/admin/authorization/rbac.md +++ b/docs/admin/authorization/rbac.md @@ -102,7 +102,7 @@ This allows administrators to define a set of common roles for the entire cluste then reuse them within multiple namespaces. For instance, even though the following `RoleBinding` refers to a `ClusterRole`, -"dave" (the subject) will only be able read secrets in the "development" +"dave" (the subject) will only be able to read secrets in the "development" namespace (the namespace of the `RoleBinding`). ```yaml @@ -258,7 +258,7 @@ A `RoleBinding` or `ClusterRoleBinding` binds a role to *subjects*. Subjects can be groups, users or service accounts. Users are represented by strings. These can be plain usernames, like -"alice", email-style names, like "bob@example.com", or numeric ids +"alice", email-style names, like "bob@example.com", or numeric IDs represented as a string. It is up to the Kubernetes admin to configure the [authentication modules](/docs/admin/authentication/) to produce usernames in the desired format. The RBAC authorization system does From bfecfa7f9c109924fca5dba8eaccf25ac15bd56e Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Wed, 13 Sep 2017 19:31:14 -0700 Subject: [PATCH 056/102] Link to persistent volume tutorial from concept doc (#5447) Signed-off-by: Ahmet Alp Balkan --- docs/concepts/storage/volumes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/concepts/storage/volumes.md b/docs/concepts/storage/volumes.md index d58e2717b8..8a4ae45fd8 100644 --- a/docs/concepts/storage/volumes.md +++ b/docs/concepts/storage/volumes.md @@ -849,4 +849,8 @@ several media types. {% endcapture %} +{% capture whatsnext %} +* Follow an example of [deploying WordPress and MySQL with Persistent Volumes](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/). +{% endcapture %} + {% include templates/concept.md %} From db3f59bea592b93413ef8fb37446bfe63e7aab68 Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Wed, 13 Sep 2017 19:37:35 -0700 Subject: [PATCH 057/102] Link cassandra statefulset tutorial from the guide (#5446) Signed-off-by: Ahmet Alp Balkan --- docs/concepts/workloads/controllers/statefulset.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/concepts/workloads/controllers/statefulset.md b/docs/concepts/workloads/controllers/statefulset.md index 52168247c7..e06551d6d4 100644 --- a/docs/concepts/workloads/controllers/statefulset.md +++ b/docs/concepts/workloads/controllers/statefulset.md @@ -226,6 +226,7 @@ update, roll out a canary, or perform a phased roll out. {% capture whatsnext %} * Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set). +* Follow an example of [deploying Cassandra with Stateful Sets](/docs/tutorials/stateful-application/cassandra/). {% endcapture %} {% include templates/concept.md %} From ccb82b10f2fd03761c89514a07085a43bb38de9f Mon Sep 17 00:00:00 2001 From: Kyle Bai Date: Thu, 14 Sep 2017 10:39:01 +0800 Subject: [PATCH 058/102] Fix init containers code block (#5428) --- docs/concepts/workloads/pods/init-containers.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/concepts/workloads/pods/init-containers.md b/docs/concepts/workloads/pods/init-containers.md index 73cb6b5b40..e902b296c6 100644 --- a/docs/concepts/workloads/pods/init-containers.md +++ b/docs/concepts/workloads/pods/init-containers.md @@ -150,7 +150,7 @@ spec: Yaml file below outlines the `mydb` and `myservice` services: -``` +```yaml kind: Service apiVersion: v1 metadata: @@ -174,7 +174,7 @@ spec: This Pod can be started and debugged with the following commands: -``` +```shell $ kubectl create -f myapp.yaml pod "myapp-pod" created $ kubectl get -f myapp.yaml @@ -220,7 +220,7 @@ $ kubectl logs myapp-pod -c init-mydb # Inspect the second init container Once we start the `mydb` and `myservice` services, we can see the Init Containers complete and the `myapp-pod` is created: -``` +```shell $ kubectl create -f services.yaml service "myservice" created service "mydb" created From c912140727d48f814f6247c7a443c696b29cd30f Mon Sep 17 00:00:00 2001 From: Jun Xiang Tee Date: Wed, 13 Sep 2017 19:43:00 -0700 Subject: [PATCH 059/102] update wordpress and mysql PV doc to use apps/v1beta2 APIs (#5424) --- .../mysql-wordpress-persistent-volume/mysql-deployment.yaml | 6 +++++- .../wordpress-deployment.yaml | 6 +++++- .../mysql-wordpress-persistent-volume.md | 2 +- .../mysql-wordpress-persistent-volume/mysql-deployment.yaml | 6 +++++- .../wordpress-deployment.yaml | 6 +++++- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml index 2253600de6..ce3eb1bf74 100644 --- a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml +++ b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml @@ -25,13 +25,17 @@ spec: requests: storage: 20Gi --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1beta2 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress spec: + selector: + matchLabels: + app: wordpress + tier: mysql strategy: type: Recreate template: diff --git a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml index e15edc5998..c354cdef88 100644 --- a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml +++ b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml @@ -25,13 +25,17 @@ spec: requests: storage: 20Gi --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1beta2 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: + selector: + matchLabels: + app: wordpress + tier: frontend strategy: type: Recreate template: diff --git a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md index 217c0c9bfd..afce6bd65d 100644 --- a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md +++ b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume.md @@ -151,7 +151,7 @@ The following manifest describes a single-instance WordPress Deployment and Serv You should see the WordPress set up page similar to the following screenshot. - ![wordpress-init](https://github.com/kubernetes/examples/blob/master/mysql-wordpress-pd/WordPress.png) + ![wordpress-init](https://raw.githubusercontent.com/kubernetes/examples/master/mysql-wordpress-pd/WordPress.png) **Warning:** Do not leave your WordPress installation on this page. If another user finds it, they can set up a website on your instance and use it to serve malicious content.

Either install WordPress by creating a username and password or delete your instance. {: .warning} diff --git a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml index 2253600de6..ce3eb1bf74 100644 --- a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml +++ b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml @@ -25,13 +25,17 @@ spec: requests: storage: 20Gi --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1beta2 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress spec: + selector: + matchLabels: + app: wordpress + tier: mysql strategy: type: Recreate template: diff --git a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml index e15edc5998..c354cdef88 100644 --- a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml +++ b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml @@ -25,13 +25,17 @@ spec: requests: storage: 20Gi --- -apiVersion: extensions/v1beta1 +apiVersion: apps/v1beta2 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: + selector: + matchLabels: + app: wordpress + tier: frontend strategy: type: Recreate template: From d428cf6581c3ceaa991c9dffa88d1b888481cd0e Mon Sep 17 00:00:00 2001 From: emanic Date: Wed, 13 Sep 2017 19:46:14 -0700 Subject: [PATCH 060/102] Adds link to Calico install instructions (#5423) --- docs/tasks/administer-cluster/calico-network-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/administer-cluster/calico-network-policy.md b/docs/tasks/administer-cluster/calico-network-policy.md index 8409bc5576..4543aa7069 100644 --- a/docs/tasks/administer-cluster/calico-network-policy.md +++ b/docs/tasks/administer-cluster/calico-network-policy.md @@ -9,7 +9,7 @@ This page shows how to use Calico for NetworkPolicy. {% endcapture %} {% capture prerequisites %} -* Install Calico for Kubernetes. +* [Install Calico for Kubernetes](https://docs.projectcalico.org/latest/getting-started/kubernetes/installation/). {% endcapture %} {% capture steps %} From 3498f8a43743712682748beee535bd5087dda221 Mon Sep 17 00:00:00 2001 From: Kyle Bai Date: Fri, 15 Sep 2017 01:25:26 +0800 Subject: [PATCH 061/102] Fix error link (#5459) --- docs/concepts/overview/components.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/concepts/overview/components.md b/docs/concepts/overview/components.md index d904cd5bdf..3cf64483ca 100644 --- a/docs/concepts/overview/components.md +++ b/docs/concepts/overview/components.md @@ -27,7 +27,7 @@ Kubernetes control plane. It is designed to scale horizontally -- that is, it sc ### etcd -[etcd](/docs/admin/etcd) is used as Kubernetes' backing store. All cluster data is stored here. Always have a backup plan for etcd's data for your Kubernetes cluster. +[etcd](/docs/tasks/administer-cluster/configure-upgrade-etcd) is used as Kubernetes' backing store. All cluster data is stored here. Always have a backup plan for etcd's data for your Kubernetes cluster. ### kube-controller-manager @@ -84,12 +84,12 @@ Containers started by Kubernetes automatically include this DNS server in their #### Container Resource Monitoring -[Container Resource Monitoring](/docs/user-guide/monitoring) records generic time-series metrics +[Container Resource Monitoring](/docs/tasks/debug-application-cluster/resource-usage-monitoring) records generic time-series metrics about containers in a central database, and provides a UI for browsing that data. #### Cluster-level Logging -A [Cluster-level logging](/docs/user-guide/logging/overview) mechanism is responsible for +A [Cluster-level logging](/docs/concepts/cluster-administration/logging) mechanism is responsible for saving container logs to a central log store with search/browsing interface. ## Node components From ef7db9422b7eedec3de619998d4addbe963aaf82 Mon Sep 17 00:00:00 2001 From: Steve Perry Date: Thu, 14 Sep 2017 10:54:37 -0700 Subject: [PATCH 062/102] Redirect v1 docs. (#5460) --- _redirects | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_redirects b/_redirects index a9aea70922..41059d2639 100644 --- a/_redirects +++ b/_redirects @@ -310,6 +310,7 @@ /serviceaccount/token /docs/tasks/configure-pod-container/configure-service-account 301 /v1.1/docs/admin/networking.html /docs/concepts/cluster-administration/networking 301 +/v1.1/docs/getting-started-guides /docs/tutorials/kubernetes-basics/ 301 ############################ @@ -317,6 +318,8 @@ # /docs/user-guide/kubectl/kubectl_* /docs/user-guide/kubectl/v1.7/#:splat 200 +/v1.1/docs/* /docs/ 301 + /docs/user-guide/kubectl/1_5/* https://v1-5.docs.kubernetes.io/docs/user-guide/kubectl/v1.5 301 /docs/user-guide/kubectl/v1.5/node_modules/* https://v1-5.docs.kubernetes.io/docs/user-guide/kubectl/v1.5 301 /docs/resources-reference/1_5/* https://v1-5.docs.kubernetes.io/docs/resources-reference/v1.5 301 From dc6c994085087b807189f9ce9f16728b98126940 Mon Sep 17 00:00:00 2001 From: kairen Date: Thu, 14 Sep 2017 14:37:48 +0800 Subject: [PATCH 063/102] Fix pod probes yaml file --- .../configure-liveness-readiness-probes.md | 2 +- docs/tasks/configure-pod-container/exec-liveness.yaml | 7 +------ docs/tasks/configure-pod-container/http-liveness.yaml | 6 +----- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md b/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md index 9ae8da1f1e..d28c89283e 100644 --- a/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md +++ b/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md @@ -65,7 +65,7 @@ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/exec-livenes Within 30 seconds, view the Pod events: -``` +```shell kubectl describe pod liveness-exec ``` diff --git a/docs/tasks/configure-pod-container/exec-liveness.yaml b/docs/tasks/configure-pod-container/exec-liveness.yaml index 7b04a5eb8d..6978ca0069 100644 --- a/docs/tasks/configure-pod-container/exec-liveness.yaml +++ b/docs/tasks/configure-pod-container/exec-liveness.yaml @@ -1,22 +1,17 @@ apiVersion: v1 kind: Pod - metadata: labels: test: liveness name: liveness-exec spec: containers: - - name: liveness - + image: gcr.io/google_containers/busybox args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 - - image: gcr.io/google_containers/busybox - livenessProbe: exec: command: diff --git a/docs/tasks/configure-pod-container/http-liveness.yaml b/docs/tasks/configure-pod-container/http-liveness.yaml index 8485e3444e..c1be66c5ba 100644 --- a/docs/tasks/configure-pod-container/http-liveness.yaml +++ b/docs/tasks/configure-pod-container/http-liveness.yaml @@ -6,14 +6,10 @@ metadata: name: liveness-http spec: containers: - - name: liveness - + image: gcr.io/google_containers/liveness args: - /server - - image: gcr.io/google_containers/liveness - livenessProbe: httpGet: path: /healthz From e229c03584b9e1f58e3005629ad3dcb86a938c3b Mon Sep 17 00:00:00 2001 From: Jun Xiang Tee Date: Thu, 14 Sep 2017 13:17:51 -0700 Subject: [PATCH 064/102] revert WordPress and MySQL PV doc changes to use apps/v1beta2 APIs (#5461) --- .../mysql-wordpress-persistent-volume/mysql-deployment.yaml | 6 +----- .../wordpress-deployment.yaml | 6 +----- .../mysql-wordpress-persistent-volume/mysql-deployment.yaml | 6 +----- .../wordpress-deployment.yaml | 6 +----- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml index ce3eb1bf74..2253600de6 100644 --- a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml +++ b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml @@ -25,17 +25,13 @@ spec: requests: storage: 20Gi --- -apiVersion: apps/v1beta2 +apiVersion: extensions/v1beta1 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress spec: - selector: - matchLabels: - app: wordpress - tier: mysql strategy: type: Recreate template: diff --git a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml index c354cdef88..e15edc5998 100644 --- a/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml +++ b/cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml @@ -25,17 +25,13 @@ spec: requests: storage: 20Gi --- -apiVersion: apps/v1beta2 +apiVersion: extensions/v1beta1 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: - selector: - matchLabels: - app: wordpress - tier: frontend strategy: type: Recreate template: diff --git a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml index ce3eb1bf74..2253600de6 100644 --- a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml +++ b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/mysql-deployment.yaml @@ -25,17 +25,13 @@ spec: requests: storage: 20Gi --- -apiVersion: apps/v1beta2 +apiVersion: extensions/v1beta1 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress spec: - selector: - matchLabels: - app: wordpress - tier: mysql strategy: type: Recreate template: diff --git a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml index c354cdef88..e15edc5998 100644 --- a/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml +++ b/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/wordpress-deployment.yaml @@ -25,17 +25,13 @@ spec: requests: storage: 20Gi --- -apiVersion: apps/v1beta2 +apiVersion: extensions/v1beta1 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: - selector: - matchLabels: - app: wordpress - tier: frontend strategy: type: Recreate template: From 6dd10648a662e9b3269a5b3e93d5cde74751a443 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Wed, 13 Sep 2017 14:10:24 +0800 Subject: [PATCH 065/102] Add a note to static pod manifest scanning --- docs/tasks/administer-cluster/static-pod.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tasks/administer-cluster/static-pod.md b/docs/tasks/administer-cluster/static-pod.md index f2f439470a..208ddad2c8 100644 --- a/docs/tasks/administer-cluster/static-pod.md +++ b/docs/tasks/administer-cluster/static-pod.md @@ -17,6 +17,7 @@ Static pod can be created in two ways: either by using configuration file(s) or ### Configuration files The configuration files are just standard pod definition in json or yaml format in specific directory. Use `kubelet --pod-manifest-path=` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there. +Note that kubelet will ignore files starting with dots when scanning the specified directory. For example, this is how to start a simple web server as a static pod: From 7eeb6031540106abb6c74667fb8a5bb1870a8f18 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Fri, 15 Sep 2017 07:17:17 +0800 Subject: [PATCH 066/102] =?UTF-8?q?ZTE-SH-CN-run-application-run-single-in?= =?UTF-8?q?stance-stateful-application-pr-2017-=E2=80=A6=20(#5363)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * zte-run-application-run-single-instance-stateful-application-pr-2017-09-09 * ZTE-SH-CN-run-application-run-single-instance-stateful-application-pr-2017-09-12 * ZTE-SH-CN-run-application-run-single-instance-stateful-application-pr-2017-09-13 * ZTE-SH-CN-run-application-run-single-instance-stateful-application-pr-2017-09-14 --- ...un-single-instance-stateful-application.md | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 cn/docs/tasks/run-application/run-single-instance-stateful-application.md diff --git a/cn/docs/tasks/run-application/run-single-instance-stateful-application.md b/cn/docs/tasks/run-application/run-single-instance-stateful-application.md new file mode 100644 index 0000000000..02ae15dc86 --- /dev/null +++ b/cn/docs/tasks/run-application/run-single-instance-stateful-application.md @@ -0,0 +1,226 @@ +--- +title: 运行一个单实例有状态应用 +--- + +{% capture overview %} + +本文介绍在Kubernetes中使用PersistentVolume和Deployment如何运行一个单实例有状态应用. 该应用是MySQL. + +{% endcapture %} + + +{% capture objectives %} + +* 在环境中通过磁盘创建一个PersistentVolume. +* 创建一个MySQL Deployment. +* 在集群内以一个已知的DNS名将MySQL暴露给其他pods. + +{% endcapture %} + + +{% capture prerequisites %} + +* {% include task-tutorial-prereqs.md %} + +* 为了数据持久性我们将在环境上通过磁盘创建一个持久卷. 环境支持的类型见这里[here](/docs/user-guide/persistent-volumes/#types-of-persistent-volumes). 本篇文档将介绍 `GCEPersistentDisk` . `GCEPersistentDisk`卷只能工作在Google Compute Engine平台上. + +{% endcapture %} + + +{% capture lessoncontent %} + +## 在环境中设置一个磁盘 + +你可以为有状态的应用使用任何类型的持久卷. 有关支持环境的磁盘列表,请参考持久卷类型[Types of Persistent Volumes](/docs/user-guide/persistent-volumes/#types-of-persistent-volumes). 对于Google Compute Engine, 请运行: + +``` +gcloud compute disks create --size=20GB mysql-disk +``` + + +接下来创建一个指向刚创建的 `mysql-disk`磁盘的PersistentVolume. 下面是一个PersistentVolume的配置文件,它指向上面创建的Compute Engine磁盘: + +{% include code.html language="yaml" file="gce-volume.yaml" ghlink="/docs/tasks/run-application/gce-volume.yaml" %} + +注意`pdName: mysql-disk` 这行与Compute Engine环境中的磁盘名称相匹配. 有关为其 +他环境编写PersistentVolume配置文件的详细信息,请参见持久卷[Persistent Volumes](/docs/concepts/storage/persistent-volumes/). + + +创建持久卷: + +``` +kubectl create -f https://k8s.io/docs/tasks/run-application/gce-volume.yaml +``` + + + +## 部署MySQL + +通过创建Kubernetes Deployment并使用PersistentVolumeClaim将其连接到现已存在的PersistentVolume上来运行一个有状态的应用. 例如, 下面这个YAML文件描述了一个运行MySQL +并引用PersistentVolumeClaim的Deployment. 该文件定义了一个volume其挂载目录为/var/lib/mysql, 然后创建一个内存为20G的卷的PersistentVolumeClaim. 此申领可以通过任 +何符合需求的卷来满足, 在本例中满足上面创建的卷. + + +注意: 在配置的yaml文件中定义密码的做法是不安全的. 具体安全解决方案请参考 +[Kubernetes Secrets](/docs/concepts/configuration/secret/). + +{% include code.html language="yaml" file="mysql-deployment.yaml" ghlink="/docs/tasks/run-application/mysql-deployment.yaml" %} + + +1. 部署YAML文件中定义的内容: + + kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-deployment.yaml + + +1. 展示Deployment相关信息: + + kubectl describe deployment mysql + + Name: mysql + Namespace: default + CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700 + Labels: app=mysql + Annotations: deployment.kubernetes.io/revision=1 + Selector: app=mysql + Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable + StrategyType: Recreate + MinReadySeconds: 0 + Pod Template: + Labels: app=mysql + Containers: + mysql: + Image: mysql:5.6 + Port: 3306/TCP + Environment: + MYSQL_ROOT_PASSWORD: password + Mounts: + /var/lib/mysql from mysql-persistent-storage (rw) + Volumes: + mysql-persistent-storage: + Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) + ClaimName: mysql-pv-claim + ReadOnly: false + Conditions: + Type Status Reason + ---- ------ ------ + Available False MinimumReplicasUnavailable + Progressing True ReplicaSetUpdated + OldReplicaSets: + NewReplicaSet: mysql-63082529 (1/1 replicas created) + Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1 + + +1. 列举出Deployment创建的pods: + + kubectl get pods -l app=mysql + + NAME READY STATUS RESTARTS AGE + mysql-63082529-2z3ki 1/1 Running 0 3m + + +1. 查看持久卷: + + kubectl describe pv mysql-pv + + Name: mysql-pv + Labels: + Status: Bound + Claim: default/mysql-pv-claim + Reclaim Policy: Retain + Access Modes: RWO + Capacity: 20Gi + Message: + Source: + Type: GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine) + PDName: mysql-disk + FSType: ext4 + Partition: 0 + ReadOnly: false + No events. + + +1. 查看PersistentVolumeClaim: + + kubectl describe pvc mysql-pv-claim + + Name: mysql-pv-claim + Namespace: default + Status: Bound + Volume: mysql-pv + Labels: + Capacity: 20Gi + Access Modes: RWO + No events. + + +## 访问MySQL实例 + + +前面YAML文件中创建了一个允许集群内其他pods访问数据库的服务. 该服务中选项 +`clusterIP: None` 让服务DNS名称直接解析为Pod的IP地址. 当在一个服务下只有一个pod +并且不打算增加pods的数量这是最好的. + + +运行MySQL客户端以连接到服务器: + +``` +kubectl run -it --rm --image=mysql:5.6 mysql-client -- mysql -h -p +``` + +此命令在集群内创建一个新的Pod并运行MySQL客户端,并通过服务将其连接到服务器.如果连接成功,你就知道有状态的MySQL database正处于运行状态. + +``` +Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false +If you don't see a command prompt, try pressing enter. + +mysql> +``` + +## 更新 + + +Deployment中镜像或其他部分同往常一样可以通过 `kubectl apply` 命令更新. 以下是 +特定于有状态应用的一些注意事项: + +* 不要弹性伸缩. 弹性伸缩仅适用于单实例应用. 下层的PersistentVolume仅只能挂载一个pod. 对于集群级有状态应用, 请参考StatefulSet文档 + [StatefulSet documentation](/docs/concepts/workloads/controllers/statefulset/). +* 在Deployment的YAML文件中使用 `strategy:` `type: Recreate` . 该选项指示Kubernetes不使用滚动升级. 滚动升级将无法工作, 由于一次不能运行多个pod. 在更新配置文件 +创建一个新的pod前 `Recreate`策略将先停止第一个pod. + + +## 删除deployment + + +通过名称删除部署的对象: + +``` +kubectl delete deployment,svc mysql +kubectl delete pvc mysql-pv-claim +kubectl delete pv mysql-pv +``` + +如果使用Compute Engine磁盘,也可以使用如下命令: + +``` +gcloud compute disks delete mysql-disk +``` + +{% endcapture %} + + +{% capture whatsnext %} + +* 了解更多Deployment对象请参考 [Deployment objects](/docs/concepts/workloads/controllers/deployment/). + +* 了解更多Deployment应用请参考 [Deploying applications](/docs/user-guide/deploying-applications/) + +* kubectl run文档请参考[kubectl run documentation](/docs/user-guide/kubectl/v1.6/#run) + +* 卷和持久卷请参考[Volumes](/docs/concepts/storage/volumes/) and [Persistent Volumes](/docs/concepts/storage/persistent-volumes/) + +{% endcapture %} + +{% include templates/tutorial.md %} From fcdf4ecc83d4b809792f2a93f78d8ecf15c810ba Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Tue, 12 Sep 2017 11:34:03 +0800 Subject: [PATCH 067/102] fix the command output fix the command output --- docs/tutorials/stateful-application/basic-stateful-set.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/stateful-application/basic-stateful-set.md b/docs/tutorials/stateful-application/basic-stateful-set.md index 557e8488bd..9aee243a0a 100644 --- a/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/docs/tutorials/stateful-application/basic-stateful-set.md @@ -464,7 +464,7 @@ Patch the container image for the `web` StatefulSet. ```shell kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.7"}]' -"web" patched +statefulset "web" patched ``` Delete the `web-0` Pod. From 6147385088c340dde08cec7b7d7d4aa5a259551d Mon Sep 17 00:00:00 2001 From: YuxiJin-tobeyjin Date: Fri, 15 Sep 2017 10:02:18 +0800 Subject: [PATCH 068/102] ZTE-SH-CN-define-environment-variable-container --- .../define-environment-variable-container.md | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 cn/docs/tasks/inject-data-application/define-environment-variable-container.md diff --git a/cn/docs/tasks/inject-data-application/define-environment-variable-container.md b/cn/docs/tasks/inject-data-application/define-environment-variable-container.md new file mode 100644 index 0000000000..74734c3255 --- /dev/null +++ b/cn/docs/tasks/inject-data-application/define-environment-variable-container.md @@ -0,0 +1,72 @@ +--- +title: 为容器设置环境变量 +--- + +{% capture overview %} + +本页将展示如何为kubernetes Pod下的容器设置环境变量。 + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture steps %} + +## 为容器设置一个环境变量 + +创建Pod时,可以为其下的容器设置环境变量。通过配置文件的`env`或者`envFrom` 字段来设置环境变量。 + +本示例中,将创建一个只包含单个容器的Pod。Pod的配置文件中设置环境变量的名称为`DEMO_GREETING`, +其值为`"Hello from the environment"`。下面是Pod的配置文件内容: + +{% include code.html language="yaml" file="envars.yaml" ghlink="/docs/tasks/inject-data-application/envars.yaml" %} + +1. 基于YAML文件创建一个Pod: + + kubectl create -f https://k8s.io/docs/tasks/inject-data-application/envars.yaml + +1. 获取一下当前正在运行的Pods信息: + + kubectl get pods -l purpose=demonstrate-envars + + 查询结果应为: + + NAME READY STATUS RESTARTS AGE + envar-demo 1/1 Running 0 9s + +1. 进入该Pod下的容器并打开一个命令终端: + + kubectl exec -it envar-demo -- /bin/bash + +1. 在命令终端中通过执行`printenv`打印出环境变量。 + + root@envar-demo:/# printenv + + 打印结果应为: + + NODE_VERSION=4.4.2 + EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237 + HOSTNAME=envar-demo + ... + DEMO_GREETING=Hello from the environment + +1. 通过键入`exit`退出命令终端。 + +{% endcapture %} + +{% capture whatsnext %} + +* 有关环境变量的更多信息,请参阅[这里](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/)。 +* 有关如何通过环境变量来使用Secret,请参阅[这里](/docs/user-guide/secrets/#using-secrets-as-environment-variables)。 +* 关于[EnvVarSource](/docs/api-reference/{{page.version}}/#envvarsource-v1-core)资源的信息。 + +{% endcapture %} + + +{% include templates/task.md %} From fe97c0b9c81005897e4742bc0e008fe330b6c3b6 Mon Sep 17 00:00:00 2001 From: Alex Contini Date: Fri, 15 Sep 2017 13:24:45 -0400 Subject: [PATCH 069/102] create homepage for user journeys --- user-journeys/index.html | 305 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 user-journeys/index.html diff --git a/user-journeys/index.html b/user-journeys/index.html new file mode 100644 index 0000000000..20ebb4fb9e --- /dev/null +++ b/user-journeys/index.html @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + +
+ Kubernetes User Journeys +
+ +
+ + + + +
+ +
+
I AM...
+
+
+ +
+
+
+
+ +
+
+ Beginner +
+
+
+ +
+ +
+ Intermediate +
+
+
+ +
+
+ Advanced +
+
+
+
+ +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit +
+
+ +
+
+
+
+
+
+ +
+
+
+
+ + +
+
+ + From 855556c1f71fe79284d3ea7cc653d8b2fd6ba03c Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Fri, 15 Sep 2017 10:32:41 -0700 Subject: [PATCH 070/102] Revert "create homepage for user journeys" This reverts commit fe97c0b9c81005897e4742bc0e008fe330b6c3b6. --- user-journeys/index.html | 305 --------------------------------------- 1 file changed, 305 deletions(-) delete mode 100644 user-journeys/index.html diff --git a/user-journeys/index.html b/user-journeys/index.html deleted file mode 100644 index 20ebb4fb9e..0000000000 --- a/user-journeys/index.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - - - - - - - - - - - -
- Kubernetes User Journeys -
- -
- - - - -
- -
-
I AM...
-
-
- -
-
-
-
- -
-
- Beginner -
-
-
- -
- -
- Intermediate -
-
-
- -
-
- Advanced -
-
-
-
- -
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit -
-
- -
-
-
-
-
-
- -
-
-
-
- - -
-
- - From 34df90be819b7bba54621c5c274f10c1a0126739 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Tue, 12 Sep 2017 14:20:07 +0800 Subject: [PATCH 071/102] Add link to AlwaysPullImages admission controller --- docs/concepts/containers/images.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/concepts/containers/images.md b/docs/concepts/containers/images.md index 1522af2f1f..6d06187dbb 100644 --- a/docs/concepts/containers/images.md +++ b/docs/concepts/containers/images.md @@ -19,10 +19,13 @@ The `image` property of a container supports the same syntax as the `docker` com ## Updating Images -The default pull policy is `IfNotPresent` which causes the Kubelet to not -pull an image if it already exists. If you would like to always force a pull -you must set a pull image policy of `Always` or specify a `:latest` tag on -your image. +The default pull policy is `IfNotPresent` which causes the Kubelet to skip +pulling an image if it already exists. If you would like to always force a pull, +you can do one of the following: + +- set the `imagePullPolicy` of the container to `Always`; +- use `:latest` as the tag for the image to use; +- enable the [AllwaysPullImages](/docs/admin/admission-controllers/#alwayspullimages) admission controller. If you did not specify tag of your image, it will be assumed as `:latest`, with pull image policy of `Always` correspondingly. From 5a0c3014fc123de33aca9d30ef183d9528701f55 Mon Sep 17 00:00:00 2001 From: Kyle Bai Date: Sat, 16 Sep 2017 07:30:06 +0800 Subject: [PATCH 072/102] Improve host aliases page (#5443) * Fix confusion code block * Add more detail command * Add pod wide output --- ...ries-to-pod-etc-hosts-with-host-aliases.md | 25 ++++++++++++++++--- .../services-networking/hostaliases-pod.yaml | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md b/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md index c087868b8f..fb16b51dbf 100644 --- a/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md +++ b/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases.md @@ -15,14 +15,19 @@ Modification not using HostAliases is not suggested because the file is managed ## Default Hosts File Content Lets start an Nginx Pod which is assigned an Pod IP: -``` + +```shell +$ kubectl run nginx --image nginx --generator=run-pod/v1 +pod "nginx" created + $ kubectl get pods --output=wide NAME READY STATUS RESTARTS AGE IP NODE nginx 1/1 Running 0 13s 10.200.0.4 worker0 ``` The hosts file content would look like this: -``` + +```shell $ kubectl exec nginx -- cat /etc/hosts # Kubernetes-managed hosts file. 127.0.0.1 localhost @@ -42,8 +47,20 @@ In addition to the default boilerplate, we can add additional entries to the hos {% include code.html language="yaml" file="hostaliases-pod.yaml" ghlink="/docs/concepts/services-networking/hostaliases-pod.yaml" %} -The hosts file content would look like this: +This Pod can be started with the following commands: + +```shell +$ kubectl apply -f hostaliases-pod.yaml +pod "hostaliases-pod" created + +$ kubectl get pod -a -o=wide +NAME READY STATUS RESTARTS AGE IP NODE +hostaliases-pod 0/1 Completed 0 6s 10.244.135.10 node3 ``` + +The hosts file content would look like this: + +```shell $ kubectl logs hostaliases-pod # Kubernetes-managed hosts file. 127.0.0.1 localhost @@ -52,7 +69,7 @@ fe00::0 ip6-localnet fe00::0 ip6-mcastprefix fe00::1 ip6-allnodes fe00::2 ip6-allrouters -10.200.0.4 hostaliases-pod +10.244.135.10 hostaliases-pod 127.0.0.1 foo.local 127.0.0.1 bar.local 10.1.2.3 foo.remote diff --git a/docs/concepts/services-networking/hostaliases-pod.yaml b/docs/concepts/services-networking/hostaliases-pod.yaml index aa57b9a9e5..643813b34a 100644 --- a/docs/concepts/services-networking/hostaliases-pod.yaml +++ b/docs/concepts/services-networking/hostaliases-pod.yaml @@ -3,6 +3,7 @@ kind: Pod metadata: name: hostaliases-pod spec: + restartPolicy: Never hostAliases: - ip: "127.0.0.1" hostnames: From 933d6a1d43fbd92912e94264b5fafdb1c16a0363 Mon Sep 17 00:00:00 2001 From: Charlie Drage Date: Thu, 14 Sep 2017 20:14:28 -0400 Subject: [PATCH 073/102] Update Kompose docs This updates the current page of Kompose with our quickstart, installation as well as user guide. --- docs/tools/kompose/user-guide.md | 526 +++++++++++++++++++------------ 1 file changed, 332 insertions(+), 194 deletions(-) diff --git a/docs/tools/kompose/user-guide.md b/docs/tools/kompose/user-guide.md index 65e467989c..483ea22ea0 100644 --- a/docs/tools/kompose/user-guide.md +++ b/docs/tools/kompose/user-guide.md @@ -1,208 +1,307 @@ --- -approvers: +assignees: - cdrage title: Translate a Docker Compose File to Kubernetes Resources +redirect_from: +- "/docs/tools/kompose/" +- "/docs/tools/kompose/index.html" --- * TOC {:toc} -`kompose` is a tool to help users who are familiar with `docker-compose` move to **Kubernetes**. `kompose` takes a Docker Compose file and translates it into Kubernetes resources. +# Kubernetes + Compose = Kompose -More information about Kompose can be found on the official [http://kompose.io](http://kompose.io/) site. +What's Kompose? It's a conversion tool for all things compose (namely Docker Compose) to container orchestrators (Kubernetes or OpenShift). -`kompose` is a convenience tool to go from local Docker development to managing your application with Kubernetes. Transformation of the Docker Compose format to Kubernetes resources manifest may not be exact, but it helps tremendously when first deploying an application on Kubernetes. +More information can be found our website at [http://kompose.io](http://kompose.io) -## Use Case +In three simple steps, we'll take you from Docker Compose to Kubernetes. -If you have a Docker Compose `docker-compose.yml` or a Docker Distributed Application Bundle `docker-compose-bundle.dab` file, you can convert it into Kubernetes deployments and services like this: +__1. Take a sample docker-compose.yaml file__ -```console -$ kompose -f docker-compose.yml convert -WARN: Unsupported key networks - ignoring -file "redis-svc.yaml" created -file "web-svc.yaml" created -file "web-deployment.yaml" created -file "redis-deployment.yaml" created +```yaml +version: "2" + +services: + + redis-master: + image: gcr.io/google_containers/redis:e2e + ports: + - "6379" + + redis-slave: + image: gcr.io/google_samples/gb-redisslave:v1 + ports: + - "6379" + environment: + - GET_HOSTS_FROM=dns + + frontend: + image: gcr.io/google-samples/gb-frontend:v4 + ports: + - "80:80" + environment: + - GET_HOSTS_FROM=dns + labels: + kompose.service.type: LoadBalancer ``` -## Installation +__2. Run `kompose up` in the same directory__ -We have multiple ways to install Kompose. Our preferred method is downloading the binary from the latest GitHub release. +```bash +$ kompose up +We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. +If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. -### GitHub release +INFO Successfully created Service: redis +INFO Successfully created Service: web +INFO Successfully created Deployment: redis +INFO Successfully created Deployment: web + +Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details. +``` + +__Alternatively, you can run `kompose convert` and deploy with `kubectl`__ + +__2.1. Run `kompose convert` in the same directory__ + +```bash +$ kompose convert +INFO Kubernetes file "frontend-service.yaml" created +INFO Kubernetes file "redis-master-service.yaml" created +INFO Kubernetes file "redis-slave-service.yaml" created +INFO Kubernetes file "frontend-deployment.yaml" created +INFO Kubernetes file "redis-master-deployment.yaml" created +INFO Kubernetes file "redis-slave-deployment.yaml" created +``` + +__2.2. And start it on Kubernetes!__ + +```bash +$ kubectl create -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml +service "frontend" created +service "redis-master" created +service "redis-slave" created +deployment "frontend" created +deployment "redis-master" created +deployment "redis-slave" created +``` + +__3. View the newly deployed service__ + +Now that your service has been deployed, let's access it. + +If you're already using `minikube` for your development process: + +```bash +$ minikube service frontend +``` + +Otherwise, let's look up what IP your service is using! + +```sh +$ kubectl describe svc frontend +Name: frontend +Namespace: default +Labels: service=frontend +Selector: service=frontend +Type: LoadBalancer +IP: 10.0.0.183 +LoadBalancer Ingress: 123.45.67.89 +Port: 80 80/TCP +NodePort: 80 31144/TCP +Endpoints: 172.17.0.4:80 +Session Affinity: None +No events. + +``` + +If you're using a cloud provider, your IP will be listed next to `LoadBalancer Ingress`. + +```sh +$ curl http://123.45.67.89 +``` + +# Installation + +We have multiple ways to install Kompose. Our prefered method is downloading the binary from the latest GitHub release. + +#### GitHub release Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes/kompose/releases). -The current release we use is `1.0.0`. - ```sh -# Linux -curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-linux-amd64 -o kompose +# Linux +curl -L https://github.com/kubernetes/kompose/releases/download/v1.1.0/kompose-linux-amd64 -o kompose # macOS -curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-darwin-amd64 -o kompose +curl -L https://github.com/kubernetes/kompose/releases/download/v1.1.0/kompose-darwin-amd64 -o kompose # Windows -curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-windows-amd64.exe -o kompose.exe -``` +curl -L https://github.com/kubernetes/kompose/releases/download/v1.1.0/kompose-windows-amd64.exe -o kompose.exe -Make the binary executable and move it to your PATH (e.g. `/usr/local/bin`) - -```sh chmod +x kompose sudo mv ./kompose /usr/local/bin/kompose ``` -## Kompose convert +Alternatively, you can download the [tarball](https://github.com/kubernetes/kompose/releases). -Currently Kompose supports to transform either Docker Compose file (both of v1 and v2) and [experimental Distributed Application Bundles](https://blog.docker.com/2016/06/docker-app-bundle/) into Kubernetes and OpenShift objects. -There is a couple of sample files in the `examples/` directory for testing. -You will convert the compose or dab file to Kubernetes or OpenShift objects with `kompose convert`. +#### Go -### Kubernetes -```console -$ cd examples/ +Installing using `go get` pulls from the master branch with the latest development changes. -$ ls -docker-compose.yml docker-compose-bundle.dab docker-gitlab.yml docker-voting.yml - -$ kompose -f docker-gitlab.yml convert -file "redisio-svc.yaml" created -file "gitlab-svc.yaml" created -file "postgresql-svc.yaml" created -file "gitlab-deployment.yaml" created -file "postgresql-deployment.yaml" created -file "redisio-deployment.yaml" created - -$ ls *.yaml -gitlab-deployment.yaml postgresql-deployment.yaml redis-deployment.yaml redisio-svc.yaml web-deployment.yaml -gitlab-svc.yaml postgresql-svc.yaml redisio-deployment.yaml redis-svc.yaml web-svc.yaml +```sh +go get -u github.com/kubernetes/kompose ``` -You can try with a Docker Compose version 2 like this: +#### CentOS -```console +Kompose is in [EPEL](https://fedoraproject.org/wiki/EPEL) CentOS repository. +If you don't have [EPEL](https://fedoraproject.org/wiki/EPEL) repository already installed and enabled you can do it by running `sudo yum install epel-release` + +If you have [EPEL](https://fedoraproject.org/wiki/EPEL) enabled in your system, you can install Kompose like any other package. + +```bash +sudo yum -y install kompose +``` + +#### Fedora +Kompose is in Fedora 24, 25 and 26 repositories. You can install it just like any other package. + +```bash +sudo dnf -y install kompose +``` + +#### macOS +On macOS you can install latest release via [Homebrew](https://brew.sh): + +```bash +brew install kompose + +``` + +# User Guide + +- CLI + - [`kompose convert`](#kompose-convert) + - [`kompose up`](#kompose-up) + - [`kompose down`](#kompose-down) +- Documentation + - [Build and Push Docker Images](#build-and-push-docker-images) + - [Alternative Conversions](#alternative-conversions) + - [Labels](#labels) + - [Restart](#restart) + - [Docker Compose Versions](#docker-compose-versions) + +Kompose has support for two providers: OpenShift and Kubernetes. +You can choose a targeted provider using global option `--provider`. If no provider is specified, Kubernetes is set by default. + + +## `kompose convert` + +Kompose supports conversion of V1, V2, and V3 Docker Compose files into Kubernetes and OpenShift objects. + +### Kubernetes + +```sh $ kompose --file docker-voting.yml convert WARN Unsupported key networks - ignoring WARN Unsupported key build - ignoring -file "worker-svc.yaml" created -file "db-svc.yaml" created -file "redis-svc.yaml" created -file "result-svc.yaml" created -file "vote-svc.yaml" created -file "redis-deployment.yaml" created -file "result-deployment.yaml" created -file "vote-deployment.yaml" created -file "worker-deployment.yaml" created -file "db-deployment.yaml" created +INFO Kubernetes file "worker-svc.yaml" created +INFO Kubernetes file "db-svc.yaml" created +INFO Kubernetes file "redis-svc.yaml" created +INFO Kubernetes file "result-svc.yaml" created +INFO Kubernetes file "vote-svc.yaml" created +INFO Kubernetes file "redis-deployment.yaml" created +INFO Kubernetes file "result-deployment.yaml" created +INFO Kubernetes file "vote-deployment.yaml" created +INFO Kubernetes file "worker-deployment.yaml" created +INFO Kubernetes file "db-deployment.yaml" created $ ls db-deployment.yaml docker-compose.yml docker-gitlab.yml redis-deployment.yaml result-deployment.yaml vote-deployment.yaml worker-deployment.yaml -db-svc.yaml docker-compose-bundle.dab docker-voting.yml redis-svc.yaml result-svc.yaml vote-svc.yaml worker-svc.yaml +db-svc.yaml docker-voting.yml redis-svc.yaml result-svc.yaml vote-svc.yaml worker-svc.yaml ``` You can also provide multiple docker-compose files at the same time: -```console +```sh $ kompose -f docker-compose.yml -f docker-guestbook.yml convert -file "frontend-service.yaml" created -file "mlbparks-service.yaml" created -file "mongodb-service.yaml" created -file "redis-master-service.yaml" created -file "redis-slave-service.yaml" created -file "frontend-deployment.yaml" created -file "mlbparks-deployment.yaml" created -file "mongodb-deployment.yaml" created -file "mongodb-claim0-persistentvolumeclaim.yaml" created -file "redis-master-deployment.yaml" created -file "redis-slave-deployment.yaml" created +INFO Kubernetes file "frontend-service.yaml" created +INFO Kubernetes file "mlbparks-service.yaml" created +INFO Kubernetes file "mongodb-service.yaml" created +INFO Kubernetes file "redis-master-service.yaml" created +INFO Kubernetes file "redis-slave-service.yaml" created +INFO Kubernetes file "frontend-deployment.yaml" created +INFO Kubernetes file "mlbparks-deployment.yaml" created +INFO Kubernetes file "mongodb-deployment.yaml" created +INFO Kubernetes file "mongodb-claim0-persistentvolumeclaim.yaml" created +INFO Kubernetes file "redis-master-deployment.yaml" created +INFO Kubernetes file "redis-slave-deployment.yaml" created $ ls -mlbparks-deployment.yaml mongodb-service.yaml redis-slave-service.jsonmlbparks-service.yaml +mlbparks-deployment.yaml mongodb-service.yaml redis-slave-service.jsonmlbparks-service.yaml frontend-deployment.yaml mongodb-claim0-persistentvolumeclaim.yaml redis-master-service.yaml frontend-service.yaml mongodb-deployment.yaml redis-slave-deployment.yaml redis-master-deployment.yaml -``` - -When multiple docker-compose files are provided the configuration is merged. Any configuration that is common will be overridden by subsequent file. - -Using `--bundle, --dab` to specify a DAB file as below: - -```console -$ kompose --bundle docker-compose-bundle.dab convert -WARN: Unsupported key networks - ignoring -file "redis-svc.yaml" created -file "web-svc.yaml" created -file "web-deployment.yaml" created -file "redis-deployment.yaml" created -``` +``` +When multiple docker-compose files are provided the configuration is merged. Any configuration that is common will be over ridden by subsequent file. + ### OpenShift -```console +```sh $ kompose --provider openshift --file docker-voting.yml convert WARN [worker] Service cannot be created because of missing port. -INFO file "vote-service.yaml" created -INFO file "db-service.yaml" created -INFO file "redis-service.yaml" created -INFO file "result-service.yaml" created -INFO file "vote-deploymentconfig.yaml" created -INFO file "vote-imagestream.yaml" created -INFO file "worker-deploymentconfig.yaml" created -INFO file "worker-imagestream.yaml" created -INFO file "db-deploymentconfig.yaml" created -INFO file "db-imagestream.yaml" created -INFO file "redis-deploymentconfig.yaml" created -INFO file "redis-imagestream.yaml" created -INFO file "result-deploymentconfig.yaml" created -INFO file "result-imagestream.yaml" created -``` - -In similar way you can convert DAB files to OpenShift. -```console -$ kompose --bundle docker-compose-bundle.dab --provider openshift convert -WARN: Unsupported key networks - ignoring -INFO file "redis-svc.yaml" created -INFO file "web-svc.yaml" created -INFO file "web-deploymentconfig.yaml" created -INFO file "web-imagestream.yaml" created -INFO file "redis-deploymentconfig.yaml" created -INFO file "redis-imagestream.yaml" created +INFO OpenShift file "vote-service.yaml" created +INFO OpenShift file "db-service.yaml" created +INFO OpenShift file "redis-service.yaml" created +INFO OpenShift file "result-service.yaml" created +INFO OpenShift file "vote-deploymentconfig.yaml" created +INFO OpenShift file "vote-imagestream.yaml" created +INFO OpenShift file "worker-deploymentconfig.yaml" created +INFO OpenShift file "worker-imagestream.yaml" created +INFO OpenShift file "db-deploymentconfig.yaml" created +INFO OpenShift file "db-imagestream.yaml" created +INFO OpenShift file "redis-deploymentconfig.yaml" created +INFO OpenShift file "redis-imagestream.yaml" created +INFO OpenShift file "result-deploymentconfig.yaml" created +INFO OpenShift file "result-imagestream.yaml" created ``` It also supports creating buildconfig for build directive in a service. By default, it uses the remote repo for the current git branch as the source repo, and the current branch as the source branch for the build. You can specify a different source repo and branch using ``--build-repo`` and ``--build-branch`` options respectively. -```console +```sh $ kompose --provider openshift --file buildconfig/docker-compose.yml convert -WARN [foo] Service cannot be created because of missing port. -INFO Buildconfig using git@github.com:rtnpro/kompose.git::master as source. -INFO file "foo-deploymentconfig.yaml" created -INFO file "foo-imagestream.yaml" created -INFO file "foo-buildconfig.yaml" created +WARN [foo] Service cannot be created because of missing port. +INFO OpenShift Buildconfig using git@github.com:rtnpro/kompose.git::master as source. +INFO OpenShift file "foo-deploymentconfig.yaml" created +INFO OpenShift file "foo-imagestream.yaml" created +INFO OpenShift file "foo-buildconfig.yaml" created ``` **Note**: If you are manually pushing the Openshift artifacts using ``oc create -f``, you need to ensure that you push the imagestream artifact before the buildconfig artifact, to workaround this Openshift issue: https://github.com/openshift/origin/issues/4518 . -## Kompose up +## `kompose up` Kompose supports a straightforward way to deploy your "composed" application to Kubernetes or OpenShift via `kompose up`. ### Kubernetes -```console +```sh $ kompose --file ./examples/docker-guestbook.yml up We are going to create Kubernetes deployments and services for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. -INFO Successfully created service: redis-master -INFO Successfully created service: redis-slave -INFO Successfully created service: frontend +INFO Successfully created service: redis-master +INFO Successfully created service: redis-slave +INFO Successfully created service: frontend INFO Successfully created deployment: redis-master INFO Successfully created deployment: redis-slave -INFO Successfully created deployment: frontend +INFO Successfully created deployment: frontend Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods' for details. @@ -228,18 +327,18 @@ Note: - Only deployments and services are generated and deployed to Kubernetes. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. ### OpenShift -```console -$kompose --file ./examples/docker-guestbook.yml --provider openshift up +```sh +$ kompose --file ./examples/docker-guestbook.yml --provider openshift up We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead. -INFO Successfully created service: redis-slave -INFO Successfully created service: frontend -INFO Successfully created service: redis-master +INFO Successfully created service: redis-slave +INFO Successfully created service: frontend +INFO Successfully created service: redis-master INFO Successfully created deployment: redis-slave INFO Successfully created ImageStream: redis-slave -INFO Successfully created deployment: frontend -INFO Successfully created ImageStream: frontend +INFO Successfully created deployment: frontend +INFO Successfully created ImageStream: frontend INFO Successfully created deployment: redis-master INFO Successfully created ImageStream: redis-master @@ -255,71 +354,118 @@ svc/frontend 172.30.46.64 80/TCP svc/redis-master 172.30.144.56 6379/TCP 8s svc/redis-slave 172.30.75.245 6379/TCP 8s NAME DOCKER REPO TAGS UPDATED -is/frontend 172.30.12.200:5000/fff/frontend -is/redis-master 172.30.12.200:5000/fff/redis-master -is/redis-slave 172.30.12.200:5000/fff/redis-slave v1 +is/frontend 172.30.12.200:5000/fff/frontend +is/redis-master 172.30.12.200:5000/fff/redis-master +is/redis-slave 172.30.12.200:5000/fff/redis-slave v1 ``` Note: - You must have a running OpenShift cluster with a pre-configured `oc` context (`oc login`) -## Kompose down +## `kompose down` -Once you have deployed "composed" application to Kubernetes, `kompose down` will help you to take the application out by deleting its deployments and services. If you need to remove other resources, use the 'kubectl' command. +Once you have deployed "composed" application to Kubernetes, `$ kompose down` will help you to take the application out by deleting its deployments and services. If you need to remove other resources, use the 'kubectl' command. -```console +```sh $ kompose --file docker-guestbook.yml down -INFO Successfully deleted service: redis-master +INFO Successfully deleted service: redis-master INFO Successfully deleted deployment: redis-master -INFO Successfully deleted service: redis-slave +INFO Successfully deleted service: redis-slave INFO Successfully deleted deployment: redis-slave -INFO Successfully deleted service: frontend +INFO Successfully deleted service: frontend INFO Successfully deleted deployment: frontend ``` Note: - You must have a running Kubernetes cluster with a pre-configured kubectl context. -## Alternate formats +## Build and Push Docker Images -The default `kompose` transformation will generate Kubernetes [Deployments](/docs/concepts/workloads/controllers/deployment/) and [Services](/docs/concepts/services-networking/service/), in yaml format. You have alternative option to generate json with `-j`. Also, you can alternatively generate [Replication Controllers](/docs/concepts/workloads/controllers/replicationcontroller/) objects, [Daemon Sets](/docs/concepts/workloads/controllers/daemonset/), or [Helm](https://github.com/helm/helm) charts. +Kompose supports both building and pushing Docker images. When using the `build` key within your Docker Compose file, your image will: -```console + - Automatically be built with Docker using the `image` key specified within your file + - Be pushed to the correct Docker repository using local credentials (located at `.docker/config`) + +Using an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/buildconfig/docker-compose.yml): + +```yaml +version: "2" + +services: + foo: + build: "./build" + image: docker.io/foo/bar +``` + +Using `kompose up` with a `build` key: + +```sh +$ kompose up +INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar' +INFO Building image 'docker.io/foo/bar' from directory 'build' +INFO Image 'docker.io/foo/bar' from directory 'build' built successfully +INFO Pushing image 'foo/bar:latest' to registry 'docker.io' +INFO Attempting authentication credentials 'https://index.docker.io/v1/ +INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io' +INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. + +INFO Deploying application in "default" namespace +INFO Successfully created Service: foo +INFO Successfully created Deployment: foo + +Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details. +``` + +In order to disable the functionality, or choose to use BuildConfig generation (with OpenShift) `--build (local|build-config|none)` can be passed. + +```sh +# Disable building/pushing Docker images +$ kompose up --build none + +# Generate Build Config artifacts for OpenShift +$ kompose up --provider openshift --build build-config +``` + +## Alternative Conversions + +The default `kompose` transformation will generate Kubernetes [Deployments](http://kubernetes.io/docs/user-guide/deployments/) and [Services](http://kubernetes.io/docs/user-guide/services/), in yaml format. You have alternative option to generate json with `-j`. Also, you can alternatively generate [Replication Controllers](http://kubernetes.io/docs/user-guide/replication-controller/) objects, [Deamon Sets](http://kubernetes.io/docs/admin/daemons/), or [Helm](https://github.com/helm/helm) charts. + +```sh $ kompose convert -j -file "redis-svc.json" created -file "web-svc.json" created -file "redis-deployment.json" created -file "web-deployment.json" created +INFO Kubernetes file "redis-svc.json" created +INFO Kubernetes file "web-svc.json" created +INFO Kubernetes file "redis-deployment.json" created +INFO Kubernetes file "web-deployment.json" created ``` The `*-deployment.json` files contain the Deployment objects. -```console -$ kompose convert --rc -file "redis-svc.yaml" created -file "web-svc.yaml" created -file "redis-rc.yaml" created -file "web-rc.yaml" created +```sh +$ kompose convert --replication-controller +INFO Kubernetes file "redis-svc.yaml" created +INFO Kubernetes file "web-svc.yaml" created +INFO Kubernetes file "redis-replicationcontroller.yaml" created +INFO Kubernetes file "web-replicationcontroller.yaml" created ``` -The `*-rc.yaml` files contain the Replication Controller objects. If you want to specify replicas (default is 1), use `--replicas` flag: `$ kompose convert --rc --replicas 3`. +The `*-replicationcontroller.yaml` files contain the Replication Controller objects. If you want to specify replicas (default is 1), use `--replicas` flag: `$ kompose convert --replication-controller --replicas 3` -```console -$ kompose convert --ds -file "redis-svc.yaml" created -file "web-svc.yaml" created -file "redis-daemonset.yaml" created -file "web-daemonset.yaml" created +```sh +$ kompose convert --daemon-set +INFO Kubernetes file "redis-svc.yaml" created +INFO Kubernetes file "web-svc.yaml" created +INFO Kubernetes file "redis-daemonset.yaml" created +INFO Kubernetes file "web-daemonset.yaml" created ``` -The `*-daemonset.yaml` files contain the Daemon Set objects. +The `*-daemonset.yaml` files contain the Daemon Set objects If you want to generate a Chart to be used with [Helm](https://github.com/kubernetes/helm) simply do: -```console -$ kompose convert -c -file "web-svc.yaml" created -file "redis-svc.yaml" created -file "web-deployment.yaml" created -file "redis-deployment.yaml" created +```sh +$ kompose convert -c +INFO Kubernetes file "web-svc.yaml" created +INFO Kubernetes file "redis-svc.yaml" created +INFO Kubernetes file "web-deployment.yaml" created +INFO Kubernetes file "redis-deployment.yaml" created chart created in "./docker-compose/" $ tree docker-compose/ @@ -335,28 +481,6 @@ docker-compose The chart structure is aimed at providing a skeleton for building your Helm charts. -## Unsupported docker-compose configuration options - -Currently `kompose` does not support some Docker Compose options, which are listed on the [conversion](http://kompose.io/conversion/) document. - -For example: - -```console -$ cat nginx.yml -nginx: - image: nginx - dockerfile: foobar - build: ./foobar - cap_add: - - ALL - container_name: foobar - -$ kompose -f nginx.yml convert -WARN Unsupported key build - ignoring -WARN Unsupported key cap_add - ignoring -WARN Unsupported key dockerfile - ignoring -``` - ## Labels `kompose` supports Kompose-specific labels within the `docker-compose.yml` file in order to explicitly define a service's behavior upon conversion. @@ -367,7 +491,7 @@ For example: ```yaml version: "2" -services: +services: nginx: image: nginx dockerfile: foobar @@ -375,7 +499,7 @@ services: cap_add: - ALL container_name: foobar - labels: + labels: kompose.service.type: nodeport ``` @@ -409,6 +533,7 @@ The currently supported options are: | kompose.service.type | nodeport / clusterip / loadbalancer | | kompose.service.expose| true / hostname | +**Note**: `kompose.service.type` label should be defined with `ports` only, otherwise `kompose` will fail. ## Restart @@ -423,6 +548,8 @@ If you want to create normal pods without controllers you can use `restart` cons **Note**: controller object could be `deployment` or `replicationcontroller`, etc. +For e.g. `pival` service will become pod down here. This container calculated value of `pi`. + ```yaml version: '2' @@ -433,5 +560,16 @@ services: restart: "on-failure" ``` -#### Warning about DeploymentConfig +#### Warning about Deployment Config's + If the Docker Compose file has a volume specified for a service, the Deployment (Kubernetes) or DeploymentConfig (OpenShift) strategy is changed to "Recreate" instead of "RollingUpdate" (default). This is done to avoid multiple instances of a service from accessing a volume at the same time. + +If the Docker Compose file has service name with `_` in it (eg.`web_service`), then it will be replaced by `-` and the service name will be renamed accordingly (eg.`web-service`). Kompose does this because "Kubernetes" doesn't allow `_` in object name. + +Please note that changing service name might break some `docker-compose` files. + +## Docker Compose Versions + +Kompose supports Docker Compose versions: 1, 2 and 3. We have limited support on versions 2.1 and 3.2 due to their experimental nature. + +A full list on compatibility between all three versions is listed in our [conversion document](/docs/conversion.md) including a list of all incompatible Docker Compose keys. From 9d9f87257a7f7377dc7b876242a800d5b794b407 Mon Sep 17 00:00:00 2001 From: Weibin Lin Date: Fri, 15 Sep 2017 14:51:34 +0800 Subject: [PATCH 074/102] Update index.md --- docs/getting-started-guides/windows/index.md | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 96e3c49216..4b7eee0141 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -9,10 +9,10 @@ Kubernetes version 1.5 introduces support for Windows Server Containers. In vers ## Prerequisites In Kubernetes version 1.5, Windows Server Containers for Kubernetes is supported using the following: -1. Kubernetes control plane running on existing Linux infrastructure (version 1.5 or later) -2. Kubenet network plugin setup on the Linux nodes -3. Windows Server 2016 (RTM version 10.0.14393 or later) -4. Docker Version 1.12.2-cs2-ws-beta or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version) +1. Kubernetes control plane running on existing Linux infrastructure (version 1.5 or later). +2. Kubenet network plugin setup on the Linux nodes. +3. Windows Server 2016 (RTM version 10.0.14393 or later). +4. Docker Version 1.12.2-cs2-ws-beta or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). ## Networking Network is achieved using L3 routing. Because third-party networking plugins (e.g. flannel, calico, etc) don't natively work on Windows Server, existing technology that is built into the Windows and Linux operating systems is relied on. In this L3 networking approach, a /16 subnet is chosen for the cluster nodes, and a /24 subnet is assigned to each worker node. All pods on a given worker node will be connected to the /24 subnet. This allows pods on the same node to communicate with each other. In order to enable networking between pods running on different nodes, routing features that are built into Windows Server 2016 and Linux are used. @@ -24,11 +24,11 @@ The above networking approach is already supported on Linux using a bridge inter Each Window Server node should have the following configuration: 1. Two NICs (virtual networking adapters) are required on each Windows Server node - The two Windows container networking modes of interest (transparent and L2 bridge) use an external Hyper-V virtual switch. This means that one of the NICs is entirely allocated to the bridge, creating the need for the second NIC. -2. Transparent container network created - This is a manual configuration step and is shown in **_Route Setup_** section below -3. RRAS (Routing) Windows feature enabled - Allows routing between NICs on the box, and also "captures" packets that have the destination IP of a POD running on the node. To enable, open "Server Manager". Click on "Roles", "Add Roles". Click "Next". Select "Network Policy and Access Services". Click on "Routing and Remote Access Service" and the underlying checkboxes -4. Routes defined pointing to the other pod CIDRs via the "public" NIC - These routes are added to the built-in routing table as shown in **_Route Setup_** section below +2. Transparent container network created - This is a manual configuration step and is shown in **_Route Setup_** section below. +3. RRAS (Routing) Windows feature enabled - Allows routing between NICs on the box, and also "captures" packets that have the destination IP of a POD running on the node. To enable, open "Server Manager". Click on "Roles", "Add Roles". Click "Next". Select "Network Policy and Access Services". Click on "Routing and Remote Access Service" and the underlying checkboxes. +4. Routes defined pointing to the other pod CIDRs via the "public" NIC - These routes are added to the built-in routing table as shown in **_Route Setup_** section below. -The following diagram illustrates the Windows Server networking setup for Kubernetes Setup +The following diagram illustrates the Windows Server networking setup for Kubernetes Setup: ![Windows Setup](windows-setup.png) ## Setting up Windows Server Containers on Kubernetes @@ -37,10 +37,10 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your ### Host Setup **Windows Host Setup** -1. Windows Server container host running Windows Server 2016 and Docker v1.12. Follow the setup instructions outlined by this blog post: https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start_windows_server -2. DNS support for Windows recently got merged to docker master and is currently not supported in a stable docker release. To use DNS build docker from master or download the binary from [Docker master](https://master.dockerproject.org/) -3. Pull the `apprenda/pause` image from `https://hub.docker.com/r/apprenda/pause` -4. RRAS (Routing) Windows feature enabled +1. Windows Server container host running Windows Server 2016 and Docker v1.12. Follow the setup instructions outlined by this blog post: https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start_windows_server. +2. DNS support for Windows recently got merged to docker master and is currently not supported in a stable docker release. To use DNS build docker from master or download the binary from [Docker master](https://master.dockerproject.org/). +3. Pull the `apprenda/pause` image from `https://hub.docker.com/r/apprenda/pause`. +4. RRAS (Routing) Windows feature enabled. 5. Install a VMSwitch of type `Internal`, by running `New-VMSwitch -Name KubeProxySwitch -SwitchType Internal` command in *PowerShell* window. This will create a new Network Interface with name `vEthernet (KubeProxySwitch)`. This interface will be used by kube-proxy to add Service IPs. **Linux Host Setup** @@ -117,7 +117,7 @@ To start your cluster, you'll need to start both the Linux-based Kubernetes cont Use your preferred method to start Kubernetes cluster on Linux. Please note that Cluster CIDR might need to be updated. ## Starting the Windows Node Components To start kubelet on your Windows node: -Run the following in a PowerShell window. Be aware that if the node reboots or the process exits, you will have to rerun the commands below to restart the kubelet +Run the following in a PowerShell window. Be aware that if the node reboots or the process exits, you will have to rerun the commands below to restart the kubelet. 1. Set environment variable *CONTAINER_NETWORK* value to the docker container network to use `$env:CONTAINER_NETWORK = ""` @@ -168,7 +168,7 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t ``` ## Known Limitations: -1. There is no network namespace in Windows and as a result currently only one container per pod is supported -2. Secrets currently do not work because of a bug in Windows Server Containers described [here](https://github.com/docker/docker/issues/28401) +1. There is no network namespace in Windows and as a result currently only one container per pod is supported. +2. Secrets currently do not work because of a bug in Windows Server Containers described [here](https://github.com/docker/docker/issues/28401). 3. ConfigMaps have not been implemented yet. -4. `kube-proxy` implementation uses `netsh portproxy` and as it only supports TCP, DNS currently works only if the client retries DNS query using TCP +4. `kube-proxy` implementation uses `netsh portproxy` and as it only supports TCP, DNS currently works only if the client retries DNS query using TCP. From fc7ea442af52d53ba7dd4027ef982aa1c1ce736b Mon Sep 17 00:00:00 2001 From: jinyuxi Date: Sat, 16 Sep 2017 07:52:01 +0800 Subject: [PATCH 075/102] ZTE-SH-CN-define-command-argument-container (#5381) * ZTE-SH-CN:define-command-argument-container * ZTE-SH-CN-define-command-argument-container detele en --- .../define-command-argument-container.md | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 cn/docs/tasks/inject-data-application/define-command-argument-container.md diff --git a/cn/docs/tasks/inject-data-application/define-command-argument-container.md b/cn/docs/tasks/inject-data-application/define-command-argument-container.md new file mode 100644 index 0000000000..bce7ea8589 --- /dev/null +++ b/cn/docs/tasks/inject-data-application/define-command-argument-container.md @@ -0,0 +1,128 @@ +--- +title: 为容器设置启动时要执行的命令及其入参 +--- + +{% capture overview %} + +本页将展示如何为Kubernetes Pod下的容器设置启动时要执行的命令及其入参。 + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture steps %} + +## 创建Pod时为其下的容器设置启动时要执行的命令及其入参 + +创建Pod时,可以为其下的容器设置启动时要执行的命令及其入参。如果要设置命令,就 +填写在配置文件的`command`字段下,如果要设置命令的入参,就填写在配置文件的`args +`字段下。一旦Pod创建完成,该命令及其入参就无法再进行更改了。 + +如果在配置文件中设置了容器启动时要执行的命令及其入参,那么容器镜像中自带的命令 +与入参将会被覆盖而不再执行。如果配置文件中只是设置了入参,却没有设置其对应的命 +令,那么容器镜像中自带的命令会使用该新入参作为其执行时的入参。 + +本示例中,将创建一个只包含单个容器的Pod。在Pod配置文件中设置了一个命令与两个入参: + +{% include code.html language="yaml" file="commands.yaml" ghlink="/docs/tasks/inject-data-application/commands.yaml" %} + +1. 基于YAML文件创建一个Pod: + + kubectl create -f https://k8s.io/docs/tasks/inject-data-application/commands.yaml + +1. 获取一下当前正在运行的Pods信息: + + kubectl get pods + + 查询结果显示在command-demo这个Pod下运行的容器已经启动完成 + +1. 如果要获取容器启动时执行命令的输出结果,可以通过Pod的日志进行查看 + + kubectl logs command-demo + + 日志中显示了HOSTNAME 与KUBERNETES_PORT 这两个环境变量的值: + + command-demo + tcp://10.3.240.1:443 + +## 使用环境变量来设置入参 + +在上面的示例中,我们直接将一串字符作为命令的入参。除此之外,我们还可以 +将环境变量作为命令的入参。 + + env: + - name: MESSAGE + value: "hello world" + command: ["/bin/echo"] + args: ["$(MESSAGE)"] + +这样一来,我们就可以将那些用来设置环境变量的方法应用于设置命令的入参,其 +中包括了[ConfigMaps](/docs/tasks/configure-pod-container/configmap/) +与 +[Secrets](/docs/concepts/configuration/secret/). + +**注意:** 环境变量需要加上括号,类似于`"$(VAR)"`。这是在`command` +或 `args`字段使用变量的格式要求。 +{: .note} + +## 通过shell来执行命令 + +有时候,需要通过shell来执行命令。 例如,命令可能由多个命令组合而成,抑或包含 +在一个shell脚本中。这时,就可以通过如下方式在shell中执行命令: + + command: ["/bin/sh"] + args: ["-c", "while true; do echo hello; sleep 10;done"] + +## 注意 + +下表给出了Docker 与 Kubernetes中对应的字段名称。 + +| Description | Docker field name | Kubernetes field name | +|----------------------------------------|------------------------|-----------------------| +| The command run by the container | Entrypoint | command | +| The arguments passed to the command | Cmd | args | + +如果要覆盖默认的Entrypoint 与 Cmd,需要遵循如下规则: + +* 如果在容器配置中没有设置`command` 或者 `args`,那么将使用Docker镜像自带的命 +令及其入参。 + +* 如果在容器配置中只设置了`command`但是没有设置`args`,那么容器启动时只会执行该 +命令,Docker镜像中自带的命令及其入参会被忽略。 + +* 如果在容器配置中只设置了`args`,那么Docker镜像中自带的命令会使用该新入参作为 +其执行时的入参。 + +* 如果在容器配置中同时设置了`command` 与 `args`,那么Docker镜像中自带的命令及 +其入参会被忽略。容器启动时只会执行配置中设置的命令,并使用配置中设置的入参作为 +命令的入参。 + +下表涵盖了各类设置场景: + +| Image Entrypoint | Image Cmd | Container command | Container args | Command run | +|--------------------|------------------|---------------------|--------------------|------------------| +| `[/ep-1]` | `[foo bar]` | <not set> | <not set> | `[ep-1 foo bar]` | +| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | <not set> | `[ep-2]` | +| `[/ep-1]` | `[foo bar]` | <not set> | `[zoo boo]` | `[ep-1 zoo boo]` | +| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | `[zoo boo]` | `[ep-2 zoo boo]` | + + +{% endcapture %} + +{% capture whatsnext %} + +* 获取更多资讯可参考 [containers and commands](/docs/user-guide/containers/). +* 获取更多资讯可参考 [configuring pods and containers](/docs/tasks/). +* 获取更多资讯可参考 [running commands in a container](/docs/tasks/debug-application-cluster/get-shell-running-container/). +* 参考 [Container](/docs/api-reference/{{page.version}}/#container-v1-core). + +{% endcapture %} + + +{% include templates/task.md %} From 82ac9251fd2c447eb874fbebf9f39ad890129ce8 Mon Sep 17 00:00:00 2001 From: qingsenLi Date: Thu, 14 Sep 2017 14:03:29 +0000 Subject: [PATCH 076/102] ZTE-SH-CN-debug-pod-replication-controller-2017-09-14-14 --- .../debug-pod-replication-controller.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 cn/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md diff --git a/cn/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md b/cn/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md new file mode 100644 index 0000000000..af1691c162 --- /dev/null +++ b/cn/docs/tasks/debug-application-cluster/debug-pod-replication-controller.md @@ -0,0 +1,87 @@ +--- +title: 调试Pods和Replication Controllers +--- + +* TOC +{:toc} + +## 调试Pods + +调试一个pod的第一步是观察它。使用下面的命令检查这个pod的当前状态和最近事件: + + $ kubectl describe pods ${POD_NAME} + +看看pod中的容器的状态。他们都是`Running`吗?有最近重启了吗? + +根据pod的状态继续调试。 + +### 我的Pod保持Pending + +如果一个pod被卡在`Pending`中,就意味着它不能调度在某个节点上。一般来说,这是因为某种类型的资源不足 +阻止调度。 看看上面的命令`kubectl describe ...`的输出。调度器的消息中应该会包含无法调度Pod的原因。 +理由包括: + +#### 资源不足 + +您可能已经耗尽了集群中供应的CPU或内存。在这个情况下你可以尝试几件事情: + +* [添加更多节点](/docs/admin/cluster-management/#resizing-a-cluster) 到集群。 + +* [终止不需要的pod](/docs/user-guide/pods/single-container/#deleting_a_pod) + 为pending中的pods提供空间。 + +* 检查该pod是否不大于您的节点。例如,如果全部节点具有`cpu:1`容量,那么具有`cpu: 1.1`请求的pod永远不会被调度。 + + 您可以使用`kubectl get nodes -o `命令来检查节点容量。 + 下面是一些能够提取必要信息的命令示例: + + kubectl get nodes -o yaml | grep '\sname\|cpu\|memory' + kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cap: .status.capacity}' + + 可以考虑配置[资源配额](/docs/concepts/policy/resource-quotas/)来限制可耗用的资源总量。如果与命名空间一起使用,它可以防止一个团队吞噬所有的资源。 + +#### 使用hostPort + +当你将一个pod绑定到一个`hostPort`时,这个pod能被调度的位置数量有限。 +在大多数情况下,`hostPort`是不必要的; 尝试使用服务对象来暴露您的pod。 +如果你需要`hostPort`,那么你可以调度的Pod数量不能超过集群的节点个数。 + +### 我的Pod一直在Waiting + +如果一个pod被卡在`Waiting`状态,那么它已被调度在某个工作节点,但它不能在该机器上运行。 +再次,来自`kubectl describe ...`的内容应该是可以提供信息的。 +最常见的原因`Waiting`的pod是无法拉取镜像。有三件事要检查: + +* 确保您的镜像的名称正确。 +* 您是否将镜像推送到存储库? +* 在您的机器上手动运行`docker pull `,看看是否可以拉取镜像。 + +### 我的Pod一直Crashing或者有别的不健康状态 + +首先,查看当前容器的日志: + + $ kubectl logs ${POD_NAME} ${CONTAINER_NAME} + +如果您的容器先前已崩溃,则可以访问上一个容器的崩溃日志: + + $ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME} + +或者,您可以使用`exec`在该容器内运行命令: + + $ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN} + +请注意,`-c ${CONTAINER_NAME}`是可选的,对于pod只包含一个容器可以省略。 + +例如,要查看正在运行的Cassandra pod的日志,可以运行: + + $ kubectl exec cassandra -- cat /var/log/cassandra/system.log + +如果这些方法都不起作用,您可以找到该运行pod所在的主机并SSH到该主机。 + +## 调试Replication Controllers + +Replication Controllers相当简单。他们能或不能创建pod。如果他们无法创建pod,那么请参考 +[上面的说明](#debugging_pods)来调试你的pod。 + +您也可以使用`kubectl describe rc ${CONTROLLER_NAME}`来检查和Replication Controllers有关的事件。 + From 831833d6b36f1f26bb59871ad77d618df731bcdc Mon Sep 17 00:00:00 2001 From: Weibin Lin Date: Sat, 16 Sep 2017 08:30:05 +0800 Subject: [PATCH 077/102] Update docs/admin/authentication.md (#5408) * Update docs/admin/authentication.md * Update authentication.md --- docs/admin/authentication.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/admin/authentication.md b/docs/admin/authentication.md index b0f4467527..c449d511ad 100644 --- a/docs/admin/authentication.md +++ b/docs/admin/authentication.md @@ -168,7 +168,7 @@ with a value of `Basic BASE64ENCODED(USER:PASSWORD)`. ### Service Account Tokens -Service accounts are an automatically enabled authenticator that uses signed +A service account is an automatically enabled authenticator that uses signed bearer tokens to verify requests. The plugin takes two optional flags: * `--service-account-key-file` A file containing a PEM encoded key for signing bearer tokens. @@ -281,8 +281,8 @@ Since all of the data needed to validate who you are is in the `id_token`, Kuber solution for authentication. It does offer a few challenges: 1. Kubernetes has no "web interface" to trigger the authentication process. There is no browser or interface to collect credentials which is why you need to authenticate to your identity provider first. -2. The `id_token` can't be revoked, it's like a certificate so it should be short-lived (only a few minutes) so it can be very annoying to have to get a new token every few minutes -3. There's no easy way to authenticate to the Kubernetes dashboard without using the `kubectl proxy` command or a reverse proxy that injects the `id_token` +2. The `id_token` can't be revoked, it's like a certificate so it should be short-lived (only a few minutes) so it can be very annoying to have to get a new token every few minutes. +3. There's no easy way to authenticate to the Kubernetes dashboard without using the `kubectl proxy` command or a reverse proxy that injects the `id_token`. #### Configuring the API Server @@ -728,7 +728,7 @@ Finally, add the following parameters into API server start parameters: ./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass 1. Generate server certificate and key. - (build-server-full [filename]: Generate a keypair and sign locally for a client or server) + (build-server-full [filename]: Generate a keypair and sign locally for a client or server.) ./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full server nopass 1. Copy `pki/ca.crt`, `pki/issued/server.crt`, and `pki/private/server.key` to your directory. @@ -748,7 +748,7 @@ Finally, add the following parameters into API server start parameters: 1. According to the ca.key generate a ca.crt (use -days to set the certificate effective time): openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt -1. Generate a server.key with 2048bit +1. Generate a server.key with 2048bit: openssl genrsa -out server.key 2048 1. According to the server.key generate a server.csr: From 667b7d474a07b5a9b72c1afd49427e39e657ed04 Mon Sep 17 00:00:00 2001 From: Kaitlyn Barnard Date: Fri, 15 Sep 2017 17:30:54 -0700 Subject: [PATCH 078/102] Adding Treasure Data to KCSP page (#5488) * Adding Treasure Data to KCSP page * Updating service partner text --- _includes/partner-script.js | 4 ++-- partners/index.html | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/_includes/partner-script.js b/_includes/partner-script.js index c77537e522..1eee70ad9f 100644 --- a/_includes/partner-script.js +++ b/_includes/partner-script.js @@ -261,7 +261,7 @@ }, { type: 2, - name: 'inwinSTACK', + name: 'InwinSTACK', logo: 'inwinstack', link: 'http://www.inwinstack.com/index.php/en/solutions-en/', blurb: 'Our container service leverages OpenStack-based infrastructure and its container orchestration engine Magnum to manage Kubernetes clusters.' @@ -498,7 +498,7 @@ blurb: 'Generate a real-time, auto-discovered application topology map! Monitor Kubernetes pods and namespaces without any code instrumentation.' }, { - type: 0, + type: 2, name: 'Treasure Data', logo: 'treasure-data', link: 'https://fluentd.treasuredata.com/kubernetes-logging/', diff --git a/partners/index.html b/partners/index.html index f19649cf77..7da3441835 100644 --- a/partners/index.html +++ b/partners/index.html @@ -17,7 +17,7 @@ cid: partners
Kubernetes Certified Service Providers
Vetted service providers with deep experience helping enterprises successfully adopt Kubernetes.

Technology Partners
Integrations and plugins that add features to Kubernetes applications.


-
Service Providers
Consulting or management services to help companies implement Kubernetes in commercial applications.

+
Service Partners
Consulting or management services to help companies implement Kubernetes in commercial applications.

Kubernetes Certified Service Providers (KCSP)

The KCSP program is a vetted tier of service providers who have deep experience helping enterprises successfully adopt Kubernetes. KCSP partners offer Kubernetes support, consulting, professional services and training for organizations embarking on their Kubernetes journey.

@@ -27,8 +27,8 @@ cid: partners

Technology partners offer integrations and plugins that add features to Kubernetes applications.

Interested in becoming a Technology Partner? Please fill out this form.

-

Services Partners

-

Service Providers offer consulting or management services to help companies implement and use Kubernetes in commercial applications.

+

Service Partners

+

Service Partners offer consulting or management services to help companies implement and use Kubernetes in commercial applications.

Interested in becoming a Service Provider? Please fill out this form

From 4aadfef47c8bf77eb812dc6567c5c6005cf45356 Mon Sep 17 00:00:00 2001 From: Sascha Marcel Schmidt Date: Sat, 16 Sep 2017 14:54:18 +0200 Subject: [PATCH 079/102] fixes #2749 --- docs/getting-started-guides/fedora/fedora_ansible_config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/fedora/fedora_ansible_config.md b/docs/getting-started-guides/fedora/fedora_ansible_config.md index a952a0cd4c..d6399f1b3f 100644 --- a/docs/getting-started-guides/fedora/fedora_ansible_config.md +++ b/docs/getting-started-guides/fedora/fedora_ansible_config.md @@ -147,9 +147,9 @@ dns_setup: true This will finally setup your whole Kubernetes cluster for you. ```shell -cd ~/contrib/ansible/ +cd ~/contrib/ansible/scripts/ -./scripts/deploy-cluster.sh +./deploy-cluster.sh ``` ## Testing and using your new cluster From c77139f1b484fdd901400aa4bc133db56fcbfd16 Mon Sep 17 00:00:00 2001 From: Ian Fisk Date: Sun, 17 Sep 2017 07:45:02 -0700 Subject: [PATCH 080/102] Fix spelling mistake. --- .../configure-access-multiple-clusters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md b/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md index 0f88d74b9a..1f73cbe204 100644 --- a/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md +++ b/docs/tasks/access-application-cluster/configure-access-multiple-clusters.md @@ -264,7 +264,7 @@ kubectl config view ``` The output shows merged information from all the files listed in your `KUBECONFIG` -environnment variable. In particular, notice that the merged information has the +environment variable. In particular, notice that the merged information has the `dev-ramp-up` context from the `config-demo-2` file and the three contexts from the `config-demo` file: From fc4731a77eb841ae7444d8699a74acef34936bc7 Mon Sep 17 00:00:00 2001 From: YuxiJin-tobeyjin Date: Mon, 18 Sep 2017 09:31:38 +0800 Subject: [PATCH 081/102] add envars.yaml --- cn/docs/tasks/inject-data-application/envars.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 cn/docs/tasks/inject-data-application/envars.yaml diff --git a/cn/docs/tasks/inject-data-application/envars.yaml b/cn/docs/tasks/inject-data-application/envars.yaml new file mode 100644 index 0000000000..97b296ac52 --- /dev/null +++ b/cn/docs/tasks/inject-data-application/envars.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: envar-demo + labels: + purpose: demonstrate-envars +spec: + containers: + - name: envar-demo-container + image: gcr.io/google-samples/node-hello:1.0 + env: + - name: DEMO_GREETING + value: "Hello from the environment" From 01c5fd384654adfd8f289250b9c4a52905eb9d77 Mon Sep 17 00:00:00 2001 From: Pingan2017 Date: Mon, 18 Sep 2017 19:24:19 +0800 Subject: [PATCH 082/102] ZTE-SH-CN-quota-pod-namespace.md-0918-10 --- .../administer-cluster/quota-pod-namespace.md | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 cn/docs/tasks/administer-cluster/quota-pod-namespace.md diff --git a/cn/docs/tasks/administer-cluster/quota-pod-namespace.md b/cn/docs/tasks/administer-cluster/quota-pod-namespace.md new file mode 100644 index 0000000000..201baa56eb --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-pod-namespace.md @@ -0,0 +1,134 @@ +--- +title: 配置命名空间下pod总数 +--- + + +{% capture overview %} + +本文主要描述如何配置一个命名空间下可运行的pod总数。资源配额详细信息可查看:[资源配额](/docs/api-reference/v1.7/#resourcequota-v1-core) +。 + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture steps %} + +## 创建一个命名空间 + +首先创建一个命名空间,这样可以将本次操作中创建的资源与集群其他资源隔离开来。 + +```shell +kubectl create namespace quota-pod-example +``` + +## 创建资源配额 + +下面是一个资源配额的配置文件: + +{% include code.html language="yaml" file="quota-pod.yaml" ghlink="/docs/tasks/administer-cluster/quota-pod.yaml" %} + +创建这个资源配额: + +```shell +kubectl create -f https://k8s.io/docs/tasks/administer-cluster/quota-pod.yaml --namespace=quota-pod-example +``` + +查看资源配额的详细信息: + +```shell +kubectl get resourcequota pod-demo --namespace=quota-pod-example --output=yaml +``` + +从输出的信息我们可以看到,该命名空间下pod的配额是2个,目前创建的pods数为0,配额使用率为0。 + +```yaml +spec: + hard: + pods: "2" +status: + hard: + pods: "2" + used: + pods: "0" +``` + +下面是一个Deployment的配置文件: + +{% include code.html language="yaml" file="quota-pod-deployment.yaml" ghlink="/docs/tasks/administer-cluster/quota-pod-deployment.yaml" %} + +在配置文件中, `replicas: 3` 告诉kubernetes尝试创建三个pods,且运行相同的应用。 + +创建这个Deployment: + +```shell +kubectl create -f https://k8s.io/docs/tasks/administer-cluster/quota-pod-deployment.yaml --namespace=quota-pod-example +``` + +查看Deployment的详细信息: + +```shell +kubectl get deployment pod-quota-demo --namespace=quota-pod-example --output=yaml +``` + +从输出的信息我们可以看到,尽管尝试创建三个pod,但是由于配额的限制,只有两个pod能被成功创建。 + +```yaml +spec: + ... + replicas: 3 +... +status: + availableReplicas: 2 +... +lastUpdateTime: 2017-07-07T20:57:05Z + message: 'unable to create pods: pods "pod-quota-demo-1650323038-" is forbidden: + exceeded quota: pod-demo, requested: pods=1, used: pods=2, limited: pods=2' +``` + +## 清理 + +删除命名空间: + +```shell +kubectl delete namespace quota-pod-example +``` + +{% endcapture %} + +{% capture whatsnext %} + +### 对于集群管理 + +* [配置命名空间下,内存默认的request值和limit值](/docs/tasks/administer-cluster/memory-default-namespace/) + +* [配置命名空间下,CPU默认的request值和limit值](/docs/tasks/administer-cluster/cpu-default-namespace/) + +* [配置命名空间下,内存的最小值和最大值](/docs/tasks/administer-cluster/memory-constraint-namespace/) + +* [配置命名空间下,CPU的最小值和最大值](/docs/tasks/administer-cluster/cpu-constraint-namespace/) + +* [配置命名空间下,内存和CPU的配额](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/) + +* [配置命名空间下,API对象的配额](/docs/tasks/administer-cluster/quota-api-object/) + +### 对于应用开发 + +* [给容器和pod分配内存资源](/docs/tasks/configure-pod-container/assign-memory-resource/) + +* [给容器和pod分配CPU资源](/docs/tasks/configure-pod-container/assign-cpu-resource/) + +* [配置pod的QoS](/docs/tasks/configure-pod-container/quality-service-pod/) + +{% endcapture %} + + +{% include templates/task.md %} + + From 99fbc2b4ae9a9a3c2fcb42d15337fa7efc0b36ca Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Mon, 18 Sep 2017 15:20:15 -0700 Subject: [PATCH 083/102] Monthly 404 fix (#5494) * Monthly 404 fix * WIP * 404 fixes cont * finish 404 fixes * file syntax tested and fixed * fix cn file for netlify preview * syntax cleanup for consistency --- _redirects | 156 ++++++++++++++---- .../inject-data-application/commands.yaml | 12 ++ .../define-command-argument-container.md | 2 +- 3 files changed, 137 insertions(+), 33 deletions(-) create mode 100644 cn/docs/tasks/inject-data-application/commands.yaml diff --git a/_redirects b/_redirects index 41059d2639..3ecb6d04c4 100644 --- a/_redirects +++ b/_redirects @@ -1,10 +1,11 @@ ############################################### # set server-side redirects in this file # # see https://www.netlify.com/docs/redirects/ # +# test at https://play.netlify.com/redirects # ############################################### /docs/admin/addons /docs/concepts/cluster-administration/addons 301 -/docs/admin/apparmor/ /docs/tutorials/clusters/apparmor 301 +/docs/admin/apparmor /docs/tutorials/clusters/apparmor 301 /docs/admin/audit /docs/tasks/debug-application-cluster/audit 301 /docs/admin/cluster-components /docs/concepts/overview/components 301 /docs/admin/cluster-management /docs/tasks/administer-cluster/cluster-management 301 @@ -23,7 +24,7 @@ /docs/admin/master-node-communication /docs/concepts/architecture/master-node-communication 301 /docs/admin/multi-cluster /docs/concepts/cluster-administration/federation 301 /docs/admin/multiple-schedulers /docs/tasks/administer-cluster/configure-multiple-schedulers 301 -/docs/admin/namespaces/ /docs/tasks/administer-cluster/namespaces 301 +/docs/admin/namespaces /docs/tasks/administer-cluster/namespaces 301 /docs/admin/namespaces/walkthrough /docs/tasks/administer-cluster/namespaces-walkthrough 301 /docs/admin/network-plugins /docs/concepts/cluster-administration/network-plugins 301 /docs/admin/networking /docs/concepts/cluster-administration/networking 301 @@ -73,7 +74,7 @@ /docs/concepts/tools/kubectl/object-management-using-imperative-commands /docs/tutorials/object-management-kubectl/imperative-object-management-command 301 /docs/concepts/tools/kubectl/object-management-using-imperative-config /docs/tutorials/object-management-kubectl/imperative-object-management-configuration 301 -/docs/getting-started-guides/ /docs/setup/pick-right-solution 301 +/docs/getting-started-guides /docs/setup/pick-right-solution 301 /docs/getting-started-guides/kubeadm /docs/setup/independent/create-cluster-kubeadm 301 /docs/getting-started-guides/network-policy/calico /docs/tasks/administer-cluster/calico-network-policy 301 /docs/getting-started-guides/network-policy/romana /docs/tasks/administer-cluster/romana-network-policy 301 @@ -90,7 +91,7 @@ /docs/tasks/administer-cluster/assign-pods-nodes /docs/tasks/configure-pod-container/assign-pods-nodes 301 /docs/tasks/administer-cluster/overview /docs/concepts/cluster-administration/cluster-administration-overview 301 /docs/tasks/administer-cluster/cpu-memory-limit /docs/tasks/administer-cluster/memory-default-namespace 301 -/docs/tasks/administer-cluster/share-configuration/ /docs/tasks/access-application-cluster/configure-access-multiple-clusters 301 +/docs/tasks/administer-cluster/share-configuration /docs/tasks/access-application-cluster/configure-access-multiple-clusters 301 /docs/tasks/configure-pod-container/apply-resource-quota-limit /docs/tasks/administer-cluster/apply-resource-quota-limit 301 /docs/tasks/configure-pod-container/calico-network-policy /docs/tasks/administer-cluster/calico-network-policy 301 @@ -110,7 +111,7 @@ /docs/tasks/kubectl/list-all-running-container-images /docs/tasks/access-application-cluster/list-all-running-container-images 301 /docs/tasks/manage-stateful-set/debugging-a-statefulset /docs/tasks/debug-application-cluster/debug-stateful-set 301 -/docs/tasks/manage-stateful-set/delete-pods docs/tasks/run-application/force-delete-stateful-set-pod 301 +/docs/tasks/manage-stateful-set/delete-pods /docs/tasks/run-application/force-delete-stateful-set-pod 301 /docs/tasks/manage-stateful-set/deleting-a-statefulset /docs/tasks/run-application/delete-stateful-set 301 /docs/tasks/manage-stateful-set/scale-stateful-set /docs/tasks/run-application/scale-stateful-set 301 /docs/tasks/manage-stateful-set/upgrade-pet-set-to-stateful-set /docs/tasks/run-application/upgrade-pet-set-to-stateful-set 301 @@ -119,7 +120,7 @@ /docs/tasks/troubleshoot/debug-init-containers /docs/tasks/debug-application-cluster/debug-init-containers 301 /docs/tasks/web-ui-dashboard /docs/tasks/access-application-cluster/web-ui-dashboard 301 /docs/templatedemos /docs/home/contribute/page-templates 301 -/docs/tools/kompose/ /docs/tools/kompose/user-guide 301 +/docs/tools/kompose /docs/tools/kompose/user-guide 301 /docs/tutorials/clusters/multiple-schedulers /docs/tasks/administer-cluster/configure-multiple-schedulers 301 /docs/tutorials/connecting-apps/connecting-frontend-backend /docs/tasks/access-application-cluster/connecting-frontend-backend 301 @@ -134,12 +135,12 @@ /docs/tutorials/stateless-application/run-stateless-application-deployment /docs/tasks/run-application/run-stateless-application-deployment 301 /docs/user-guide/accessing-the-cluster /docs/tasks/access-application-cluster/access-cluster 301 -/docs/user-guide/add-entries-to-pod-etc-hosts-with-host-aliases/ /docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases 301 +/docs/user-guide/add-entries-to-pod-etc-hosts-with-host-aliases /docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases 301 /docs/user-guide/annotations /docs/concepts/overview/working-with-objects/annotations 301 /docs/user-guide/application-troubleshooting /docs/tasks/debug-application-cluster/debug-application 301 /docs/user-guide/compute-resources /docs/concepts/configuration/manage-compute-resources-container 301 /docs/user-guide/config-best-practices /docs/concepts/configuration/overview 301 -/docs/user-guide/configmap/ /docs/tasks/configure-pod-container/configmap 301 +/docs/user-guide/configmap /docs/tasks/configure-pod-container/configmap 301 /docs/user-guide/configuring-containers /docs/tasks/ 301 /docs/user-guide/connecting-applications /docs/concepts/services-networking/connect-applications-service 301 /docs/user-guide/connecting-to-applications-port-forward /docs/tasks/access-application-cluster/port-forward-access-application-cluster 301 @@ -150,9 +151,9 @@ /docs/user-guide/debugging-services /docs/tasks/debug-application-cluster/debug-service 301 /docs/user-guide/deploying-applications /docs/tasks/run-application/run-stateless-application-deployment 301 /docs/user-guide/deployments /docs/concepts/workloads/controllers/deployment 301 -/docs/user-guide/downward-api/ /docs/tasks/inject-data-application/downward-api-volume-expose-pod-information 301 -/docs/user-guide/downward-api/volume/ /docs/tasks/inject-data-application/downward-api-volume-expose-pod-information 301 -/docs/user-guide/environment-guide/ /docs/tasks/inject-data-application/environment-variable-expose-pod-information 301 +/docs/user-guide/downward-api /docs/tasks/inject-data-application/downward-api-volume-expose-pod-information 301 +/docs/user-guide/downward-api/volume /docs/tasks/inject-data-application/downward-api-volume-expose-pod-information 301 +/docs/user-guide/environment-guide /docs/tasks/inject-data-application/environment-variable-expose-pod-information 301 /docs/user-guide/federation/cluster /docs/tasks/administer-federation/cluster 301 /docs/user-guide/federation/configmap /docs/tasks/administer-federation/configmap 301 /docs/user-guide/federation/daemonsets /docs/tasks/administer-federation/daemonset 301 @@ -160,24 +161,24 @@ /docs/user-guide/federation/events /docs/tasks/administer-federation/events 301 /docs/user-guide/federation/federated-ingress /docs/tasks/administer-federation/ingress 301 /docs/user-guide/federation/federated-services /docs/tasks/federation/federation-service-discovery 301 -/docs/user-guide/federation/ /docs/concepts/cluster-administration/federation 301 +/docs/user-guide/federation /docs/concepts/cluster-administration/federation 301 /docs/user-guide/federation/namespaces /docs/tasks/administer-federation/namespaces 301 /docs/user-guide/federation/replicasets /docs/tasks/administer-federation/replicaset 301 /docs/user-guide/federation/secrets /docs/tasks/administer-federation/secret 301 /docs/user-guide/garbage-collection /docs/concepts/workloads/controllers/garbage-collection 301 /docs/user-guide/getting-into-containers /docs/tasks/debug-application-cluster/get-shell-running-container 301 /docs/user-guide/gpus /docs/tasks/manage-gpus/scheduling-gpus 301 -/docs/user-guide/horizontal-pod-autoscaling/ /docs/tasks/run-application/horizontal-pod-autoscale 301 +/docs/user-guide/horizontal-pod-autoscaling /docs/tasks/run-application/horizontal-pod-autoscale 301 /docs/user-guide/horizontal-pod-autoscaling/walkthrough /docs/tasks/run-application/horizontal-pod-autoscale-walkthrough 301 /docs/user-guide/identifiers /docs/concepts/overview/working-with-objects/names 301 /docs/user-guide/images /docs/concepts/containers/images 301 -/docs/user-guide/ /docs/home/ 301 +/docs/user-guide /docs/home/ 301 /docs/user-guide/ingress /docs/concepts/services-networking/ingress 301 /docs/user-guide/introspection-and-debugging /docs/tasks/debug-application-cluster/debug-application-introspection 301 /docs/user-guide/jobs /docs/concepts/workloads/controllers/jobs-run-to-completion 301 -/docs/user-guide/jobs/expansions/ /docs/tasks/job/parallel-processing-expansion 301 -/docs/user-guide/jobs/work-queue-1/ /docs/tasks/job/coarse-parallel-processing-work-queue/ 301 -/docs/user-guide/jobs/work-queue-2/ /docs/tasks/job/fine-parallel-processing-work-queue/ 301 +/docs/user-guide/jobs/expansions /docs/tasks/job/parallel-processing-expansion 301 +/docs/user-guide/jobs/work-queue-1 /docs/tasks/job/coarse-parallel-processing-work-queue/ 301 +/docs/user-guide/jobs/work-queue-2 /docs/tasks/job/fine-parallel-processing-work-queue/ 301 /docs/user-guide/kubeconfig-file /docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig 301 /docs/user-guide/labels /docs/concepts/overview/working-with-objects/labels 301 /docs/user-guide/liveness /docs/tasks/configure-pod-container/configure-liveness-readiness-probes 301 @@ -189,37 +190,37 @@ /docs/user-guide/monitoring /docs/tasks/debug-application-cluster/resource-usage-monitoring 301 /docs/user-guide/namespaces /docs/concepts/overview/working-with-objects/namespaces 301 /docs/user-guide/networkpolicies /docs/concepts/services-networking/network-policies 301 -/docs/user-guide/node-selection/ /docs/concepts/configuration/assign-pod-node 301 -/docs/user-guide/persistent-volumes/ /docs/concepts/storage/persistent-volumes 301 +/docs/user-guide/node-selection /docs/concepts/configuration/assign-pod-node 301 +/docs/user-guide/persistent-volumes /docs/concepts/storage/persistent-volumes 301 /docs/user-guide/persistent-volumes/walkthrough /docs/tasks/configure-pod-container/configure-persistent-volume-storage 301 /docs/user-guide/petset /docs/concepts/workloads/controllers/petset 301 -/docs/user-guide/petset/bootstrapping/ /docs/concepts/workloads/controllers/petset 301 -/docs/user-guide/pod-preset/ /docs/tasks/inject-data-application/podpreset 301 -/docs/user-guide/pod-security-policy/ /docs/concepts/policy/pod-security-policy 301 +/docs/user-guide/petset/bootstrapping /docs/concepts/workloads/controllers/petset 301 +/docs/user-guide/pod-preset /docs/tasks/inject-data-application/podpreset 301 +/docs/user-guide/pod-security-policy /docs/concepts/policy/pod-security-policy 301 /docs/user-guide/pod-states /docs/concepts/workloads/pods/pod-lifecycle 301 /docs/user-guide/pod-templates /docs/concepts/workloads/pods/pod-overview 301 -/docs/user-guide/pods/ /docs/concepts/workloads/pods/pod 301 +/docs/user-guide/pods /docs/concepts/workloads/pods/pod 301 /docs/user-guide/pods/init-container /docs/concepts/workloads/pods/init-containers 301 /docs/user-guide/pods/multi-container /docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume 301 /docs/user-guide/pods/single-container /docs/tasks/run-application/run-stateless-application-deployment 301 /docs/user-guide/prereqs /docs/tasks/tools/install-kubectl 301 /docs/user-guide/production-pods /docs/tasks/ 301 -/docs/user-guide/projected-volume/ /docs/tasks/configure-pod-container/configure-projected-volume-storage 301 +/docs/user-guide/projected-volume /docs/tasks/configure-pod-container/configure-projected-volume-storage 301 /docs/user-guide/quick-start /docs/tasks/access-application-cluster/service-access-application-cluster 301 /docs/user-guide/replicasets /docs/concepts/workloads/controllers/replicaset 301 -/docs/user-guide/replication-controller/ /docs/concepts/workloads/controllers/replicationcontroller 301 +/docs/user-guide/replication-controller /docs/concepts/workloads/controllers/replicationcontroller 301 /docs/user-guide/rolling-updates /docs/tasks/run-application/rolling-update-replication-controller 301 -/docs/user-guide/secrets/ /docs/concepts/configuration/secret 301 +/docs/user-guide/secrets /docs/concepts/configuration/secret 301 /docs/user-guide/secrets/walkthrough /docs/tasks/inject-data-application/distribute-credentials-secure 301 /docs/user-guide/service-accounts /docs/tasks/configure-pod-container/configure-service-account 301 /docs/user-guide/services-firewalls /docs/tasks/access-application-cluster/configure-cloud-provider-firewall 301 -/docs/user-guide/services/ /docs/concepts/services-networking/service 301 +/docs/user-guide/services /docs/concepts/services-networking/service 301 /docs/user-guide/services/operations /docs/tasks/access-application-cluster/connecting-frontend-backend 301 /docs/user-guide/sharing-clusters /docs/tasks/administer-cluster/share-configuration 301 /docs/user-guide/simple-nginx /docs/tasks/run-application/run-stateless-application-deployment 301 /docs/user-guide/thirdpartyresources /docs/tasks/access-kubernetes-api/extend-api-third-party-resource 301 /docs/user-guide/ui /docs/tasks/access-application-cluster/web-ui-dashboard 301 -/docs/user-guide/update-demo/ /docs/tasks/run-application/rolling-update-replication-controller 301 +/docs/user-guide/update-demo /docs/tasks/run-application/rolling-update-replication-controller 301 /docs/user-guide/volumes /docs/concepts/storage/volumes 301 /docs/user-guide/working-with-resources /docs/tutorials/object-management-kubectl/object-management 301 @@ -229,7 +230,7 @@ ############## # address 404s # -/concepts/containers/container-lifecycle-hooks /docs/concepts/containers/container-lifecycle-hooks 301 +/concepts/containers/container-lifecycle-hooks /docs/concepts/containers/container-lifecycle-hooks 301 /docs/api-reference/apps/v1alpha1/definitions https://v1-4.docs.kubernetes.io/docs/api-reference/apps/v1alpha1/definitions 301 /docs/api-reference/apps/v1beta1/operations https://v1-4.docs.kubernetes.io/docs/api-reference/apps/v1beta1/operations 301 @@ -279,12 +280,12 @@ /docs/stable/user-guide/labels /docs/concepts/overview/working-with-objects/labels 301 /docs/tasks/access-application-cluster/access-cluster.md /docs/tasks/access-application-cluster/access-cluster 301 -/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/ /docs/tasks/access-application-cluster/configure-access-multiple-clusters 301 +/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig /docs/tasks/access-application-cluster/configure-access-multiple-clusters 301 /docs/tasks/access-kubernetes-api/access-kubernetes-api/http-proxy-access-api /docs/tasks/access-kubernetes-api/http-proxy-access-api 301 /docs/tasks/administer-cluster/reserve-compute-resources/out-of-resource.md /docs/tasks/administer-cluster/out-of-resource 301 /docs/tasks/configure-pod-container/configure-pod-disruption-budget /docs/tasks/run-application/configure-pdb 301 /docs/tasks/configure-pod-container/define-command-argument-container /docs/tasks/inject-data-application/define-command-argument-container 301 -/docs/tasks/debug-application-cluster/sematext-logging-monitoring https://sematext.com/kubernetes/ 301 +/docs/tasks/debug-application-cluster/sematext-logging-monitoring https://sematext.com/kubernetes/ 301 /docs/tasks/job/work-queue-1 /docs/concepts/workloads/controllers/jobs-run-to-completion 301 /docs/tasks/manage-stateful-set/delete-pods /docs/tasks/run-application/delete-stateful-set 301 @@ -306,7 +307,7 @@ /kubernetes-bootcamp/2-1.html /docs/tutorials/kubernetes-basics 301 /kubernetes-bootcamp/2-3-2.html /docs/tutorials/kubernetes-basics 301 /kubernetes /docs 301 -/kubernetes/swagger-spec https://github.com/kubernetes/kubernetes/tree/master/api/swagger-spec 301 +/kubernetes/swagger-spec https://github.com/kubernetes/kubernetes/tree/master/api/swagger-spec 301 /serviceaccount/token /docs/tasks/configure-pod-container/configure-service-account 301 /v1.1/docs/admin/networking.html /docs/concepts/cluster-administration/networking 301 @@ -358,3 +359,94 @@ # Redirect users with chinese language preference to /cn # #/ /cn 302 Language=zh + + +########################### +# Fixed 404s from analytics + +/concepts/containers/container-lifecycle-hooks /docs/concepts/containers/container-lifecycle-hooks 301 +/docs/abstractions/controllers/petset /docs/concepts/workloads/controllers/petset 301 + +/docs/admin/add-ons /docs/concepts/cluster-administration/addons 301 +/docs/admin/limitrange/Limits /docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage 301 + +/docs/api-reference/1_5/* /docs/api-reference/v1.5 301 + +/docs/concepts/cluster-administration/device-plugins /docs/concepts/cluster-administration/network-plugins 301 +/docs/concepts/configuration/container-command-args /docs/tasks/inject-data-application/define-command-argument-container 301 +/docs/concepts/ecosystem/thirdpartyresource /docs/tasks/access-kubernetes-api/extend-api-third-party-resource 301 +/docs/concepts/overview /docs/concepts/overview/what-is-kubernetes 301 +/docs/concepts/policy/container-capabilities /docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container 301 +/docs/concepts/policy/security-context /docs/tasks/configure-pod-container/security-context 301 +/docs/concepts/storage/volumes/emptyDirapiVersion /docs/concepts/storage/volumes/#emptydir 301 +/docs/concepts/tools/kubectl/object-management-using-commands /docs/tutorials/object-management-kubectl/imperative-object-management-command 301 +/docs/concepts/workload/pods/pod-overview /docs/concepts/workloads/pods/pod-overview 301 +/docs/concepts/workloads/controllers/cron-jobs/deployment /docs/concepts/workloads/controllers/cron-jobs 301 +/docs/concepts/workloads/controllers/statefulsets /docs/concepts/workloads/controllers/statefulset 301 +/docs/concepts/workloads/pods/init-containers/Kubernetes /docs/concepts/workloads/pods/init-containers 301 + +/docs/consumer-guideline/pod-security-coverage /docs/concepts/policy/pod-security-policy 301 + +/docs/contribute/create-pull-request /docs/home/contribute/create-pull-request 301 +/docs/contribute/page-templates /docs/home/contribute/page-templates 301 +/docs/contribute/review-issues /docs/home/contribute/review-issues 301 +/docs/contribute/stage-documentation-changes /docs/home/contribute/stage-documentation-changes 301 +/docs/contribute/style-guide /docs/home/contribute/style-guide 301 + +/docs/deprecated /docs/reference/deprecation-policy 301 +/docs/deprecation-policy /docs/reference/deprecation-policy 301 + + +/docs/federation/api-reference /docs/reference/federation/v1/operations 301 +/docs/federation/api-reference/extensions/v1beta1/operations /docs/reference/federation/extensions/v1beta1/operations 301 +/docs/federation/api-reference/federation/v1beta1/operations /docs/reference/federation/extensions/v1beta1/operations 301 +/docs/federation/api-reference/v1/operations /docs/reference/federation/v1/operations 301 + +/docs/getting-started-guide/* /docs/setup 301 + +/docs/home/deprecation-policy /docs/reference/deprecation-policy 301 + +/docs/resources-reference/1_5/* /docs/resources-reference/v1.5 301 +/docs/resources-reference/1_6/* /docs/resources-reference/v1.6 301 +/docs/resources-reference/1_7/* /docs/resources-reference/v1.7 301 + +/docs/stable/user-guide/labels /docs/concepts/overview/working-with-objects/labels 301 + + +/docs/tasks/administer-cluster/apply-resource-quota-limit /docs/tasks/administer-cluster/quota-api-object 301 +/docs/tasks/administer-cluster/configure-namespace-isolation /docs/concepts/services-networking/network-policies 301 +/docs/tasks/administer-cluster/configure-pod-disruption-budget /docs/tasks/run-application/configure-pdb 301 + +/docs/tasks/administer-cluster/cpu-management-policies /docs/concepts/configuration/manage-compute-resources-container 301 +/docs/tasks/administer-cluster/default-cpu-request-limit /docs/tasks/configure-pod-container/assign-cpu-resource/#specify-a-cpu-request-and-a-cpu-limit 301 +/docs/tasks/administer-cluster/default-memory-request-limit /docs/tasks/configure-pod-container/assign-memory-resource/#specify-a-memory-request-and-a-memory-limit 301 + +/docs/tasks/configure-pod-container/cilium-network-policy /docs/tasks/administer-cluster/cilium-network-policy 301 +/docs/tasks/configure-pod-container/define-command-argument-container /docs/tasks/inject-data-application/define-command-argument-container 301 +/docs/tasks/configure-pod-container/projected-volume /docs/tasks/configure-pod-container/configure-projected-volume-storage 301 + +/docs/tasks/stateful-sets/deleting-pods /docs/tasks/run-application/force-delete-stateful-set-pod 301 + +/docs/templatedemos/* /docs/home/contribute/page-templates 301 + +/docs/tutorials/getting-started/* /docs/tutorials/kubernetes-basics 301 + +/docs/user-guide/federation/* /docs/concepts/cluster-administration/federation 301 +/docs/user-guide/garbage-collector /docs/concepts/workloads/controllers/garbage-collection 301 +/docs/user-guide/horizontal-pod-autoscaler/* /docs/tasks/run-application/horizontal-pod-autoscale 301 + + +/docs/user-guide/liveness /docs/tasks/configure-pod-container/configure-liveness-readiness-probes 301 +/docs/user-guide/logging /docs/concepts/cluster-administration/logging 301 +/docs/user-guide/replication-controller/operations /docs/concepts/workloads/controllers/replicationcontroller 301 +/docs/user-guide/service-accounts/working-with-resources /docs/tutorials/object-management-kubectl/object-management 301 +/docs/user-guide/StatefulSet /docs/concepts/workloads/controllers/statefulset 301 +/docs/user-guide/ui-access /docs/tasks/access-application-cluster/web-ui-dashboard 301 + +/kubernetes-bootcamp/* /docs/tutorials/kubernetes-basics 301 + +/latest/docs /docs/home 301 + +/kubernetes/swagger-spec https://github.com/kubernetes/kubernetes/tree/master/api/swagger-spec 301 +/swagger-spec/* https://github.com/kubernetes/kubernetes/tree/master/api/swagger-spec 301 +/third_party/swagger-ui/* /docs/reference 301 diff --git a/cn/docs/tasks/inject-data-application/commands.yaml b/cn/docs/tasks/inject-data-application/commands.yaml new file mode 100644 index 0000000000..8d58007db4 --- /dev/null +++ b/cn/docs/tasks/inject-data-application/commands.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: command-demo + labels: + purpose: demonstrate-command +spec: + containers: + - name: command-demo-container + image: debian + command: ["printenv"] + args: ["HOSTNAME", "KUBERNETES_PORT"] diff --git a/cn/docs/tasks/inject-data-application/define-command-argument-container.md b/cn/docs/tasks/inject-data-application/define-command-argument-container.md index bce7ea8589..23fce58e28 100644 --- a/cn/docs/tasks/inject-data-application/define-command-argument-container.md +++ b/cn/docs/tasks/inject-data-application/define-command-argument-container.md @@ -30,7 +30,7 @@ title: 为容器设置启动时要执行的命令及其入参 本示例中,将创建一个只包含单个容器的Pod。在Pod配置文件中设置了一个命令与两个入参: -{% include code.html language="yaml" file="commands.yaml" ghlink="/docs/tasks/inject-data-application/commands.yaml" %} +{% include code.html language="yaml" file="commands.yaml" ghlink="/cn/docs/tasks/inject-data-application/commands.yaml" %} 1. 基于YAML文件创建一个Pod: From 5095e3ea39edf437ac40971243de316460315758 Mon Sep 17 00:00:00 2001 From: zouyee Date: Tue, 19 Sep 2017 10:32:13 +0800 Subject: [PATCH 084/102] fix version.md link --- docs/concepts/overview/kubernetes-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/overview/kubernetes-api.md b/docs/concepts/overview/kubernetes-api.md index b24aef8824..7d106aa58f 100644 --- a/docs/concepts/overview/kubernetes-api.md +++ b/docs/concepts/overview/kubernetes-api.md @@ -39,7 +39,7 @@ multiple API versions, each at a different API path, such as `/api/v1` or We chose to version at the API level rather than at the resource or field level to ensure that the API presents a clear, consistent view of system resources and behavior, and to enable controlling access to end-of-lifed and/or experimental APIs. The JSON and Protobuf serialization schemas follow the same guidelines for schema changes - all descriptions below cover both formats. Note that API versioning and Software versioning are only indirectly related. The [API and release -versioning proposal](https://git.k8s.io/community/contributors/design-proposals/versioning.md) describes the relationship between API versioning and +versioning proposal](https://git.k8s.io/community/contributors/design-proposals/release/versioning.md) describes the relationship between API versioning and software versioning. From 7a9ab3eda692ba9bc8954b64ee9aa759a9130508 Mon Sep 17 00:00:00 2001 From: zouyee Date: Tue, 19 Sep 2017 10:46:51 +0800 Subject: [PATCH 085/102] update api-group link --- docs/concepts/overview/kubernetes-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/overview/kubernetes-api.md b/docs/concepts/overview/kubernetes-api.md index b24aef8824..17a38c553f 100644 --- a/docs/concepts/overview/kubernetes-api.md +++ b/docs/concepts/overview/kubernetes-api.md @@ -68,7 +68,7 @@ in more detail in the [API Changes documentation](https://git.k8s.io/community/c ## API groups -To make it easier to extend the Kubernetes API, we implemented [*API groups*](https://git.k8s.io/community/contributors/design-proposals/api-group.md). +To make it easier to extend the Kubernetes API, we implemented [*API groups*](https://git.k8s.io/community/contributors/design-proposals/api-machinery/api-group.md). The API group is specified in a REST path and in the `apiVersion` field of a serialized object. Currently there are several API groups in use: From 6f76cc9145ab0148975fd5b550950d426482e58e Mon Sep 17 00:00:00 2001 From: zouyee Date: Tue, 19 Sep 2017 11:16:03 +0800 Subject: [PATCH 086/102] update aggregated-api-servers.md link --- docs/concepts/overview/kubernetes-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/overview/kubernetes-api.md b/docs/concepts/overview/kubernetes-api.md index b24aef8824..b4edde8992 100644 --- a/docs/concepts/overview/kubernetes-api.md +++ b/docs/concepts/overview/kubernetes-api.md @@ -84,7 +84,7 @@ There are two supported paths to extending the API with [custom resources](/docs 1. [CustomResourceDefinition](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/) is for users with very basic CRUD needs. 1. Coming soon: users needing the full set of Kubernetes API semantics can implement their own apiserver - and use the [aggregator](https://git.k8s.io/community/contributors/design-proposals/aggregated-api-servers.md) + and use the [aggregator](https://git.k8s.io/community/contributors/design-proposals/api-machinery/aggregated-api-servers.md) to make it seamless for clients. From 08479e46db83bd3ac2d2df4c8d7ed3d688625bef Mon Sep 17 00:00:00 2001 From: kairen Date: Tue, 19 Sep 2017 13:50:04 +0800 Subject: [PATCH 087/102] Fix incorrect links --- docs/tasks/run-application/horizontal-pod-autoscale.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/tasks/run-application/horizontal-pod-autoscale.md b/docs/tasks/run-application/horizontal-pod-autoscale.md index 7e3722e393..83489f38de 100644 --- a/docs/tasks/run-application/horizontal-pod-autoscale.md +++ b/docs/tasks/run-application/horizontal-pod-autoscale.md @@ -12,7 +12,7 @@ This document describes the current state of Horizontal Pod Autoscaling in Kuber With Horizontal Pod Autoscaling, Kubernetes automatically scales the number of pods in a replication controller, deployment or replica set based on observed CPU utilization -(or, with alpha support, on some other, application-provided metrics). Note that Horizontal +(or, with alpha support, on some other, application-provided metrics). Note that Horizontal Pod Autoscaling does not apply to objects that can't be scaled, for example, DaemonSet. The Horizontal Pod Autoscaler is implemented as a Kubernetes API resource and a controller. @@ -44,7 +44,7 @@ or the custom metrics API (for all other metrics). Please note that if some of the pod's containers do not have the relevant resource request set, CPU utilization for the pod will not be defined and the autoscaler will not take any action - for that metric. See the [autoscaling algorithm design document](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md#autoscaling-algorithm) for further + for that metric. See the [autoscaling algorithm design document](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#autoscaling-algorithm) for further details about how the autoscaling algorithm works. * For per-pod custom metrics, the controller functions similarly to per-pod resource metrics, @@ -64,7 +64,7 @@ See [Support for custom metrics](#support-for-custom-metrics) for more details o The autoscaler accesses corresponding replication controller, deployment or replica set by scale sub-resource. Scale is an interface that allows you to dynamically set the number of replicas and examine each of their current states. -More details on scale sub-resource can be found [here](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md#scale-subresource). +More details on scale sub-resource can be found [here](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#scale-subresource). ## API Object @@ -78,7 +78,7 @@ can be found in `autoscaling/v2alpha1`. The new fields introduced in `autoscalin are preserved as annotations when working with `autoscaling/v1`. More details about the API object can be found at -[HorizontalPodAutoscaler Object](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md#horizontalpodautoscaler-object). +[HorizontalPodAutoscaler Object](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#horizontalpodautoscaler-object). ## Support for Horizontal Pod Autoscaler in kubectl @@ -149,6 +149,6 @@ custom metrics API with the API aggregation layer. Both of these API servers mus ## Further reading -* Design documentation: [Horizontal Pod Autoscaling](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md). +* Design documentation: [Horizontal Pod Autoscaling](https://git.k8s.io/community/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md). * kubectl autoscale command: [kubectl autoscale](/docs/user-guide/kubectl/v1.6/#autoscale). * Usage example of [Horizontal Pod Autoscaler](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/). From 308e243a5f4a9e7f885440bf644148751cd038e8 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Tue, 19 Sep 2017 14:45:32 +0800 Subject: [PATCH 088/102] update the admission-controllers.md index.md what-is-kubernetes.md link --- docs/admin/admission-controllers.md | 6 +++--- docs/concepts/overview/what-is-kubernetes.md | 2 +- docs/reference/index.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/admin/admission-controllers.md b/docs/admin/admission-controllers.md index 6be627e481..e25bc55fcb 100644 --- a/docs/admin/admission-controllers.md +++ b/docs/admin/admission-controllers.md @@ -238,7 +238,7 @@ When the plug-in sets a compute resource request, it does this by *annotating* t the pod spec rather than mutating the `container.resources` fields. The annotations added contain the information on what compute resources were auto-populated. -See the [InitialResouces proposal](https://git.k8s.io/community/contributors/design-proposals/initial-resources.md) for more details. +See the [InitialResouces proposal](https://git.k8s.io/community/contributors/design-proposals/autoscaling/initial-resources.md) for more details. ### LimitPodHardAntiAffinity @@ -253,7 +253,7 @@ your Kubernetes deployment, you MUST use this plug-in to enforce those constrain be used to apply default resource requests to Pods that don't specify any; currently, the default LimitRanger applies a 0.1 CPU requirement to all Pods in the `default` namespace. -See the [limitRange design doc](https://git.k8s.io/community/contributors/design-proposals/admission_control_limit_range.md) and the [example of Limit Range](/docs/tasks/configure-pod-container/limit-range/) for more details. +See the [limitRange design doc](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md) and the [example of Limit Range](/docs/tasks/configure-pod-container/limit-range/) for more details. ### NamespaceAutoProvision @@ -373,7 +373,7 @@ This plug-in will observe the incoming request and ensure that it does not viola enumerated in the `ResourceQuota` object in a `Namespace`. If you are using `ResourceQuota` objects in your Kubernetes deployment, you MUST use this plug-in to enforce quota constraints. -See the [resourceQuota design doc](https://git.k8s.io/community/contributors/design-proposals/admission_control_resource_quota.md) and the [example of Resource Quota](/docs/concepts/policy/resource-quotas/) for more details. +See the [resourceQuota design doc](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md) and the [example of Resource Quota](/docs/concepts/policy/resource-quotas/) for more details. It is strongly encouraged that this plug-in is configured last in the sequence of admission control plug-ins. This is so that quota is not prematurely incremented only for the request to be rejected later in admission control. diff --git a/docs/concepts/overview/what-is-kubernetes.md b/docs/concepts/overview/what-is-kubernetes.md index 502a35864f..a34d5cd0fb 100644 --- a/docs/concepts/overview/what-is-kubernetes.md +++ b/docs/concepts/overview/what-is-kubernetes.md @@ -93,7 +93,7 @@ Even though Kubernetes provides a lot of functionality, there are always new sce Additionally, the [Kubernetes control plane](/docs/concepts/overview/components/) is built upon the same [APIs](/docs/reference/api-overview/) that are available to developers and users. Users can write their own controllers, such as [schedulers](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/devel/scheduler.md), with [their own APIs](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/extending-api.md) that can be targeted by a general-purpose [command-line tool](/docs/user-guide/kubectl-overview/). -This [design](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/principles.md) has enabled a number of other systems to build atop Kubernetes. +This [design](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/architecture/principles.md) has enabled a number of other systems to build atop Kubernetes. #### What Kubernetes is not diff --git a/docs/reference/index.md b/docs/reference/index.md index 8560829169..44bfce50f4 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -40,4 +40,4 @@ client libraries: ## Design Docs -An archive of the design docs for Kubernetes functionality. Good starting points are [Kubernetes Architecture](https://git.k8s.io/community/contributors/design-proposals/architecture.md) and [Kubernetes Design Overview](https://github.com/kubernetes/kubernetes/tree/{{page.fullversion}}/docs/design). +An archive of the design docs for Kubernetes functionality. Good starting points are [Kubernetes Architecture](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md) and [Kubernetes Design Overview](https://github.com/kubernetes/kubernetes/tree/{{page.fullversion}}/docs/design). From 5e07e96abf1082e8a238ff37b9cf90fbd3f71827 Mon Sep 17 00:00:00 2001 From: "Tim(Xiaoyu) Zhang" Date: Tue, 19 Sep 2017 16:21:28 +0800 Subject: [PATCH 089/102] use para. page.version to replace specific version --- .../run-application/rolling-update-replication-controller.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/run-application/rolling-update-replication-controller.md b/docs/tasks/run-application/rolling-update-replication-controller.md index 6fc36ad889..867321e23b 100644 --- a/docs/tasks/run-application/rolling-update-replication-controller.md +++ b/docs/tasks/run-application/rolling-update-replication-controller.md @@ -131,7 +131,7 @@ Optional fields are: is `1m0s`. Valid units are as described for `--poll-interval` above. Additional information about the `kubectl rolling-update` command is available -from the [`kubectl` reference](/docs/user-guide/kubectl/v1.6/#rolling-update). +from the [`kubectl` reference](/docs/user-guide/kubectl/{{page.version}}/#rolling-update). ## Walkthrough From d47d4044770b98a1a2ccdf115e3737b0de05492d Mon Sep 17 00:00:00 2001 From: Pingan2017 Date: Tue, 19 Sep 2017 18:53:52 +0800 Subject: [PATCH 090/102] ZTE-SH-CN-rolling-update-replication-controller.md-5 --- .../rolling-update-replication-controller.md | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 cn/docs/tasks/run-application/rolling-update-replication-controller.md diff --git a/cn/docs/tasks/run-application/rolling-update-replication-controller.md b/cn/docs/tasks/run-application/rolling-update-replication-controller.md new file mode 100644 index 0000000000..e7fe348aa8 --- /dev/null +++ b/cn/docs/tasks/run-application/rolling-update-replication-controller.md @@ -0,0 +1,225 @@ +--- +approvers: +- janetkuo +title: 基于Replication Controller执行滚动升级 +--- + +* TOC +{:toc} + +## 概述 + +**注**: 创建副本应用的首选方法是使用[Deployment](/docs/api-reference/{{page.version}}/#deployment-v1beta1-apps),Deployment使用[ReplicaSet](/docs/api-reference/{{page.version}}/#replicaset-v1beta1-extensions)来进行副本控制。 +更多信息, 查看[使用Deployment运行一个无状态应用](/docs/tasks/run-application/run-stateless-application-deployment/)。 + +为了在更新服务的同时不中断业务, `kubectl` 支持['滚动更新'](/docs/user-guide/kubectl/v1.6/#rolling-update),它一次更新一个pod,而不是同时停止整个服务。 有关更多信息,请参阅 [滚动更新设计文档](https://git.k8s.io/community/contributors/design-proposals/simple-rolling-update.md) 和 [滚动更新示例](/docs/tasks/run-application/rolling-update-replication-controller/)。 + +请注意, `kubectl rolling-update` 仅支持Replication Controllers。 但是,如果使用Replication Controllers部署应用,请考虑将其切换到[Deployments](/docs/concepts/workloads/controllers/deployment/). Deployment是一种被推荐使用的更高级别的控制器,它可以对应用进行声明性的自动滚动更新。 如果您仍然希望保留您的Replication Controllers并使用 `kubectl rolling-update`进行滚动更新, 请继续往下阅读: + +滚动更新可以对replication controller所管理的Pod的配置进行变更,变更可以通过一个新的配置文件来进行,或者,如果只更新镜像,则可以直接指定新的容器镜像。 + +滚动更新的工作流程: + +1. 通过新的配置创建一个replication controller +2. 在新的控制器上增加副本数,在旧的上面减少副本数,直到副本数达到期望值 +3. 删除之前的replication controller + +使用`kubectl rolling-update`命令来进行滚动更新: + + $ kubectl rolling-update NAME \ + ([NEW_NAME] --image=IMAGE | -f FILE) + +## 通过配置文件更新 + +通过配置文件来进行滚动更新,需要在`kubectl rolling-update`命令后面带上新的配置文件: + + $ kubectl rolling-update NAME -f FILE + +这个配置文件必须满足以下条件: + +* 指定不同的`metadata.name`值 + +* 至少要修改`spec.selector`中的一个标签值 + +* `metadata.namespace`字段必须相同 + +Replication Controllers的配置文件详细介绍见[创建Replication Controllers](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/). + +### 示例 + + // 通过新的配置文件frontend-v2.json来更新frontend-v1的pods + $ kubectl rolling-update frontend-v1 -f frontend-v2.json + + // 将frontend-v2.json数据传到标准输入来更新frontend-v1的pods + $ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - + +## 更新容器镜像 + +仅更新容器镜像的话,可通过如下命令,该命令可以指定一个新的控制器名称(可选),通过`--image`参数来指定新的镜像名称和标签。 + + $ kubectl rolling-update NAME [NEW_NAME] --image=IMAGE:TAG + +`--image`参数仅支持单容器pod,多容器pod使用`--image`参数会返回错误。 + +如果没有指定 `NEW_NAME` ,新的replication controller创建后会使用一个临时名称,当更新完成,旧的controller被删除后,新的controller名称会被更新成旧的controller名称。 + +如果`IMAGE:TAG` 和当前值相同,更新就会失败。 因此,我们建议使用版本号来作为标签,而不是使用 `:latest`。从一个 `image:latest`镜像升级到一个新的 `image:latest` 镜像将会失败,即使这两个镜像不是相同的。 +所以,我们不建议使用 `:latest` 来作为标签,详细信息见[最佳配置实践](/docs/concepts/configuration/overview/#container-images) 。 + +### 示例 + + // 更新frontend-v1的pod到frontend-v2 + $ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 + + // 更新frontend的pods,不更改replication controller的名称 + $ kubectl rolling-update frontend --image=image:v2 + +## 必选和可选字段 + +必选字段: + +* `NAME`: 需要进行滚动更新的replication controller名称 + +下面两个字段选其一: + +* `-f FILE`: 新的replication controller的配置文件,JSON或者YAML格式均可。配置文件必须指定一个新的顶层`id`值,且至少包含一个现有`spec.selector`中的键值对。 + 详细信息见[通过Replication Controller运行无状态应用](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/#replication-controller-configuration-file)。 +
+
+ 或者: +
+
+* `--image IMAGE:TAG`: 更新后的镜像的名称和标签。必须和当前的image:tag不同。 + +可选字段包括: + +* `NEW_NAME`: 只和 `--image` 一起使用,不和 `-f FILE` 一起使用。标识新的replication controller的名称。 +* `--poll-interval DURATION`: 在更新后轮询控制器状态的间隔时间。有效单位有 `ns` (纳秒),`us` 或 `µs`(微秒),`ms`(毫秒),`s`(秒),`m`(分钟)或 `h`(小时)。 单位可以自由组合(例如 `1m30s`)。 默认值为 `3s`。 +* `--timeout DURATION`: 退出更新之前,等待控制器更新一个pod的最大时间。默认是`5m0s`。有效单位如`--poll-interval`所述。 +* `--update-period DURATION`: 更新两个pod之间等待的时间,默认值是`1m0s`。有效单位如`--poll-interval`所述。 + +有关`kubectl rolling-update`命令的更多信息见[`kubectl`参考](/docs/user-guide/kubectl/v1.6/#rolling-update). + +## 实践 + +现在你运行了一个1.7.9版本的nginx应用: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: my-nginx +spec: + replicas: 5 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 +``` + +要更新到1.9.1版本,你可以使用[`kubectl rolling-update --image`](https://git.k8s.io/community/contributors/design-proposals/simple-rolling-update.md)来指定一个新的镜像: + +```shell +$ kubectl rolling-update my-nginx --image=nginx:1.9.1 +Created my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 +``` + +在终端上打开另一个窗口 ,你可以看到`kubectl` 给每个pod都增加了一个值为配置文件哈希值的 `deployment` 标签,用来区分新旧pod: + +```shell +$ kubectl get pods -l app=nginx -L deployment +NAME READY STATUS RESTARTS AGE DEPLOYMENT +my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-k156z 1/1 Running 0 1m ccba8fbd8cc8160970f63f9a2696fc46 +my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-v95yh 1/1 Running 0 35s ccba8fbd8cc8160970f63f9a2696fc46 +my-nginx-divi2 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e +my-nginx-o0ef1 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e +my-nginx-q6all 1/1 Running 0 8m 2d1d7a8f682934a254002b56404b813e +``` + +使用`kubectl rolling-update`可以实时看到更新的进度: + +``` +Scaling up my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 0 to 3, scaling down my-nginx from 3 to 0 (keep 3 pods available, don't exceed 4 pods) +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 1 +Scaling my-nginx down to 2 +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 2 +Scaling my-nginx down to 1 +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 3 +Scaling my-nginx down to 0 +Update succeeded. Deleting old controller: my-nginx +Renaming my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 to my-nginx +replicationcontroller "my-nginx" rolling updated +``` + +如果遇到问题,你可以中途停止滚动更新,并且使用 `--rollback` 来回滚到以前的版本: + +```shell +$ kubectl rolling-update my-nginx --rollback +Setting "my-nginx" replicas to 1 +Continuing update with existing controller my-nginx. +Scaling up nginx from 1 to 1, scaling down my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 1 to 0 (keep 1 pods available, don't exceed 2 pods) +Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 down to 0 +Update succeeded. Deleting my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 +replicationcontroller "my-nginx" rolling updated +``` + +这个例子说明容器的不变性是个巨大的优点。 + +如果你不仅仅是需要更新镜像,(例如,更新命令参数,环境变量等),你可以创建一个新的replication controller配置文件,包含一个新的名称和不同的标签值,例如: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: my-nginx-v4 +spec: + replicas: 5 + selector: + app: nginx + deployment: v4 + template: + metadata: + labels: + app: nginx + deployment: v4 + spec: + containers: + - name: nginx + image: nginx:1.9.2 + args: ["nginx", "-T"] + ports: + - containerPort: 80 +``` + +然后使用它来进行更新: + +```shell +$ kubectl rolling-update my-nginx -f ./nginx-rc.yaml +Created my-nginx-v4 +Scaling up my-nginx-v4 from 0 to 5, scaling down my-nginx from 4 to 0 (keep 4 pods available, don't exceed 5 pods) +Scaling my-nginx-v4 up to 1 +Scaling my-nginx down to 3 +Scaling my-nginx-v4 up to 2 +Scaling my-nginx down to 2 +Scaling my-nginx-v4 up to 3 +Scaling my-nginx down to 1 +Scaling my-nginx-v4 up to 4 +Scaling my-nginx down to 0 +Scaling my-nginx-v4 up to 5 +Update succeeded. Deleting old controller: my-nginx +replicationcontroller "my-nginx-v4" rolling updated +``` + +## 故障分析 + +如果更新过程中,达到超时时长`timeout`后还没更新完成,则更新会失败。这时,一些pod会属于新的replication controller,一些会属于旧的。 + +如果更新失败,可以尝试使用同样的命令来继续更新过程。 + +在尝试更新之前如果需要回滚到之前的状态,可在之前的命令后面添加`--rollback=true`参数,这将回退所有的更改。 From f81b83998efd352f7cec4b0276dd11d17527859b Mon Sep 17 00:00:00 2001 From: qingsenLi Date: Tue, 19 Sep 2017 14:03:32 +0000 Subject: [PATCH 091/102] ZTE-SH-CN-debug-stateful-set-2017-09-19 --- .../debug-stateful-set.md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 cn/docs/tasks/debug-application-cluster/debug-stateful-set.md diff --git a/cn/docs/tasks/debug-application-cluster/debug-stateful-set.md b/cn/docs/tasks/debug-application-cluster/debug-stateful-set.md new file mode 100644 index 0000000000..9b77f375a6 --- /dev/null +++ b/cn/docs/tasks/debug-application-cluster/debug-stateful-set.md @@ -0,0 +1,77 @@ +--- +title: 调试StatefulSet +--- + +{% capture overview %} + +此任务展示如何调试StatefulSet。 + +{% endcapture %} + +{% capture prerequisites %} + + +* 你需要有一个Kubernetes集群,通过必要的配置使kubectl命令行工具与您的集群进行通信。 +* 你应该有一个运行中的StatefulSet,以便用于调试。 + +{% endcapture %} + +{% capture steps %} + +## 调试StatefulSet + +由于StatefulSet在创建时设置了`app=myapp`标签,列出仅属于该StatefulSet的所有pod时,可以使用以下命令: + +```shell +kubectl get pods -l app=myapp +``` + +如果您发现列出的任何Pods长时间处于`Unknown` 或`Terminating`状态,关于如何处理它们的说明任务,请参阅[删除 StatefulSet Pods](/docs/tasks/manage-stateful-set/delete-pods/)。您可以参考[调试 Pods](/docs/user-guide/debugging-pods-and-replication-controllers/#debugging-pods)指南来调试StatefulSet中的各个Pod。 + +StatefulSets提供调试机制,可以使用注解来暂停所有控制器在Pod上的操作。在任何StatefulSet Pod上设置`pod.alpha.kubernetes.io/initialized`注解为`"false"`将*暂停* StatefulSet的所有操作。暂停时,StatefulSet将不执行任何伸缩操作。一旦调试钩子设置完成后,就可以在StatefulSet pod的容器内执行命令,而不会造成伸缩操作的干扰。您可以通过执行以下命令将注解设置为`"false"`: + +```shell +kubectl annotate pods pod.alpha.kubernetes.io/initialized="false" --overwrite +``` + +当注解设置为`"false"`时,StatefulSet在其Pods变得不健康或不可用时将不会响应。StatefulSet不会创建副本Pod直到每个Pod上删除注解或将注解设置为`"true"`。 + +### 逐步初始化 + +创建StatefulSet之前,您可以通过使用和上文相同的注解,即将yaml文件中`.spec.template.metadata.annotations`里的`pod.alpha.kubernetes.io/initialized`字段设置为`"false"`,对竞态条件的StatefulSet进行调试。 + +```yaml +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: my-app +spec: + serviceName: "my-app" + replicas: 3 + template: + metadata: + labels: + app: my-app + annotations: + pod.alpha.kubernetes.io/initialized: "false" +... +... +... + +``` + +设置注解后,如果创建了StatefulSet,您可以等待每个Pod来验证它是否正确初始化。StatefulSet将不会创建任何后续的Pods,直到在已经创建的每个Pod上将调试注解设置为`"true"` (或删除)。 您可以通过执行以下命令将注解设置为`"true"`: + +```shell +kubectl annotate pods pod.alpha.kubernetes.io/initialized="true" --overwrite +``` + +{% endcapture %} + +{% capture whatsnext %} + +点击链接[调试init-container](/docs/tasks/troubleshoot/debug-init-containers/),了解更多信息。 + +{% endcapture %} + +{% include templates/task.md %} From 0bcdd3c714b0bf8a937dcc2e6ec13f98c00bd9a8 Mon Sep 17 00:00:00 2001 From: wangyamei Date: Tue, 19 Sep 2017 09:14:26 -0400 Subject: [PATCH 092/102] ZTE-SH-CN-configure-pod-container-opaque-integer-resource-2017-09-19-22 --- .../opaque-integer-resource.md | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 cn/docs/tasks/configure-pod-container/opaque-integer-resource.md diff --git a/cn/docs/tasks/configure-pod-container/opaque-integer-resource.md b/cn/docs/tasks/configure-pod-container/opaque-integer-resource.md new file mode 100644 index 0000000000..7e2a42ef20 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/opaque-integer-resource.md @@ -0,0 +1,137 @@ +--- +title: 给容器分配非透明整型资源 +--- + +{% capture overview %} + +本页展示了如何给容器分配非透明整型资源。 + +{% include feature-state-alpha.md %} + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +在做这个练习之前,请在[给节点配置非透明整型资源](/docs/tasks/administer-cluster/opaque-integer-resource-node/)文档中进行练习, +该文档介绍了在一个节点上配置dongle资源。 + +{% endcapture %} + + +{% capture steps %} + +## 给Pod分配非透明整型资源 + +为了请求一个非透明整型资源,需要在容器配置文件中包含`resources:requests`字段。 +非透明整型资源类型前缀是`pod.alpha.kubernetes.io/opaque-int-resource-`。 + +下面是含有一个容器的Pod的配置文件: + +{% include code.html language="yaml" file="oir-pod.yaml" ghlink="/cn/docs/tasks/configure-pod-container/oir-pod.yaml" %} + +在配置文件中,可以看到容器请求了3个dongles资源。 + +创建Pod: + +```shell +kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/oir-pod.yaml +``` + +验证Pod是否正在运行: + +```shell +kubectl get pod oir-demo +``` + +查询Pod的状态: + +```shell +kubectl describe pod oir-demo +``` + +输出显示了dongle请求: + +```yaml +Requests: + pod.alpha.kubernetes.io/opaque-int-resource-dongle: 3 +``` + +## 尝试创建第二个Pod + +下面是含有一个容器的Pod的配置文件。该容器请求了两个dongles资源。 + +{% include code.html language="yaml" file="oir-pod-2.yaml" ghlink="/docs/tasks/configure-pod-container/oir-pod-2.yaml" %} + +Kubernetes无法再满足两个dongles的请求,因为第一个Pod已经使用了四个可用dongles中的三个。 + +尝试创建Pod: + +```shell +kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/oir-pod-2.yaml +``` + +查询Pod的状态 + +```shell +kubectl describe pod oir-demo-2 +``` + +输出显示该Pod无法被调度,因为没有节点有两个可用的dongles资源: + + +``` +Conditions: + Type Status + PodScheduled False +... +Events: + ... + ... Warning FailedScheduling pod (oir-demo-2) failed to fit in any node +fit failure summary on nodes : Insufficient pod.alpha.kubernetes.io/opaque-int-resource-dongle (1) +``` + +查看Pod的状态: + +```shell +kubectl get pod oir-demo-2 +``` + +输出显示Pod已创建,但是没有被调度并运行在节点上。 +它的状态为Pending: + +```yaml +NAME READY STATUS RESTARTS AGE +oir-demo-2 0/1 Pending 0 6m +``` + +## 删除 + +删除本练习中创建的Pod: + +```shell +kubectl delete pod oir-demo +``` + +{% endcapture %} + +{% capture whatsnext %} + +### 对于应用开发者 + +* [分配内存资源](/docs/tasks/configure-pod-container/assign-memory-resource/) +* [分配CPU资源](/docs/tasks/configure-pod-container/assign-cpu-resource/) + +### 对于集群管理员 + +* [给节点配置非透明整型资源](/docs/tasks/administer-cluster/opaque-integer-resource-node/) + +{% endcapture %} + + +{% include templates/task.md %} + + + From db0623830e164d01c8fd07a5099b82f56c7dccf8 Mon Sep 17 00:00:00 2001 From: jianglingxia Date: Tue, 19 Sep 2017 14:13:29 +0800 Subject: [PATCH 093/102] fix link of secret --- docs/concepts/configuration/secret.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/concepts/configuration/secret.md b/docs/concepts/configuration/secret.md index 102eee8648..3cc7671b7f 100644 --- a/docs/concepts/configuration/secret.md +++ b/docs/concepts/configuration/secret.md @@ -7,7 +7,7 @@ title: Secrets Objects of type `secret` are intended to hold sensitive information, such as passwords, OAuth tokens, and ssh keys. Putting this information in a `secret` is safer and more flexible than putting it verbatim in a `pod` definition or in -a docker image. See [Secrets design document](https://git.k8s.io/community/contributors/design-proposals/secrets.md) for more information. +a docker image. See [Secrets design document](https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md) for more information. * TOC {:toc} @@ -118,7 +118,7 @@ data: ``` The data field is a map. Its keys must match -[`DNS_SUBDOMAIN`](https://git.k8s.io/community/contributors/design-proposals/identifiers.md), except that leading dots are also +[`DNS_SUBDOMAIN`](https://git.k8s.io/community/contributors/design-proposals/architecture/identifiers.md), except that leading dots are also allowed. The values are arbitrary data, encoded using base64. Create the secret using [`kubectl create`](/docs/user-guide/kubectl/v1.7/#create): @@ -688,7 +688,7 @@ the app needs. For improved performance over a looping `get`, clients can design resources that reference a secret then `watch` the resource, re-requesting the secret when the reference changes. Additionally, a ["bulk watch" API]( -https://github.com/kubernetes/community/blob/master/contributors/design-proposals/bulk_watch.md) +https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/bulk_watch.md) to let clients `watch` individual resources has also been proposed, and will likely be available in future releases of Kubernetes. From cd67108ba72d128a584a63f07387f43996d78df7 Mon Sep 17 00:00:00 2001 From: Kyle Bai Date: Wed, 20 Sep 2017 06:22:19 +0800 Subject: [PATCH 094/102] Remove User FAQ refer links (#5467) * Remove User FAQ refer links * Remove all of the wiki refer links --- _data/tasks.yml | 4 ---- docs/home/index.md | 6 ------ docs/tasks/debug-application-cluster/debug-application.md | 4 ---- docs/tasks/debug-application-cluster/troubleshooting.md | 6 ------ 4 files changed, 20 deletions(-) diff --git a/_data/tasks.yml b/_data/tasks.yml index 8bc8f7b50e..fce07a3f5d 100644 --- a/_data/tasks.yml +++ b/_data/tasks.yml @@ -158,8 +158,6 @@ toc: - docs/tasks/administer-cluster/configure-multiple-schedulers.md - docs/tasks/administer-cluster/ip-masq-agent.md - docs/tasks/administer-cluster/dns-custom-nameservers.md - - title: Change Cluster Size - path: https://github.com/kubernetes/kubernetes/wiki/User-FAQ#how-do-i-change-the-size-of-my-cluster/ - title: Federation - Run an App on Multiple Clusters section: @@ -185,5 +183,3 @@ toc: - title: Manage GPUs section: - docs/tasks/manage-gpus/scheduling-gpus.md - - diff --git a/docs/home/index.md b/docs/home/index.md index 187d5cc672..d9cdc94f34 100644 --- a/docs/home/index.md +++ b/docs/home/index.md @@ -34,9 +34,3 @@ The [Tools](/docs/tools/) page contains a list of native and third-party tools f ## Troubleshooting The [Troubleshooting](/docs/tasks/debug-application-cluster/troubleshooting) page outlines some resources for troubleshooting and finding help. - -## Frequently Asked Questions - -* [User FAQ](https://github.com/kubernetes/kubernetes/wiki/User-FAQ) -* [Debugging FAQ](https://github.com/kubernetes/kubernetes/wiki/Debugging-FAQ) -* [Services FAQ](https://github.com/kubernetes/kubernetes/wiki/Services-FAQ) diff --git a/docs/tasks/debug-application-cluster/debug-application.md b/docs/tasks/debug-application-cluster/debug-application.md index 4a8004e850..3b7a17a0c6 100644 --- a/docs/tasks/debug-application-cluster/debug-application.md +++ b/docs/tasks/debug-application-cluster/debug-application.md @@ -12,10 +12,6 @@ This is *not* a guide for people who want to debug their cluster. For that you * TOC {:toc} -## FAQ - -Users are highly encouraged to check out our [FAQ](https://github.com/kubernetes/kubernetes/wiki/User-FAQ). - ## Diagnosing the problem The first step in troubleshooting is triage. What is the problem? Is it your Pods, your Replication Controller or diff --git a/docs/tasks/debug-application-cluster/troubleshooting.md b/docs/tasks/debug-application-cluster/troubleshooting.md index a70bad2954..1bcbcc2c9c 100644 --- a/docs/tasks/debug-application-cluster/troubleshooting.md +++ b/docs/tasks/debug-application-cluster/troubleshooting.md @@ -31,12 +31,6 @@ development scenarios. The [Reference](/docs/reference/) section provides detailed documentation on the [Kubernetes API](/docs/api-reference/{{page.version}}/) and command-line interfaces (CLIs), such as [`kubectl`](/docs/user-guide/kubectl-overview/). -We also have a number of FAQ pages: - - * [User FAQ](https://github.com/kubernetes/kubernetes/wiki/User-FAQ) - * [Debugging FAQ](https://github.com/kubernetes/kubernetes/wiki/Debugging-FAQ) - * [Services FAQ](https://github.com/kubernetes/kubernetes/wiki/Services-FAQ) - You may also find the Stack Overflow topics relevant: * [Kubernetes](http://stackoverflow.com/questions/tagged/kubernetes) From ec3671b0ea2377724148e57ec024a92d6085b733 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Wed, 20 Sep 2017 14:35:28 +0200 Subject: [PATCH 095/102] psp.yaml: add allowedCapabilities: '*' to permissive PSP. --- docs/concepts/policy/psp.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/concepts/policy/psp.yaml b/docs/concepts/policy/psp.yaml index 9f037f67d0..f82f7a856f 100644 --- a/docs/concepts/policy/psp.yaml +++ b/docs/concepts/policy/psp.yaml @@ -16,3 +16,5 @@ spec: max: 8080 volumes: - '*' + allowedCapabilities: + - '*' From 91f526421da1f369ffc9063f3283c65c6f6a4a9b Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Wed, 20 Sep 2017 15:29:58 +0200 Subject: [PATCH 096/102] Fix some broken links to proposals. --- _data/reference.yml | 8 ++++---- cn/docs/concepts/architecture/nodes.md | 2 +- docs/api-reference/v1.7/index.html | 4 ++-- docs/concepts/architecture/nodes.md | 2 +- .../federation/extensions/v1beta1/definitions.html | 2 +- docs/resources-reference/v1.7/index.html | 4 ++-- docs/tasks/configure-pod-container/security-context.md | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/_data/reference.yml b/_data/reference.yml index 108635adab..e86d87fae2 100644 --- a/_data/reference.yml +++ b/_data/reference.yml @@ -90,16 +90,16 @@ toc: - title: Kubernetes Design Docs section: - title: Kubernetes Architecture - path: https://git.k8s.io/community/contributors/design-proposals/architecture.md + path: https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md - title: Kubernetes Design Overview path: https://github.com/kubernetes/kubernetes/tree/release-1.6/docs/design - title: Kubernetes Identity and Access Management - path: https://git.k8s.io/community/contributors/design-proposals/access.md + path: https://git.k8s.io/community/contributors/design-proposals/auth/access.md - docs/admin/ovs-networking.md - title: Security Contexts - path: https://git.k8s.io/community/contributors/design-proposals/security_context.md + path: https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md - title: Security in Kubernetes - path: https://git.k8s.io/community/contributors/design-proposals/security.md + path: https://git.k8s.io/community/contributors/design-proposals/auth/security.md - title: Kubernetes Issues and Security section: diff --git a/cn/docs/concepts/architecture/nodes.md b/cn/docs/concepts/architecture/nodes.md index 1e611c896a..f5159814d7 100644 --- a/cn/docs/concepts/architecture/nodes.md +++ b/cn/docs/concepts/architecture/nodes.md @@ -18,7 +18,7 @@ redirect_from: ## 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.md#the-kubernetes-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 状态 diff --git a/docs/api-reference/v1.7/index.html b/docs/api-reference/v1.7/index.html index 893ed4ea10..a4a4b2aac5 100644 --- a/docs/api-reference/v1.7/index.html +++ b/docs/api-reference/v1.7/index.html @@ -191,7 +191,7 @@ Appears In: securityContext
SecurityContext -Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://git.k8s.io/community/contributors/design-proposals/security_context.md +Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md stdin
boolean @@ -59749,7 +59749,7 @@ Appears In: seLinuxOptions
SELinuxOptions -seLinuxOptions required to run as; required for MustRunAs More info: https://git.k8s.io/community/contributors/design-proposals/security_context.md +seLinuxOptions required to run as; required for MustRunAs More info: https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md diff --git a/docs/concepts/architecture/nodes.md b/docs/concepts/architecture/nodes.md index 43c5d722c0..ec213463e5 100644 --- a/docs/concepts/architecture/nodes.md +++ b/docs/concepts/architecture/nodes.md @@ -14,7 +14,7 @@ A `node` is a worker machine in Kubernetes, previously known as a `minion`. A no may be a VM or physical machine, depending on the cluster. Each node has the services necessary to run [pods](/docs/user-guide/pods) and is managed by the master components. The services on a node include Docker, kubelet and kube-proxy. See -[The Kubernetes Node](https://git.k8s.io/community/contributors/design-proposals/architecture.md#the-kubernetes-node) section in the +[The Kubernetes Node](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node) section in the architecture design doc for more details. ## Node Status diff --git a/docs/reference/federation/extensions/v1beta1/definitions.html b/docs/reference/federation/extensions/v1beta1/definitions.html index 1d63515168..24da7f55d8 100755 --- a/docs/reference/federation/extensions/v1beta1/definitions.html +++ b/docs/reference/federation/extensions/v1beta1/definitions.html @@ -5778,7 +5778,7 @@ Both these may change in the future. Incoming requests are matched against the h

securityContext

-

Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://git.k8s.io/community/contributors/design-proposals/security_context.md

+

Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md

false

v1.SecurityContext

diff --git a/docs/resources-reference/v1.7/index.html b/docs/resources-reference/v1.7/index.html index 89073c6965..cfd98274c9 100644 --- a/docs/resources-reference/v1.7/index.html +++ b/docs/resources-reference/v1.7/index.html @@ -124,7 +124,7 @@ Appears In: securityContext
SecurityContext -Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://git.k8s.io/community/contributors/design-proposals/security_context.md +Security options the pod should run with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ More info: https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md stdin
boolean @@ -12868,7 +12868,7 @@ Appears In: seLinuxOptions
SELinuxOptions -seLinuxOptions required to run as; required for MustRunAs More info: https://git.k8s.io/community/contributors/design-proposals/security_context.md +seLinuxOptions required to run as; required for MustRunAs More info: https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md diff --git a/docs/tasks/configure-pod-container/security-context.md b/docs/tasks/configure-pod-container/security-context.md index 92a7c00935..a86c920827 100644 --- a/docs/tasks/configure-pod-container/security-context.md +++ b/docs/tasks/configure-pod-container/security-context.md @@ -342,7 +342,7 @@ label given to all Containers in the Pod as well as the Volumes. * [PodSecurityContext](/docs/api-reference/{{page.version}}/#podsecuritycontext-v1-core) * [SecurityContext](/docs/api-reference/{{page.version}}/#securitycontext-v1-core) * [Tuning Docker with the newest security enhancements](https://opensource.com/business/15/3/docker-security-tuning) -* [Security Contexts design document](https://git.k8s.io/community/contributors/design-proposals/security_context.md) +* [Security Contexts design document](https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md) * [Ownership Management design document](https://git.k8s.io/community/contributors/design-proposals/volume-ownership-management.md) * [Pod Security Policies](/docs/concepts/policy/pod-security-policy/) From a3f3056ff0202c4651222622c069a1b26f872736 Mon Sep 17 00:00:00 2001 From: zhangqx2010 Date: Thu, 21 Sep 2017 12:08:16 +0800 Subject: [PATCH 097/102] update webhook.md --- cn/docs/admin/authorization/webhook.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cn/docs/admin/authorization/webhook.md b/cn/docs/admin/authorization/webhook.md index a3015eb8e7..bbf95d52b9 100644 --- a/cn/docs/admin/authorization/webhook.md +++ b/cn/docs/admin/authorization/webhook.md @@ -11,7 +11,7 @@ title: Webhook Mode {% capture overview %} -WebHook 是一个 HTTP 回调:当某些事情发生时的一个 HTTP POST 请求;通过 HTTP POST 发送的一个简单事件通知。一个继续 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL 。 +WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL 。 {% endcapture %} @@ -42,8 +42,8 @@ WebHook 是一个 HTTP 回调:当某些事情发生时的一个 HTTP POST 请 clusters: - name: name-of-remote-authz-service cluster: - certificate-authority: /path/to/ca.pem # 用于确认远程服务的CA. - server: https://authz.example.com/authorize # 远程服务的查询 URL. 必须是 'https'. + certificate-authority: /path/to/ca.pem # 对远程服务进行身份认证的CA。 + server: https://authz.example.com/authorize # 远程服务的查询 URL. 必须使用 'https'。 # users 代表 API 服务器的 webhook 配置. users: @@ -52,7 +52,7 @@ users: client-certificate: /path/to/cert.pem # webhook plugin 使用的 cert。 client-key: /path/to/key.pem # cert 所对应的 key。 -# kubeconfig 文件必须有上下文. 需要提供一个给 API 服务器. +# kubeconfig 文件必须有 context 。 需要提供一个给 API 服务器。 current-context: webhook contexts: - context: @@ -77,8 +77,8 @@ contexts: -需要注意的是 webhook API 对象对于 [versioning compatibility rules](/docs/api/) 和其他 Kuberntes API 来说是同一个主题。 -实施人员应该了解 beta 对象的松耦合承诺,同时确认请求的 "apiVersion" 字段以确保能被正确地反序列化。 +需要注意的是 webhook API 对象与其他 Kubernetes API 对象一样都同样都服从 [版本兼容规则](/docs/api/) 。 +实施人员应该了解 beta 对象的更宽松的兼容性承诺,同时确认请求的 "apiVersion" 字段以确保能被正确地反序列化。 此外,API 服务器还必须启用 `authorization.k8s.io/v1beta1` API 扩展组(`--runtime-config=authorization.k8s.io/v1beta1=true`)。 @@ -108,7 +108,7 @@ contexts: 远程服务被预期能填写请求和反馈的 SubjectAccessReviewStatus 字段,无论是允许访问还是拒绝访问。 -反馈内容的 "spec" 字段是被忽略的,也是可以被省略的。一个允许的反馈的返回值会是: +反馈内容的 "spec" 字段是被忽略的,也是可以被省略的。当请求是被允许的时候,返回的响应如下例所示: ```json { @@ -164,7 +164,7 @@ contexts: 非资源类的路径包括:`/api`, `/apis`, `/metrics`, `/resetMetrics`, `/logs`, `/debug`, `/healthz`, `/swagger-ui/`, `/swaggerapi/`, `/ui`, and `/version`。 客户端需要访问 `/api`, `/api/*`, `/apis`, `/apis/*`, 和 `/version` 以便 -能发现服务器上有什么资源和版本。对于其他非资源类的路径访问在没有 REST api 访问限制的情况下拒绝。 +能发现服务器上有什么资源和版本。对于其他非资源类的路径访问在没有 REST API 访问限制的情况下拒绝。 From bbf6a50f6df3c730d78e573154516aac43677f5d Mon Sep 17 00:00:00 2001 From: zhangqx2010 Date: Thu, 21 Sep 2017 12:10:16 +0800 Subject: [PATCH 098/102] update bootstrap-tokens.md --- cn/docs/admin/bootstrap-tokens.md | 69 +++++++++++++++---------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/cn/docs/admin/bootstrap-tokens.md b/cn/docs/admin/bootstrap-tokens.md index 45d613e278..c3e95f3837 100644 --- a/cn/docs/admin/bootstrap-tokens.md +++ b/cn/docs/admin/bootstrap-tokens.md @@ -2,7 +2,7 @@ assignees: - jbeda -title: Webhook 模式 +title: 使用启动引导令牌(Bootstrap Tokens)认证 --- * TOC @@ -17,10 +17,10 @@ title: Webhook 模式 -启动引导令牌是一种简单的 bearer token ,这种令牌是在新建集群或者在现有集群中添加新加新节点时使用的。 -它被设计成能支持 [`kubeadm`](/docs/admin/kubeadm/),但是也可以被用在其他上下文中以便用户在 -不使用 `kubeadm` 的情况下启动cluster。它也被设计成可以通过 RBAC 策略,结合[Kubelet TLS -Bootstrapping](/cn/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 +启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群或者在现有集群中添加新加新节点时使用的。 +它被设计成能够支持 [`kubeadm`](/docs/admin/kubeadm/),但是也可以被用在其他 context 中以便用户在 +不使用 `kubeadm` 的情况下启动集群。它也被设计成可以通过 RBAC 策略,结合 [Kubelet TLS +Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 @@ -29,15 +29,14 @@ Bootstrapping](/cn/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 -启动引导令牌被定义成一个特定类型的secrets (`bootstrap.kubernetes.io/token`),并存在于 +启动引导令牌被定义成一个特定类型的 secrets(`bootstrap.kubernetes.io/token`),并存在于 `kube-system` 命名空间中。然后这些 secrets 会被 API 服务器上的启动引导的认证器读取。 -过期的令牌与令牌清除控制器会被控制管理器一起清除。令牌也会被用于创建签名,签名用于 -启动引导签名控制器在 "discovery" 进程中特定的 configmap 。 +过期的令牌与 TokenCleaner 会被控制管理器一起清除。令牌也会被用于创建特定 configmap 的签名, +而这个 configmap 会通过启动引导签名控制器在 "discovery" 过程中使用。 - -目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性的变化。 +目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性变化。 ## 令牌格式 @@ -51,14 +50,14 @@ Bootstrapping](/cn/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 -令牌的第一部分是 "Token ID" ,它是公共信息。它被用于引用一个 token 用于认证而不会泄漏保密部分。 +令牌的第一部分是 "Token ID" ,它是公共信息。它被用于引用一个用于认证的令牌而不会泄漏令牌的保密部分。 第二部分是 "Token Secret",它应该只能被信任方共享。 ## 启用启动引导令牌 -所有启动引导令牌的特新在 Kubernetes v1.6 版本中都是默认禁用的。 +所有启动引导令牌的特性在 Kubernetes v1.6 版本中默认都是禁用的。 @@ -68,7 +67,7 @@ Bootstrapping](/cn/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 你可以在 API 服务器上通过 `--experimental-bootstrap-token-auth` 参数启用启动引导令牌。 你可以在控制管理器上通过 `--controllers` 参数,比如 `--controllers=*,tokencleaner,bootstrapsigner` 来启用启动引导令牌。 -在使用 `kubeadm` 时,这个是自动完成的。 +在使用 `kubeadm` 时,这是自动完成的。 HTTPS 调用中的令牌是这样使用的: @@ -84,13 +83,13 @@ Authorization: Bearer 07401b.f395accd246ae52d 每个合法的令牌是通过一个 `kube-system` 命名空间中的 secret 隐藏的。 -你可以从[这里](https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md)找到完整设计文档。 +你可以从 [这里](https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md) 找到完整设计文档。 -这是 secret 看起来的样子。注意,`base64(string)` 表示值应该是通过 base64 编码的。 -这里使用的是解码版本以便于阅读。 +这是 secret 看起来的样子。注意,`base64(string)` 表示应该通过 base64 对值进行编码。 +这里使用的是未解码的版本以便于阅读。 ```yaml apiVersion: v1 @@ -113,12 +112,12 @@ data: -secret的类型必须是 `bootstrap.kubernetes.io/token` ,而名字必须是 `bootstrap-token-`。 +secret 的类型必须是 `bootstrap.kubernetes.io/token` ,而且名字必须是 `bootstrap-token-`。 `description` 是人类可读的描述,而不应该是机器可读的信息。令牌 ID 和 Secret 是包含在数据字典中的。 -The `usage-bootstrap-*` members indicate what this secret is intended to be used -for. A value must be set to `true` to be enabled. - `usage-bootstrap-*` 成员代表了这个 secret 被用于什么。启用时,值必须设置为 `true`。 + + + `usage-bootstrap-*` 成员表示这个 secret 的用途。启用时,值必须设置为 `true`。 @@ -127,7 +126,7 @@ for. A value must be set to `true` to be enabled. `usage-bootstrap-authentication` 表示令牌可以用于 API 服务器的认证。认证器会以 `system:bootstrap:` 认证。它被包含在 `system:bootstrappers` 组中。 -命名和组是故意受限制的,以阻碍用户在启动引导后再使用这些令牌。 +命名和组是故意受限制的,以防止用户在启动引导后再使用这些令牌。 @@ -136,8 +135,8 @@ for. A value must be set to `true` to be enabled. -`expiration` 数据成员列举了令牌在失效后的时间。这是通过 RFC3339 进行编码的 UTC 时间。 -令牌清理控制器会删除过期的令牌。 +`expiration` 数据成员列举了令牌在失效后的时间。这是遵循 RFC3339 进行编码的 UTC 时间。 +TokenCleaner 控制器会删除过期的令牌。 ## 使用 `kubeadm` 管理令牌 @@ -147,18 +146,18 @@ for. A value must be set to `true` to be enabled. -你可以是用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群(`/etc/kubernetes/admin.conf`) -自动抓取默认管理员密码。你可以对下面命令指定一个另外的 kubeconfig 文件抓取密码,参数使用 `--kubeconfig`。 +你可以使用 `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 |.` 删除令牌。 - 令牌可以只用 ID 来确认,或者用整个令牌的值。如果只用 ID,密文不符合的令牌也会被删除。 + 令牌可以只用 ID 来确认,也可以用整个令牌的值。如果只用 ID 的情况下,密文不匹配的令牌也会被删除。 ### ConfigMap签名 @@ -166,16 +165,16 @@ for. A value must be set to `true` to be enabled. -除了认证之外,令牌可以用于签名 ConfigMap。这在集群启动流程的早期,在客户端信任 API服务器之前被使用。 -签名过的 ConfigMap 可以通过共享令牌被认证。 +除了认证之外,令牌可以用于签名 ConfigMap。这在集群启动过程的早期,在客户端信任 API 服务器之前被使用。 +被签名的 ConfigMap 可以通过共享令牌被认证。 -签名过的 ConfigMap 是 `kube-public` 命名空间中的 `cluster-info`。 -典型的工作流中,客户端读取这个 ConfigMap 而不管认证和 TLS 报错。 -它会通过 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。 +被签名的 ConfigMap 是 `cluster-info`,存在于 `kube-public` 命名空间中。 +典型的工作流中,客户端在未经认证和忽略 TLS 报错的状态下读取这个 ConfigMap。 +通过 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。 ConfigMap 会是这个样子的: @@ -206,7 +205,7 @@ data: ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件。 -这里主要交换的信息是 `certificate-authority-data`。在将来可能会被扩展。 +这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。 @@ -216,6 +215,6 @@ ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件 签名是一个 JWS 签名,使用了 "detached" 模式。为了检验签名,用户应该按照 JWS 规则 -(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 载荷进行编码。那样编码过载荷会被通过插入 JWS 并存在于两个点的中间 -,用于形成一个完整的 JWS。你可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥, +(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间 +,用于形成一个完整的 JWS。可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥, 通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 用户 _必须_ 确保使用了 HS256。 \ No newline at end of file From dbd35c639abc4b1823647fec58c7e0757ce86b9b Mon Sep 17 00:00:00 2001 From: zhangqx2010 Date: Thu, 21 Sep 2017 12:11:05 +0800 Subject: [PATCH 099/102] update cluster-large.md --- cn/docs/admin/cluster-large.md | 62 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/cn/docs/admin/cluster-large.md b/cn/docs/admin/cluster-large.md index 6288aacf05..fda7e096c4 100644 --- a/cn/docs/admin/cluster-large.md +++ b/cn/docs/admin/cluster-large.md @@ -3,23 +3,23 @@ assignees: - davidopp - lavalamp -title:搭建大型集群 +title: 搭建大型集群 --- ## 支持 -在 {{page.version}} 版本中,Kubernetes 支持集群节点数可达1000个。更具体地说,我们配置能够支持*所有*如下条件: +在 {{page.version}} 版本中,Kubernetes 支持集群节点(node)数可达1000个。更具体地说,我们配置能够支持*所有*如下条件: -* 不超过2000个 -* 不超过总共6000个 pods -* 不超过总共12000个节点容器 -* 单节点不超过100个 pods +* 不超过2000个节点 +* 不超过总共6000个 pod +* 不超过总共12000个 container +* 单节点不超过100个 pod
@@ -30,13 +30,13 @@ title:搭建大型集群 ## 安装 -集群是一组运行着 Kubernetes 代理的节点(物理或者虚机),被 "主服务器" (集群层面的控制台)所管理。 +集群是一组运行着 Kubernetes 代理的节点(物理或者虚机),被 "主服务器" (集群层面的控制台)所管理。 -通常来说,集群中的节点数是通过平台相关的 `config-default.sh` 文件(例子参考[GCE's `config-default.sh`](http://releases.k8s.io/{{page.githubbranch}}/cluster/gce/config-default.sh)中的 `NUM_NODES` 值控制的。 +通常来说,集群中的节点数是通过平台特定的 `config-default.sh` 文件(例子参考 [GCE's `config-default.sh`](http://releases.k8s.io/{{page.githubbranch}}/cluster/gce/config-default.sh) )中的 `NUM_NODES` 值控制的。 -然而,单单把这个值更改到很大会导致脚本在许多云服务商平台上运行失败。例如 GCE 部署,会有配额问题导致集群启动失败。 +然而,单单把这个值更改到很大的数值会导致安装脚本在许多云服务商平台上运行失败。例如 GCE 部署,会有配额问题导致集群启动失败。 当需要建立大规模 Kubernetes 集群时,必须考虑下列问题: @@ -45,26 +45,26 @@ title:搭建大型集群 ### 配额问题 -为了避免云服务商的配额导致问题,当创建一个许多节点的集群是,要考虑: +为了避免在云服务商平台上发生配额问题,当创建一个许多节点的集群时,要考虑: * 增加这些资源的配额,比如 CPU ,IP 地址等等。 * 在 [GCE 中,举个例子](https://cloud.google.com/compute/docs/resource-quotas) 你会需要增加: * CPU * 虚拟机实例 - * 总共保留的永久磁盘 + * 永久磁盘的预留总量 * 在使用的 IP 地址 * 防火墙规则 * 转发规则 * 路由 * 目标池 -* 调整好安装脚本,让它能够在创建虚拟机节点的批处理间能有等待时间,因为很多云服务商对于虚拟机有创建频率的限制。 +* 调整好安装脚本,让它能够在创建虚拟机节点的批处理中有等待时间,因为很多云服务商平台对于虚拟机的创建频率有限制。 ### Etcd 存储 -为了提高大规模集群的性能,我们将 events 存储在一个独立的特定的etcd实例中。 +为了提高大规模集群的性能,我们将 event 存储在一个独立的 etcd 实例中。 当创建一个集群时,现有的 salt 脚本会: @@ -72,14 +72,14 @@ title:搭建大型集群 * 启动并配置额外的 etcd 实例 -* 配置 api-server 使用它来储存 events +* 配置 api-server 用于储存 event ### 主服务器和主服务器组件的规格 在 GCE/GKE 和 AWS 上,`kube-up` 自动为你的主服务器配置合适的虚拟机规格,规格取决于集群中的节点数量。 -对于其他云服务商,你需要进行手工配置。作为参考,我们在 GCE 上使用的规格是: +对于其他云服务商平台,你需要手工配置。作为参考,我们在 GCE 上使用的规格是: * 1-5 节点: n1-standard-1 @@ -101,13 +101,13 @@ title:搭建大型集群 * 超过 500 节点: c4.8xlarge -注意这些主服务器节点规格只能在集群启动是设置,如果后续对于集群扩容或者缩容(比如,手工或者使用集群自动扩展器删除或增加节点),规格是不会调整的。 +注意,主服务器节点规格只能在集群启动时设置,如果后续对于集群扩容或者缩容(比如,使用手工或集群自动扩展器进行增加或删除节点),规格是不会调整的。 -### Addon (插件)资源 +### 插件(Addon)资源 -为了防止[集群 addons](https://releases.k8s.io/{{page.githubbranch}}/cluster/addons) 内存泄漏或者其他资源问题导致消耗完节点的所有资源,Kubernetes 对 addon 容器设定了资源限制,以限制他们使用 CPU 和内存资源。(参见 PR [#10653](http://pr.k8s.io/10653/files) 和 [#10778](http://pr.k8s.io/10778/files)) +为了防止 [集群插件](https://releases.k8s.io/{{page.githubbranch}}/cluster/addons) 内存泄漏或者其他资源问题导致消耗完节点的所有资源,Kubernetes 对插件容器设定了资源限制,以限制他们使用 CPU 和内存资源。(参见 PR [#10653](http://pr.k8s.io/10653/files) 和 [#10778](http://pr.k8s.io/10778/files)) 举例: @@ -123,38 +123,38 @@ title:搭建大型集群 ``` -除了 Heapster,这些限制是固定的,并且是基于我们对于 addon 运行在4节点集群的采样数据(见 [#10335](http://issue.k8s.io/10335#issuecomment-117861225))。运行在大规模集群上时,addon 会消耗更多的资源(见 [#5880](http://issue.k8s.io/5880#issuecomment-113984085))。所以,如果大规模集群没有调整这些参数时,addon 可能会被持续杀死,因为他们总是达到限制。 +除了 Heapster 之外,这些限制是固定的,并且是基于我们对于插件运行在4节点集群的采样数据(见 [#10335](http://issue.k8s.io/10335#issuecomment-117861225))。运行在大规模集群上时,插件会消耗更多的资源(见 [#5880](http://issue.k8s.io/5880#issuecomment-113984085))。所以,如果大规模集群没有调整这些参数时,插件容器可能会被持续杀死,因为他们总是达到限制。 -为了避免集群的 addon 资源问题出现,当创建一个许多节点的集群是,考虑如下问题: +为了避免集群的插件资源问题出现,当创建一个许多节点的集群时,考虑如下问题: - * 为以下每个 addon 调整内存和 CPU 限制,使用时,随着你的集群扩容 (每个 addon 有一个 replica 来处理整个集群,所以 CPU/内存 使用量会随着集群的 规模/负载 按比例增加): + * 为以下每个插件调整内存和 CPU 限制,使用时,随着你的集群扩容(每个插件有一个 replica 来处理整个集群,所以 CPU/内存 使用量会随着集群的 规模/负载 按比例增加): * [InfluxDB and Grafana](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/cluster-monitoring/influxdb/influxdb-grafana-controller.yaml) * [kubedns, dnsmasq, and sidecar](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/kubedns-controller.yaml.in) * [Kibana](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/kibana-controller.yaml) - * 为以下这些 addon 调整 replicas 数量, 使用时, 随着集群规模数量一起调整 (每个 addon 会有多个 replicas, 所以增加 replicas 应该能帮助处理增加的负载,但是,由于每个 replica 的负载也稍稍增加, 同时需要考虑增加 CPU/内存 限制): + * 为以下这些插件调整 replicas 数量, 使用时, 随着集群规模数量一起调整(每个插件会有多个 replicas, 所以增加 replicas 应该能帮助处理增加的负载,但是,由于每个 replica 的负载也稍稍增加, 同时需要考虑增加 CPU/内存 限制): * [elasticsearch](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/es-controller.yaml) - * 为以下这些 addon 稍稍增加 memory 和 CPU 使用限制, 使用时, 随着集群规模数量一起调整 (每个节点有一个 replica,但是 CPU/内存 使用量与集群的 负载/规模 会稍稍增加): + * 为以下这些插件稍稍增加内存和 CPU 使用限制, 使用时, 随着集群规模数量一起调整(每个节点有一个 replica,但是 CPU/内存 使用量随着集群的 负载/规模 会稍稍增加): * [FluentD with ElasticSearch Plugin](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml) * [FluentD with GCP Plugin](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/fluentd-gcp/fluentd-gcp-ds.yaml) -Heapseter 的资源限制是基于集群的初始规模动态配置的 (见 [#16185](http://issue.k8s.io/16185) 和 [#22940](http://issue.k8s.io/22940))。 -如果你发现 Hepaster 的资源不够,你应该调整 heapster 对于内存的请求公式 (详见这些 PRs)。 +Heapster 的资源限制是基于集群的初始规模动态配置的(见 [#16185](http://issue.k8s.io/16185) 和 [#22940](http://issue.k8s.io/22940))。 +如果你发现 Heapster 的资源不够,你应该调整 Heapster 对于内存的请求的计算公式(详见这些 PRs)。 -对于如何检查 addon 容器是否达到了资源使用限制,参考 [Troubleshooting section of Compute Resources](/docs/concepts/configuration/manage-compute-resources-container/#troubleshooting)。 +对于如何检查插件容器是否达到了资源使用限制,参考 [计算资源的问题排查章节](/docs/concepts/configuration/manage-compute-resources-container/#troubleshooting)。 -在[未来](http://issue.k8s.io/13048),我们预期会基于集群规模来设置所有集群 addon 的资源限制,并且会在你的集群扩容或缩容时进行动态调整。 -我们欢迎实现这些功能的 PR 。 +在 [未来](http://issue.k8s.io/13048),我们预期会基于集群规模来设置所有集群插件的资源限制,并且会在你的集群扩容或缩容时进行动态调整。 +我们欢迎致力于实现这些功能的 PR 。 ### 允许少数节点在启动时失败 由于各种原因 (详细信息见 [#18969](https://github.com/kubernetes/kubernetes/issues/18969)),运行 `kube-up.sh` 建立非常大 -的 `NUM_NODES` 集群会由于个别的节点启动失败而失败。目前你有两个选择:重启集群 (再次运行 `kube-down.sh` 和 `kube-up.sh`), -或者,在运行 `kube-up.sh` 之前,将 `ALLOWED_NOTREADY_NODES` 环境变量设置成你觉得合适值。这会让 `kube-up.sh` 在少于 `NUM_NODES` -节点启动的时候成功完成。根据不同的失败的原因,这些额外的节点可以在稍后再加入集群,或者集群可以保持在 `NUM_NODES - ALLOWED_NOTREADY_NODES` 的规模。 \ No newline at end of file +的 `NUM_NODES` 数量的集群会由于个别的节点的启动失败而失败。目前你有两个选择:重启集群(再次运行 `kube-down.sh` 和 `kube-up.sh`), +或者,在运行 `kube-up.sh` 之前,将 `ALLOWED_NOTREADY_NODES` 环境变量设置成合适的值。这会让 `kube-up.sh` 在少于 `NUM_NODES` +节点启动的时候成功完成。根据不同的失败原因,这些额外的节点可以在稍后再加入集群,或者集群可以保持在 `NUM_NODES - ALLOWED_NOTREADY_NODES` 的规模。 \ No newline at end of file From 7b6571da0e6037d787974cd0d9d4d280f221fa4e Mon Sep 17 00:00:00 2001 From: zhangqx2010 Date: Thu, 21 Sep 2017 12:11:37 +0800 Subject: [PATCH 100/102] update service-accounts-admin.md --- cn/docs/admin/service-accounts-admin.md | 70 ++++++++++++------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/cn/docs/admin/service-accounts-admin.md b/cn/docs/admin/service-accounts-admin.md index 356ad76711..b607591f55 100644 --- a/cn/docs/admin/service-accounts-admin.md +++ b/cn/docs/admin/service-accounts-admin.md @@ -4,53 +4,53 @@ assignees: - davidopp - lavalamp - liggitt -title: Managing Service Accounts +title: 管理服务帐号(Service Accounts) --- -*本文是 service accounts 管理员手册。需要[Service Accounts 用户手册](/cn/docs/user-guide/service-accounts)的知识背景。* -*对于 authorization 和 user accounts 支持已经在计划中,但是还未完成。为了更好地解释 service -accounts,有时会提到一些未完成的功能特性。* + +*本文是服务帐户管理员手册。需要[服务帐户用户手册](/docs/user-guide/service-accounts)的知识背景。* + +*对于认证和用户帐号(user accounts)的支持已经在计划中,但是还未完成。为了更好地解释用户帐户,有时会提到一些未完成的功能特性。* ## 用户账号 vs 服务账号 -Kubernetes 将 user account 和 service account 的概念区分开,主要基于以下几个原因: +Kubernetes 将用户账号和服务账号的概念区分开,主要基于以下几个原因: - - user account 是给人使用的。servcice account是给 pod 中运行的进程使用的。 - - user account 为全局设计。命名必须在一个集群的所有命名空间中唯一,未来的用户资源不会被设计到命名空间中。 - service account 是按命名空间的。 - - 典型场景中,一个集群的 user account 是来自于企业数据库的,在数据库中新建用户一般需要特殊权限,并且账号是与复杂都业务流程关联的。 - service account的创建往往更轻量,允许集群用户为特定的任务创建service account(即,权限最小化原则)。 + - 用户账号是给人使用的。服务账号是给 pod 中运行的进程使用的。 + - 用户账号为全局设计的。命名必须在一个集群的所有命名空间中唯一,未来的用户资源不会被设计到命名空间中。 + 服务账号是在命名空间里的。 + - 典型场景中,一个集群的用户账号是从企业数据库的同步来的,在数据库中新用户帐号一般需要特殊权限,并且账号是与复杂的业务流程关联的。 + 服务账号的创建往往更轻量,允许集群用户为特定的任务创建服务账号(即,权限最小化原则)。 - 对于人和服务的账号,审计要求会是不同的。 - - 对于复杂系统而言,配置包可以包含该系统各类组件的 service account 定义, - 因为 service account 可以有临时的创建需求和自己的命名空间,这类配置是便携式的。 + - 对于复杂系统而言,配置包可以包含该系统各类组件的服务账号定义, + 因为服务账号能被临时创建,并且有命名空间分类的名字,这类配置是便携式的。 ## 服务账号自动化 -service accounts 的自动化由三个独立的组建共同配合实现: +服务账号的自动化由三个独立的组件共同配合实现: - - A Service account admission controller (service account 准入控制器) - - A Token controller (令牌控制器) - - A Service account controller (service account 控制器) + - 用户账号准入控制器(A Service account admission controller) + - 令牌控制器(A Token controller) + - 服务账号控制器(A Service account controller) ### 服务账号准入控制器 -对于 pods 的操作是通过一个叫做 [准入控制器](/cn/docs/admin/admission-controllers) 的插件实现的。它是 apiserver 的一部分。 -当准入控制器被创建或更新时,他会对 pod 同步进行操作。当这个插件时活动状态时(大部分版本默认是活动状态),并在 pod 被创建或者更改时, +对于 pods 的操作是通过一个叫做 [准入控制器](/docs/admin/admission-controllers) 的插件(plugin)实现的。它是 APIserver 的一部分。 +当 pod 被创建或更新时,它会同步更改 pod。当这个插件是活动状态时(大部分版本默认是活动状态),在 pod 被创建或者更改时, 它会做如下操作: - 1. 如果 pod 没有配置 `ServiceAccount`,它会将 `ServiceAccount` 设置为 `default`。 - 2. 它会确保被 pod 关联的 `ServiceAccount` 是存在的,否则就拒绝请求。 - - 4. 如果 pod 没有包含任何的 `ImagePullSecrets`,那么 `ServiceAccount` 的 `ImagePullSecrets` 就会被添加到 pod。 - 5. 它会把一个 `volume` 添加给 pod, 该 pod 包含有一个用于 API 访问的 token。 - 6. 它会把一个 `volumeSource` 添加到 pod 的每个 container,并挂载到 `/var/run/secrets/kubernetes.io/serviceaccount`。 + 1. 如果 pod 没有配置 `ServiceAccount`,它会将 `ServiceAccount` 设置为 `default`。 + 2. 确保被 pod 关联的 `ServiceAccount` 是存在的,否则就拒绝请求。 + 3. 如果 pod 没有包含任何的 `ImagePullSecrets`,那么 `ServiceAccount` 的 `ImagePullSecrets` 就会被添加到 pod。 + 4. 它会把 `volume` 添加给 pod,该 pod 包含有一个用于 API 访问的令牌。 + 5. 它会把 `volumeSource` 添加到 pod 的每个容器,挂载到 `/var/run/secrets/kubernetes.io/serviceaccount`。 ### 令牌控制器 @@ -59,21 +59,20 @@ service accounts 的自动化由三个独立的组建共同配合实现: 令牌控制器(TokenController)作为 controller-manager 的一部分运行。它异步运行。它会: - 监听对于 serviceAccount 的创建动作,并创建对应的 Secret 以允许 API 访问。 -- 监听对于 serviceAccount 的删除动作,并删除所有对应的 ServiceAccountToken Secrets。 -- 监听对于 secret 的添加动作,确保相关联的 ServiceAccount 是存在的,并在根据需要为 secret 添加一个 token。 +- 监听对于 serviceAccount 的删除动作,并删除所有对应的 ServiceAccountToken Secret。 +- 监听对于 secret 的添加动作,确保相关联的 ServiceAccount 是存在的,并根据需要为 secret 添加一个令牌。 - 监听对于 secret 的删除动作,并根据需要删除对应 ServiceAccount 的关联。 -你必须给令牌控制器(token controller)传递一个 service account 的私钥(private key),可以通过 `--service-account-private-key-file` 参数完成。 -传递的私钥将被用来对 service account tokens 进行签名。类似的,你必须给 kube-apiserver 传递一个公钥(public key),通过 `--service-account-key-file` -参数完成。传递的公钥会被用来验证认证过程中的令牌(token)。 +你必须给令牌控制器传递一个服务帐号的私钥(private key),通过 `--service-account-private-key-file` 参数完成。传递的私钥将被用来对服务帐号令牌进行签名。 +类似的,你必须给 kube-apiserver 传递一个公钥(public key),通过 `--service-account-key-file` 参数完成。传递的公钥在认证过程中会被用于验证令牌。 -#### 创建额外的 API 令牌 +#### 创建额外的 API 令牌(API token) -控制器的循环运行会确保对于每个 service account 都存在一个带有 API token(API 令牌)的secret。 -如需要为一个 service account 创建一个额外的 API 令牌(API token),可以创建一个 `ServiceAccountToken` -类型的 secret,并添加与 service account 对应的 annotation 属性,控制器会为它更新 token: +控制器的循环运行会确保对于每个服务帐号都存在一个带有 API 令牌的 secret。 +如需要为服务帐号创建一个额外的 API 令牌,可以创建一个 `ServiceAccountToken` +类型的 secret,并添加与服务帐号对应的 annotation 属性,控制器会为它更新令牌: secret.json: @@ -97,7 +96,7 @@ kubectl describe secret mysecretname ``` -#### 删除/作废服务账号令牌 +#### 删除/作废服务账号令牌 ```shell kubectl delete secret mysecretname @@ -107,5 +106,4 @@ kubectl delete secret mysecretname ### 服务账号控制器 -Service Account Controller 在 namespaces 内管理 ServiceAccount,需要保证名为 "default" 的 -ServiceAccount在每个命名空间中存在。 \ No newline at end of file +服务帐号控制器在命名空间内管理 ServiceAccount,需要保证名为 "default" 的 ServiceAccount 在每个命名空间中存在。 \ No newline at end of file From 24072e4ba8f774be5db2110739deecb5e44e0514 Mon Sep 17 00:00:00 2001 From: zhangqx2010 Date: Thu, 21 Sep 2017 12:12:21 +0800 Subject: [PATCH 101/102] update communicate-containers-same-pod-shared-volume.md --- ...icate-containers-same-pod-shared-volume.md | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md b/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md index b6c679b274..65ef1d9ee4 100644 --- a/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md +++ b/cn/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume.md @@ -3,8 +3,8 @@ title: 同 Pod 内的容器使用共享卷通信 redirect_from: - "/docs/user-guide/pods/multi-container/" - "/docs/user-guide/pods/multi-container.html" -- "docs/tasks/configure-pod-container/communicate-containers-same-pod/" -- "docs/tasks/configure-pod-container/communicate-containers-same-pod.html" +- "/docs/tasks/configure-pod-container/communicate-containers-same-pod/" +- "/docs/tasks/configure-pod-container/communicate-containers-same-pod.html" --- @@ -12,7 +12,7 @@ redirect_from: -本文旨在说明如何使用一个卷(Volume)让一个 Pod 内的两个容器进行通信 +本文旨在说明如何让一个 Pod 内的两个容器使用一个卷(Volume)进行通信。 {% endcapture %} @@ -27,7 +27,7 @@ redirect_from: {% capture steps %} -## 创建一个两个容器的 Pod +## 创建一个包含两个容器的 Pod @@ -46,7 +46,7 @@ Pod 的配置文件如下: 配置文件中的第一个容器运行了一个 nginx 服务器。共享卷的挂载路径是 `/usr/share/nginx/html`。 -第二个容器是基于 debian 镜像的,有一个挂载路径是 `/pod-data`。第二个容器运行了下面的命令然后终止。 +第二个容器是基于 debian 镜像的,有一个 `/pod-data` 的挂载路径。第二个容器运行了下面的命令然后终止。 echo Hello from the debian container > /pod-data/index.html @@ -126,7 +126,7 @@ Pod 的配置文件如下: root@two-containers:/# curl localhost -输出显示了 nginx 提供了 debian 容器写的页面: +输出表示 nginx 提供了 debian 容器写的页面: Hello from the debian container @@ -145,9 +145,10 @@ Pod 的配置文件如下: -Pod 能有多个容器的主要原因是为了支持协助主应用的辅助应用。辅助应用的典型例子是数据抽取,数据推送和代理。 -辅助应用和主应用经常需要相互通信。通常这是通过共享文件系统完成的,就如这个练习所示,或者通过回环网络接口 -localhost 完成。网络接口的例子是 web 服务器带有一个协助程序用于拉取 Git 仓库的更新。 +Pod 能有多个容器的主要原因是为了支持辅助应用(helper applications),以协助主应用(primary application)。 +辅助应用的典型例子是数据抽取,数据推送和代理。辅助应用和主应用经常需要相互通信。 +就如这个练习所示,通信通常是通过共享文件系统完成的,或者,也通过回环网络接口 localhost 完成。 +举个网络接口的例子,web 服务器带有一个协助程序用于拉取 Git 仓库的更新。 @@ -167,17 +168,17 @@ localhost 完成。网络接口的例子是 web 服务器带有一个协助程 -* 学习[模块化架构的混合容器](http://www.slideshare.net/Docker/slideshare-burns)。 +* 学习 [模块化架构的混合容器](http://www.slideshare.net/Docker/slideshare-burns)。 -* 参见[配置一个使用存储卷的 Pod](/cn/docs/tasks/configure-pod-container/configure-volume-storage/)。 +* 参见 [配置一个使用存储卷的 Pod](/docs/tasks/configure-pod-container/configure-volume-storage/)。 -* 参见 [卷](/cn/docs/api-reference/v1.6/#volume-v1-core)。 +* 参见 [卷](/docs/api-reference/v1.6/#volume-v1-core)。 -* 参见 [Pod](/cn/docs/api-reference/v1.6/#pod-v1-core). +* 参见 [Pod](/docs/api-reference/v1.6/#pod-v1-core). {% endcapture %} From 3b396298afc479fa8d187b9d29cf5fc0360599db Mon Sep 17 00:00:00 2001 From: zhangqx2010 Date: Thu, 21 Sep 2017 12:14:53 +0800 Subject: [PATCH 102/102] update connection-frontend-backend.md --- .../connecting-frontend-backend.md | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md b/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md index 7be1ea58fb..f2d82fae7e 100644 --- a/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md +++ b/cn/docs/tasks/access-application-cluster/connecting-frontend-backend.md @@ -8,8 +8,8 @@ title: 使用 Service 把前端连接到后端 -这项任务会描述如何创建一个前端和一个后端的微服务。后端微服务是一个 hello 欢迎程序。 -前端和后端的连接是通过 Kubernetes Service 对象完成的。 +本任务会描述如何创建前端微服务和后端微服务。后端微服务是一个 hello 欢迎程序。 +前端和后端的连接是通过 Kubernetes 服务对象(Service object)完成的。 {% endcapture %} @@ -19,9 +19,9 @@ title: 使用 Service 把前端连接到后端 -* 使用 Deployment 对象创建并运行一个微服务 +* 使用部署对象(Deployment object)创建并运行一个微服务 * 从后端将流量路由到前端 -* 使用 Service 对象把前端应用连接到后端应用 +* 使用服务对象把前端应用连接到后端应用 {% endcapture %} @@ -31,9 +31,9 @@ title: 使用 Service 把前端连接到后端 * {% include task-tutorial-prereqs.md %} -* 本项任务使用[外部负载均衡服务](/cn/docs/tasks/access-application-cluster/create-external-load-balancer/), - 所以需要对应的可支持此功能的环境。如果你的环境不能支持,你可以使用[NodePort](/cn/docs/user-guide/services/#type-nodeport) - 的类型 Service 来代替。 +* 本任务使用 [外部负载均衡服务](/docs/tasks/access-application-cluster/create-external-load-balancer/), + 所以需要对应的可支持此功能的环境。如果你的环境不能支持,你可以使用 + [NodePort](/docs/user-guide/services/#type-nodeport) 类型的服务代替。 {% endcapture %} @@ -41,7 +41,7 @@ title: 使用 Service 把前端连接到后端 {% capture lessoncontent %} -### 使用 Deployment 创建后端 +### 使用部署对象(Deployment)创建后端 @@ -85,14 +85,14 @@ Events: ``` -### 创建后端 Service 对象 +### 创建后端服务对象(Service object) 前端连接到后端的关键是 Service。Service 创建一个固定 IP 和 DNS 解析名入口, -使得后端微服务可达。Service 使用 selector 标签来寻找目的地 Pods。 +使得后端微服务可达。Service 使用 selector 标签来寻找目标 Pod。 首先,浏览 Service 的配置文件: @@ -101,7 +101,7 @@ Events: -配置文件中,你可以看到 Service 将流量路由到包含 `app: hello` 和 `tier: backend` 标签的 Pods。 +配置文件中,你可以看到 Service 将流量路由到包含 `app: hello` 和 `tier: backend` 标签的 Pod。 创建 `hello` Service: @@ -147,7 +147,7 @@ kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/frontend. ``` -输出确认两个资源都已经被创建: +通过输出确认两个资源都已经被创建: ``` deployment "frontend" created @@ -159,8 +159,8 @@ service "frontend" created -**注意**:这个 nginx 配置文件是被打包在[容器镜像](/cn/docs/tasks/access-application-cluster/frontend/Dockerfile)里的。 -更好的方法是使用 [ConfigMap](/cn/docs/tasks/configure-pod-container/configmap/),这样的话你可以更轻易地更改配置。 +**注意**:这个 nginx 配置文件是被打包在 [容器镜像](/docs/tasks/access-application-cluster/frontend/Dockerfile) 里的。 +更好的方法是使用 [ConfigMap](/docs/tasks/configure-pod-container/configmap/),这样的话你可以更轻易地更改配置。 ### 与前端 Service 交互 @@ -175,7 +175,7 @@ kubectl get service frontend -外部 IP 的字段的生成可能需要一些时间。如果是这种情况,外部 IP 会显示为 ``。 +外部 IP 字段的生成可能需要一些时间。如果是这种情况,外部 IP 会显示为 ``。 ``` NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE @@ -215,8 +215,8 @@ curl http:// -* 了解更多 [Services](/cn/docs/concepts/services-networking/service/) -* 了解更多 [ConfigMaps](/cn/docs/tasks/configure-pod-container/configmap/) +* 了解更多 [Services](/docs/concepts/services-networking/service/) +* 了解更多 [ConfigMaps](/docs/tasks/configure-pod-container/configmap/) {% endcapture %}