0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GCP】GAEからGKEへHTTPアクセスできた動作確認メモ

Last updated at Posted at 2021-01-10

はじめに

GCP (Google Cloud Platform)を使ったお仕事をさせていただいているおじさんです。
GAE (Google Application Engine)からGKE(Google Kubernetes Engine)にアクセスできたので、興奮冷めやらぬ?うちにメモを残しておきます。

動作確認メモ

作戦は以下の通りです。行う実装・設定は

(1) Google の解説にある [内部 TCP / UDP ロードバランサの使用]
(https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing) に従って、Kubernetes Cluster に外部IPを用意する
(2) 用意した外部IPにアクセスするための「サーバレスVPCコネクタ」を用意する
(3) GAEアプリケーションが用意した「サーバレスVPCコネクタ」を使えるようにする

用意したGAEがロードバランサを参照すると、GKEのポッドが返事をするのを確認します。

Cluster の外側にIPアドレスを設定(Load Balancer)

Kubernetes は Cluster の中でcontainer の管理を行います。その中にnode があり、ここにdeploy したり、container の数を増やしたり減らしたりします。一方で、service と呼ぶ仮想的なIPパケット通信を行うためのルータやスイッチのような役割を果たすものがあり、LoadBalancer も service の一つになります。

ここでは、Google の解説そのままですが、なぞった時のメモです。Cluster はひとつasia-northeast1 に作ってあり、そこで作業しています。

サンプルimage をデプロイ

以下のマニフェストをkubectl apply -f my-deployment.yamlします。このサンプルGoogle の解説にあるものそのままです。

my-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
spec:
  selector:
    matchLabels:
      app: hello
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"

確かにpod ができていることを確認します。


$ kubectl get deployments
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
hello-app   3/3     3            3           94s
$ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
hello-app-7f46745f74-24ldc   1/1     Running   0          82s
hello-app-7f46745f74-2xl25   1/1     Running   0          83s
hello-app-7f46745f74-z4hzc   1/1     Running   0          82s

Load Balancer の作成

つづいて、service (load balancer)を作ります。以下のマニフェストを kubectl apply -f my-service.yaml します。

my-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: ilb-service
  annotations:
    cloud.google.com/load-balancer-type: "Internal"
  labels:
    app: hello
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

service が作られていることを確認します。EXTERNL-IPが割り当てられていることを確認します。


$ kubectl get service ilb-service
NAME          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
ilb-service   LoadBalancer   10.79.247.115   10.146.0.9    80:32456/TCP   3m14s

$ gcloud compute forwarding-rules list --filter="loadBalancingScheme=INTERNAL"
NAME                              REGION           IP_ADDRESS
IP_PROTOCOL  TARGET
a91aceace48744715a2391849b778aeb  asia-northeast1  10.146.0.9  TCP     asia-northeast1/backendServices/a91aceace48744715a2391849b778aeb

$ gcloud compute backend-services describe a91aceace48744715a2391849b778aeb --region asia-northeast1
...(略)

サーバレスVPCコネクタ

ここでは、コンソール(GCPのWEBブラウザからの操作)で行いました。「VPCネットワーク」から「サーバレスVPCアクセス」を選択します。
ここではに従い、深いことは何も考えず、default を選択して、以下のように作りました。

image.png

ここでネットワークというのがよくわかりませんでした。これはこのプロジェクト?で使われているdefault のネットワークのようで、以下のようなzone に対応したアドレスの総体のようでした。今回使用しているのは、asia-northeast1 なのですが、このアドレス空間(subnet)は10.146.0.0/20 で、さきほど作成したClustger の LoadBalancer は 10.146.0.9 がEXTERNAL IPとして割り振られていました。というわkで、何となく、GCPのあぷりから 10.146.0.9 にアクセスできそうな気がしてきます。

一方で、「サーバレス」なGAEはまた別のネットワークにいるのかもしれませんが、理解できていないことを先に書いておきます。

GAEからVPCコネクタを経由してCluster の Load Balancer にアクセスする

書くと長いですが、サンプルはごく簡単です。これもGoogle のサンプルをを少し修正しただけです。

