概述
k8s 中所有的资源都有对应的控制器在操控这个资源,管理资源的生命周期,实现”声明式“效果。Deployment、Service、Replicaset等资源的控制器封装在k8s内置的 controller-manager进程中。
对于外部请求如何进入集群内部,K8s 官方定义了 Ingress 这个资源,但是官方并没有提供 Ingress 的控制器,使用时必须手动安装一个 官方文档 ingress controller。云厂商有自己的 ingress controller,开源界也有一下 ingress controller :
- nginx ingress:基于 nginx
- Traefik:基于 Traefik
- Ambassador:基于 envoy 官方文档
- Apache APISIX ingress:基于 APISIX
- Gloo开源: 基于 envoy官方文档
- HAProxy Ingress :基于HAProxy
- 其他控制器
所有的 Ingress 都包括数据面和控制面,控制面负责监听 k8s 资源,生成配置,下发给数据面。
Nginx Ingress 作为使用广泛的 Ingress,底层基于 Nginx,动态生成 nginx.conf 文件,实现将请求重定向到pod内部的目的。
nginx 的优点在于周边生态丰富,和传统运维无缝集成,不需要更多的学习成本。但是缺点在于热加载的支持不友好,需要重启服务。云原生时代 envoy 逐渐占据风头,出现大量基于 envoy 的 Ingress。
安装部署
有两种方式安装 nginx-ingress:helm 和 kubectl apply
helm安装官方
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
kubectl apply
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml
工作过程:
Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。(后续会链接ingress及ingress controllers)
生成配置
- 动态生成 nginx 需要的配置文件 nginx.conf
- 默认nginx配置修改需要重启才生效。而 nginx-ingress 如果只是更新了 upstream 信息,是不需要重启服务的。这是通过 lua-nginx-model 来实现的
nginx建模过程
- 通过 k8s infomrer 机制监听 k8s 资源:比如 Ingress、Service、Endpoint、Secret、Configmap,以生成配置文件。
没有办法知道哪次修改会影响最终配置,因此每次变更都会从零重建模型,并和当前模型比较。
- 如果模型不变,就不会重新生成nginx.conf 配置文件,避免重启。
- 如果只是 Endpoints 变化,用post请求发送一个 endpoint 列表给运行在 nginx里面的 lua handler。也可以避免重新生成配置文件和服务重启。
- 如果以上情况都不是,会创建新的模型的配置文件,并触发nginx 重启。
- 使用时,应该避免不必要的配置变更和冲突定义,以减少服务重启。
- 配置文件是通过 go template 渲染出来的。
nginx-reload触发
- 新的 Ingress 资源创建。
- 添加 TLS 到现有的 Ingress 中。
- 修改非 upstream_configuration 相关的 annotation(load-balance 注解不会触发 reload)。
- Ingress 中的 Path 添加或者修改。
- Ingress 或者 Service 资源被移除。
- Ingress 中配置的 Service 或 Secret 资源变成可用状态。
- Secret 更新。
- .......
排错
检查ingress 资源事件
kubectl get ing -n
kubectl describe ing -n 编写ingress 资源事件
kubectl get ing -n
kubectl edit ingress -n kubectl describe ing -n #查看状态 检查日志事件
kubectl get pods -n
kubectl logs -n 检查nginx主配置文件
kubectl get pods -n
kubectl exec -it -n -- cat /etc/nginx/nginx.conf /etc/nginx $ pwd /etc/nginx /etc/nginx $ nginx -t #语法检测 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 检查后端SVC
kubectl get svc -A -n
kubectl get svc -A |grep svc
日志格式
log_format upstreaminfo
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'$request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr '
'$upstream_response_length $upstream_response_time $upstream_status $req_id';
- $proxy_protocol_addr 启用代理协议时的远程地址
- $remote_addr 客户端的源IP地址
- $remote_user 随基本身份验证提供的用户名
- $time_local 通用日志格式的本地时间
- $request 完整的原始请求行
- $status 响应状态
- $body_bytes_sent 发送到客户端的字节数,不包括响应头
- $http_referer Referer 标头的值
- $http_user_agent User-Agent 标头的值
- $request_length 请求长度(包括请求行、请求头和请求体)
- $request_time 从客户端读取第一个字节后经过的时间
- $upstream_addr 上游服务器的 IP 地址和端口(或域套接字的路径)。如果在请求处理期间联系了多个服务器,则它们的地址用逗号分隔。
- $upstream_response_length 从上游服务器获得的响应的长度
- $upstream_response_time 以毫秒为单位从上游服务器接收响应所花费的时间
- $upstream_status 从上游服务器获取的响应的状态码
- $req_id X-Request-IDHTTP 标头的值。如果未设置标头,则为随机生成的 ID。
- $proxy_upstream_name 上游的名称。格式是upstream-
- -
Debug日志
使用 --v=XX 参数可以增加日志等级,修改 deployment 文件
kubectl get deploy -n
kubectl edit deploy -n
备注:增加 --v=X 到 - args
- --v=2 显示配置文件差异的细节
- --v=3 显示 svc、ingress、endpoint细节,并且打印出 json 格式的 nginx 配置文件
- --v=5 以 Debug 模型运行 nginx
基本配置
- 支持 配置 ingressClassName
支持配置 ingressclass.kubernetes.io/is-default-class: "true" 注解 官方注解详情
- 用于:IngressClass
- 当单个 IngressClass 资源将此注解设置为 "true"时,新的未指定 Ingress 类的 Ingress 资源将被设置为此默认类。
注意:kubernetes.io/ingress.class (官方已弃用)
说明: 从 v1.18 开始,不推荐使用此注解以鼓励使用 spec.ingressClassName。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: iminimal-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: iminimal-ingress
annotations:
# use the shared ingress-nginx
#默认入口使用ingressclass.kubernetes.io/is-default-class: "true" 注解
kubernetes.io/ingress.class: "nginx" #咱这里使用的kubernetes.io/ingress.class 多个入口
spec:
rules:
- host: nginx.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test
port:
number: 80
注解说明
注解的 key 和 value 只支持 string,因此 bool 或者 int 必须使用引号。比如 “ture”、“100”、“false”
注解的前缀默认是 “nginx.ingress.kubernetes.io",可以通过 --annotations-prefix 命令修改
工作中用到的注解 官方注解
自定义最大车身尺寸
请求中的大小超过客户端请求正文的最大允许大小时,将向客户端返回 413 错误nginx.ingress.kubernetes.io/proxy-body-size: 8m
自定义超时
注意⚠️:所有超时值都是无单位的,以秒为单位。nginx.ingress.kubernetes.io/proxy-connect-timeout : "10" nginx.ingress.kubernetes.io/proxy-send-timeout : "90" nginx.ingress.kubernetes.io/proxy-read-timeout : "120"
- 通过重定向执行服务器端 HTTPS
默认情况下,如果为该入口启用了 TLS,则控制器会将 (308) 重定向到 HTTPS。如果要全局禁用此行为,可以ssl-redirect: "false"在 NGINX ConfigMap中使用。
要为特定入口资源配置此功能,可以使用以下命令
nginx.ingress.kubernetes.io/ssl-redirect: "false"
在集群外部使用 SSL 卸载(例如 AWS ELB)时,即使没有可用的 TLS 证书,强制重定向到 HTTPS 也可能很有用。这可以通过使用以下命令特定资源中的注释来实现。
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
如果要使用 保留 URI 中的尾部斜杠,请为该特定资源ssl-redirect设置注释。
nginx.ingress.kubernetes.io/preserve-trailing-slash: "true"
- 连接代理标头
使用此注解将覆盖 NGINX 设置的默认连接头。要在 Ingress 规则中使用自定义值,请定义注释:
nginx.ingress.kubernetes.io/connection-proxy-header: "close"
如有@侵权,请联系 [email protected] 改版。