k8s面试-实操篇

Posted by 白行简 on Wednesday, May 25, 2022

k8s基础篇

1.K8S 生产中遇到过哪些印象深刻的问题?怎么排查和解决的?(重点)

问题:前端负载均衡服务器上的 Keepalived出现脑裂现象。

脑裂指的是本应由主服务器持有的 VIP,同时被主备服务器持有,可能导致网络流量的混乱。以下是当时的处理流程:

问题表现:VIP 同时出现在主服务器和备服务器上,但奇怪的是业务并未受到明显影响。

  1. 初步排查:查看备服务器上的日志,发现有 VRRP 超时,导致备服务器接管了 VIP。查看主服务器日志和进程状态,都显示正常。
  2. 进一步排查:检查防火墙和 SELinux,确认它们都是关闭状态。
  3. 数据包分析:使用 tcpdump 抓包分析,发现备服务器确实在发送 VRRP 心跳包,导致外部流量进入备服务器。
  4. 怀疑原因:初步猜测可能是 VRRP 心跳包的时间间隔过长,检测脚本的设置也可能不合理。
  5. 调整设置:将 VRRP 心跳包间隔从 2 秒调整为 1 秒,检测脚本的失败次数检测从连续两次失败才判定为失败。
  6. 重新测试:重启主备服务器上的 Keepalived,一切恢复正常。
  7. 再次复现:第二天凌晨同样时间,又出现脑裂现象。怀疑网络问题,排查了路由器,确认没有禁用 VRRP 协议。
  8. 最终解决:根据文档,发现默认的组播模式容易冲突,改为单播模式后,问题彻底解决。 总结:这个问题的根本原因是 Keepalived 默认使用组播模式,导致多个实例发生冲突。通过改为单播模式,保证了心跳包的唯一性,彻底解决了脑裂问题。

2.K8S 生产中遇到的另一个问题:ETCD 集群出现两个 Leader

  • 问题现象:搭建好的 K8S 测试集群,发现 kubectl get nodes 无法正常显示节点资源,而 kubectl get namespace 有时能显示,有时不能。

排查步骤:

  • 怀疑网络插件问题:起初以为是 Calico 没有安装导致的,但仔细分析后认为即使没有网络插件,也不至于完全没有资源发现。
  • 怀疑 ETCD 集群问题:因为所有的 K8S 资源都是存储在 ETCD 中,开始检查 ETCD 服务。
  • 发现两个 Leader:查看日志发现 ETCD 集群有两个 Leader,这是不正常的,ETCD 集群应该只有一个 Leader。
  • 重启和修改配置无效:尝试修改配置文件、重启服务、重新颁发证书,但问题依旧。
  • 最终解决:删除整个 ETCD 集群,重新搭建,问题解决。
  • 总结:ETCD 出现多个 Leader 的原因可能是配置问题或者环境异常。在生产环境中,遇到此类问题时,一定要先做好数据备份,然后再进行进一步操作。

3.如何让一个 Node 脱离集群调度(比如要停机维护,但不影响业务)?

当你需要维护某个节点,但又不希望这个节点上的业务受到影响,可以使用 kubectl drain 命令。
这个命令会将节点上的 Pod 安全地迁移到其他节点上,确保业务不中断。

具体步骤:

  • 首先,使用 kubectl drain ,这会让 K8S 把该节点上的所有 Pod 迁移到其他节点上。
  • 如果有些 Pod 设置了 PodDisruptionBudget,确保你理解并满足其要求。
  • 维护完成后,可以使用 kubectl uncordon ,重新允许该节点参与调度。

4.Service 无法访问及解决方案

一、问题描述

当用户尝试通过 Service的 P 地址或 DNS 名称访问后端 Pod 时,可能会遇到以下情况:
无法连接到 Service
请求超时
返回错误信息(如 404、500 等)

二、故障排查步骤

- 1. 确认 Service 状态
首先,检查 Service 是否已成功创建并处于正常状态。
kubectl get svc
输出示例:
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
my-service    ClusterIP   10.96.0.1      <none>        80/TCP     10m

- 2. 检查 Pod 状态
确认与 Service 关联的 Pod 是否处于 Running 和 Ready 状态。
kubectl get pods -l app=my-app

输出示例:
AME            READY   STATUS    RESTARTS   AGE
my-app-1       1/1     Running   0          5m
my-app-2       1/1     Running   0          5m

- 3. 查看 Service 详细信息
查看 Service 的详细信息,确认选择器(selector)是否正确,以及端口配置是否合理。
kubectl describe svc my-service
输出示例:
Name:              my-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=my-app
Type:              ClusterIP
IP:                10.96.0.1
Port:              <unnamed>  80/TCP
Endpoints:         10.244.1.2:8080,10.244.1.3:8080

- 4. 测试 Pod 之间的连接
在集群内部,可以使用 kubectl exec 命令进入某个 Pod,测试对 Service 的访问。
kubectl exec -it <some-pod-name> -- curl http://my-service

如果返回错误,进一步检查 Pod 的网络连接和配置。

三、常见原因及解决方案

    1. Service 类型不正确
