【nginx】解决k8s中部署nginx转发不会自动更新域名解析启动失败的问题

embedded/2024/9/25 10:38:29/

文章目录

  • 1. 问题
  • 2.解决办法
  • 3.扩展说明
    • 3.1 DNS解析阶段划分
    • 3.2 问题说明
      • 3.2.1 先看/etc/resolv.conf说明
      • 3.2.2 针对第一个问题
      • 3.2.3 针对第二个问题

【后端】Nginx+lua+OpenResty高性能实践
参考: https://blog.csdn.net/u010837612/article/details/123275026

1. 问题

k8s中使用nginx作为后端接口反向代理,大概配置如下:

  location /api {proxy_set_header   X-Forwarded-Proto $scheme;proxy_set_header   Host              $http_host;proxy_set_header   X-Real-IP         $remote_addr;proxy_pass http://api-server-svc:8080/;}

其中api-server-svc是后端服务的serviceName
这个配置会有两个问题:

1.要求api-server-svc这个service要先创建,否则nginx启动时会因为无法解析api-server-svc而启动失败
2.·nginx·服役期间,如果后端服务重启(这里指的容器重新创建,并非更新镜像,因为更新镜像ip不会变动,还是原来容器),svc ip改变了,代理会失败,因为nginx缓存了旧ip

2.解决办法

修改nginx配置如下:

  # dns设置缓存时间5s,解决问题2resolver kube-dns.kube-system.svc.cluster.local valid=300s;# 使用变量方式,解决问题1set $apiserver api-server-svc.xxx.svc.cluster.local;location /api {proxy_set_header   X-Forwarded-Proto $scheme;proxy_set_header   Host              $http_host;proxy_set_header   X-Real-IP         $remote_addr;rewrite /api/(.*) /$1 break;proxy_pass http://$apiserver:8080;}

set $apiserver api-server-svc.xxx.svc.cluster.local; 中域名一定要写全域名,不能简写成api-server-svc
之前之所以可以简写,因为容器/etc/resolv.conf中有配置了search,在解析域名时会自动帮你补全域名。
但此处我们使用了resolver指定了域名服务器,在解析时是不会自动帮我们补全的

3.扩展说明

3.1 DNS解析阶段划分

一般来说,Nginx在配置解析阶段(即Nginx启动时读取配置文件并解析配置的阶段)和请求处理阶段(即Nginx接收并处理客户端请求的阶段)对域名的处理方式是不同的。
配置解析阶段:

  • 在这个阶段,如果Nginx配置文件中直接使用了域名(而不是通过变量引用),Nginx会在启动时尝试解析这些域名。这个解析过程通常是同步且阻塞的,Nginx会使用系统配置的DNS服务器(如/etc/resolv.conf中指定的DNS服务器)来解析域名。
  • 如果在配置文件中使用了变量来引用域名(例如,在set指令中设置了一个变量来存储域名),并且这个变量在请求处理阶段被用于反向代理或重定向等场景,那么域名的解析可能会推迟到请求处理阶段进行。

请求处理阶段:

  • 在请求处理阶段,如果Nginx需要根据变量中的域名进行动态解析(例如,在proxy_pass指令中使用了变量),Nginx可以使用其内置的动态DNS解析机制。这个机制允许Nginx在需要时根据配置的DNS服务器(通过resolver指令指定)来解析域名。
  • resolver指令可以在http块、server块或location块中设置,用于指定Nginx用于动态DNS解析的DNS服务器地址。Nginx会按照这些地址的顺序尝试解析域名,直到成功为止。
  • 如果在Nginx配置中使用了resolver指令,并且变量中的域名在请求处理阶段被用于需要DNS解析的场景,那么Nginx就会根据resolver指令中指定的DNS服务器来解析这个域名,而不会去读取/etc/resolv.conf文件。这是因为resolver指令已经明确告诉了Nginx应该使用哪些DNS服务器进行解析。
  • k8s中一般都是这个DNS解析服务器:kube-dns.kube-system.svc.cluster.local ;
  • 一般配置了set 域名,都要搭配使用resolver如果没有配置 resolver,Nginx可能会依赖于系统默认的DNS解析设置(如/etc/resolv.conf文件),但这并不是Nginx直接的行为,而是系统层面的行为。然而,需要注意的是,Nginx在处理域名解析时并不一定会直接读取/etc/resolv.conf文件,特别是在一些特定配置或环境下(配置set 要配置resolver,因为至少我在docker中测试时,如果不配置resovler,在请求处理阶段,并不会去根据/etc/resolv.f解析域名)
    • 必须配置resolver:如果Nginx配置中使用了变量来存储需要解析的域名,并且这个域名在请求处理阶段被使用,那么通常需要在Nginx配置中显式地配置resolver指令,以指定用于解析域名的DNS服务器。
    • 系统默认行为可能不适用:虽然Nginx可能会依赖于系统默认的DNS解析设置,但在Nginx配置中明确指定resolver是更可靠和可控的做法。

3.2 问题说明

3.2.1 先看/etc/resolv.conf说明

在这里插入图片描述

3.2.2 针对第一个问题

如果是proxy_pass: http://serviceName:port,那么启动时默认情况会去根据/etc/resolv.conf的search字段拼接成serviceName.namespace.svc.cluster.local,然后根据这个域名去nameserver指定的域名服务器解析,解析到serviceName的ip地址,会进行缓存,后续访问就会使用,如ip1是:10.96.3.33
但是如果这个服务不存在,ip1就会拿不到,从而导致启动nginx失败。
报错:host not found in upstream “aaa” in /etc/nginx/nginx.conf:63
在这里插入图片描述

如果使用set指定域名,那么这个域名会到请求阶段才会解析

3.2.3 针对第二个问题

需要用到set自定义变量,请求时才解析域名,这里按理说只配置serviceName解析即可,(按照理解,默认会去根据/etc/resolv.conf解析),但是请求时并没有去解析/etc/resolv.conf,从而无法根据search自动补全,所以这里需要配置完整的路径serviceName.namespace.svc.cluster.local; 同时也需要指定resolver,去明确指定DNS服务器,否则会报错(no resolver defined to resolve throwbill.zj-ywxt-ns.svc.cluster.local
resolver kube-dns.kube-system.svc.cluster.local valid=120s;
在这里插入图片描述


http://www.ppmy.cn/embedded/92693.html

相关文章

SpringBoot自动装配原理

SpringBoot自动装配原理 SpringBootApplication 中包含了三个核心注解 SpringBootConfiguration 声明当前的类是配置类 ComponentScan 组件扫描,默认扫描引导类所在包以及子包 EnableAutoConfiguration 实现SpringBoot自动化配置的核心注解 EnableAutoConfiguration …

24.8.5数据结构|栈

栈-弹夹 1、定义: 栈就是特殊的线性表,与之前的线性表的区别就是增加了约束,只允许在一端插入和删除,就这麽简单。 2、基本操作 栈的插入操作叫:入栈{进栈、压栈};栈的删除:出栈{退栈&#x…

BitNet——用单个比特进行推理的大语言模型,性能媲美全精度Transformer

概述 为了实现高精确度,大规模语言模型变得越来越大,但随着模型越来越大,其部署也面临挑战,人们担心计算量和能耗会增加。本研究提出了权重为 1 的单比特变换器,结果表明它能以更少的计算资源和更高的能效实现与传统 …

大数据信用报告查询有什么作用?怎么选择查询平台?

随着互联网的快速发展,人们的金融行为越来越多地依赖于网络平台。然而,网络上的金融交易存在着一定的风险,为了有效地防范这些风险,金融机构采用了大数据技术进行风险控制,下面,小易大数据平台将详细介绍大…

【滴水三期】32/64位——PE文件头字段打印与解析

一、【作业描述】 1、编写程序读取一个exe文件,输出所有的PE头信息; 2、使用第三方的PE工具,对比如下信息,看是否一致; 二、【PE头字段解析】 注:海哥发的PE结构 PDF也不是特别全的,可以去&…

【深度学习】TTS,LibriTTS数据集

下载地址: https://openslr.elda.org/resources/60/ LibriTTS 是一个包含英文音频数据的数据集。LibriTTS 数据集主要基于 LibriVox 的有声书内容,用于训练和评估文本到语音(TTS)系统。这个数据集包括高质量的录音和对应的文本转录,可以帮助开发者构建和优化 TTS 模型。 …

MySQL —— 约束

MySQL —— 约束 引言not nulluniqueprimary key —— 主键auto_increment复合主键 foreign key —— 外键插入数据删除主表的数据 default 引言 在设计表的时候,有些列是必填项(如果用户不填,那这个数据就没有必要存进数据库)&a…

Django基础知识

文章目录 新建Django项目helloworld关联数据库admin 新建Django项目 创建django-admin startproject project_name 运行 python manage.py runserver 创建app: python manage.py startapp app_name 目录: 配置文件 settings.py 路由配置 urls.py 项目管理 manage.p…