课程目标
- kubernetes目前并没有集成记录日志的功能
- 知道使用哪个产品可以来收集日志
- 了解最基础的错误定位的流程
- 讨论怎样使用sidecar在pod内记录日志
1. 简介
Kubernetes依赖于API调用,所以对网络问题非常敏感。标准的Linux工具和进程是定位集群故障的最佳方法。如果一个shell(如bash)在有问题的Pod中不可用,请考虑使用一个shell部署另一个类似的Pod,如busybox。DNS配置文件和诸如dig之类的工具是一个很好的定位问题的方式。对于更困难的挑战,您可能需要安装其他工具,如tcpdump。
大而多样的workload可能很难跟踪,因此对使用情况的监视是必不可少的。监视是收集关键指标,如CPU、内存和磁盘使用率,以及节点上的网络带宽,以及监视应用程序中的关键指标。这些特性会被Metric服务器采集到Kubernetes中,Metric服务器是现在被弃用的Heapster的精简版本。一旦安装,Metrics服务器就会公开一个标准API,其他agent(比如autoscaler)可以使用它。一旦安装,这个endpoint可以在主服务器上找到:/apis/metrics/k8s.io/。
记录所有节点的活动是Kubernetes之外的另一个特性。使用Fluentd可以成为统一日志记录层的有用数据收集器。拥有聚合的日志可以帮助我们将问题可视化,并提供搜索所有日志的能力。当本地网络故障排除没有暴露根本原因时,我们就可以通过日志追溯问题的根源。
CNCF的另一个项目结合了日志记录、监视和警报,被称为prometheus-您可以从[prometheus网站]了解更多。它提供一个时间序列数据库,以及与Grafana的集成,用于可视化和dashboard。
我们将回顾一些基本的kubectl命令,我们可以使用这些命令来调试正在发生的事情,我们将引导大家完成基本步骤,以便能够调试您的容器、pending的容器以及Kubernetes中的系统。
2. 最基本的定位问题的步骤
故障排除流程应该从最简单的地方入手。如果命令行中有错误,请先进行调查。问题的症状可能会决定下一步的检查手段。从运行在容器中的应用程序入手,然后再去调查集群是个非常普遍的方式。应用程序的镜像内可能有一个可以使用的shell,例如:
$ kubectl create deploy busybox --image=busybox --command sleep 3600
$ kubectl exec -ti <busybox_pod> -- /bin/sh
Security settings can also be a challenge. RBAC, covered in the security chapter, provides mandatory or discretionary access control in a granular manner. SELinux and AppArmor are also common issues, especially with network-centric applications.
A newer feature of Kubernetes is the ability to enable auditing for the kube-apiserver, which can allow a view into actions after the API call has been accepted.
The issues found with a decoupled system like Kubernetes are similar to those of a traditional datacenter, plus the added layers of Kubernetes controllers:
如果Pod正在运行,请使用kubectl logs Pod name从容器外部查看日志。如果没有日志,可以考虑在Pod中部署一个sidecar容器来生成和处理日志。下一个要检查的地方是网络,包括DNS、防火墙和标准的连接,这个时候就使用标准的Linux命令和工具。
安全设置可能是一个问题。安全章节中介绍的RBAC以细粒度的方式提供强制或自主访问控制。SELinux和AppArmor也是常见的问题,特别是在以网络为中心的应用程序中。
Kubernetes的一个新特性是能够为kube apiserver启用审计,这允许在接受API调用后查看操作。
像Kubernetes这样的解耦系统发现的问题与传统数据中心的问题类似,但是需要考虑Kubernetes控制器的问题:
- 命令行中报出的错误
- Pod日志和Pod状态
- 使用Shell来定位Pod的DNS和网络问题
- 检查节点的错误日志,确保有足够的资源用于新Pod的分配
- RBAC, SELinux 或者 AppArmor 等安全配置
- 控制器和kube-apiserver的API调用是否正常
- 打开审计功能
- 内部node之间的网络问题,DNS问题和防火墙问题
- Master节点的控制器(kube-controller是不是出于pending或者error状态,检查日志文件中的错误,冲突的资源等等)
3. Ephemeral Containers短生命周期容器
1.16版本的一个新特性是能够将容器添加到正在运行的pod中。这将允许一个有各种功能的容器被添加到现有的pod中,而不必终止和重新创建。间歇性和难以确定的问题可能需要一段时间才能重现,或者添加完容器之后问题就消失了。
作为alpha稳定性特征,它可以随时更改或删除。此外,它们不会自动重新启动,而且有很多资源是没办法使用的,比如端口。
这些容器是通过ephemeralcontainers处理程序通过API调用添加的,而不是通过podSpec添加的。因此,无法使用kubectl edit。
您可以使用kubectl attach命令加入容器中的现有进程。这有助于替代执行新进程的kubectl exec。附加进程的功能完全取决于您附加到的是什么。
kubectl debug buggypod --image debian --attach
4. 集群启动的顺序
如果使用kubeadm构建集群,则集群启动序列以systemd开头。其他工具可能利用不同的方法。使用系统控制状态kubelet.服务查看用于运行kubelet二进制文件的当前状态和配置文件。
-
使用/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
在config.yaml文件您将找到二进制文件的几个设置,包括staticPodPath它指示kubelet将读取每个yaml文件并启动每个pod的目录。如果您将一个yaml文件放在这个目录中,这是一种排除调度器故障的方法,因为pod是用对调度器的任何请求创建的。
-
使用/var/lib/kubelet/config.yaml配置文件
-
staticPodPath设置为/etc/kubernetes/manifests/
四个默认的yaml文件将启动运行集群所需的基本pod:
- kubelet的目录中:kube apiserver、etcd、kube controller manager、kube scheduler中的*.yaml创建所有pods。
一旦kube controller manager中的监视循环和控制器使用etcd数据运行,将创建其余配置对象。
5. 监控监控是从基础设施和应用程序收集度量。
监控是从基础设施和应用程序收集metrics。
从前一直在使用的Heapster已被集成的Metrics-server所取代。一旦安装并配置好,服务器就会暴露一个标准API,其他agent可以使用它来确定集群的使用情况。我们还可以自定义metrics,然后自动扩展控制器也可以使用这些度量来确定是否应执行操作。
6. Plugin
我们一直在使用kubectl命令。基本命令可以以更复杂的方式一起使用,以扩展可以执行的操作。有超过70个和不断增长的插件可用于与Kubernetes对象和组件交互。
在编写本课程时,插件不能覆盖现有的kubectl命令,也不能向现有命令添加子命令。编写新插件应该考虑命令行运行时包和插件作者的Go库。
作为插件,要使用的名称空间或容器等选项的声明必须在命令之后。
$ kubectl sniff bigpod-abcd-123 -c mainapp -n accounting
插件可以通过多种方式来发布。我们可以使用krew(kubectl的插件管理命令)跨平台打包并且帮我们找到有用的插件。
安装krew请参考 krew’s GitHub repository.
$ kubectl krew help
安装好以后就可以通过kubectl krew来使用了
kubectl krew [command]...
Usage:
krew [command]
6.1. 可用的命令
COMMAND | DESCRIPTION |
---|---|
help | Help about any command |
info | Show information about kubectl plugin |
install | Install kubectl plugins |
list | List installed kubectl plugins |
search | Discover kubectl plugins |
uninstall | Uninstall plugins |
update | Update the local copy of the plugin index |
upgrade | Upgrade installed plugins to newer versions |
version | Show krew version and diagnostics |
6.2. 管理插件
使用help选项可以查看基础的操作。安装完成之后要保证$PATH目录中有插件,krew就可以轻松愉快的使用了
$ export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
$ kubectl krew search
NAME DESCRIPTION INSTALLED
access-matrix Show an RBAC access matrix for server resources no
advise-psp Suggests PodSecurityPolicies for cluster. no
....
$ kubectl krew install tail
Updated the local copy of plugin index.
Installing plugin: tail
Installed plugin: tail
\
| Use this plugin:
....
| | Usage:
| |
| | # match all pods
| | $ kubectl tail
| |
| | # match pods in the 'frontend' namespace
| | $ kubectl tail --ns staging
....
列出当前所有的插件
kubectl plugin list
查找新的插件
kubectl krew search
安装新的插件
kubectl krew install new-plugin
安装完成之后的插件还可以随时的更新和卸载
6.3. 使用Wireshark嗅探网络
群集网络通信被加密,使得可能的网络问题的故障排除变得更加复杂。使用sniff插件,您可以从内部查看流量。sniff需要Wireshark和导出图形显示的能力。
sniff命令将使用第一个找到的容器,除非我们传递-c选项来声明pod中要用于流量监视的容器。
$ kubectl krew install sniff nginx-123456-abcd -c webcont
7. 日志工具
日志记录和监视一样,是其中一个庞大的主题。它有很多工具可以作为我们工具的一部分。
通常,日志在被搜索引擎接收之前在本地收集和聚合,并可以通过正则表达式显示。其实有许多软件堆栈可用于日志记录,Elasticsearch、Logstash和Kibana堆栈(ELK)已经很普遍了。
在Kubernetes中,kubelet将容器日志写入本地文件(通过Docker日志驱动程序)。kubectl logs命令允许您检索这些日志。
集群范围内,您可以使用Fluentd以聚合日志。查看群集管理日志记录概念详细描述。
Fluentd是云计算本地计算基础的一部分,与Prometheus一起,它们为监控和日志记录提供了一个很好的组合。你可以找到运行Fluentd on Kubernetes的详细介绍在Kubernetes文档中。