Knative路由管理

Posted

tags:

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

Knative通过控制入口网关的流量分配来实现服务的路由管理。Knative为每个服务生成唯一的域名,入口网关会根据域名转发请求到对应的服务。

1 定制Knative服务的主域名

Knative默认为每个Service生成一个域名,Istio Gateway会根据域名判断请求应该转发给哪个服务。Knative默认使用的主域名是example.com,由于该域名不能用作线上服务,需要修改默认主域名,添加自定义域名或根据路径关联到不同的服务。

以下示例中,首先部署一个Knative服务,将配置保存到service.yaml文件中,然后执行kubectl apply-f service.yaml,这样就可以把helloworld服务部署到default命名空间。

apiVersion: serving.knative.dev/v1 
kind: Service
metadata:
name: helloworld
spec:
template:
metadata:
labels:
app: helloworld
annotations:
autoscaling.knative.dev/target: "10"
spec:
containers:
- image: registry.cnlab.dangdang.com/knative-sample/helloworld-go
env:
- name: TARGET
value: "World"

通过以下命令查看Knative服务自动生成的域名配置:

# kubectl-n default get ksvc
NAME        URL           LATESTCREATED   LATESTREADY   READY   REASON
helloworld  http://helloworld.default.example.com  helloworld-xsabn   
  helloworld-xsabn   True

使用curl命令指定Host来访问Knative服务时,首先需要获取可以访问到入口网关Istio Gateway的IP地址和端口号。

如果istio-ingressgateway的Kubernetes服务类型为LoadBalancer,我们可以通过如下方式获得入口网关的IP地址和端口号。(通常,各大公有云厂商都会提供Kubernetes的托管服务与LoadBalancer服务之间的集成。)

# export GATEWAY_IP=kubectl get svc istio-ingressgateway--namespace istio-
  system--output jsonpath=".status.loadBalancer.ingress[*][ip]"
## 获取istio-ingressgateway k8s服务的NodePort端口号
# export GATEWAY_PORT=kubectl get svc istio-ingressgateway--namespace istio-
  system--output jsonpath=".spec.ports[1].nodePort"

如果istio-ingressgateway的Kubernetes服务类型为NodePort(通常在本地部署环境中使用),NodePort端口在集群节点范围内有效,则Kubernetes集群任一节点IP都可以。

# export GATEWAY_IP=kubectl get nodes --output jsonpath=".items[0].status.
  addresses[0].address"
## 获取istio-ingressgateway Kubernetes服务的NodePort端口号
# export GATEWAY_PORT=kubectl get svc istio-ingressgateway--namespace istio-
  system--output jsonpath=".spec.ports[1].nodePort"

访问knative helloworld服务。

# curl http://$GATEWAY_IP:$GATEWAY_PORT--header "Host:helloworld.default.
  example.com"
Hello World!

如果需要对外提供服务,需要使用自己的公网域名对外暴露服务。假设想要使用的主域名是knative.dangdang.cn,就需要修改knative-serving命名空间的config-domain ConfigMap配置来实现。下面在config-domain中添加knative.dangdang.cn域名进行说明。

apiVersion: v1
data:
_example: |
################################
# #
# EXAMPLE CONFIGURATION #
# #
################################

# This block is not actually functional configuration,
# but serves to illustrate the available configuration
# options and document them in a way that is accessible
# to users that kubectl edit this config map.
#
# These sample configuration options may be copied out of
# this example block and unindented to be in the data block
# to actually change the configuration.
# Default value for domain.
# Although it will match all routes, it is the least-specific rule so it
# will only be used if no other domain matches.
example.com: |
# These are example settings of domain.
# example.org will be used for routes having app=nonprofit.
example.org: |
selector:
app: nonprofit
# Routes having domain suffix of svc.cluster.local will not be exposed
# through Ingress. You can define your own label selector to assign that
# domain suffix to your Route here, or you can set the label
# "serving.knative.dev/visibility=cluster-local"
# to achieve the same effect. This shows how to make routes having
# the label app=secret only exposed to the local cluster.
svc.cluster.local: |
selector:
app: secret
knative.dangdang.cn: ""
kind: ConfigMap
metadata:
creationTimestamp: "2020-06-03T08:51:40Z"
labels:
serving.knative.dev/release: v0.15.0
name: config-domain
namespace: knative-serving
resourceVersion: "65723826"
selfLink: /api/v1/namespaces/knative-serving/configmaps/config-domain
uid: 02ec18af-75fc-4cb2-ba67-5386157c5560

可以通过命令kubectl edit cm config-domain--namespace knative-serving修改配置,修改完成后保存退出。再看一下Knative服务的域名,显示修改的域名已生效。

