切换语言为:繁体

记录istio无法转发服务的一次bug

  • 爱糖宝
  • 2024-08-23
  • 2051
  • 0
  • 0

现象说明

由于扩容需要,我把k8s的一台服务器重启了。然后跑在k8s上的项目访问不了了。

我做了如下的一些尝试:

1. 确认k8s集群是正常的。

  • 判断节点状态

kubectl get nodes -o wide

发现有的node 显示 not ready。通过重启节点上的kubelet服务等方式,使得节点状态转换为ready

# 不正常的node 上重启服务
systemctl restart docker

systemctl restart kubelet

  • 查看kubelet日志,看有无错误

# 各个node上, 查看状态
systemctl status kubelet

# 查看日志
journalctl -u kubelet -f

如果有日志错误,就查询相应的解决方法

2. 判断服务状态

# 查看pod状态
kubectl get pods -n <namespace_name>

# 查看pod描述
kubectl describe pod -n <namespace_name> <pod_name>

# 查看pod日志
kubectl logs -n <namespace_name> <pod_name>

确定所有的pod都启动正常,没有报错

3. 确定是否是请求转发的问题

由于istio不好定位问题,因为一方面我对它不熟,另一方面多了好多流量转发的过程,不好定位问题所在。我直接把系统的端口通过k8s暴露出来。

暴露服务的配置文件expose.yml 如下:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  # 这里修改你自己的命名空间
  namespace: my_namespace
spec:
  selector:
    # 这里修改为你自己的选择器,选择需要暴露的服务
    app: xxx
  type: NodePort
  ports:
  - name: http
    # 这里修改为你自己的服务端口和对外暴露的端口
    port: 80
    targetPort: 80
    protocol: TCP
    nodePort: 8080

执行命令,部署到k8s上

# 修改下面命令中的文件名为你自己的文件
kubectl apply -f expose.yml

然后可以在外部访问 8080端口,发现是能够访问该服务的。 那就确认了是istio的问题。

4. 确认 istio的服务正常。

istio 正常情况下也是需要部署一些pod、service、crd等,到k8s上的。最可能出问题的就是pod和service

  • 确认istio 的pod正常启动 这里都在istio-system命名空间中

# 查看pod状态
kubectl get pods -n istio-system

# 查看pod描述
kubectl describe pod -n istio-system <pod_name>

# 查看pod日志
kubectl logs -n istio-system <pod_name>

我这里有两个pod istio-ingressgatewway是负责进入的流量转发的, istiod是控制平面的服务

记录istio无法转发服务的一次bug

开始的时候,我这两个pod都启动不了,一直是creating的状态。描述中的报错是

MountVolume.SetUp failed for volume "istio-token" : failed to fetch token: the server could not find the requested resource

找了好久,没有好的解决方法。有的人说是和第一方和第三方认证啥的相关。感觉不是很靠谱的样子,毕竟istio官网,也没说这个事情。

后来灵光一闪,是不是istio版本的问题?

找到的问题1: istio版本问题

突然想到我之前有两个版本的istio安装过。经过确认是istio版本和k8s版本不匹配的问题。我卸载了istio,然后安装了正确的版本,istio的两个pod启动起来了。

为什么会这样?

我就重启了一下服务器,没有重新安装istio,为什么之前可以,现在istio启动不了?

我印象中我用过 1.4 和1.5两个版本的istio。

  • 最开始安装的1.4版本是正确的,正常启动的。

  • 然后为了项目能够一键启动,项目的启动文件里,配置了istio的安装脚本,这里配置了1.5的版本

  • 后来也根据安装脚本使用kubectl apply -f xxx.yaml 更新过项目,istio 也更新了,没事

  • 服务器重启了,istio启动失败

我认为这可能是k8s的一个bug,就是1.4 版本安装好之后,

kubectl apply -f install-1.4.yml

再安装1.5

kubectl apply -f install-1.5.yml

并不会杀掉旧版本istio的pod,istio正常提供转发服务。服务器重新启动后,会根据install-1.5.yml启动1.5 版本的istio,版本不匹配这个时候就出错了。

之前也遇到过类似的事情。

给我的启发是,k8s中的服务yml配置有更新的时候,最好kubectl delete 之后,再 kubectl apply -f xxx

找到的问题2:

istio的pod都启动了,但是还是无法访问我们的项目。 我又重新确认了一下istio的gateway、 virtual service、service的配置情况,没有问题。

之前是使用脚本批量执行kubectl apply 的。为了好定位问题,我手动一条一条执行,发现gateway.yml部署的时候,报错,

Error from server: error when creating "gateway.yaml": admission webhook "validation.istio.io" denied the request: configuration is invalid: port name must be set: number:80  protocol:"HTTP" Error from server: error when creating "gateway.yaml": admission webhook "validation.istio.io" denied the request: configuration is invalid: port name must be set: number:8080  protocol:"HTTP"

这个报错信息很明确了,就是配置文件错了,少了一个name没有配置。其实这个name无所谓,随便写个名字就行。

修改保存,然后执行

kubectl apply -f gateway.yml

部署成功。

这个问题,我就没想明白是怎么回事了,之前的配置文件都是正常部署的,istio也没更新,k8s也没更新,咋就不行了呢? 奇怪。。。。。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.