GKE(Google Kubernetes Engine)は、HTTPSサービスをKubernetes Gateway/Ingressを用いて公開できます。
非HTTPのサービスを公開するには、
外部TCP/UDPネットワーク負荷分散を別途構築しServiceへのルーティングを設定します。
GKEは1クラスタで共用できますが、TCPロードバランサは公開するポートごとに1つずつ追加する構成になります。
また、HTTPSサービスであってもGCPの付加機能を利用したい場合には手動構成が必要になる場合があります。
NEGの作成
リクエストを処理するNetwork Endpoint Group(NEG)までは、kubernetesで作成できます。
Serviceにcloud.google.com/neg
アノテーションを追加すると、GCPのスタンドアロンNEGが作成されます。
対応するDeploymentなどのPodはごく普通の構成で動作します。
apiVersion: v1
kind: Service
metadata:
name: mail
labels:
name: mail
annotations:
cloud.google.com/neg: '{"exposed_ports": {"25": {"name": "mail"}}}'
spec:
type: ClusterIP
selector:
name: mail
ports:
- port: 25
targetPort: mail-smtp
リソース状況は、kubectl get ServiceNetworkEndpointGroups [-o yaml <NEG name>]
コマンドで確認できます。
NEGが不要になった場合にはkubectl delete
でServiceを削除すると同時に削除されます。
exposed_ports
アノテーションのポート番号には、ロードバランサーがアクセスする番号を指定する必要があります。
TCPロードバランサーの場合は公開するポート番号、httpsロードバランサーの場合には443または80です。
exposed_ports
にはspec.ports.[].port
の番号を指定するため、Podが公開ポートと異なるポートをサーブしている場合にはtargetPort
を用いて変換する必要があります。
NEG作成エラー
なお、NEGはゾーン内で同名オブジェクトを重複作成できず、ゾーンが異なる場合には重複可能です。ゾーンはk8sクラスタのロケーションで決まります。
重複など作成エラー時には、k8s Serviceは作成されるもののNEGが追加されない、という分かりづらい挙動になります。
kubectl describe service <service-name>
を実行することでエラーログを確認できます。Events
欄の具体的なメッセージを解釈することが重要です。NEGの作成に失敗している場合にも、ログレベルはWARNING
にとどまります。
ロードバランサの作成
HTTPサービスにはingressがあり、GKE ingressはコンテナネイティブ負荷分散に対応しています。
一方、TCPサービスには対応するKubernetesサービスがなく、gcloud compute
コマンドで手動構築します。
依存関係に沿って health check, backend service, TCP proxy, forwarding rule の順で作成します。
Backend service作成
$ gcloud compute health-checks create tcp <tcp-basic-check> --use-serving-port
--use-serving-port
はサービスのポート設定を参照して監視します。
$ gcloud compute backend-services create <gke-bs> \
--global --protocol TCP \
--global-health-checks --health-checks <tcp-basic-check> \
--timeout 5m
TCPプロキシがglobalスコープのサービスであるため、backend serviceは--global
で作成します。
$ gcloud compute backend-services add-backend <gke-bs> --global \
--network-endpoint-group=<mail> --network-endpoint-group-zone=asia-northeast1-a \
--balancing-mode CONNECTION --max-connections-per-endpoint 10
backend serviceのリージョン(global)に加えてNEGのzoneも指定する必要があります。
TCPプロキシ作成
$ gcloud compute target-tcp-proxies create <gke-lb-proxy> --backend-service <gke-bs> [--proxy-header PROXY_V1]
IP保持のためにproxyプロトコルを使いたい場合には、target-tcp-proxies
作成オプションでPROXY_V1
を指定します。
HTTPSプロキシ作成
HTTPSサービスはIngressなどのk8s Gatewayで構築でき、基本的な構成にはgcloud
によるネットワーク構築は不要です。
ロードバランサが提供する独自機能を利用したい場合には、target-tcp-proxy
に換えてHTTPS向けにtarget-https-proxy
, url-maps
, ssl-certificates
のセットを作成します。
HTTPSロードバランサのオブジェクトは複雑であるため、とくに初回はWebコンソールから作成した方が手軽でしょう。
url-maps
のルーティング先がbackend-services
を指す構成となり、NEG経由で各k8s Serviceに到達します。
health-checks
とbackend-services
, forwarding-rules
はTCPプロキシと共通です。
フォワーディング・ルール作成
$ gcloud compute forwarding-rules create <tcp-gke-forwarding-rule> --global \
--target-tcp-proxy <gke-lb-proxy> --ports 25 --address <some-static-ip>
--address
オプションは、事前に確保しておいた静的IPを指定します。複数の転送ルールを作成する際、ポートが重複しなければ同一IPに設定できます。
ルーティングオブジェクトの管理
target-tcp-proxy
, forwarding-rules
, backend-services
, health-checks
の4種はGCP独自オブジェクトです。
これらをkubernetesのようにコードとして管理するにはTerraformを利用するのが手軽です。
Terraformerを利用することで、gcloud
コマンドで作成したオブジェクトをエクスポートできます。
クラスタ移行
上の手順でグローバルの外部TCPプロキシロードバランサを作成した場合、構築した4つのGCPオブジェクトのうちbackend-services
が参照するNEGを変更するだけでクラスタ移行が完了します。
プロキシはグローバルにサービス提供しているためそのまま流用でき、IPアドレスも変わりません。
- k8sの新クラスタを作成し、ServiceやPod群をデプロイ
- Serviceマニフェストのアノテーションにより、NEGは新クラスタのゾーンに自動作成
- クラスタを同一ゾーンに作成すると、NEGの重複エラーになる点に注意。アノテーションの編集が必要
backend-services
の設定変更- gcloudまたはterraformを用いる
health-checks
はグローバルオブジェクトであり、同一サービスならゾーンが変わっても流用できる
terraformを使う場合、backendServices
のresource.backend.group
のURIを書き換えることで、backendServicesが指すNEGを変更できます。
次の例では、zones
以下を新クラスタのロケーションに合わせて変更します(該当箇所のみ抜粋)。
resource "google_compute_backend_service" "tfer--mail" {
backend {
group = "https://www.googleapis.com/compute/v1/projects/<some-project-name>/zones/asia-northeast1-b/networkEndpointGroups/<NEG-name>"
}
}
編集できたら、標準手順に沿ってterraform plan
で確認のうえterraform apply
で設定できます。
この過程でhealth-checks
も流用します。
ただし、構築時のgcloud
オプションしだいでリージョンTCPロードバランサも作成可能であるため、着手前に構成の特定は必須です。サービスのバリエーションについては
GCPロードバランサーの分類で解説しています。
リージョンTCPロードバランサの場合には、全体的に再構築が必要で、IPアドレスも変わるため最終的にDNS設定変更で切り替えることになります。
また、ネットワーク以外の総合的な指針は GKEクラスタ移行のホワイトペーパーで解説しています。
Chuma Takahiro