十八. Kubernetes Ingress

2023-11-16

一. Ingress 基础解释

  1. 官方文档
  2. 什么是Ingress: Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP和HTTPS。Ingress 可以提供负载均衡、SSL 和基于名称的虚拟托管,提供了负载均衡,缓存, api网关防火墙等功能
  3. 先说一下k8s中使用service方式对外暴露服务时的问题:

k8s 基于service对外暴露服务时主要有两种方式:NotePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持

  1. 为什么需要Ingress?
  1. Service可以使用NodePort暴露集群外访问端口,性能低,暴露端口不安全,并且例如大型应用集群使用该方式暴露时端口不够用,不好管理
  2. 缺少Layer7的统一访问入口,可以负载均衡,限流等,也就是指没有应用层无法解析数据包,根据请求数据进行指定操作,例如根据请求参数路由,限流,负载等等
  3. Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
  4. 使用Ingress作为整个集群统一的入口,配置Ingress规则,根据规则将请求转到对应的Service
  1. ingress相当于一个7层的负载均衡器,可以看成一个网关,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则
    在这里插入图片描述
  2. ingress中包括:ingressController和ingressResources
  1. ingress controller:是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。
  2. ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员

二. ingressController 安装

  1. ingresscontroller:是一个deployment,实现方式有多种, 当前使用nginx,一个改版的nginx,也有两种IngressNginx和nginxIngress
  1. IngressNginx: 这是k8s官方做的,会及时更新一些特性,性能很高,被广泛采用官方文档
  2. nginxIngress: 这是nginx官方适配k8s做的分为开源版和nginx plus版(收费)文档地址
  1. 实际整个ingress就可以理解为安装ingressController,而现在ingressController通常用改版的nginx, 所以ingressController就是一个nginx,反过来看ingress就是选择指定节点安装改版的nginx,通过这个nginx编写需要的yaml,实现指定功能,其中包含负载均衡,缓存, api网关防火墙等
  2. 可以选择k8s中指定一个或多个节点部署ingressController也就是nginx,如果修改其中一个,会自动同步
  3. 自建集群使用 裸金属安装方式需要如下修改:
  1. 修改ingress-nginx-controller镜像为 registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx- controller:v0.46.0
  2. 修改Deployment为DaemonSet比较好
  3. 修改Container使用主机网络,直接在主机上开辟 80,443端口,无需中间解析,速度更快
  4. Container使用主机网络,对应的dnsPolicy策略也需要改为主机网络的
  5. 修改Service为ClusterIP,无需NodePort模式了
  6. 修改DaemonSet的nodeSelector: ingress-node=true 。这样只需要给node节点打上 ingress- node=true 标签,即可快速的加入/剔除 ingress-controller的数量
  1. 安装完毕后,配置使用只需要编写Ingress的yaml文件即可, 一个Ingress的yaml配置文件就是nginx的一项应用配置
  2. 另外还有nginx服务本身的全局配置
  1. “kubectl edit cm ingress-nginx-controller -n ingress-nginx”
  2. 修改配置添加"data: 配置项:配置值"保存退出即可
  3. 服务本身配置项参考官方文档:configmap
  1. 在使用ingressNginx时,给nginx添加功能只需要在编写nginx 的yaml应用配置项时配置一下对应的Annotations即可官方文档:annotations

六. ingress 使用示例

  1. 选择k8s中指定一个或多个节点部署ingressController也就是nginx
  1. 针对服务封装service,内网部署,对外关闭所有端口更安全,例如service使用ClusterIP或者无头服务类型
  2. ingressController 选择指定k8s节点安装改版nginx,称为ingressNginx
  3. 编写yaml配置nginx中监听的域名与对应service映射关系,通过nginx代理service服务,多个nginx域名配置完毕后会相互同步
  4. 此时请求服务域名,先到达nginx,由nginx将请求发送给指定的service
  5. 在nginx上层也可以添加负载均衡器(例如使用云服务商提供的负载均衡器,F5等),对nginx进行负载均衡
  6. 此时我们只需要设置好域名与ip的映射关系,请求的域名被nginx拦截,然后负载到指定的service
    在这里插入图片描述
  1. 实际整个ingress就可以理解为安装ingressController,而现在ingressController通常用改版的nginx, 所以ingressController就是一个nginx,反过来看ingress就是选择指定节点安装改版的nginx,通过这个nginx编写需要的yaml,实现指定功能,其中包含负载均衡,缓存, api网关防火墙等
  2. ingress yaml 示例,一个Ingress的yaml配置文件就是nginx的一项应用配置

