linkerd实战HTTP1.1 Identifiers详解

Posted 微服务云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linkerd实战HTTP1.1 Identifiers详解相关的知识,希望对你有一定的参考价值。

概述

上一篇我们一步一步搭建了linkerd示例,用到了默认的Identifier将服务调用方的请求转换成service name。现在我们来具体了解一下linkerd中Identifier的使用。

在linkerd中所有的基于http/1.1协议的Identifier都有一个kind属性配置,不同的kind配置使用不同转换策略对请求进行转换生成service name。如果不配置默认为kind:io.l5d.header.token

Header Token Identifier

将使用http header的项作为servive name的标识。如果不设置header名称,默认会使用Host。

kind:io.l5d.header.token

额外属性配置:

配置名

默认值

描述

header

Host

选用哪个Http Header作为service name标识

转换目标service name模板:

/ dstPrefix / [headerValue]

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

headerValue

N/A

配置的header值

示例:

修改示例,我们采用test-header作为自定义的header,配置调整如下:

routers:

- protocol: http

identifier:

kind: io.l5d.header.token

header: test-header

dtab: |

/svc => /#/io.l5d.fs;

servers:

- port: 4140

ip: 0.0.0.0

运行:

$ curl -H "test-header:test" http://127.0.0.1:4140

It works!

Method and Host Identifier

将组合使用http header的项Host,method和URL(可选)作为servive name的标识。

kind: io.l5d.methodAndHost

额外属性配置:

配置名

默认值

描述

httpUriInDst

false

是否把请求uri作为service name标识的一部分,

建议使用path identifier来更精确控制uri

Http1.1中转换目标service name模板:

/ dstPrefix / 1.1 / method / host [/ uri* ]

Http1.0中转换目标service name模板(没有host信息):

/ dstPrefix / 1.1 / method [/ uri* ]

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

method

N/A

请求method,如get、post、head等

host

N/A

请求的Host header,大小写敏感,在http1.0不适用

uri

Not used

只在将path作为service name一部分时使用

示例:

修改示例,配置调整如下:

routers:

- protocol: http

identifier:

kind: io.l5d.methodAndHost

dtab: |

/svc => /#/io.l5d.fs;

servers:

- port: 4140

ip: 0.0.0.0

运行:

$ curl -H "test-header:test" http://127.0.0.1:4140

