k8s教程(service篇)-ingress 7层路由机制(下)

简介: k8s教程(service篇)-ingress 7层路由机制(下)

4.4 路径类型(pathType)

对于每条规则(rule)中的路径(path),都必须设置一个相应的路径类型, 目前支持以下3种类型。

  • ImplementationSpecific:系统默认,由IngressClass控制器提供具体实现;
  • Exact:精确匹配URL路径,区分大小写。
  • Prefix:匹配URL路径的前缀,区分大小写,路径由“/”符号分隔为一个个元素,匹配规则为逐个元素进行前缀匹配。如果路径中的最后一个元素是请求路径中最后一个元素的子字符串,则不会判断为匹配,例如/foo/bar是路 径/foo/bar/baz的前缀,但不是路径/foo/barbaz的前缀。

如表所示是常见的路径类型匹配规则示例:

路径类型 在ingress中配置的路径 请求路径 是否匹配
Prefix / (all paths)
Exact /foo /foo
Exact /foo /bar
Exact /foo /foo/
Exact /foo/ /foo
Prefix /foo /foo,/foo/
Prefix /foo/ /foo,/foo/
Prefix /aaa/bb /aaa/bbb
Prefix /aaa/bbb /aaa/bbb
Prefix /aaa/bbb/ /aaa/bbb 是,忽略结尾的“/”
Prefix /aaa/bbb /aaa/bbb/ 是,匹配结尾的“/”
Prefix /aaa/bbb /aaa/bbb/ccc 是,匹配子路径
Prefix /aaa/bbb /aaa/bbbxyz 否,无匹配前缀
Prefix /,/aaa /aaa/ccc 是,匹配的是/aaa前缀
Prefix /,/aaa,/aaa/bbb /aaa/bbb 是,匹配的是/aaa/bbb前缀
Prefix /,/aaa,/aaa/bbb /ccc 是,匹配了"/"
Prefix /aaa /ccc
Exact+Prefix配合 /foo(Prefix), /foo(Exact) /foo 是,优先匹配Exact

在某些情况下,Ingress中的多个路径都会匹配一个请求路径。在这种情况 下,将优先考虑最长的匹配路径。如果两个匹配的路径仍然完全相同,则Exct类 型的规则优先于Prefix类型的规则生效。

4.5 host通配符设置

在规则(rule)中设置的host用于匹配请求中的域名(虚拟主机名),设置为完整的字符串表示精确匹配,例如:“foo.bar.com”。

Kubernetes从1.18版本开始支 持为host设置通配符“*”,例如“*.foo.com”。

  • 精确匹配要求HTTP请求头中host参数的值必须与Ingress host设置的值完全一致 ;
  • 通配符匹配要求HTTP请求头中host参数的值需要与Ingress host设置的值的后缀一致,并且仅支持一层DNS匹配。

下面是常见的一些host通配符匹配规则示例:

ingress host 配置 请求头中的host值 是否匹配
*.foo.com bar.foo.com
*.foo.com baz.bar.foo.com 否,不是一层DNS匹配
*.foo.com foo.com 否,不是一层DNS匹配

下例中的 Ingress包含精确匹配host"foo.bar.com"通配符匹配 host"*.foo.com"两条规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wildcard-host
spec:
  rules:
    - host: "foo.bar.com"
    http:
      paths:
      - pathType: Prefix
        path: "/bar"
        backend:
          service:
          name: service1
          port:
            number: 80
    - host: "*foo.com"
      http:
      paths:
      - pathType: Prefix
        path: "/foo"
        backend:
         service:
           name: service2
           port:
             number: 80

4.6 ingressClassName和ingressClass资源对象

在一个Kubernetes集群内,用户可以部署多个不同类型的Ingress Controller 同时提供服务,此时需要在Ingress资源上注明该策略由哪个Controller管理

Kubernetes在1.18版本之前,可以在Ingress资源上设置一个名为kubernetes.io/ingress.classannotation进行声明。但annotation的定义没有标准规范,Kubernetes从1.18版本开始引入一个新的资源对象IngressClass对其进行规范定义。在IngressClass中除了可以设置Ingress的管理Controller,还可以配置更加丰富的参数信息(通过parameters字段进行设置)。

例如下面的IngressClass定义了一个名为“example.com/ingress--controller‘”的Controller和一组参数:

apiversion: networking.k8s.io/v1 
kind: Ingressclass
metadata:
  name: external-lb
spec:
  controller:example.com/ingress-controller 
  parameters:
    apiGroup: k8s.example.com 
    kind: IngressParameters 
    name: external-lb

然后在Ingress资源对象的定义中通过ingressClassName字段引用该IngressClass,标明使用其中指定的Ingress Controller和相应的参数:

apiversion: networking.k8s.io/v1 
kind: Ingress
metadata: 
  name: example-ingress 
