在使用 Kubernetes 中,经常会遇到一个奇怪的现象,当 Pod 与 CoreDNS 在同一个 Node 节点时,此 Pod 无法解析 DNS 记录。

我清楚的知道 Service 是使用 iptables NAT DNAT + SNAT 规则实现的,因此我排查的方向是抓包查看数据包的流向。

经过抓包分析,发现同一个 Node 节点访问 Service 只是对访问的流量进行了 DNAT,没有做 SNAT。但当时并没有找到解决方法,今天又遇到了一样的问题,通过爬文找到了这篇文章,所描述的问题现象一模一样,也附带了解决方法,并有详细的排查过程,读者可以去拜读一下。

我的 Kubernetes 集群是使用 kubeadm 部署的,因此解决方法是修改 kube-proxy 的 ConfigMap

[root@k8s-master01 ~]# kubectl -n kube-system get cm
NAME                                 DATA   AGE
coredns                              1      20d
extension-apiserver-authentication   6      20d
kube-flannel-cfg                     2      20d
kube-proxy                           2      20d
kubeadm-config                       2      20d
kubelet-config-1.18                  1      20d
metrics-server-config                1      19d
kubectl -n kube-system edit cm kube-proxy

# 修改 masqueradeAll: true

重启所有节点的 kube-proxy:

[root@k8s-master01 monitoring]# kubectl -n kube-system get pods
NAME                                      READY   STATUS    RESTARTS   AGE
coredns-66bff467f8-5v2j7                  1/1     Running   1          20d
coredns-66bff467f8-gtrdb                  1/1     Running   0          26m
etcd-k8s-master01                         1/1     Running   1          20d
kube-apiserver-k8s-master01               1/1     Running   1          20d
kube-controller-manager-k8s-master01      1/1     Running   2          20d
kube-flannel-ds-94n7x                     1/1     Running   1          20d
kube-flannel-ds-nf26k                     1/1     Running   1          20d
kube-flannel-ds-nl2dl                     1/1     Running   1          20d
kube-flannel-ds-thl9f                     1/1     Running   2          20d
kube-proxy-gpxhb                          1/1     Running   1          20d
kube-proxy-k2gjh                          1/1     Running   1          20d
kube-proxy-lp5jw                          1/1     Running   1          20d
kube-proxy-z67qm                          1/1     Running   1          20d
kube-scheduler-k8s-master01               1/1     Running   3          20d
metrics-server-v0.3.6-5d9877d6b6-bqq8d    2/2     Running   2          19d
nfs-client-provisioner-5fbf5f4476-fpmdq   1/1     Running   2          10d
# 删掉Pod,让其重建
kubectl -n kube-system delete pod kube-proxy-gpxhb kube-proxy-k2gjh kube-proxy-lp5jw kube-proxy-z67qm

至此,问题解决。

说起日志,我相信每个从业人员都不陌生。从分析问题、观测软件运行状态等都离不开日志,程序日志记录了程序的运行轨迹,往往还包含了一些关键数据、错误信息等。

因此在使用 Kubernetes 的过程中,对应的日志收集也是我们不得不考虑的问题,我们需要日志去了解集群内部的运行状况。

Kubernetes 中的日志收集 VS 传统日志收集

传统应用中,往往是在虚拟机或物理机直接运行程序,程序日志输出到本机的文件系统的某个目录中,或者是由rsyslog、systemd-journald等工具托管。在此类环境中,日志目录是相对固定不变的,因此收集日志只需要访问日志目录即可。

而在 Kubernetes 中,日志收集相比传统虚拟机、物理机方式要复杂得多。

首先,Kubernetes 日志的形式非常多样化,一个完整的日志系统至少需要收集以下三种:

  • Kubernetes 各组件的运行日志,如 kubelet、docker、kube-prpoxy 等
  • 业务容器的运行日志,如 tomcat、nginx 等
  • Kubernetes 的各种 Event,如 Pod 的创建、删除、错误等事件