# kubectl-n default get ksvc
NAME        URL           LATESTCREATED   LATESTREADY   READY   REASON
helloworld  http://helloworld.default.knative.dangdang.cn  helloworld-xsabn   
  helloworld-xsabn   True

2 DNS泛域名解析配置

如果定制了服务的主域名,希望在集群外部直接使用该域名访问Knative服务,还需要对集群外部使用的DNS进行配置。

Knative服务默认生成的域名规则是servicename.namespace.default-domain。不同的命名空间会生成不用的子域名,每个Knative服务会生成集群范围内唯一的子域名。为了让所有服务都能够在集群外部被访问到,需要做一个泛域名解析,把*.knative.dangdang.cn解析到Istio Gateway服务对应的外部IP地址上,一般是通过在DNS中添加一个A记录*.knative.dangdang.cn,并将其对应的IP地址设置为可以访问到Istio Gateway服务的IP地址。在公有云中,该地址通常是LoadBalancer的地址。本地部署的Kubernetes集群通常会采用NodePort对外暴露Istio Gateway服务。NodePort端口范围默认为30 000~32 767,这会导致服务监听的端口并不是默认的80和443端口。为了解决这个问题,还需要在集群外部搭建一个L4的反向代理来完成端口的转发。DNS中添加的A记录*.knative.dangdang.cn对应的IP地址就是该反向代理的IP地址。通常,使用nginx或HAProxy来实现。

下面以Nginx为例展示反向代理的配置。

server 
listen 80;
proxy_connect_timeout 10s;
proxy_timeout 10s;
proxy_pass k8s_80;

server
listen 443;
proxy_connect_timeout 10s;
proxy_timeout 10m;
proxy_pass k8s_443;

# upstream中的server ip:port 对应Kubernetes集群中各节点的IP地址和NodePort端口号
upstream k8s_80
hash $remote_addr consistent;
server 10.6.10.1:30080 weight=1 max_fails=3 fail_timeout=30s;
server 10.6.10.2:30080 weight=1 max_fails=3 fail_timeout=30s;

upstream k8s_443
hash $remote_addr consistent;
server 10.6.10.1:30443 weight=1 max_fails=3 fail_timeout=30s;
server 10.6.10.2:30443 weight=1 max_fails=3 fail_timeout=30s;

3 服务的可见范围控制

默认情况下,通过Knative部署的服务会发布到外部IP地址,从而使它们成为具有公共URL的服务。这对于需要从集群外部访问的服务很有用,但往往只需要构建一个集群内部可用的后端服务,且该服务并不需要在集群外可见。

Knative提供了两种方式来开启仅集群内部可用的专有服务。

1)如果想要使所有服务仅在集群内部可用,可通过修改config-domain的ConfigMap,将默认域更改为svc.cluster.local。该配置将实现Knative部署的全部服务在仅集群内部可用,在集群外部无法使用。

2)如果只是想要修改个别服务的集群可见性,可以在相应服务或路由对象上打上相应的标签,以避免服务被发布到外部网关。

下面介绍将服务标记为cluster-local的方法。

为了配置一个KService的可用范围为集群内部网络(cluster-local),可以将标签serving.knative.dev/visibility=cluster-local应用到KService、Route或Kubernetes Service对象。

标记KService的方法:

kubectl label ksvc $KSVC_NAME serving.knative.dev/visibility=cluster-local

标记Route的方法:

kubectl label route $ROUTE_NAME serving.knative.dev/visibility=cluster-local

标记Kubernetes Service的方法:

kubectl label svc $SERVICE_NAME serving.knative.dev/visibility=cluster-local

通过标记Kubernetes Service,可以在更细粒度来限制服务的可见性。

下面通过标记已部署的Hello World例子来转换集群可见性。

kubectl label ksvc helloworld-go serving.knative.dev/visibility=cluster-local

验证helloword-go服务的URL的改变:

kubectl get ksvc helloworld-go

NAME           URL                            LATESTCREATED   LATESTREADY     READY   REASON
helloworld-go  http://helloworld-go.default.  helloworld-go-  helloworld-go-  True
               svc.cluster.local              2bz5l           2bz5l

服务返回的URL以svc.cluster.local为主域名,表示服务仅在集群本地网络范围内可用。

 

以上是关于Knative路由管理的主要内容,如果未能解决你的问题,请参考以下文章

Knative 实战:如何在 Knative 中配置自定义域名及路由规则

Knative 实战:如何在 Knative 中配置自定义域名及路由规则

【Knative系列】理解 Knative Serving扩缩容系统的设计

使用Knative的服务管理组件管理应用

谷歌向CNCF捐赠Knative

Serverless 开源引擎Knative