rules中配置拦截"test.com"域名,使用Prefix 前缀匹配拦截前缀为"/bbbbbc/"请求,将这个请求,路由到名为cluster-service的service上

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
  annotations: #基于k8s注解为nginx添加其他功能,例如当前"nginx.ingress.kubernetes.io/limit-rps" 表示设置限流
    nginx.ingress.kubernetes.io/limit-rps: 1
spec:
  defaultBackend: #接收到未设置映射路径的请求时路由的目标服务,相当于提供一个默认值
    service:
      name: php-apache
      port:
        number: 80
  rules: #路由设置
  - host: test.com #指定监听的主机域名(对标以前nginx中监听的server中的域名)
    http: #指定请求路由规则
      paths:
      - path: /bbbbbc #拦截的url
        pathType: Prefix #匹配规则: Prefix前缀匹配, Exact精确匹配, ImplementationSpecific自定义匹配
        backend: #设置当前拦截请求路由到的目标service
          service:
            name: cluster-service #目标service名
            port:
              number: 80 #目标service端口号
           #resource: #指定资源
           
  - host: demo.com #指定监听的主机域名(对标以前nginx中监听的server中的域名)
    http: #指定请求路由规则
      paths:
      - path: /ssss #拦截的url
        pathType: Prefix #匹配规则: Prefix前缀匹配, Exact精确匹配, ImplementationSpecific自定义匹配
        backend: #设置当前拦截请求路由到的目标service
          service:
            name: cluster-service #目标service名
            port:
              number: 80 #目标service端口号
           #resource: #指定资源
  1. ingress yaml编写完成后会应用到k8s安装的所有ingress nginx上,并且后续修改一个,多个nginx会互相同步

pathType 详细:

  1. Prefix: 基于以 / 分隔的 URL 路径前缀匹配,区分大小写
  2. Exact: 精确匹配 URL 路径,且区分大小写。
  3. ImplementationSpecific: 对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理
  1. 注意如果没有指定路由规则

annotations 基于k8s注解为 nginx 添加功能示例

  1. 在使用ingressNginx时,给nginx添加功能只需要在编写nginx 的yaml应用配置项时配置一下对应的Annotations即可官方文档:annotations
  2. 以添加限流功能为例: 在文档上找到限流相关注解在Rate Limiting下,官方文档:Rate Limiting
    在这里插入图片描述
    在这里插入图片描述
  3. yaml示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
  annotations: #基于k8s注解为nginx添加其他功能,例如当前"nginx.ingress.kubernetes.io/limit-rps" 表示设置限流每秒允许一个请求
    nginx.ingress.kubernetes.io/limit-rps: 1 #添加限流功能,每秒允许一个请求
spec:
  defaultBackend: #接收到未设置映射路径的请求时路由的目标服务,相当于提供一个默认值
    service:
      name: php-apache
      port:
        number: 80
  rules: #路由设置
  - host: test.com #指定监听的主机域名(对标以前nginx中监听的server中的域名)
    http: #指定请求路由规则
      paths:
      - path: /bbbbbc #拦截的url
        pathType: Prefix #匹配规则: Prefix前缀匹配, Exact精确匹配, ImplementationSpecific自定义匹配
        backend: #设置当前拦截请求路由到的目标service
          service:
            name: cluster-service #目标service名
            port:
              number: 80 #目标service端口号
           #resource: #指定资源