ありものを修正して使います。コードに直書きです。同じディレクトリに3つのファイルを用意します。

├── app.yaml
├── main.py
└── requirements.txt

VPC コネクタの利用

app.yamlに2行記述します。

app.yaml
runtime: python37
vpc_access_connector:
  name: projects/PROJECT_ID/locations/asia-northeast1/connectors/CONNECTEOR_NAME

接続テスト用flask サーバ

ずばり、HTTP GET が来たら、先ほどのCluster のEXTERNAL IPにHTTP リクエストを出して、その結果を返す、というものです。

main.py

from flask import Flask
import requests

app = Flask(__name__)

@app.route('/')
def hello():
    try:
        r = requests.get('http://10.146.0.9:80/')
        print(r)
        print(r.status_code)
        print(r.headers)
        print(r.content)
        return "Hello World! response: (OK!)" + r.content.decode('utf-8')
    except Exception as e:
        return str(e)

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True)

Python3.8でrequests==2.25.1 としたらエラーが出たので、適当に変更しています。

requirements.txt
Flask==1.1.2
requests>=2.22.0

これらが置いてあるディレクトリで

gcloud app deploy 

します。

動作確認

ブラウザ

いざ、Chromeに https://PROJECT_ID.an.r.appspot.com/ を入れてみると、、、(GAE のサービス名が default のままの場合)

Hello World! response: (OK!)Hello, world! Version: 2.0.0 Hostname:
hello-app-7f46745f74-24ldc

と無事に表示されました。

GAEのログ

GAEのログでもHTTP 200を確認できます。

$ gcloud app logs tail -s default
...
2021-01-10 15:27:31 default[20210111t002221]  "GET / HTTP/1.1" 200
2021-01-10 15:27:31 default[20210111t002221]  <Response [200]>
2021-01-10 15:27:31 default[20210111t002221]  200
2021-01-10 15:27:31 default[20210111t002221]  {'Date': 'Sun, 10 Jan 2021 15:27:31 GMT', 'Content-Length': '66', 'Content-Type':'text/plain; charset=utf-8'}
2021-01-10 15:27:31 default[20210111t002221]  b'Hello, world!\nVersion: 2.0.0\nHostname: hello-app-7f46745f74-2xl25\n'

良かった。。。本当に、良かった。

おわりに

GAEからGKEとHTTP通信できることを確認しました。

  • Kubernetes Cluster にService(load balancer)を用意すること
  • GAEはサーバレスVPCコネクタに接続すること

がポイントのようでした。とりあえず動きましたが、VPCやアドレス空間をまだよく理解できていません。だれがルータなのか。。

情報源

もとは、この記事を参考にすれば簡単にできるだろう、と思っていました。

しかし、実際に自分で動かそうとテストしようとしても、できません。テスト用のプログラムが良くないのか、設定が良くないのか切り分けができず、数日を使ってしまいました。結果として、設定が良くなかったです。理由は以下のように考えています。

  • 自分が作ったdeployment に対して用意したservice が適応されなかった。用意したservice のマニフェストのselector などでdeployment を参照するようになっていなかったのでは。
  • また、この例では「限定公開のクラスタ」ということなので、独自に作ったネットワークをりようしていましたが、自分はdefault のものを利用していたので、azia-northeast1 にある10.146.....が外部IPになりましたが、サンプルでは、192.168... となっていました。これ自体は問題にはならないと思いますが。

以下も何度も?眺めました。

TODO

とりあえず動いたレベルなので、もう少ししくみをよく理解したい。。。

  • Service の Load Balancer のEXTERNAL IPはどこで決められるのか。これ、CI/CDにくこむときは、毎回このservice.yaml も実行することになるのかな。
  • private のネットワークにクラスタを作っている記事があった。何故だろう。
  • サーバレスVPCコネクタの役割、とGAEが属するネットワークについての情報。

あと、きじによると、Cloud DNSでCluseter のExternal IPを登録すると名前でアクセスできるようになる、というがあるので、それも合わせて試してみたい。

真夜中だぞ、、、体に悪いぞ、、、寝よう。
(2021/01/11)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?