Knative Serving的核心對象
一個 Knative 應用主要包括四類對象:Service(不同於Kubernetes的Service)、Route(類似但不是OpenShift的Route)、Configuration、Revision。
- Service(不同於Kubernetes的Service):它是一個集合,可以在Service中通過Template定義Knative的Route和Configuration對象。
- Configuration(類似OpenShift的DeploymentConfig): 創建並記錄所有Revision的情況。用kn命令更新Service的時候實際就是在更新Configuration,而每次更新Configuration都會生成一個新的Revision。
- Revision:是一個特定的應用和配置環境的快照。該對象一旦生成就不可更改了(Immutable)。一個Revision對象對應一個Kubernetes Deployment對象。由於每次更新Configuration對象都會生成一個新的Revision,因此要不然每次都指定一個不同的Revision名稱,要不就讓Knative自動生成一個Revision名稱。
- Route(類似但不是OpenShift的Route對象):Knative的Route是運行在也是用來做請求分發路由的,它是用Istio VirtualRoute實現,它定義了請求如何通過Traffic策略發給指定的Revision。藍綠部署和金絲雀發佈都是通過Route實現的。
無服務器應用的特點就是當沒有外部請求的時候服務器是不需要運行Pod,只有在有請求的時候在啓動Pod運行應用處理請求。在Knative中,這種按需的運行應用的效果是通過Activator和Autoscaler實現的。我們可以在OpenShift中的knative-serving項目中看到相關的支撐環境。
- 當首次通過Route訪問Knative應用(假設此時還沒有運行應用的Pod)的時候,請求將會先被Route發給Activator,Activator會激活目標Revision環境,Revision在通過Kubernetes Deployment啓動Pod運行應用。這個過程完成了從無服務器到有服務器的過程,當有服務器運行Pod後就可以處理請求了。
- 當已經有運行應用的Pod的情況下,Route會直接將請求發給和Revsion對應的Pod。
- Autoscaler會監控Revision中的Pod運行其情況並收集Metrics數據,然後根據策略決定是擴展還是收縮Pod的數量。而擴展或收縮的動作是Revision通知Kubernetes的Deployment完成的。
創建Knative Serving應用
一個Knative Serving應用包括Service、Route、Configuration、Revision對象。他們的關係是Service=Route+Configuration,因此可以通過分別操作Route和Configuration或操作Service實現對Knative Serving應用的配置。
通過Configuration和Route實現藍綠部署
- 創建新項目。
$ oc new-project kn-blue-green
- 創建內容如下的blue-config.yaml文件,其中定義了名爲blue-green-demo的Configuration對象,該對象使用的鏡像是“gcr.io/knative-samples/knative-route-demo:blue”。
apiVersion: serving.knative.dev/v1
kind: Configuration
metadata:
name: blue-green-demo
spec:
template:
spec:
containers:
- image: gcr.io/knative-samples/knative-route-demo:blue
env:
- name: T_VERSION
value: "blue"
- 根據blue-config.yaml創建名爲blue-green-demo的Configuration。
$ oc apply -f blue-config.yaml
configuration "blue-green-demo" configured
- 查看項目中的對象,可以看到伴隨Configuration還生成了Revision、Deployment、Replicset和Pod。其中Revision名爲自動生成的blue-green-demo-jvtg7。
$ oc get all
NAME READY STATUS RESTARTS AGE
pod/blue-green-demo-jvtg7-deployment-8cb94b4d7-qhvg7 2/2 Running 0 44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/blue-green-demo-jvtg7-deployment 1/1 1 1 44s
NAME DESIRED CURRENT READY AGE
replicaset.apps/blue-green-demo-jvtg7-deployment-8cb94b4d7 1 1 1 44s
NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON
revision.serving.knative.dev/blue-green-demo-jvtg7 blue-green-demo 1 Unknown Deploying
NAME LATESTCREATED LATESTREADY READY REASON
configuration.serving.knative.dev/blue-green-demo blue-green-demo-jvtg7 Unknown
- 創建以下內容的blue-route.yaml文件,其中定義了Route對象。注意:需要將文件中的"revisionName"名稱中的“blue-green-demo-XXX”替換爲上一步創建的名爲“blue-green-demo-jvtg7”的Revision。
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: blue-green-demo # The name of our route; appears in the URL to access the app
spec:
traffic:
- revisionName: blue-green-demo-XXX # replace XXX with your RevisionName
percent: 100 # All traffic goes to this revision
- 執行blue-route.yaml文件創建Route對象。
$ oc apply -f blue-route.yaml
route "blue-green-demo" configured
- 訪問通過blue-green-demo的Route訪問應用。確認返回頁面中有“App v1”。
$ curl $(kn route list blue-green-demo | grep blue-green-demo | awk '{print $2}')
<!DOCTYPE html>
<html lang="en">
<head>
<title>Knative Routing Demo</title>
<link rel="stylesheet" type="text/css" href="/css/app.css" />
</head>
<body>
<div class="blue">App v1</div>
</div>
</body>
- 創建內容如下的green-config.yaml文件,其中定義了名爲blue-green-demo的Configuration對象,該對象使用的鏡像是“gcr.io/knative-samples/knative-route-demo:green”。
apiVersion: serving.knative.dev/v1
kind: Configuration
metadata:
name: blue-green-demo # Configuration name is unchanged, since we're updating an existing Configuration
spec:
template:
spec:
containers:
- image: gcr.io/knative-samples/knative-route-demo:green # URL to the new version of the sample app docker image
env:
- name: T_VERSION
value: "green" # Updated value for the T_VERSION environment variable
- 執行green-config.yaml文件,更新名爲blue-green-demo的Configuration。
$ oc apply -f green-config.yaml
configuration.serving.knative.dev/blue-green-demo configured
- 查看項目中對象的變化情況。
$ oc get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/blue-green-demo ExternalName <none> cluster-local-gateway.knative-serving-ingress.svc.cluster.local <none> 43m
service/blue-green-demo-d44kj ClusterIP 172.30.202.156 <none> 80/TCP 32m
service/blue-green-demo-d44kj-private ClusterIP 172.30.114.50 <none> 80/TCP,9090/TCP,9091/TCP,8022/TCP 32m
service/blue-green-demo-jvtg7 ClusterIP 172.30.254.229 <none> 80/TCP 50m
service/blue-green-demo-jvtg7-private ClusterIP 172.30.214.59 <none> 80/TCP,9090/TCP,9091/TCP,8022/TCP 50m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/blue-green-demo-d44kj-deployment 0/0 0 0 32m
deployment.apps/blue-green-demo-jvtg7-deployment 0/0 0 0 50m
NAME DESIRED CURRENT READY AGE
replicaset.apps/blue-green-demo-d44kj-deployment-b8fb879f6 0 0 0 32m
replicaset.apps/blue-green-demo-jvtg7-deployment-5bf694ccf9 0 0 0 50m
NAME URL READY REASON
route.serving.knative.dev/blue-green-demo http://blue-green-demo.knative-demo.apps.cluster-shanghai-c30f.shanghai-c30f.example.opentlc.com Unknown IngressNotConfigured
NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON
revision.serving.knative.dev/blue-green-demo-d44kj blue-green-demo blue-green-demo-d44kj 2 True
revision.serving.knative.dev/blue-green-demo-jvtg7 blue-green-demo blue-green-demo-jvtg7 1 True
NAME LATESTCREATED LATESTREADY READY REASON
configuration.serving.knative.dev/blue-green-demo blue-green-demo-d44kj blue-green-demo-d44kj True
- 創建以下內容的green-route.yaml文件,其中更新了Route對象。注意:需要將文件中的2個"revisionName"名稱中的“blue-green-demo-XXX”和““blue-green-demo-XXX””替換爲上一步創建的名爲“blue-green-demo-jvtg7”和“blue-green-demo-d44kj”的Revision。
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: blue-green-demo # Route name is unchanged, since we're updating an existing Route
spec:
traffic:
- revisionName: blue-green-demo-XXX
percent: 0
- revisionName: blue-green-demo-YYY
percent: 100
tag: v2 # A named route
- 執行blue-green-route.yaml文件,更新名爲blue-green-demo的Route。
$ oc apply -f blue-green-route.yaml
configuration.serving.knative.dev/blue-green-demo configured
- 訪問通過blue-green-demo的Route訪問應用。確認返回頁面中有“App v2”。
$ curl $(kn route list blue-green-demo | grep blue-green-demo | awk '{print $2}')
<!DOCTYPE html>
<html lang="en">
<head>
<title>Knative Routing Demo</title>
<link rel="stylesheet" type="text/css" href="/css/app.css" />
</head>
<body>
<div class="green">App v2</div>
</div>
</body>
- 還可進一步編輯blue-green-route.yaml文件中的Traffic比例,從而從green回退到blue版本,同時還可實現金絲雀發佈。
通過Service部署應用
- 創建定義Service的greeter-service.yaml文件,爲以下內容。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: greeter
spec:
template:
metadata:
name: greeter-v1
spec:
containers:
- image: quay.io/rhdevelopers/knative-tutorial-greeter:quarkus
- 執行命令創建Service對象。
$ oc apply -f greeter-service.yaml
service.serving.knative.dev/greeter created
- 確認名爲greeter的Knative Route已經是READY爲True的狀態。
$ kn route list greeter
NAME URL READY
greeter http://greeter.knative-demo.apps.cluster-shanghai-c30f.shanghai-c30f.example.opentlc.com True
- 通過Knative Route訪問greeter應用。
$ curl $(kn route list greeter | grep greeter | awk '{print $2}')
Hi greeter => '9861675f8845' : 1