问题描述:Service 的类型可能未设置为适用的类型(如 ClusterIP、NodePort、LoadBalancer)。
解决方案:

确认 Service 的类型是否符合预期。对于外部访问,确保使用 NodePort 或 LoadBalancer 类型。
修改 Service 类型:
yaml apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30007
  • 2.选择器未匹配到Pod
问题描述:Service 的选择器可能未正确匹配到 Pod 的标签。
解决方案:

检查 Service 的选择器与 Pod 标签是否一致。
示例:
kubectl get pods --show-labels
确保选择器 app=my-app 正确匹配到相关的Pod
  • 3.Pod 未处于运行状态
问题描述:与 Service 关联的 Pod 可能未处于运行状态。
解决方案:
使用以下命令查看 Pod 状态:
kubectl get pods
如果 Pod 处于 CrashLoopBackOff 或其他非正常状态,查看其日志:
kubectl logs <pod-name>
  • 4.网络策略限制访问
问题描述:网络策略(Network Policies)可能限制了 Pod 之间的访问。
解决方案:
检查当前命名空间的网络策略:
kubectl get networkpolicy
如果存在限制,更新网络策略以允许流量。
  • 5.DNS解析失败
问题描述:其他 Pod 可能无法通过 Service 名称解析到正确的 IP 地址。
解决方案:
确认 CoreDNS 是否正常运行:
kubectl get pods -n kube-system -l k8s-app=kube-dns
查看 CoreDNS 日志,确认没有错误:
kubectl logs -n kube-system <coredns-pod-name>
测试 DNS 解析:
kubectl exec -it <some-pod-name> -- nslookup my-service.default.svc.cluster.local
  • 6.防火墙或安全组限制
问题描述:云环境中,防火墙或安全组可能阻止了对某些端口的访问。
解决方案:
检查云提供商的安全组设置,确保允许访问 NodePort 或 LoadBalancer 的端口。
  • 7.负载均衡器未分配 IP
问题描述:LoadBalancer 类型的 Service 创建后未分配外部 IP 地址。
解决方案:
检查 Service 的状态:
kubectl get svc my-service
确认你的 Kubernetes 集群配置了负载均衡器,并查看云提供商的控制台。
  • 8.Pod 之间的网络问题
问题描述:可能存在网络问题,导致 Pod 之间无法通信。
解决方案:

使用 kubectl exec 在 Pod 内部测试网络连接:
kubectl exec -it <pod-name> -- ping <another-pod-ip>
确保网络插件(如 Calico、Flannel 等)正常运行
四、总结
Kubernetes Service 是实现 Pod 之间和 Pod 与外部之间通信的重要组件,确保其正常访问至关重要。在排查 Service 无法访问的问题时,可以按照上述步骤逐一检查,确认配置的正确性和网络的可用性。通过有效的监控和日志管理,可以更快地定位问题并恢复服务。

4、Kubernetes集群联邦的跨云服务部署实践

https://www.cnblogs.com/seamounts/p/13371141.html
准备工作

在开始我们的跨云服务部署实践之前,首先需要准备以下工作:
一个或多个Kubernetes集群,它们可以在同一云服务商或不同云服务商上;
安装和配置Kubernetes集群联邦的控制平面,通常可以选择使用Federation V2项目。
在准备工作完成之后,我们可以开始跨云服务部署的实践了。

创建跨云服务的Namespace

首先,我们需要在多个Kubernetes集群上创建用于跨云服务的Namespace。Namespace在Kubernetes中是用于对一组资源进行隔离和共享的机制。通过在不同的集群上创建相同的Namespace,我们可以为跨云服务提供统一的部署空间。

配置跨云服务的部署和服务

在创建了Namespace之后,我们可以在不同的集群上部署跨云服务的应用程序。例如,我们可以使用Deployment和Service对象来完成应用程序的部署和服务发现。

在集群A上的部署和服务配置:**

在集群B上的部署和服务配置:**

在实际部署中,我们可以根据具体需求对Deployment和Service进行调整,例如添加负载均衡、健康检查等配置。

跨云路由和负载均衡

在多个云服务商的环境中,如何实现跨云路由和负载均衡是一个关键问题。一种常见的解决方案是利用云服务商提供的负载均衡器,将流量导向不同的Kubernetes集群。例如,可以使用AWS的ELB(Elastic Load Balancing)和Azure的Azure Load Balancer等服务。

此外,也可以考虑使用第三方的多云负载均衡解决方案,如F5、Citrix等厂商提供的产品。

四、总结

在本文中,我们介绍了Kubernetes集群联邦在跨云服务部署中的应用实践。通过Kubernetes集群联邦,可以比较轻松地管理跨越不同云服务商的多个Kubernetes集群,并实现统一的部署和治理。然而,实际的跨云服务部署涉及到的问题远不止本文涉及到的内容,需要根据具体场景进行更加深入的规划和部署。

希望本文能够对想要在多云环境中部署应用程序的开发人员和系统管理员有所帮助。

「真诚赞赏,手留余香」

观测猿

真诚赞赏,感谢认可

使用微信扫描二维码完成支付