spec:
  ingressclassName: external-lb 
    rules:
    - host: "*example.com"
      http:
        paths:
        - path: /example
          pathType: Prefix
          backend:
          service:
        name: example-service 
        port:
          number: 80

05 ingress策略配置

为了实现灵活的路由转发策略,Ingress策略可以按多种方式进行配置,下面对几种常见的Ingress转发策略进行说明。

5.1 转发到单个后端服务

基于这种设置,客户端发送到Ingress Controller的访问请求都将被转发到后端的唯一服务,在这种情况下,Ingress无须定义任何rule,只需设置一个默认的 后端服务(defaultBackend)。

通过如下所示的设置,对Ingress Controller的访问请求都将被转发到 “myweb:8080”这个服务:

# ingress-single-backend-service.yaml 
apiversion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
spec:
  defaultBackend:
    service:
      name: webapp
    port:
      number: 8080

通过kubectl create命令创建后,查看ingress详情,可以看到系统为其设置了正确的后端目标地址:

5.2 将同一域名的不同URL路径转发到不同的服务(Simple Fanout)

这种配置常用于一个网站通过不同的路径提供不同的服务的场景,例如/web 表示访问Web页面,/api表示访问API接口,对应到后端的两个服务,只需在Ingress规则定义中设置将同一域名的不同URL路径转发到不同的后端服务,如图所示:

通过如下所示的设置,对"mywebsite.com/web"的访问请求将被转发到"web- service:80"服务,对"mywebsite.com/api"的访问请求将被转发到"api-service: 80"服务:

# ingress-simple-fanout.yaml 
apiversion: networking.k8s.io/v1 
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  rules:
  - host: mywebsite.com
    http:
      paths:
      - path: /web
        pathType: ImplementationSpecific 
        backend:
        service:
        name: web-service
        port:
          number: 8080
    - path: /api
      pathType: ImplementationSpecific
      backend:
      service:
      name: api-service
      port:
        number: 8081

通过kubectl create创建之后,查看ingress详情,可以看到系统为不同的path设置了转发规则:

5.3 将不同的域名(虚拟主机名)转发到不同的服务

这里 指基于host域名的Ingress规则将客户端发送到同一个IP地址的HTTP请求,根据不同的域名转发到后端不同的服务,例如foo.bar.com域名由service1提供服务,bar.foo.com域名由service2提供服务,如图所示:

通过如下所示的设置,请求头中host=foo.bar.com的访问请求将被转发到“service1:80”服务,请求头中host=bar.foo.com的访问请求将被转发到 “service2:80”服务:

apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
      service:
        name: service1
        port:
          number: 80
  - host: bar.foo.com
    http:
    paths:
    - pathType: Prefix
      path:
      backend:
      service:
        name: service2
      port:
        number: 80

5.4 不使用域名的转发规则

如果在Ingress中不定义任何host域名,Ingress Controller则将所有客户端请求都转发到后端服务

例如下面的配置为将"<ingress-controller-ip>/demo"的访问请求转发到"webapp:8080/demo"服务:

apiversion: networking.k8s.io/v1 
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
  - http:
    paths:
      path: /demo
      pathType: Prefix
      backend:
        service:
          name: webapp
          port:
            number: 8080

06 ingress的TLS安全设置

Kubernetes支持为Ingress设置TLS安全访问机制,通过为Ingress的host(域名)配置包含TLS私钥和证书的Secret进行支持

  • Ingress资源仅支持单个TLS端口号443,并且假设在Ingress访问点(Ingress Controller)结束TLS安全机制,向后端服务转发的流量将以明文形式发送。
  • 如果Ingress中的TLS配置部分指定了不同的host,那么它们将根据通过SNI TLS扩展指定的虚拟主机名(这要求Ingress Controller支持SNI)在同一端口进行复用。

TLS Secret中的文件名必须为“tls.crt”和“tls.key”,它们分别包含用于TLS的证书和私钥,例如:

apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64 encoded cert 
  tls.key: base64 encoded key 
type: kubernetes.io/tls

然后,需要在Ingress资源对象中引用该Secret,这将通知Ingress Controller
使用TLS加密客户端到负载均衡器的网络通道

用户需要确保在TLS证书(tls.crt)中包含相应host的全限定域名(FQDN)被包含在其CNCommon Name)配置中。

TLS的功能特性依赖于Ingress Controller的具体实现,不同Ingress Controller的实现机制可能不同,用户需要参考各个Ingress Controller的文档。

下面以Nginx Ingress为例,对Ingress的TLS配置进行说明,步骤如下:

  1. 创建自签名的密钥和SSL证书文件;
  2. 将证书保存到Kubernetes的Secret资源对象中;
  3. 在Ingress资源中引用该Secret。

6.1 生成秘钥和证书

下面通过OpenSSL工具生成密钥和证书文件,将参数-subj中的/CN设置为host全限定域名(FQDN) “mywebsite.com”:

通过以上命令将生成tls.keytls.crt两个文件。

