2.3. [kustz] 解析 URL 为 Ingress

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 2.3. [kustz] 解析 URL 为 Ingress> 大家好, 我是老麦, 一个运维小学生。> 今天我们处理 Ingress, 对外提供服务。

2.3. [kustz] 解析 URL 为 Ingress

大家好, 我是老麦, 一个运维小学生。
今天我们处理 Ingress, 对外提供服务。

image.png

代码还是在 Github, 文章中有不清楚的可以上去看看

https://github.com/tangx/kustz/tree/chapter/03-parse-url-to-ingress

Kubernetes Ingress

之前已经提到过, 在 kustz.yml 中的字段值, 要尽量做到 见名知义

对于 Ingress 而言, 在发布之后, 我们访问的就是 URL 地址。

http://api.example.com/v1

因此我们可以考虑 从结果推导解析渲染 Ingress

老规矩, 我们还是通过命令看看创建一个 ingress 需要提供哪些参数。

$ kubectl create ingress simple --rule="foo.com/bar=svc1:8080,tls=my-cert" -o
yaml --dry-run=client

在 rule 中, 提供了两组 k-v。 其中, foo.com/bar 就是一个不带协议的 URL。

再来看看输出结果。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  creationTimestamp: null
  name: simple
spec:
  rules:
  - host: foo.com   # 多 host
    http:
      paths:
      - backend:    # 一个 host 多个后端服务
          service:
            name: svc1
            port:
              number: 8080
        path: /bar
        pathType: Exact
  tls:
  - hosts:         # 多个证书
    - foo.com
    secretName: my-cert

一个基本的 Ingress API 配置, 包含了

  1. 主要由两个模块 rulestls 构成。
  2. rules 是个数组, 即 一条或多条 URL。
  3. 每条规则可以有多个后端服务。
  4. 规则路径有一个特殊的 pathType 参数, 表示规则是 Prefix(前缀匹配) 还是 Excat(精确匹配)
补充, 还有一个重要的模块 annotations 通过声明控制 ingress-class 行为。
$ kubectl create ingress annotated --class=default --rule="foo.com/bar=svc:port" --annotation ingress.annotation1=foo

编码

有了之前 Service 打样, Ingress 就容易很多了。

kustz.yml 配置

之前已经提到过了, 我们希望 ingress rule 所见即所得。

# ...省略
ingress:
  rules:
    - http://api.example.com/user/*?tls=my-cert&svc=srv-webapp-demo:8080
    - http://demo.example.com/login?tls=my-cert
  annotations:
    k1: v1
    k2: v2
  1. rule 就是最终实际对外暴露的 URL
  2. rule 通过 query 参数 tlssvc 传递后端证书名和服务。
  3. 为了区分 PrefixExact 两种 PathType, 我使用了 通配符 *

Annotations

Annotation 还是很简单的, 本身就是 map 对象, 直接赋值就可以了。

    ing := &netv1.Ingress{
        TypeMeta: metav1.TypeMeta{
            APIVersion: "networking.k8s.io/v1",
            Kind:       "Ingress",
        },
        ObjectMeta: metav1.ObjectMeta{
            Name:        kz.Name,
            Labels:      kz.CommonLabels(),
            Annotations: kz.Ingress.Annotations,
        },
        // ... 省略
    }

Kubernetes 官方 IngressRule

在官方 IngressRule 结构体中规则描述还是挺多的。 截取部分

  1. 需要满足 RFC 3986 规范

    1. host 字段不能是 IP 地址。
    2. 不支持 80,443 之外的端口。 即只支持 httphttps 协议。
  2. host 可以带 * 号, 即支持泛域名。
文档中还专门强调了, 这些规则在以后可能会改变。

PathType

之前提到过, PathType 在控制匹配行为上非常重要。

  1. Prefix: 前缀匹配, 也可以理解为模糊匹配。
  2. Exact: 精确匹配, 只有100%匹配才生效。
  3. 不建议使用 还有一个值 ImplementationSpecific, 表示由 ingress-class 决定值是 Prefix 或者 Excat

PathType 其实虽说不难, 但是官网还是给了一个 Example 详细列举了匹配规则。 建议还是看一下。
https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types

代码中

  1. Type 默认类型是 Excat。 相对比较安全。
  2. 通过判断 path 末尾最后一个字符是 * 则为 Prefix 规则。