路径重写

  1. 接收请求时,重写原请求路径,使用"annotations:nginx.ingress.kubernetes.io/rewrite-target" 配置路径重写规则官方文档
  1. 下方示例中实习效果,如果访问请求为"test.com/api/ssss",会将路径修改为"目标服务service名/sss"去除了"/api"
  2. 使用场景: 例如前后端分离是,前后端代码部署在同一个服务器上,通过指定路径前缀判断访问前端还是后端,在访问后端时,去除标识前缀访问实际接口路径
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-aaa
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2 #保留的部分
spec:
  defaultBackend: ## 只要未指定的映射路径
    service:
      name: php-apache
      port:
        number: 80
  rules:
  - host: test.com #监听的域名
    http:
      paths:
      - path: /api(/|$)(.*) #path中需要使用正则表达式定义路径,并在rewrite-target中结合捕获组一起使用
        pathType: Prefix #拦截规则
        backend:
          service:
            name: test-service #目标service名字
            port:
              number: 80

Session Affinity 会话保持

  1. 多副本负载均衡时,同一个用户的多次访问负载到同一个副本上官方文档
  2. 部署一个三个Pod的Deployment并封装Service,用来测试Session Affinity
apiVersion: v1
kind: Service
metadata:
  name: session-affinity
  namespace: default
spec:
  selector:
    app: session-affinity
  type: ClusterIP
  ports:
  - name: session-affinity
    port: 80
    targetPort: 80
    protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  session-affinity
  namespace: default
  labels:
    app:  session-affinity
spec:
  selector:
    matchLabels:
      app: session-affinity
  replicas: 3
  template:
    metadata:
      labels:
        app:  session-affinity
    spec:
      containers:
      - name:  session-affinity
        image:  nginx
  1. 编写具有会话亲和的ingress, 利用每次请求携带同样的cookie,来标识是否是同一个会话
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: session-test
  namespace: default
  annotations: #设置会话保持
    nginx.ingress.kubernetes.io/affinity: "cookie" #
    nginx.ingress.kubernetes.io/session-cookie-name: "key-session" #cookie名字
spec:
  rules:
  - host: test.com #监听域名
    http:
      paths:
      - path: /   #如果此处的路径以前有配置过,已最后一次为准
        pathType: Prefix
        backend:
          service:
            name: session-affinity #目标service名
            port:
              number: 80
  1. 当设置了会话保持
  1. 接收到请求后通过"nginx.ingress.kubernetes.io/affinity"会向相求中添加cookie参数,并且后续请求都会携带cookie,统一cookie下的请求会负载到同一个副本上
  2. 默认cookie的key为"INGRESSCOOKIE",可以使用"nginx.ingress.kubernetes.io/session-cookie-name"自定义,

配置SSL

  1. 首先要生成证书(也可以去青云申请免费证书进行配置)
//1.生成测试证书命令,解释:
//-x509:生成x509证书
//-days 365: 有效时间365天
//rsa:2048: 使用rsa的2048位加密算法
//tls.key: 指定证书的key文件
//tls.cert:指定证书文件
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.cert
-subj "/CN=组织机构域名.com/O=组织名.com"

//2.根据上面指定的证书key与证书文件执行命令,创建证书秘钥
kubectl create secret tls 生成秘钥文件名-tls --key tls.key --cert tls.cert

//3.查看秘钥资源命令,能获取到前面创建的秘钥文件
kubectl get secret 

//4.进入秘钥文件,以yaml展示,在文件内部有一个"tls.crt","tls.key"
kubectl get secret 秘钥文件名-tls -o yaml
  1. 通过上面配置了免费的ssl证书,生成了秘钥文件,在编写ingress时,在内部的tls属性中配置即可
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
spec:
  tls:
   - hosts:
     - test.com #监听需要使用证书的域名
     secretName: 生成的秘钥文件-tls
  rules:
  - host: 监听域名.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-nginx-svc
            port:
              number: 80

