Cloud Run Anthosの処理の流れ

#はじめに
Cloud Run AnthosのHTTPリクエストの処理の流れを追ってみたいと思います。
通信の種類は、Cluster外からの通信とCluster内からの通信の2種類になります。

本記事で記載する処理の流れは、Revisionに Pod が存在する場合の流れになります。
Podが存在しない場合は、Pod のスケールアップのために、Activatorによって、受信したリクエストが一時的にキューに入れられ、指標がオートスケーラーに push するといった処理が入ります。
https://cloud.google.com/run/docs/gke/architecture-overview

#Cluster外からのアクセス
Cluster外からのアクセスは、Network Loadbalancerをに対して、接続先のknative serviceをホストヘッダーに指定してアクセスします。

```
curl -H "Host: my-service.default.example.com" http://＜Network LoadbalancerのIPアドレス＞
```

HTTPのURLは、以下のコマンドで確認できます。

```
k get ksvc my-service
NAME         URL                                     LATESTCREATED          LATESTREADY            READY   REASON
my-service   http://my-service.default.example.com   my-service-00001-nex   my-service-00001-nex   True
```

カスタムドメインを使用してアクセスしたい場合は、以下の手順で実装可能です。
https://cloud.google.com/run/docs/mapping-custom-domains

Network Loadbalancerではなく、HTTPS Loadbalancer（Ingress）を使用したい場合は、以下の手順で実装可能です。
https://cloud.google.com/solutions/integrating-https-load-balancing-with-istio-and-cloud-run-for-anthos-deployed-on-gke

カスタムドメインとIngressをあわせて使用する方法については、以下のQiitaの記事を以前書きました。
https://qiita.com/atsumjp/items/dfe857d7650a7d157e37

##Client->Network Loadbalancer->GCEインスタンスグループ->Istio Ingress Gateway
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/59115780-5cd7-055c-1c7b-be71c87e6824.png)

ClientからのHTTPリクエストは、Type: Loadbalancerとして作成されたGCPのNetwork Loadbalancerが受信します。
上記の図には記載してませんが、Network Loadbalancerのバックエンドには、KubernetesのNodeとなるGCEのインスタンスグループが設定されており、Network LoadbalancerからGCEのインスタンスまでHTTPリクエストが転送され、Service meshの入り口となるIstio ingress gatewayのDeploymentとして作成されたEnvoyのPodに転送されます。IstioのCRDであるGatewayは、「gke-system-gateway」という名称で作成されています。

```
$ k get gateway gke-system-gateway -n knative-serving
NAME                 AGE
gke-system-gateway   9d
```

「istio-ingress」Serviceは、「Type: LoadBalancer」として作成されます。　

```
$ k get svc istio-ingress -n gke-system
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                                      AGE
istio-ingress   LoadBalancer   10.244.10.185   xx.xx.xx.xx   15020:31341/TCP,80:32048/TCP,443:32217/TCP   9d
```

以下が、Envoy proxyのDeploymentになります。

```
$ k get deployment istio-ingress -n gke-system
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
istio-ingress   1/1     1            1           9d
```

##Istio Ingress GatewayのEnvoy Pod->Knativeのservice->Deployment
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/a1939b70-fe0a-c896-57a5-2e194a37615b.png)


Envoyは、IstioのCRDのVirtualServiceに設定されたルーティング情報を元にServceにHTTPリクエストを転送します。

以下はVSの抜粋になります。受け取ってるIstio Ingres Gatewayに紐付いてるgatewayは、「gke-system-gateway」なので、「my-service-00001-nex.default.svc.cluster.local」Servie配下のPodに転送されます。

```
$ k get vs my-service-ingress -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
  name: my-service-ingress
  namespace: default
spec:
  gateways:
  - knative-serving/cluster-local-gateway
  - knative-serving/gke-system-gateway
  - knative-serving/knative-ingress-gateway
  hosts:
  - my-service.default
  - my-service.default.example.com
  - my-service.default.svc
  - my-service.default.svc.cluster.local
   http:
  - headers:
      request:
        set:
          K-Network-Hash: 1ad4941b9a39ec9b0902e11dd7e829a46e50ff7b12c0592fa18a2e2ef4b7adec
    match:
    - authority:
        prefix: my-service.default.example.com
      gateways:
      - knative-serving/gke-system-gateway
      - knative-serving/knative-ingress-gateway
    retries:
      attempts: 3
      perTryTimeout: 900s
      retryOn: 5xx,connect-failure,refused-stream,cancelled,resource-exhausted,retriable-status-codes
    route:
    - destination:
        host: my-service-00001-nex.default.svc.cluster.local
        port:
          number: 80
      headers:
        request:
          set:
            Knative-Serving-Namespace: default
            Knative-Serving-Revision: my-service-00001-nex
      weight: 100
    timeout: 900s
```

以下が、knative serviceです。

```
$ k get ksvc my-service
NAME         URL                                     LATESTCREATED          LATESTREADY            READY   REASON
my-service   http://my-service.default.example.com   my-service-00001-nex   my-service-00001-nex   True
```

KnativeのCRDのrouteです。

```
k get route my-service
NAME         URL                                     READY   REASON
my-service   http://my-service.default.example.com   True
```

KnativeのCRDのconfigurationです。

```
$ k get configuration my-service
NAME         LATESTCREATED          LATESTREADY            READY   REASON
my-service   my-service-00001-nex   my-service-00001-nex   True
```

KnativeのCRDのrevisionです。

