一、Revision
#关于Revision
◼ 应用程序代码及相关容器配置某个版本的不可变快照
◼ KService上的spec.template的每次变动,都会自动生成一个新的Revision
◼ 通常不需要手动创建及维护
#Revision的使用场景
◼ 将流量切分至不同版本的应用程序间(Canary Deployment、Blue/Green Deployment)
◼ 版本回滚
![]()
#获取特定KService相关的Revision
[root@xianchaomaster1 domainmapping]# kn revision list -s hello
NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
hello-knative hello 100% 3 51m 4 OK / 4 True
hello-world-002 hello 2 74m 3 OK / 4 True
hello-world hello 1 84m 3 OK / 4 True
#打印最新创建的Revision
[root@xianchaomaster1 domainmapping]# kubectl get ksvc hello -o jsonpath={.status.latestCreatedRevisionName}
hello-knative[
#找到就绪状态的最新版本的Revision
[root@xianchaomaster1 domainmapping]# kubectl get ksvc hello -o jsonpath={.status.latestReadyRevisionName}
hello-knative
#查看特定的Revision是否已经就绪
[root@xianchaomaster1 domainmapping]# kubectl get revision hello-knative -o jsonpath="{.status.conditions[?(@.type=='Ready')].status}"
True
#用kn获取信息latestCreatedRevisionName、latestReadyRevisionName、traffic
[root@xianchaomaster1 domainmapping]# kubectl get kservice hello -o yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"serving.knative.dev/v1","kind":"Service","metadata":{"annotations":{},"name":"hello","namespace":"default"},"spec":{"template":{"metadata":{"name":"hello-world-002"},"spec":{"containerConcurrency":10,"containers":[{"env":[{"name":"TARGET","value":"World-002"}],"image":"ikubernetes/helloworld-go","ports":[{"containerPort":8080}]}]}}}}
serving.knative.dev/creator: kubernetes-admin
serving.knative.dev/lastModifier: kubernetes-admin
creationTimestamp: "2023-07-05T05:46:49Z"
generation: 3
name: hello
namespace: default
resourceVersion: "58997"
uid: 05303f44-5c0a-46ea-a403-c3538f99d614
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/max-scale: "10"
autoscaling.knative.dev/min-scale: "1"
client.knative.dev/updateTimestamp: "2023-07-05T06:19:55Z"
creationTimestamp: null
name: hello-knative
spec:
containerConcurrency: 10
containers:
- env:
- name: TARGET
value: Knative-CLI
image: ikubernetes/helloworld-go
name: user-container
ports:
- containerPort: 8080
protocol: TCP
readinessProbe:
successThreshold: 1
tcpSocket:
port: 0
resources: {}
enableServiceLinks: false
timeoutSeconds: 300
traffic:
- latestRevision: true
percent: 100
status:
address:
url: http://hello.default.svc.cluster.local
conditions:
- lastTransitionTime: "2023-07-05T06:19:59Z"
status: "True"
type: ConfigurationsReady
- lastTransitionTime: "2023-07-05T06:34:20Z"
status: "True"
type: Ready
- lastTransitionTime: "2023-07-05T06:34:20Z"
status: "True"
type: RoutesReady
latestCreatedRevisionName: hello-knative
latestReadyRevisionName: hello-knative
observedGeneration: 3
traffic:
- latestRevision: true
percent: 100
revisionName: hello-knative
url: http://hello.default.xks.com
二、KService的客户端流量处理
#集群外部流量
◼ 通过KService的外部名称(ksvc-name.namespace.DOMAIN)将流量发给入口网关(例如istio-ingressgateway的Service使用的ExternalIP)的外部地址
◆需要在集群外部的DNS系统上设定相应的名称解析
◆暴露的服务较多时,可以使用泛域名解析
◼ 通过KService使用的Domainmapping中定义的名称,将流量发往入口网关的外部地址
#集群内部流量
◼ 未启用mesh时:通过KService的内部名称(ksvc-name.namespace.DOMAIN)将流量发往Knative使用的istio-system名称空间下的knative专用本地流量网关knative-local-gateway
◼ 启用mesh时,流量将由mesh根据流量策略进行转发
◆此时,无须再设置本地流量网关
#支撑一个KService对象的流量转发的关键是Route
[root@xianchaomaster1 domainmapping]# kubectl get gw -n knative-serving
NAME AGE
knative-ingress-gateway 3h
knative-local-gateway 3h
Route
#Route
◼ 由KService的spec.traffic自动生成
◼ 未定义时,将由就绪状态的Revision列表中的最新版本的Revision接收和处理该KService的所有请求
◼ Route依托入口网关和网格(或本地网关)完成流量转发
◼ Route会自动按需创建如下资源
◆Kubernetes Service
◆Istio VirtualService(以Istio为网络层时)
#配置Private KService
◼ 默认情况下,KService会由Knative同时配置内部(私有)或公共服务
◼ 仅创建私有服务的方法
◆全局配置:修改configmap/config-domain,将默认域设置为svc.cluster.local;
◆单KService配置:使用“networking.knative.dev/visibility”标签,并设定其值为cluster-local
⚫ 设定于KService对象之上
⚫ 无KService时,设定于相关的Route和Kubernetes Service之上
◼ 示例:~$ kubectl label ksvc hello networking.knative.dev/visibility=cluster-local
◆提示:若为ksvc/hello设置了域名映射,则外部客户端依然可通过该映射对其进行访问
#设置私有服务
[root@xianchaomaster1 domainmapping]# kubectl label ksvc hello networking.knative.dev/visibility=cluster-local
service.serving.knative.dev/hello labeled
#此时hello 不能通过
[root@xianchaomaster1 domainmapping]# kubectl get vs
NAME GATEWAYS HOSTS AGE
demoapp-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local","demoapp.default.xks.com"] 161m
demoapp-mesh ["mesh"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local"] 161m
hello-ingress ["knative-serving/knative-local-gateway"] ["hello.default","hello.default.svc","hello.default.svc.cluster.local"] 97m
hello-mesh ["mesh"] ["hello.default","hello.default.svc","hello.default.svc.cluster.local"] 97m
hello.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["hello.ik8s.io"] 30m
www.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["www.ik8s.io"] 21m
#访问不到
[root@xianchaomaster1 domainmapping]# curl -H "Host: hello.default.xks.com" 192.168.40.190
#域名映射过的还是可以访问
[root@xianchaomaster1 domainmapping]# curl -H "Host: www.ik8s.io" 192.168.40.190
Hello Knative-CLI!
[root@xianchaomaster1 domainmapping]# curl -H "Host: hello.ik8s.io" 192.168.40.190
Hello Knative-CLI!
#取消私有服务
[root@xianchaomaster1 domainmapping]# kubectl label ksvc hello networking.knative.dev/visibility-
service.serving.knative.dev/hello unlabeled
#域名都恢复 可以访问了
[root@xianchaomaster1 domainmapping]# kubectl get vs
NAME GATEWAYS HOSTS AGE
demoapp-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local","demoapp.default.xks.com"] 167m
demoapp-mesh ["mesh"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local"] 167m
hello-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["hello.default","hello.default.svc","hello.default.svc.cluster.local","hello.default.xks.com"] 103m
hello-mesh ["mesh"] ["hello.default","hello.default.svc","hello.default.svc.cluster.local"] 103m
hello.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["hello.ik8s.io"] 37m
www.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["www.ik8s.io"] 27m
[root@xianchaomaster1 domainmapping]# curl -H "Host: hello.default.xks.com" 192.168.40.190
Hello Knative-CLI!
[root@xianchaomaster1 domainmapping]# curl -H "Host: hello.ik8s.io" 192.168.40.190
Hello Knative-CLI!
[root@xianchaomaster1 domainmapping]# curl -H "Host: www.ik8s.io" 192.168.40.190
Hello Knative-CLI!
三、自定义流量策略
#修改KService流量策略的途径
◼ 命令行命令:kn service update <service-name> --traffic revisionRef=percent
◆引用revision的方法:revisionName、Tag,以及使用“@latest”引用最新的就绪版本
◆“--traffic”选项可以多次使用,直到全部的流量比例之和为100%
◼ 在KService的资源配置上,使用spec.traffic进行定义
◼ 为目标KService创建自定义的Route资源,为其配置临时流量策略
#命令式命令配置示例
◼ 将流量完全发送至指定的某个Revision(回滚)
◆~$ kn service update hello --traffic hello-00001=100
◼ 将流量切分至不同的Revision
◆~$ kn service update hello --traffic hello-00001=90 --traffic hello-00002=10
◼ 将流量完全发送至最新就绪版本的Revision
◆~$ kn service update hello --traffic '@latest'=100
#hello-knative - 100%
[root@xianchaomaster1 domainmapping]# kn revision list
NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
demoapp-00001 demoapp 100% 1 174m 3 OK / 4 True
hello-knative hello 100% 3 77m 4 OK / 4 True
hello-world-002 hello 2 100m 3 OK / 4 True
hello-world hello 1 110m 3 OK / 4 True
#进行切换到hello-world - 100%
[root@xianchaomaster1 domainmapping]# kn service update hello --traffic hello-world=100
Updating Service 'hello' in namespace 'default':
0.019s The Route is still working to reflect the latest desired specification.
0.050s Ingress has not yet been reconciled.
0.091s Waiting for load balancer to be ready
0.262s Ready to serve.
Service 'hello' with latest revision 'hello-knative' (unchanged) is available at URL:
http://hello.default.xks.com
#切换成功到hello-world
[root@xianchaomaster1 domainmapping]# kn revision list
NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
demoapp-00001 demoapp 100% 1 175m 3 OK / 4 True
hello-knative hello 3 78m 3 OK / 4 True
hello-world-002 hello 2 102m 3 OK / 4 True
hello-world hello 100% 1 111m 3 OK / 4 True
[root@xianchaomaster1 domainmapping]# kn service describe hello
Name: hello
Namespace: default
Age: 1h
URL: http://hello.default.xks.com
Revisions:
+ hello-knative (current @latest) [3] (1h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
100% hello-world [1] (1h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
Conditions:
OK TYPE AGE REASON
++ Ready 27s
++ ConfigurationsReady 1h
++ RoutesReady 27s
[root@xianchaomaster1 domainmapping]# curl -H "Host: hello.default.xks.com" 192.168.40.190
Hello World!
#三个版本分别流量分发配置
[root@xianchaomaster1 domainmapping]# kn revision list
NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
demoapp-00001 demoapp 100% 1 3h4m 3 OK / 4 True
hello-knative hello 3 87m 3 OK / 4 True
hello-world-002 hello 2 111m 3 OK / 4 True
hello-world hello 100% 1 120m 3 OK / 4 True
[root@xianchaomaster1 domainmapping]# kn service update hello --traffic hello-knative=50 --traffic hello-world-002=30 --traffic hello-world=20
Updating Service 'hello' in namespace 'default':
0.017s The Route is still working to reflect the latest desired specification.
0.048s Ingress has not yet been reconciled.
0.083s Waiting for load balancer to be ready
0.263s Ready to serve.
Service 'hello' with latest revision 'hello-knative' (unchanged) is available at URL:
http://hello.default.xks.com
You have new mail in /var/spool/mail/root
[root@xianchaomaster1 domainmapping]# kn service describe hello
Name: hello
Namespace: default
Age: 2h
URL: http://hello.default.xks.com
Revisions:
50% hello-knative (current @latest) [3] (1h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 1/1
30% hello-world-002 [2] (1h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
20% hello-world [1] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
Conditions:
OK TYPE AGE REASON
++ Ready 9s
++ ConfigurationsReady 1h
++ RoutesReady 9s
[root@xianchaomaster1 domainmapping]# while true; do curl -H "Host: hello.default.xks.com" 192.168.40.190; sleep .2;done
Hello Knative-CLI!
Hello World-002!
Hello Knative-CLI!
Hello Knative-CLI!
Hello World!
Hello World-002!
Hello World-002!
Hello World-002!
Hello World!
Hello Knative-CLI!
Hello Knative-CLI!
Hello World-002!
Hello World-002!
Hello World!
Hello World-002!
Hello World-002!
四、路由标签(Tag)
#路由标签能够为特定的路由项创建基于tag的目标地址
◼ 附带的tag的路由项指向的Revision,可通过<tag-name>-<route-name>.<namespace>.<domain>的格式访问
◼ 无tag的路由项,仅可通过<route-name>.<namespace>.<domain>的格式访问
#管理标签的方法
◼ 在Traffic Target上直接配置
◼ 命令
◆设定标签:kn service udpate <name> --tag revisionRef=tagName
◆删除标签:kn service update <name> --untag tagName
[root@xianchaomaster1 revision-and-route]# kn service describe hello
Name: hello
Namespace: default
Age: 2h
URL: http://hello.default.xks.com
Revisions:
50% hello-knative (current @latest) [3] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 1/1
30% hello-world-002 [2] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
20% hello-world [1] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
Conditions:
OK TYPE AGE REASON
++ Ready 38m
++ ConfigurationsReady 2h
++ RoutesReady 38m
You have new mail in /var/spool/mail/root
[root@xianchaomaster1 revision-and-route]# kn service update hello --tag hello-knative=green
Updating Service 'hello' in namespace 'default':
0.019s The Route is still working to reflect the latest desired specification.
0.046s Ingress has not yet been reconciled.
0.084s Waiting for load balancer to be ready
0.269s Ready to serve.
Service 'hello' with latest revision 'hello-knative' (unchanged) is available at URL:
http://hello.default.xks.com
[root@xianchaomaster1 revision-and-route]# kn service update hello --tag hello-world-002=black
Updating Service 'hello' in namespace 'default':
0.018s The Route is still working to reflect the latest desired specification.
0.044s Ingress has not yet been reconciled.
0.093s Waiting for load balancer to be ready
0.280s Ready to serve.
Service 'hello' with latest revision 'hello-knative' (unchanged) is available at URL:
http://hello.default.xks.com
[root@xianchaomaster1 revision-and-route]# kn service update hello --tag hello-world=grey
Updating Service 'hello' in namespace 'default':
0.015s The Route is still working to reflect the latest desired specification.
0.043s Ingress has not yet been reconciled.
0.087s Waiting for load balancer to be ready
0.277s Ready to serve.
Service 'hello' with latest revision 'hello-knative' (unchanged) is available at URL:
http://hello.default.xks.com
[root@xianchaomaster1 revision-and-route]# kn service describe hello
Name: hello
Namespace: default
Age: 2h
URL: http://hello.default.xks.com
Revisions:
50% hello-knative (current @latest) #green [3] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 1/1
30% hello-world-002 #black [2] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
20% hello-world #grey [1] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
Conditions:
OK TYPE AGE REASON
++ Ready 45s
++ ConfigurationsReady 2h
++ RoutesReady 45s
[root@xianchaomaster1 revision-and-route]# curl -H "Host: green-hello.default.xks.com" 192.168.40.190
Hello Knative-CLI!
[root@xianchaomaster1 revision-and-route]# curl -H "Host: grey-hello.default.xks.com" 192.168.40.190
Hello World!
[root@xianchaomaster1 revision-and-route]# curl -H "Host: black-hello.default.xks.com" 192.168.40.190
Hello World-002!
#vs中增加了 hosts 记录
[root@xianchaomaster1 revision-and-route]# kubectl get vs
NAME GATEWAYS HOSTS AGE
demoapp-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local","demoapp.default.xks.com"] 3h51m
demoapp-mesh ["mesh"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local"] 3h51m
hello-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["black-hello.default","black-hello.default.svc","black-hello.default.svc.cluster.local","black-hello.default.xks.com","green-hello.default","green-hello.default.svc","green-hello.default.svc.cluster.local","green-hello.default.xks.com","grey-hello.default","grey-hello.default.svc","grey-hello.default.svc.cluster.local","grey-hello.default.xks.com","hello.default","hello.default.svc","hello.default.svc.cluster.local","hello.default.xks.com"] 167m
hello-mesh ["mesh"] ["black-hello.default","black-hello.default.svc","black-hello.default.svc.cluster.local","green-hello.default","green-hello.default.svc","green-hello.default.svc.cluster.local","grey-hello.default","grey-hello.default.svc","grey-hello.default.svc.cluster.local","hello.default","hello.default.svc","hello.default.svc.cluster.local"] 167m
hello.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["hello.ik8s.io"] 100m
www.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["www.ik8s.io"] 91m
#取消tag
[root@xianchaomaster1 revision-and-route]# kn service update hello --untag green --untag black --untag grey
Updating Service 'hello' in namespace 'default':
0.018s The Route is still working to reflect the latest desired specification.
0.051s Ingress has not yet been reconciled.
0.079s Waiting for load balancer to be ready
0.270s Ready to serve.
Service 'hello' with latest revision 'hello-knative' (unchanged) is available at URL:
http://hello.default.xks.com
You have new mail in /var/spool/mail/root
[root@xianchaomaster1 revision-and-route]# kn service describe hello
Name: hello
Namespace: default
Age: 2h
URL: http://hello.default.xks.com
Revisions:
50% hello-knative (current @latest) [3] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 1/1
30% hello-world-002 [2] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
20% hello-world [1] (2h)
Image: ikubernetes/helloworld-go (at 5ea96b)
Replicas: 0/0
Conditions:
OK TYPE AGE REASON
++ Ready 15s
++ ConfigurationsReady 2h
++ RoutesReady 15s
#已被取消
[root@xianchaomaster1 revision-and-route]# kubectl get vs
NAME GATEWAYS HOSTS AGE
demoapp-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local","demoapp.default.xks.com"] 3h53m
demoapp-mesh ["mesh"] ["demoapp.default","demoapp.default.svc","demoapp.default.svc.cluster.local"] 3h53m
hello-ingress ["knative-serving/knative-ingress-gateway","knative-serving/knative-local-gateway"] ["hello.default","hello.default.svc","hello.default.svc.cluster.local","hello.default.xks.com"] 169m
hello-mesh ["mesh"] ["hello.default","hello.default.svc","hello.default.svc.cluster.local"] 169m
hello.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["hello.ik8s.io"] 103m
www.ik8s.io-ingress ["knative-serving/knative-ingress-gateway"] ["www.ik8s.io"]
#
五、Configuration Target和流量逐步迁移
#Configuration Target
◼ ConfigurationName也可以作为路由项中的流量目标,意味着相关的流量部分由该Configurate下最新就绪的
#Revision承载
◼ 存在问题
◆在新的Revision就绪之后,Configuration Target上的所有流量会立即转移至该Revision
◆这可能会导致QP或Activator的请求队列过长,以至于部分请求可能会被拒绝
◼ 解决方式
◆在KService或Route上使用“serving.knative.dev/rollout-duration”注解来指定流量迁移过程的时长
◆新的Revision上线后,它会先从Configuration Target迁出1%的流量
◆随后再等分迁出余下的流量部分
![]()
六、Yaml文件配置 Service 示例:
[root@xianchaomaster1 revision-and-route]# cat 001-hello-world.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: ikubernetes/helloworld-go
ports:
- containerPort: 8080
env:
- name: TARGET
value: "World"
[root@xianchaomaster1 revision-and-route]# cat 002-hello-knative.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: ikubernetes/helloworld-go
ports:
- containerPort: 8080
env:
- name: TARGET
value: "Knative"
#流量分配
[root@xianchaomaster1 revision-and-route]# cat 003-hello-traffic-route.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: ikubernetes/helloworld-go
ports:
- containerPort: 8080
env:
- name: TARGET
value: "Knative"
traffic:
- latestRevision: true
percent: 100
- revisionName: hello-00001
percent: 0
# tag: staging 打标签
[root@xianchaomaster1 revision-and-route]# cat 004-hello-CloudNative.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: ikubernetes/helloworld-go
ports:
- containerPort: 8080
env:
- name: TARGET
value: "Cloud-Native"
traffic:
- latestRevision: true
percent: 0
tag: staging
- revisionName: hello-00002
percent: 90
- revisionName: hello-00001
percent: 10