kubernetes的timeout问题

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介: kubernetes+alpine+php特别容易出现访问外网/解析外网地址的时候出现超时的问题.

kubernetes+alpine+php特别容易出现访问外网/解析外网地址的时候出现超时的问题.

原因

docker容器访问外网的时候,整个完整路径是这样的.

容器-->主机-->外网-->主机-->容器

容器到主机之间的流量要经过源地址转换(SNAT)才能顺利流通.

SNAT就像是一个搬运工,把砖(流量)从容器搬到主机

如果一个主机上面运行多个容器,并发访问外网(特别是PHP这种没有连接池的)时向系统申请可用端口(nf_nat_l4proto_unique_tuple),不可用时+1,然后再申请,再校验.这个过程一多,最终就会导致寻址超时.

说白了是个系统内核问题.

详细的解释见

记一次Docker/Kubernetes上无法解释的连接超时原因探寻之旅

解决方案

最优解

节点升级到 5.1的Linux内核.

iptables升级到1.6.2以上

用基于IPVS模式,尽量少做SNAT/DNAT,支持随机端口SNAT的网络插件启动kubernetes

或者用绕过SNAT的网络插件插件方案,比如阿里云的terway.但这个插件跟阿里云绑定得比较深入,需要每台机器额外购买一个弹性网卡.

次优解

用ds部署name sever,所有节点的DNS解析走节点上的name server,通过最小程度的SNAT+dns cache缓解此类问题.

伪解决方案(不能解决根本问题)

默认的pod的/etc/resolv.conf一般长这样

sh-4.2# cat /etc/resolv.conf
nameserver <kube-dns-vip>
search <namespace>.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5

这个配置的意思是,默认nameserver指向kube-dns/core-dns,所有查询中,如果.的个数少于5个,则会根据search中配置的列表依次搜索,如果没有返回,则最后再直接查询域名本
身。ndots就是n个.(dots)的意思

举个例子

sh-4.2# host -v baidu.com
Trying "baidu.com.<namespace>.svc.cluster.local"
Trying "baidu.com.svc.cluster.local"
Trying "baidu.com.cluster.local"
Trying "baidu.com.localdomain"
Trying "baidu.com"
......

重开socket

        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c 
              - "/bin/echo 'options single-request-reopen' >> /etc/resolv.conf"

设置重开socket是规避容器并发A,AAAA查询

2级域名直接走上层解析

参考kubernetes 使用基于 alpine 镜像无法正常解析外网DNS 做的

直接运行 sed -i 's/options ndots:5/#options ndots:5/g' /etc/resolv.conf 会报错

alpine的echo命令会吞换行符,而resolv.conf格式不对DNS解析会报错

  dnsConfig:
    options:
      - name: ndots
        value: "2"
      - name: single-request-reopen

去掉了options ndots:5,变会默认值1,这样的话,容器内部直接访问还是没问题的,走search列表,<svc>.<namespace>.svc.cluster.local,还是能够访问。

而解析Google.com,实际上是解析Google.com.,.的数量超过1个,这时不走search列表,直接用上层DNS

综上所述,去掉ndots/ndots设为1 降低了频繁DNS查询的可能性。对于外网IP的解析有“奇效”。

但如果该主机运行其他容器(这不废话吗,一个节点不跑多个容器那还用啥kubernetes),其他容器也会并发地请求,SNAT的问题还是会出现,所以说修改/etc/resolv.conf文件并不能解决根本问题

歪门邪道1

          lifecycle:
            postStart:
              exec:
                command:
                - /bin/sh
                - -c 
                - "head -n 2 /etc/resolv.conf > /etc/temp.conf;cat /etc/temp.conf > /etc/resolv.conf;rm -rf /etc/temp.conf"

歪门邪道2

      initContainers:
      - name: alpine
        image: alpine
        command:
         - /bin/sh
         - -c 
         - "head -n 2 /etc/resolv.conf > /etc/temp.conf;cat /etc/temp.conf > /etc/resolv.conf;rm -rf /etc/temp.conf"

衍生的问题

DNAT

容器访问clusterIP(因为是虚拟IP所以需要DNAT)也有可能出现这类超时的问题

注意Virtual domain的问题

non-headservice的域名格式是<svc>.<namespace>.svc.cluster.local

如果我们容器直接访问<svc>.<namespace>.svc.cluster.local,因为默认DNS设置的问题,解析的次数反而更多。正确的方式是访问<svc>

例子:假设test下面有个s的svc

host -v s 
# 解析1次
host -v s.test.svc.cluster.local
# 解析4次