灰度发布

  1. k8s中可以使用Service配合Deployment进行金丝雀部署,但是不能自定义灰度逻辑,比如指定用户进行灰度,可以使用Ingress进行灰度
  2. 基于Ingress中可以对请求拆解包,根据请求标识判断将请求路由到指定service官方文档:Canary实现流程
  1. 在更新版本上线时,原版本service与对应的ingress继续提供服务,
  2. 部署新版本的service,对应新版本的ingress
  3. 新版本ingress与老版本的ingress监听相同域名, 但是新版本中配置获取请求中的指定参数标识,如果表示存在,才将请求路由到rules中配置的新版本service上
  1. Ingress基于annotations注解实现金丝雀部署功能:
  1. “nginx.ingress.kubernetes.io/canary”: 为true表示开启
  2. 在获取路由表示时提供了:“canary-by-header”," canary-by-cookie"与"canary-weight"(权重)三种,可以共同作用,有优先级
  3. 如果通过"canary-by-header"," canary-by-cookie"与"canary-weight"获取到了需要的请求参数,则将请求路由到rules中指定的service上
  1. ingress金丝雀示例与以"nginx.ingress.kubernetes.io/canary-by-header"为例解释:
  1. "nginx.ingress.kubernetes.io/canary-by-header"设置获取key为"headerKey"请求头参数
  2. 默认情况下"headerKey"获取到的参数为"always"时将请求路由到下方rules指定的新表service上"v2-service",如果获取到的请求参数为"never",那么这个请求会通过原ingerss路由
  3. 也可以通过对应的注解指定灰度标识值,例如"nginx.ingress.kubernetes.io/canary-by-header-value",设置参数为"ssss"表示当通过"headerKey"获取到的参数为"ssss"时,将请求路由到v2-service上
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-02-haha
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"  ## 代表这是金丝雀版本
    nginx.ingress.kubernetes.io/canary-by-header: "headerKey"  
    ## headerKey= always:流量路由到金丝雀版本
    ## headerKey= never: 流量永远不会路由到金丝雀版本
    # nginx.ingress.kubernetes.io/canary-by-header-value: "ssss"
    nginx.ingress.kubernetes.io/canary-by-cookie: "cccc"
    ## cccc = always:流量路由到金丝雀版本
    ## cccc = never: 流量永远不会路由到金丝雀版本
    nginx.ingress.kubernetes.io/canary-weight: "50" #权重,当前表示50%的到达下方的v2-service上
    ## 优先级:canary-by-header -> canary-by-cookie -> canary-weight

spec:
  rules:
  - host: test.canary.com #监听域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: v2-service #目标service
            port:
              number: 80
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

十八. Kubernetes Ingress 的相关文章