No hosts are available for /svc/1.1/GET/test, Dtab.base=[/svc=>/#/io.l5d.fs], Dtab.local=[] ...

这时候我们的请求被转换成/svc/1.1/GET/test,对应的服务发现没有配置。

我们把之前定义在disco下的test文件复制到1.1/GET下面

$ cp disco\test disco\1.1\GET\

再次运行:

$ curl -H "test-header:test" http://127.0.0.1:4140

It works!

Path Identifier

将使用path或path中部分路径作为servive name的标识。可以通过额外配置指定截取url前几个“/”作为service name。

kind: io.l5d.path

额外属性配置:

配置名

默认值

描述

segments

1

path中前几段作为service name

consume

false

是否把path中匹配到的部分路径从请求中移除,如果true,

Http1.1中转换目标service name模板:

/ dstPrefix [/ *urlPath ]

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

urlPath

N/A

根据segments配置截取的path中匹配到的部分路径

示例:

修改示例,配置调整如下:

routers:

- protocol: http

identifier:

kind: io.l5d.path

segments: 1

consume: true

dtab: |

/svc => /#/io.l5d.fs;

servers:

- port: 4140

ip: 0.0.0.0

运行:

$ curl http://127.0.0.1:4140/test

It works!

如果我们不配置consume,则发往目标请求也会带上/test,导致404错误。

Header Identifier

将单独使用Http Header中的项作为servive name的标识。因为service name 标识路径,因此配置的Header项的值必须/开头。

kind: io.l5d.header

额外属性配置:

配置名

默认值

描述

header

l5d-name

作为service name的header项

Http1.1中转换目标service name模板:

/ dstPrefix [*headerValue ]

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

headerValue

N/A

配置的header项的值

示例:

修改示例,配置调整如下:

routers:

- protocol: http

identifier:

kind: io.l5d.header

header:test-header

dtab: |

/svc => /#/io.l5d.fs;

servers:

- port: 4140

ip: 0.0.0.0

运行:

$ curl -H "test-header:/test" http://127.0.0.1:4140

It works!

如果header的值不是/开头,则linkerd在做识别的时候会抛出错误。

$ curl -H "test-header:test" http://127.0.0.1:4140

Unknown destination: Request("GET /", from /127.0.0.1:50727) / '/' expected but 't' found at '[t]est'

Ingress Identifier

将使用 Kubernetes ingress controller,通过请求比较ingress resource rules,然后根据规则返回service name。

kind: io.l5d.ingress

额外属性配置:

配置名

默认值

描述

namespace

(all)

ingress resources部署的命名空间,默认搜索所有

ingressClassAnnotation

linkerd

当使用 multiple ingress controllers,

Linkerd只会选择带这个注解的类

ignoreDefaultBackends

false

标识仅匹配显示申明 host或者path的请求

host

localhost

Kubernetes master host.

port

8001

Kubernetes master port.

Http1.1中转换目标service name模板:

/ dstPrefix / namespace / port / service

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

namespace

N/A

Kubernetes namespace

port

N/A

端口

service

N/A

服务名

示例:

修改示例,配置调整如下:

routers: 

  - protocol: http  

      identifier:    

        kind: io.l5d.ingress    

        namespace: default

    servers:  

      - port: 4140  

    dtab: /svc => /#/io.l5d.k8s 

namers: 

    - kind: io.l5d.k8s


假设ingeress resource配置:

apiVersion: extensions/v1beta1 

kind: Ingress 

metadata:  

  name: my-first-ingress  

  namespace: default 

annotations:  kubernetes.io/ingress.class: "linkerd" 

spec:  rules:  

    - http:      

       paths:      

          - path: /testpath        

             backend:          

               serviceName: test          

               servicePort: 80

请求 http://localhost:4140/test将转换为/svc/default/80/test,因需要k8s环境,这里不做代码演示。

Istio Identifier

将请求和 istio route-rules 比对并基于规则转换成service name。

kind: io.l5d.k8s.istio

额外属性配置:

配置名

默认值

描述

discoveryHost

istio-pilot

 Istio-Pilot 主机

discoveryPort

8080

 Istio-Pilot 主机服务发现端口

apiserverHost

istio-pilot

 Istio-Pilot 主机

apiserverPort

8081

 Istio-Pilot 主机api server端口

Http1.1中转换目标service name模板:

请求未匹配k8s集群

/ dstPrefix / "ext" / host / port

请求未匹配route-rule

/ dstPrefix / "dest" / cluster / "::" / port

请求匹配route-rule

/ dstPrefix / "route" / routeRule

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

routeRule

N/A

匹配请求的规则名称

host

N/A

请求的host

cluster

N/A

请求的集群

port

N/A

请求的port

示例:

修改示例,配置调整如下:

routers: - protocol: http  identifier:    kind: io.l5d.k8s.istio

因需要k8s环境,这里不做代码演示。

Static Identifier

将所有请求转换为静态的service name固定值。

kind: io.l5d.static

额外属性配置:

配置名

默认值

描述

path

required

作为service name的值

Http1.1中转换目标service name模板:

/ dstPrefix / *path

模板占位符

默认值

描述

dstPrefix

/svc

在routers中配置的dstPrefix前缀值

path

N/A

配置的path的值

示例:

修改示例,配置调整如下:

routers: - protocol: http  identifier:    kind: io.l5d.static    path: /test

运行:

$ curl  http://127.0.0.1:4140

It works!

小结

Linkerd在路由请求的第一阶段,将请求转换为serveice name的时候,提供了一组Identifiers来处理转换。若不能满足需要,还可以自己开发Identifier作为插件来扩展功能。


以上是关于linkerd实战HTTP1.1 Identifiers详解的主要内容,如果未能解决你的问题,请参考以下文章

Linkerd 2.10(Step by Step)—多集群通信

Linkerd 2.10(Step by Step)—配置代理并发

Linkerd 2.10(Step by Step)—控制平面调试端点

http1.1长连接实战

了解 Linkerd Service Mesh 架构

如何在Windows PC上安装Linkerd?