Convert site to Hugo (#8316)

This commit converts content and layout to use Hugo.
This commit is contained in:
Bjørn Erik Pedersen
2018-05-05 18:00:51 +02:00
committed by k8s-ci-robot
parent 7745f0e0c5
commit 7f3b633aa0
2327 changed files with 10928 additions and 171503 deletions
@@ -0,0 +1,177 @@
---
title: 应用故障排查
---
本指南帮助用户来调试kubernetes上那些没有正常运行的应用。
本指南*不能*调试集群。如果想调试集群的话,请参阅[这里](/docs/admin/cluster-troubleshooting)。
{{< toc >}}
## 诊断问题
故障排查的第一步是先给问题分下类。这个问题是什么?PodsReplication Controller或者Service
* [Debugging Pods](#debugging-pods)
* [Debugging Replication Controllers](#debugging-replication-controllers)
* [Debugging Services](#debugging-services)
### Debugging Pods
调试pod的第一步是看一下这个pod的信息,用如下命令查看一下pod的当前状态和最近的事件:
```shell
$ kubectl describe pods ${POD_NAME}
```
查看一下pod中的容器所处的状态。这些容器的状态都是`Running`吗?最近有没有重启过?
后面的调试都是要依靠pods的状态的。
#### pod停留在pending状态
如果一个pod卡在`Pending`状态,则表示这个pod没有被调度到一个节点上。通常这是因为资源不足引起的。
敲一下`kubectl describe ...`这个命令,输出的信息里面应该有显示为什么没被调度的原因。
常见原因如下:
* **资源不足**:
你可能耗尽了集群上所有的CPU和内存,此时,你需要删除pods,调整资源请求,或者增加节点。
更多信息请参阅[Compute Resources document](/docs/user-guide/compute-resources/#my-pods-are-pending-with-event-message-failedscheduling)
* **使用了`hostPort`**:
如果绑定一个pod到`hostPort`,那么能创建的pod个数就有限了。
多数情况下,`hostPort`是非必要的,而应该采用服务来暴露pod。
如果确实需要使用`hostPort`,那么能创建的pod的数量就是节点的个数。
#### pod停留在waiting状态
如果一个pod卡在`Waiting`状态,则表示这个pod已经调试到节点上,但是没有运行起来。
再次敲一下`kubectl describe ...`这个命令来查看相关信息。
最常见的原因是拉取镜像失败。可以通过以下三种方式来检查:
* 使用的镜像名字正确吗?
* 镜像仓库里有没有这个镜像?
*`docker pull <image>`命令手动拉下镜像试试。
#### pod处于crashing状态或者unhealthy
首先,看一下容器的log:
```shell
$ kubectl logs ${POD_NAME} ${CONTAINER_NAME}
```
如果容器是crashed的,用如下命令可以看到crash的log:
```shell
$ kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
```
或者,用`exec`在容器内运行一些命令:
```shell
$ kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
```
注意:当一个pod内只有一个容器时,可以不带参数`-c ${CONTAINER_NAME}`
例如,名为Cassandra的pod,处于running态,要查看它的log,可运行如下命令:
```shell
$ kubectl exec cassandra -- cat /var/log/cassandra/system.log
```
如果以上方法都不起作用,找到这个pod所在的节点并用SSH登录进去做进一步的分析。
通常情况下,是不需要在Kubernetes API中再给出另外的工具的。
因此,如果你发现需要ssh进一个主机来分析问题时,请在GitHub上提一个特性请求,描述一个你的场景并说明为什么已经提供的工具不能满足需求。
#### pod处于running态,但是没有正常工作
如果创建的pod不符合预期,那么创建pod的描述文件应该是存在某种错误的,并且这个错误在创建pod时被忽略掉。
通常pod的定义中,章节被错误的嵌套,或者一个字段名字被写错,都可能会引起被忽略掉。
例如,希望在pod中用命令行执行某个命令,但是将`command`写成`commnd`,pod虽然可以创建,但命令并没有执行。
如何查出来哪里出错?
首先,删掉这个pod再重新创建一个,重创时,像下面这样带着`--validate`这个参数:
`kubectl create --validate -f mypod.yaml``command`写成`commnd`的拼写错误就会打印出来了。
```shell
I0805 10:43:25.129850 46757 schema.go:126] unknown field: commnd
I0805 10:43:25.129973 46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842
pods/mypod
```
<!-- TODO: Now that #11914 is merged, this advice may need to be updated -->
如果上面方法没有看到相关异常的信息,那么接下来就要验证从apiserver获取到的pod是否与期望的一致,比如创建Pod的yaml文件是mypod.yaml。
运行如下命令来获取apiserver创建的pod信息并保存成一个文件:
`kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml`
然后手动对这两个文件进行比较:
apiserver获得的yaml文件中的一些行,不在创建pod的yaml文件内,这是正常的。
如果创建Pod的yaml文件内的一些行,在piserver获得的yaml文件中不存在,可以说明创建pod的yaml中的定义有问题。
### Debugging Replication Controllers
RC相当简单。他们要么能创建pod,要么不能。如果不能创建pod,请参阅上述[Debugging Pods](#debugging-pods)。
也可以使用`kubectl describe rc ${CONTROLLER_NAME}`命令来监视RC相关的事件。
### Debugging Services
服务提供了多个Pod之间的负载均衡功能。
有一些常见的问题可以造成服务无法正常工作。以下说明将有助于调试服务的问题。
首先,验证服务是否有端点。对于每一个Service对像,apiserver使`endpoints`资源可用。
通过如下命令可以查看endpoints资源:
```shell
$ kubectl get endpoints ${SERVICE_NAME}
```
确保endpoints与服务内容器个数一致。
例如,如果你创建了一个nginx服务,它有3个副本,那么你就会在这个服务的endpoints中看到3个不同的IP地址。
#### 服务缺少endpoints
如果缺少endpoints,请尝试使用服务的labels列出所有的pod。
假如有一个服务,有如下的label
```yaml
...
spec:
- selector:
name: nginx
type: frontend
```
你可以使用如下命令列出与selector相匹配的pod,并验证这些pod是否归属于创建的服务:
```shell
$ kubectl get pods --selector=name=nginx,type=frontend
```
如果pod列表附合预期,但是endpoints仍然为空,那么可能没有暴露出正确的端口。
如果服务指定了`containerPort`,但是列表中的Pod没有列出该端口,则不会将其添加到端口列表。
验证该pod的`containerPort`与服务的`containerPort`是否匹配。
#### 网络业务不工作
如果可以连接到服务上,但是连接立即被断开了,并且在endpoints列表中有endpoints,可能是代理和pods之间不通。
确认以下3件事情:
* Pods工作是否正常? 看一下重启计数,并参阅[Debugging Pods](#debugging-pods)
* 可以直接连接到pod上吗?获取pod的IP地址,然后尝试直接连接到该IP上;
* 应用是否在配置的端口上进行服务?Kubernetes不进行端口重映射,所以如果应用在8080端口上服务,那么`containerPort`字段就需要设定为8080。
#### 更多信息
如果上述都不能解决你的问题,请按照[Debugging Service document](/docs/user-guide/debugging-services)中的介绍来确保你的`Service`处于running态,有`Endpoints``Pods`真正的在服务;你有DNS在工作,安装了iptables规则,kube-proxy也没有异常行为。
你也可以访问[troubleshooting document](/docs/troubleshooting/)来获取更多信息。
@@ -0,0 +1,114 @@
---
title: 集群故障排查
---
本篇文档是介绍集群故障排查的;我们假设对于你碰到的问题,你已经排除了是由应用程序造成的。
对于应用的调试,请参阅[应用故障排查指南](/cn/docs/tasks/debug-application-cluster/debug-application)。
你也可以访问[troubleshooting document](/docs/troubleshooting/)来获取更多的信息。
## 显示出集群的节点列表
调试的第一步是查看所有的节点是否都正确的注册。
运行
```shell
kubectl get nodes
```
接下来,验证你的所有节点都能够显示出来,并且都处于`Ready`状态。
## 查看logs
现在,挖掘出集群更深层的信息就需要登录到相关的机器上。下面是相关log文件所在的位置。
(注意,对于基于systemd的系统,你可能需要使用`journalctl`)
### Master
* /var/log/kube-apiserver.log - API Server, 提供API服务
* /var/log/kube-scheduler.log - Scheduler, 负责调度决策
* /var/log/kube-controller-manager.log - 管理replication controllers的控制器
### Worker Nodes
* /var/log/kubelet.log - Kubelet, 管控节点上运行的容器
* /var/log/kube-proxy.log - Kube Proxy, 负责服务的负载均衡
## 集群故障模式的概述
下面是一个不完整的列表,列举了一些可能出错的场景,以及通过调整集群配置来解决相关问题的方法。
根本原因:
- VM(s)关机
- 集群之间,或者集群和用户之间网络分裂
- Kubernetes软件本身崩溃了
- 数据丢失或者持久化存储不可用(如:GCE PD 或 AWS EBS卷)
- 操作错误,如:Kubernetes或者应用程序配置错误
具体情况:
- Apiserver所在的VM关机或者apiserver崩溃
- 结果
- 不能停止,更新,或者启动新的podsservicesreplication controller
- 现有的pods和services在不依赖Kubernetes API的情况下应该能继续正常工作
- Apiserver 后端存储丢失
- 结果
- apiserver应该不能起来
- kubelets将不能访问它,但是能够继续运行之前的Pods和提供相同的服务代理
- 在apiserver重启之前,需要手动恢复或者重创apiserver的状态
- Kubernetes服务组件(节点控制器,副本控制器,调度器等等)所在的VM关机或者崩溃
- 当前,这些控制器是和apiserver共存的,它们不可用的现象是与apiserver类似的
- 将来,这些控制器也会复制为多份,并且可能为非共存的
- 它们没有自己的持久状态
- 单个节点(VM或者物理机)关机
- 结果
- 此节点上的所有Pods都停止运行
- 网络分裂(Network partition)
- 结果
- partition A认为partition B中所有的节点都down掉了;partition B认为apiserver是down掉了(假定master所在的VM位于partition A内)。
- Kubelet软件故障
- 结果
- 崩溃的kubelet就不能在其所在的节点上启动新的pods
- kubelet可能删掉pods或者不删
- 节点被标识为非健康态
- 副本控制器会在其它的节点上启动新的pods
- 集群操作错误
- 结果
- 丢失pods,服务等等
- 丢失apiserver后端存储
- 用户无法读取API
- 等等
缓解措施:
- 措施:对于IaaS上的VMs,使用IaaS的自动VM重启功能
- 缓解:Apiserver VM关机或apiserver崩溃
- 缓解:Kubernetes服务组件所在的VM关机或崩溃
- 措施: 对于具有apiserver+etcd的VM,使用IaaS提供的可靠的存储(例如GCE PD或者AWS EBS卷)
- 缓解:Apiserver后端存储的丢失
- 措施:使用(实验)[高可用性](/docs/admin/high-availability)的配置
- 缓解:master VM关机或者master组件(scheduler, API server, controller-managing)崩馈
- 将容许一个或多个节点或组件同时出现故障
- 缓解:apiserver后端存储(例如etcd的数据目录)丢失
- 假定你使用了集群化的etcd。
- 措施:定期的对apiserver的PDs/EBS卷进行快照
- 缓解:apiserver后端存储丢失
- 缓解:一些操作错误的场景
- 缓解:一些Kubernetes软件本身故障的场景
- 措施:在pods的前面使用副本控制器或服务
- 缓解:节点关机
- 缓解:Kubelet软件故障
- 措施:应用(容器)设计成容许异常重启
- 缓解:节点关机
- 缓解:Kubelet软件故障
- 措施:[多个独立的集群](/docs/admin/multi-cluster)(并且避免一次性地对所有的集群进行有风险性的修改)
- 缓解:以上列出的所有情况
@@ -0,0 +1,86 @@
---
title: 调试Pods和Replication Controllers
---
{{< 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 <format>`命令来检查节点容量。
下面是一些能够提取必要信息的命令示例:
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 <image>`,看看是否可以拉取镜像。
### 我的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有关的事件。
@@ -0,0 +1,78 @@
---
title: 调试StatefulSet
content_template: templates/task
---
{{% capture overview %}}
此任务展示如何调试StatefulSet。
{{% /capture %}}
{{% capture prerequisites %}}
* 你需要有一个Kubernetes集群,通过必要的配置使kubectl命令行工具与您的集群进行通信。
* 你应该有一个运行中的StatefulSet,以便用于调试。
{{% /capture %}}
{{% 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-name> 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-name> pod.alpha.kubernetes.io/initialized="true" --overwrite
```
{{% /capture %}}
{{% capture whatsnext %}}
点击链接[调试init-container](/docs/tasks/troubleshoot/debug-init-containers/),了解更多信息。
{{% /capture %}}