```
$ k get revision my-service-00001-nex
NAME                   CONFIG NAME   K8S SERVICE NAME       GENERATION   READY   REASON
my-service-00001-nex   my-service    my-service-00001-nex   1 
```

こちらは、最終的にHTTPリクエストを処理するPodをデプロイするためのDeploymentです。

```
$ k get deployment my-service-00001-nex-deployment
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
my-service-00001-nex-deployment   0/0     0            0           8d
```

#Cluster内からのアクセス
Cluser内からの通信は、「http://internal-my-service.default.svc.cluster.local」に対してHTTPリクエストを送信します。

```
curl http://internal-my-service.default.svc.cluster.local
```

HTTPのURLは、以下のコマンドで確認できます。

```
$ k get ksvc internal-my-service
NAME                  URL                                                    LATESTCREATED                   LATESTREADY                     READY   REASON
internal-my-service   http://internal-my-service.default.svc.cluster.local   internal-my-service-00001-sub   internal-my-service-00001-sub   True
```

##Client->KnativeのService->Cluster LocalのIstio Ingress Gateway
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/57e16e3d-cf3d-2b66-f51a-0071aa4c95ea.png)

ClientのPodからknativeのService用のエンドポイント（http://internal-my-service.default.svc.cluster.local）にHTTPリクエストを送信します。

「internal-my-service」Serviceは、Type: ExternalNameが指定されており、別名はとして「cluster-local-gateway.gke-system.svc.cluster.local」が指定されています。「cluster-local-gateway.gke-system.svc.cluster.local」は、Cluster内の通信用のIstio Ingress Gatewayです。「cluster-local-gateway.gke-system.svc.cluster.local」に紐付いてるEnvoyのPodにHTTPリクエストが転送されます。

```
$ k get gateway cluster-local-gateway -n knative-serving
NAME                    AGE
cluster-local-gateway   9d
```

```
$ k get svc cluster-local-gateway -n gke-system
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                    AGE
cluster-local-gateway   ClusterIP   10.244.1.243   <none>        15020/TCP,80/TCP,443/TCP   9d
```

以下が、Envoy proxyのDeploymentになります。

```
$ k get deployment cluster-local-gateway -n gke-system
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
cluster-local-gateway   1/1     1            1           9d
```

##Istio Ingress GatewayのEnvoy Pod-->KnativeのService->Deployment
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/1e5ceb8b-8ae2-3546-2a0d-dc481f316978.png)

以下はVSの抜粋になります。HTTPリクエストを受け取ってるIstio Ingres Gatewayに紐付いてるgatewayは、「cluster-local-gateway」なので、「internal-my-service-00001-sub.default.svc.cluster.local」Servie配下のPodに転送されます。

```
$ k get vs internal-my-service-ingress -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
  name: internal-my-service-ingress
  namespace: default
spec:
  gateways:
  - knative-serving/cluster-local-gateway
  hosts:
  - internal-my-service.default
  - internal-my-service.default.svc
  - internal-my-service.default.svc.cluster.local
  http:
  - headers:
      request:
        set:
          K-Network-Hash: 6580b5bf10ae2ca188fcc85f285ec4f7100910f803f2f6653a2f9d4f3e07a0f7
    match:
    - authority:
        prefix: internal-my-service.default
      gateways:
      - knative-serving/cluster-local-gateway
    retries:
      attempts: 3
      perTryTimeout: 900s
      retryOn: 5xx,connect-failure,refused-stream,cancelled,resource-exhausted,retriable-status-codes
    route:
    - destination:
        host: internal-my-service-00001-sub.default.svc.cluster.local
        port:
          number: 80
      headers:
        request:
          set:
            Knative-Serving-Namespace: default
            Knative-Serving-Revision: internal-my-service-00001-sub
      weight: 100
    timeout: 900s
```

以下が、knative serviceです。

```
$ k get ksvc internal-my-service
NAME                  URL                                                    LATESTCREATED                   LATESTREADY                     READY   REASON
internal-my-service   http://internal-my-service.default.svc.cluster.local   internal-my-service-00001-sub   internal-my-service-00001-sub   True
```

KnativeのCRDのrouteです。

```
k get route internal-my-service
NAME                  URL                                                    READY   REASON
internal-my-service   http://internal-my-service.default.svc.cluster.local   True
```

KnativeのCRDのconfigurationです。

```
$ k get configurations internal-my-service
NAME                  LATESTCREATED                   LATESTREADY                     READY   REASON
internal-my-service   internal-my-service-00001-sub   internal-my-service-00001-sub   True
```

KnativeのCRDのrevisionです。

```
$ k get revision internal-my-service-00001-sub
NAME                            CONFIG NAME           K8S SERVICE NAME                GENERATION   READY   REASON
internal-my-service-00001-sub   internal-my-service   internal-my-service-00001-sub   1            True
```

こちらは、最終的にHTTPリクエストを処理するPodをデプロイするためのDeploymentです。

```
$ k get deployment internal-my-service-00001-sub-deployment
NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
internal-my-service-00001-sub-deployment   0/0     0            0           43m
```

Podには、queue-proxyがサイドカープロキシとしてインジェクションされています。

```
$ k get deployment internal-my-service-00001-sub-deployment -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
-略-
        image: gke.gcr.io/knative/queue@sha256:5ca3d40a75c8f09b1d00c46a2bea7553e76a3c05fa842b5ada38b73331151c6d
        imagePullPolicy: IfNotPresent
        name: queue-proxy
        ports:
```