其次,我们知道 Pod 是“用完即焚”的,当 Pod 的生命周期结束后,其日志也会被删除。但是这个时候我们仍然希望可以看到具体的日志,用于查看和分析业务的运行情况,以及帮助我们发现出容器异常的原因。

再次,Kubernetes 集群中的资源状态可能随时会发生变化,Pod 实例数量随时都可能会受 HPA(Horizontal Pod Autoscaler ) 的影响或管理员的操作而变化。我们并无法预知 Pod 会在哪个节点上运行,而且 Kubernetes 工作节点也无时无刻可能会宕机。

在一切都是动态的场景下,Kubernetes 日志系统在设计时就要考虑这些不确定因素

几种常见的 Kubernetes 日志收集架构

Kubernetes 集群本身其实并没有提供日志收集的解决方案,但依赖 Kubernetes 自身提供的各项能力,可以帮助我们解决日志收集的诉求。根据上面提到的三大基本日志需求,一般来说我们有如下有三种方案来做日志收集:

  • 应用程序自身将日志推送到日志系统
  • 在每个节点上运行一个 Agent 来采集节点级别的日志
  • 在一个 Pod 内使用一个 Sidecar 容器来收集应用日志

下面分别分析这三种方案的使用场景和优缺点。

- 阅读剩余部分 -

说起Kubernetes监控,绕不开的话题就是Prometheus。随着Prometheus的发展,已然成为Kubernetes监控体系中的标准。

本文主要介绍通过yaml部署清单来安装Prometheus。

部署Prometheus

包含组件:

  • prometheus
  • kube-state-metrics
  • node-exporter
  • pushgateway
  • alertmanager
  • grafana

prometheus组件.png

- 阅读剩余部分 -

dashboard组件为我们提供了一个WebUI,使得K8S集群的管理更加的方便和直观。

篇一篇二分别介绍了如果搭建Kubernetes集群和部署metrics-server指标数据监控组件,本篇介绍如何在Kubernetes集群中部署dashboard组件。

dashboardyaml部署文件位于github仓库 这里这里。同样的,作为K8S插件部署与K8S集群中。

下载yaml部署文件

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dashboard/dashboard.yaml

设置登录过期时间

默认情况下在dashboard界面空闲几分钟没有操作就自动登出了,我们可以通过修改启动参数来修改这个自动登出时长。

修改dashboard.yaml,添加启动参数--token-ttl=86400,即无操作24小时后自动登出

          args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            - --token-ttl=86400

- 阅读剩余部分 -

Kubernetes v1.12之前的版本,资源指标监控主要是heapster来实现,在Kubernetes v1.12之后的版本,heapster逐渐被废弃了,取而代之的是metrics-server

metrics-server作为k8s插件部署在k8s集群内,提供资源指标监控数据。其yaml部署文件在这里

但是这个yaml清单是没办法直接使用的,会报一些错误,下面我记录下来都会遇到哪些问题以及其解决方法。

下载yaml部署清单

mkdir metrics-server
cd metrics-server

for file in auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml; do
  wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/metrics-server/$file
done

metrics-server-deployment.yaml文件中使用了两个镜像,镜像地址是k8s.gcr.io,由于国内网络限制,改为阿里云的镜像地址

  • registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
  • registry.cn-hangzhou.aliyuncs.com/google_containers/addon-resizer:1.8.11

metrics-server-deployment.yaml中metrics-server-nanny镜像的启动参数有几个变量,不能直接使用,需要修改如下:

        command:
          - /pod_nanny
          - --config-dir=/etc/config
          - --cpu=100m
          - --extra-cpu=20m
          - --memory=100Mi
          - --extra-memory=10Mi
          - --threshold=5
          - --deployment=metrics-server-v0.3.6
          - --container=metrics-server
          - --poll-period=300000
          - --estimator=exponential
          # Specifies the smallest cluster (defined in number of nodes)
          # resources will be scaled to.
          - --minClusterSize=2
          # Use kube-apiserver metrics to avoid periodically listing nodes.
          - --use-metrics=true

- 阅读剩余部分 -