所以,访问同namespace其他svc,直接用svc名去访问即可,没必要装逼使用<svc>.<namespace>.svc.cluster.local这种格式。

其他知识

dns记录类型

  1. A记录:地址记录,用来指定域名的IPv4地址(如:8.8.8.8),如果需要将域名指向一个IP地址,就需要添加A记录。
  2. CNAME: 如果需要将域名指向另一个域名,再由另一个域名提供ip地址,就需要添加CNAME记录。
  3. TXT:在这里可以填写任何东西,长度限制255。绝大多数的TXT记录是用来做SPF记录(反垃圾邮件)。
  4. NS:域名服务器记录,如果需要把子域名交给其他DNS服务商解析,就需要添加NS记录。
  5. AAAA:用来指定主机名(或域名)对应的IPv6地址(例如:ff06:0:0:0:0:0:0:c3)记录。
  6. MX:如果需要设置邮箱,让邮箱能收到邮件,就需要添加MX记录。
  7. 显性URL:从一个地址301重定向到另一个地址的时候,就需要添加显性URL记录(注:DNSPod目前只支持301重定向)。
  8. 隐性URL:类似于显性URL,区别在于隐性URL不会改变地址栏中的域名。
  9. SRV:记录了哪台计算机提供了哪个服务。格式为:服务的名字、点、协议的类型,例如:_xmpp-server._tcp。

用到的命令

安装方法:

  yum install -y bind-utils
  sudo apt-get install -y dnsutils
  apk add bind-tools

dig

dig +trace +ndots=5 +search $host

host

host -v $host

参考链接:

  1. iptables中DNAT、SNAT和MASQUERADE的理解
  2. linux根文件系统 /etc/resolv.conf 文件详解
  3. kube-dns per node #45363
  4. DNS intermittent delays of 5s #56903
  5. /etc/resolv.conf
  6. /etc/resolv.conf search和ndots配置
  7. DNS for Services and Pods
相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
Kubernetes Linux API
[没接触过kubevirt?]15分钟快速入门kubevirt
什么是kubevirt? kubevirt是一个容器方式运行虚拟机的项目。`kubevirt`是附加`kubernetes`集群上的,它是通过 `CustomResourceDefinition(CRD)`部署到`Kubernetes API`变成资源对象。使用方式类似创建`deploy、pod`......这些资源清单。
5362 0
[没接触过kubevirt?]15分钟快速入门kubevirt
|
Linux Shell 网络安全
|
缓存 Linux 开发工具
CentOS 7- 配置阿里镜像源
阿里镜像官方地址http://mirrors.aliyun.com/ 1、点击官方提供的相应系统的帮助 :2、查看不同版本的系统操作: 下载源1、安装wget yum install -y wget2、下载CentOS 7的repo文件wget -O /etc/yum.
258664 0
|
Kubernetes 容器 Perl
【kubernetes】解决: kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = faile...
【kubernetes】解决: kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = faile...
16690 0
|
存储 Kubernetes 调度
k8s常见的排错指南Node,svc,Pod等以及K8s网络不通问题
k8s常见的排错指南Node,svc,Pod等以及K8s网络不通问题
4918 1
|
Kubernetes 负载均衡 应用服务中间件
部署Kubernetes(k8s)多主的高可用集群
在CentOS7上安装Kubernetes多主节点的集群,并且安装calico网络插件和metallb。使用keepalived和haproxy进行负载均衡。最后部署应用
4469 0
|
SQL 关系型数据库 Java
PostgreSQL统计信息的几个重要视图
PostgreSQL统计信息的几个重要视图
485 1
|
存储 安全 算法
MD5的日常实践应用:确保数据完整性与基础安全校验
**MD5概览:** 作为过时但仍然流行的散列函数,MD5用于生成数据固定长度的散列,常用于文件完整性校验和非安全密码验证。虽因易受碰撞攻击而不适于安全用途,但在低敏感场景下仍有应用。例如,Python代码展示如何计算文件MD5校验和及模拟MD5密码验证。不过,对于高安全需求,推荐使用SHA-256等更安全的算法。【6月更文挑战第17天】
1145 1
|
消息中间件 Kubernetes Cloud Native
【混沌工程】Chaos Mesh:Kubernetes 的混沌工程平台。
Chaos Mesh 是云原生计算基金会 (CNCF) 托管的项目。 它是一个云原生混沌工程平台,可在 Kubernetes 环境中编排混沌。 在当前阶段,它具有以下组件:
|
设计模式 缓存 Devops
微服务架构最强讲解,那叫一个通俗易懂!
微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。你可以将其看作是在架构层次而非获取服务的
31336 2
微服务架构最强讲解,那叫一个通俗易懂!