cn-translation-from-2017-08-14-to-2017-09-03 (#5364)

This commit is contained in:
打雷不怕
2017-09-10 00:45:38 +08:00
committed by Steve Perry
parent 7eb3fa9f2e
commit fdbe5086a0
9 changed files with 1358 additions and 0 deletions
@@ -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 %}
@@ -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: <none>
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 %}
@@ -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 <your-class-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
这里的 `<your-class-name>` 是您选择的 StorageClass 的名字。
3. 标记一个 StorageClass 为默认的:
和前面的步骤类似,您需要添加/设置注解 `storageclass.kubernetes.io/is-default-class=true`
kubectl patch storageclass <your-class-name> -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 %}
@@ -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 <your-pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
这里的 `<your-pv-name>` 是你选择的 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 %}
@@ -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/<version>` 标志来打开或关闭特定的 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) 命令用法。