func NewIngressRuleFromString(value string) *IngressRule {
// ...省略
    // ex: /api/*
    path := ur.Path
    typ := netv1.PathTypeExact
    if strings.HasSuffix(path, "*") {
        path = strings.TrimSuffix(path, "*")
        typ = netv1.PathTypePrefix
    }
// ...省略
确认 Prefix 之后, 别忘记把 * 从 path 中去掉。

渲染 Ingress

在官方 Ingress 结构体中字段一层套一层, 少说五六层。

因此在代码中定义了一个 IngressRuleString 保存所需要的字段信息。

type IngressRuleString struct {
    Host      string
    Path      string
    PathType  netv1.PathType
    TLSSecret string
    Service   string
}
  1. 通过函数 NewIngressRuleFromString 解析字符串。
func NewIngressRuleFromString(value string) *IngressRuleString {
}
  1. 通过方法 KubeIngressTLS,KubeIngressRule 创建 tls 和 rule。
func (ir *IngressRuleString) KubeIngressTLS() *netv1.IngressTLS {
}

func (ir *IngressRuleString) KubeIngressRule() netv1.IngressRule {
}

IngressRuleString

注意, 在定义 IngressRuleString 的时候, 我偷了个懒。

前面说过, ingress rule 是支持多个后端服务的, 所以 Service 应该是 切片 类型。

type IngressRuleString struct {
    Service   []string
}

但在我的定义中是 字符串 类型。

// 渲染 Ingress
func (kz *Config) KubeIngress() *netv1.Ingress {
    rules, tlss := ParseIngreseRulesFromStrings(kz.Ingress.Rules, kz.Name)
    // ... 省略
}

// 解析字符串
func ParseIngreseRulesFromStrings(values []string, defaultService string) ([]netv1.IngressRule, []netv1.IngressTLS) {
    // ... 省略
    for _, value := range values {
        ing := NewIngressRuleFromString(value)
        if ing.Service == "" {
            ing.Service = defaultService
        }
    }

    // ... 省略
}
  1. 在调用的时候传递了一个 服务同名 默认值。
  2. 服务同名 不包含端口, 即 srv-webapp-demo。 省略端口默认为 80
func (ir *IngressRuleString) toKubeIngressBackend() netv1.IngressBackend {
    // srv-webapp-demo[:8080]
    svc := ir.Service
    port := int32(80)

    parts := strings.Split(svc, ":")
    if len(parts) == 2 {
        svc = parts[0]
        port = StringToInt32(parts[1])
    }
}

这一处默认值 反过来要求了 Service 的端口映射必须是 80:xxxx

# kustz.yml
service:
  ports:
    - "80:8080" # cluster ip
为什么?

因为当管理多个服务(尤其是多个团队或语言的服务)时, 统一使用 80 为 Service 入口也可以作为一个强制规则约束, 节省脑细胞。

测试

执行命令, 检查结果是不是和自己期待的一样。

$ go test -timeout 30s -run ^Test_KustzIngress$ ./pkg/kustz/ -v

如果不是, 就回去检查代码吧。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
域名解析 缓存 网络协议
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
|
8月前
|
安全 搜索推荐 Java
Java的URL与URLConnection技术深度解析
Java的URL与URLConnection技术深度解析
679 0
|
5月前
|
XML Android开发 UED
"掌握安卓开发新境界:深度解析AndroidManifest.xml中的Intent-filter配置,让你的App轻松响应scheme_url,开启无限交互可能!"
【8月更文挑战第2天】在安卓开发中,scheme_url 通过在`AndroidManifest.xml`中配置`Intent-filter`,使应用能响应特定URL启动或执行操作。基本配置下,应用可通过定义特定URL模式的`Intent-filter`响应相应链接。
132 12
|
6月前
|
算法 安全 API
淘宝获得淘口令真实URL接口的技术解析
淘口令是淘宝的加密链接,用于商品推广。官方未提供直接解密API,但第三方工具或API能模拟解析。示例代码展示了如何通过第三方接口(需替换为真实接口)获取淘口令所对应的URL、标题和图片信息,但使用时需注意安全风险。
149 2
|
7月前
|
域名解析 存储 缓存
HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口
【6月更文挑战第23天】 HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口;TCP连接(HTTP/1.1可能需排队);三次握手;发送请求头与体;服务器处理并返回响应;TCP连接可能关闭或保持;浏览器接收并显示响应,更新缓存。HTTP版本间有差异。
119 5
|
6月前
|
存储 SQL Python
`urllib.parse`模块是Python标准库`urllib`中的一个子模块,它提供了处理URL(统一资源定位符)的实用功能。这些功能包括解析URL、组合URL、转义URL中的特殊字符等。
`urllib.parse`模块是Python标准库`urllib`中的一个子模块,它提供了处理URL(统一资源定位符)的实用功能。这些功能包括解析URL、组合URL、转义URL中的特殊字符等。
|
6月前
|
JavaScript
js 获取并解析 url 中参数的三种方法
js 获取并解析 url 中参数的三种方法
703 0
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
103 2
|
21天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
21天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

推荐镜像

更多