随机推荐

  • Android Studio编译报错:sdk:minSdkVersion 1 cannot be smaller than version 7 declared in library

    背景 有一个以前的项目从Eclipse迁移到Android Studio 结果编译的时候报错如下 Error Execution failed for task lDrawer processDebugAndroidTestManifest
  • ListView动态加载数据

    当listview需要加载的数据过多时 若一次性载入则速度会相当缓慢 影响用户体验 这时候就需要动态加载数据 即每次载入固定长度的数据 android market的listview就是采用这种方式 使得加载看起来很平滑 响应速度很快 有助
  • 物联网的四种计算类型

    简介 从一个实践者的角度来看 我经常看到计算更加可用和分布的必要性 当我开始将物联网与OT和IT系统集成时 我面临的第一个问题是设备发送到我们服务器的数据量太大 我在一个工厂自动化场景中工作 我们集成了400个传感器 这些传感器每1秒发送3
  • Qt内存管理(三) Qt的智能指针

    智能指针则可以在退出作用域时 不管是正常流程离开或是因异常离开 总调用delete来析构在堆上动态分配的对象 Qt常用的智能指针有QPointer QScopedPointer QSharedPointer 关于这几个智能指针 网上的博客基
  • 每天一个linux命令(30): chown命令

    chown将指定文件的拥有者改为指定的用户或组 用户可以是用户名或者用户ID 组可以是组名或者组ID 文件是以空格分开的要改变权限的文件列表 支持通配符 系统管理员经常使用chown命令 在将文件拷贝到另一个用户的名录下之后 让用户拥有使用
  • 双系统卸载Linux,重装Deepin

    卸载掉之前的Linux系统 参考资料 https www bilibili com video av209430195 下载diskgenius https www diskgenius cn download php 删除Linux分区
  • StackExchange.Redis Timeout performing 超时问题

    最近在做的一个项目 用的 net core 2 1 然后缓存用的Redis 缓存相关封装是同事写的 用的驱动是StackExchange Redis version 2 0 571 一直听说这个驱动并发情况下有TimeOut bug 项目开
  • Flutter--Button浅谈

    作为一个常用到不能再常用的组件 material库中的button组件都有一点奇怪 存在无法设置的内外边距 我们做一个简单的展示 选几个常见button 统一使用Text做child 外加一个带红色的Container组件 观察margin
  • JavaScript-1-100之间整数的和

    要求 求1 100之间整数的和 实现代码
  • 图像数据库

    ImageNet ImageNet是一个计算机视觉系统识别项目 是目前世界上图像识别最大的数据库 是美国斯坦福的计算机科学家李飞飞模拟人类的识别系统建立的 能够从图片识别物体 目前已经包含14197122张图像 是已知的最大的图像数据库 每
  • $(this).parent("tr").find("td").eq(0).text()

    this parent tr find td eq 0 text
  • 新年新气象---多数据源配置

    概述 2022年第一天 在这祝大家新年快乐 好运连连 事业爱情双丰收 本文主要是通过注解结合aop的方式实现多数据源的动态切换 一 配置文件 spring datasource type com alibaba druid pool Dru
  • 增强现实-实验一

    实验一 1 手工制作一个空间增强现实盒子 如示例所示 放置在平板或手机屏幕上 搭配应用实现立体投影效果 2 制作立体投影所需的视频 程序 unity 全息投影 伪 视频 盒子蛮好做的主要是视频 之前没接触过unity 研究了一番 首先设置四
  • 关于js操作cookie

    一 什么是cookie 我们在浏览器中 经常涉及到数据的交换 比如你登录邮箱 登录一个页面 我们经常会在此时设置30天内记住我 或者自动登录选项 那么它们是怎么记录信息的呢 答案就是今天的主角cookie了 Cookie是由HTTP服务器设
  • 修饰符-访问修饰符internal sealed

    摘自 internal C 参考 摘自 sealed C 参考 Internal 访问仅限于当前程序集 protected internal 访问限制到当前程序集或从包含派生的类型的类别 程序集就是代码编译后bin目录下生产的 exe或者
  • 16-DFS(深度优先搜索算法)

    DFS 深度优先算法 是常见的搜索算法 早期常用于需要搜索的地方 并且还拓展出很多其它算法 深度优先算法 DFS DFS 深度优先算法 是早期开发爬虫时常用的算法 它的搜索思路是从树根开始一直找直到找到树型数据结构的叶节点 以搜索一个节点数
  • 小程序iOS兼容问题总结

    1 IOS 上 JS 只支持 new Date YYYY MM DD 这一种格式 YYYY MM DD 等格式都不支持
  • Raft 一致性算法

    文章目录 1 CAP 定理 1 Raft 基本概念 2 Raft 算法核心 2 1 Leader 选举 2 2 日志复制 3 总结 1 CAP 定理 文章参考 lt 零声教育 gt 的C C linux服务期高级架构系统教程学习 服务器高级
  • POI框架导出EXCEL的简单列子(跨行跨列)合并单元格

    public static void main String args throws IOException try HSSFWorkbook wb new HSSFWorkbook HSSFSheet sheet wb createShe
  • 十八. Kubernetes Ingress

    目录 一 Ingress 基础解释 二 ingressController 安装 六 ingress 使用示例 pathType 详细 annotations 基于k8s注解为 nginx 添加功能示例 路径重写 Session Affin