nginx - nginx 入口:在 nginx-controller 日志中忽略 yaml 定义中的冲突主机,但创建非工作情况
问题描述
安装:https ://helm.nginx.com/稳定版
[root@node1 ~]# helm search repo nginx-stable
NAME CHART VERSION APP VERSION DESCRIPTION
nginx-stable/nginx-ingress 0.6.1 1.8.1 NGINX Ingress Controller
kubectl run nginx --image=nginx
kubectl run apache --image=httpd
kubectl expose pod nginx --port=80 --name=nginx-svc
kubectl expose pod apache --port=80
作为测试两个 pod 的方法,nodeport 可以成功访问
我创建了两个 yaml 文件来让入口工作
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ing-rule
annotations:
nginx.org/rewrites: "serviceName=nginx-svc rewrite=/"
spec:
rules:
- host: kubernetes.somelan.lan
http:
paths:
- path: /nginx
backend:
serviceName: nginx-svc
servicePort: 80
对于阿帕奇
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: apache-ingress
annotations:
nginx.org/rewrites: "serviceName=apache rewrite=/"
spec:
rules:
- host: kubernetes.somelan.lan
http:
paths:
- path: /apache
backend:
serviceName: apache
servicePort: 80
当我分别应用这两个 yaml 时,它们被 nginx-controller 接受,无论它记录
conflicting server name "kubernetes.somelan.lan" on 0.0.0.0:80, ignored
结果: 我可以成功访问http://kubernetes.somelan.lan/apache,但是我无法访问http://kubernetes.somelan.lan/nginx。以不同的顺序应用 yaml 会呈现相同的结果如果我删除 apache yaml,则 nginx 入口开始工作;我可以访问http://kubernetes.somelan.lan/nginx
错误代码和日志是:
020/10/27 20:34:28 [error] 62#62: *20 open() "/etc/nginx/html/nginx" failed (2: No such file or directory), client: 10.10.70.22, server: kubernetes.somelan.lan, request: "GET /nginx HTTP/1.1", host: "kubernetes.somelan.lan"
10.10.70.22 - - [27/Oct/2020:20:34:28 +0000] "GET /nginx HTTP/1.1" 404 153 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0" "-"
2020/10/27 20:34:28 [error] 62#62: *20 open() "/etc/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.10.70.22, server: kubernetes.somelan.lan, request: "GET /favicon.ico HTTP/1.1", host: "kubernetes.somelan.lan", referrer: "kubernetes.somelan.lan/nginx"
10.10.70.22 - - [27/Oct/2020:20:34:28 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "kubernetes.somelan.lan/nginx" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0" "-"
但是,如果我创建一个 yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ing-rule
annotations:
nginx.org/rewrites: "serviceName=nginx-svc rewrite=/; serviceName=apache rewrite=/"
spec:
rules:
- host: kubernetes.somelan.lan
http:
paths:
- path: /nginx
backend:
serviceName: nginx-svc
servicePort: 80
- path: /apache
backend:
serviceName: apache
servicePort: 80
一切都按预期工作,我可以访问 /nginx 和 /apache
在 nginx 控制器上,使用单个 yaml 会在控制器上提供以下配置:
# configuration for default/nginx-ing-rule
upstream default-nginx-ing-rule-kubernetes.somelan.lan-apache-80 {
zone default-nginx-ing-rule-kubernetes.somelan.lan-apache-80 256k;
random two least_conn;
server 10.233.112.2:80 max_fails=1 fail_timeout=10s max_conns=0;
}
upstream default-nginx-ing-rule-kubernetes.somelan.lan-nginx-svc-80 {
zone default-nginx-ing-rule-kubernetes.somelan.lan-nginx-svc-80 256k;
random two least_conn;
server 10.233.64.2:80 max_fails=1 fail_timeout=10s max_conns=0;
}
server {
listen 80;
server_tokens on;
server_name kubernetes.somelan.lan;
location /nginx {
proxy_http_version 1.1;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 1m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering on;
proxy_pass http://default-nginx-ing-rule-kubernetes.somelan.lan-nginx-svc-80/
}
location /apache {
proxy_http_version 1.1;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 1m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering on;
proxy_pass http://default-nginx-ing-rule-kubernetes.somelan.lan-apache-80/;
}
如果我应用我之前指定的 2 个 yaml,nginx 控制器有 2 个配置
Apache入口的配置
# configuration for default/apache-ingress
upstream default-apache-ingress-kubernetes.somelan.lan-apache-80 {
zone default-apache-ingress-kubernetes.somelan.lan-apache-80 256k;
random two least_conn;
server 10.233.112.2:80 max_fails=1 fail_timeout=10s max_conns=0;
}
server {
listen 80;
server_tokens on;
server_name kubernetes.somelan.lan;
location /apache {
proxy_http_version 1.1;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 1m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering on;
proxy_pass http://default-apache-ingress-kubernetes.somelan.lan-apache-80/;
}
}
}
nginx入口的配置
# configuration for default/nginx-ing-rule
upstream default-nginx-ing-rule-kubernetes.somelan.lan-nginx-svc-80 {
zone default-nginx-ing-rule-kubernetes.somelan.lan-nginx-svc-80 256k;
random two least_conn;
server 10.233.64.2:80 max_fails=1 fail_timeout=10s max_conns=0;
}
server {
listen 80;
server_tokens on;
server_name kubernetes.somelan.lan;
location /nginx {
proxy_http_version 1.1;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 1m;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering on;
proxy_pass http://default-nginx-ing-rule-kubernetes.somelan.lan-nginx-svc-80/;
}
}
我期望使用两个 yaml 的方法应该呈现与使用一个 yaml 文件相同的结果,我错了吗?
解决方案
这里几乎没有什么需要解释的。
- 您看到的错误:
conflicting server name "kubernetes.somelan.lan" on 0.0.0.0:80, ignored
是因为你不能有两个相同的服务器块并在同server_name
一个端口上侦听。
- 了解nginx 模型中的操作是如何工作的很重要。这些如下:
按字段排序 Ingress 规则
CreationTimestamp
,即旧规则优先。如果同一主机的相同路径在多个 Ingress 中定义,则最旧的规则获胜。
如果多个 Ingress 包含同一主机的 TLS 部分,则最旧的规则获胜。
如果多个 Ingress 定义了影响 Server 块配置的注释,则最旧的规则获胜。
创建 NGINX 服务器列表(每个主机名)
创建 NGINX 上游列表
如果多个 Ingress 为同一主机定义了不同的路径,则入口控制器将合并定义。
注释应用于 Ingress 中的所有路径。
多个 Ingress 可以定义不同的注解。这些定义不在 Ingress 之间共享。
- 另外,请记住当需要重新加载时:
新入口资源已创建。
TLS 部分已添加到现有 Ingress。
Ingress 注释的变化不仅仅影响上游配置。例如负载平衡注释不需要重新加载。
从 Ingress 添加/删除路径。
一个 Ingress、Service、Secret 被移除。
Ingress 中一些缺失的引用对象是可用的,例如 Service 或 Secret。
更新了一个秘密。
- 现在,根据上面的信息,在您的用例中,如果您创建了两个单独的 Ingress,则应该发生以下场景:
如果多个 Ingress 为同一主机定义了不同的路径,则入口控制器将合并定义。
如果这还没有发生,您需要检查您的 Ingress Controller 及其版本,以确保它支持合并操作。您可以在此处查看更多详细信息。
- 最后回答你的主要问题:
我期望使用两个 yaml 的方法应该呈现与使用一个 yaml 文件相同的结果,我错了吗?
这取决于您的配置和您使用的 Ingress Controller。server_name
在您的特定用例中,由于冲突,使用两个 yaml 与使用单个 yaml 的工作方式不同。您发现很难启用合并选项,请考虑使用Merge Ingress Controller:
Merge Ingress Controller 将多个入口资源组合成一个新资源。
推荐阅读
- validation - 在数据验证中复制和粘贴升序单元格
- java - 在列表中查找匹配项以使用 Java 8 创建新列表
- r - R数据框:按组创建加权平均
- automapper - Automapper ProjectTo 不映射多语言实体
- node.js - 角; 为生产而建设给出了不清楚的错误
- r - 将包含字符的对象添加到列表 R
- sql - 无法在 Microsoft SQL Server 中插入空整数值
- apache-spark - 如何广播 DataFrame?
- angularjs - 在 AngularJS 中,ng-model-options 与绑定结合使用时不起作用
- sql - 从另一个表中更新计数