6.2 创建secret资源对象

然后根据tls.key和tls.crt文件创建secret资源对象,有以下两种方法。


方法一:使用kubectl create secret tls命令直接通过tls.keytls.crt文件创建secret对象


方法二:编辑mywebsite-ingress-secret.yaml文件,将tls.keytls.crt文件的内容经过BASE64编码的结果复制进去,使用kubectl create命令进行创建

# mywebsite-ingress-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: mywebsite-ingress-secret 
type: kubernetes.io/tls 
data:
  tls.crt:
    MIIDAzCC.......
  tls.key:
    MIIEV......

然后使用kubectl create命令创建即可。

6.3 多个域名的配置

如果需要配置TLS的host域名有多个,例如前面第3种Ingress策略配置方式, 则SSL证书需要使用额外的一个x509 v3配置文件辅助完成,在[alt_names]段中完成多个DNS域名的设置

首先编写openssl.cnf文件,内容如下:

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name 
[req distinguished name]
[v3 req]
basicConstraints = CA:FALSE
keyusage = nonRepudiation,digitalSignature,keyEncipherment subjectAltName = @alt_names 
[alt names]
DNS.1 = mywebsite.com 
DNS.2 = mywebsite2.com

接着使用OpenSSL工具完成密钥和证书的创建,生成自签名CA证书:

# openssl genrsa -out ca.key 2048
Generating RSA private key,2048 bit long modulus (2 primes)
·······················++++++++++++
············++++++++++++
e  is  65537(0x10001)
# openssl req -x509 -new -nodes -key ca.key -days 5000 -out ca.crt -subj "/CN=mywebsite.com"

基于openssl.cnf和CA证书生成Ingress TLS证书:

# openssl genrsa -out ingress.key 2048
Generating RSA private key,2048 bit long modulus (2 primes)
·······················++++++++++++
············++++++++++++
e is  65537(0x10001)
# openssl req -new -key ingress.key -out ingress.csr -subj "/CN=mywebsite.com" -config openss1.cnf
# openssl x509 -req -in ingress.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ingress.crt -days 5000 -extensions v3 req -extfile openssl.cnf
Signature ok
subject=/CN=mywebsite.com
Getting CA Private Key

然后根据ingress.keyingress.crt文件创建secret资源对象,同样可以通过 kubectl create secret tls命令或YAML文件生成。这里通过命令行直接生成:

$ kubectl create secret tls mywebsite-ingress-secret --key ingress.key --cert ingress.crt
secret "mywebsite-ingress-secret"created

至此,IngressTLS证书和密钥就成功创建到Secret对象中了, 下面创建Ingress对象,在tls段引用刚刚创建好的Secret对象:

# mywebsite-ingress-tls.yaml 
apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
  name: mywebsite-ingress-tls 
spec:
  tls:
  - hosts:  
    - mywebsite.com
    secretName: mywebsite-ingress-secret 
  rules:
  - host: mywebsite.com
    http:
      paths:
      - path: /demo
        pathType: Prefix
        backend:
      service:
        name: webapp
        port:
          number: 8080

成功创建该Ingress资源之后,就可以通过HTTPS安全访问Ingress了。

以使用curl命令行工具为例,访问Ingress Controller的URL"https:/192.168.18.3/demo/":

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
1月前
|
缓存 Kubernetes Docker
容器服务ACK常见问题之容器服务ACK ingress websocket配置失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
1月前
|
存储 运维 Kubernetes
容器服务ACK常见问题之修改service的名字失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
2月前
|
Kubernetes 应用服务中间件 nginx
百度搜索:蓝易云【使用Kubernetes部署Nginx应用教程】
现在,你已经成功在Kubernetes集群上部署了Nginx应用。通过访问Service的外部IP地址,你可以访问Nginx服务。
42 4
|
3月前
|
Kubernetes 负载均衡 应用服务中间件
kubernetes—Ingress详解
kubernetes—Ingress详解
74 0
|
3月前
|
Kubernetes 应用服务中间件 nginx
|
4月前
|
Kubernetes 应用服务中间件 nginx
k8s ingress不生效的bug 解决了。
k8s ingress不生效的bug 解决了。
100 0
|
4月前
|
Kubernetes 负载均衡 应用服务中间件
k8s学习-Ingress(安装、模板、创建、删除)
k8s学习-Ingress(安装、模板、创建、删除)
101 0
|
4月前
|
Kubernetes 负载均衡 网络协议
k8s学习-Service(概念、模板、创建、外部代理、删除等)
k8s学习-Service(概念、模板、创建、外部代理、删除等)
145 0
|
3月前
|
Kubernetes 负载均衡 网络协议
|
1月前
|
容器
在容器服务ACK中,如果你想更改ALB Ingress的域名和端口
【2月更文挑战第15天】在容器服务ACK中,如果你想更改ALB Ingress的域名和端口
15 3