見出し画像

GKEの外部IPアドレスを静的IPアドレスにしてみた


はじめに

Acompanyプロダクト部門 DCR チームの高橋です。本記事は「#アカンクリスマスアドベントカレンダー2023」17日目の記事となります。

本記事では、QuickMPCをGoogle Kubernetes Engine (以下、GKE)上にデプロイしようとした際に発生した問題と解決策について記載しようと思います。

QuickMPCとは?

QuickMPCはPETs(Privacy-enhancing technologies)のひとつであるSMPC(Secure Multiparty Computation)の実用的なエンジンです。
弊社Acompanyが公開しているOSSであり、QuickMPCを用いることでClient側は以下のような短いPythonスクリプトで情報理論的安全性を有する暗号化手法によって秘匿化しながらデータ連携をすることが可能になります。

import pandas as pd
import quickmpc
import quickmpc.pandas as qpd

""" Step 1. QMPCの設定 """
""" 計算サーバのアドレスを指定する """
qmpc: quickmpc.QMPC = quickmpc.QMPC(
    ["<party1-address>","<party2-address>"]
)

""" Step 2. シェア送信 """
data_dir: str = "../data/"
df1: pd.DataFrame = qpd.read_csv(f"{data_dir}/data-join1.csv",
                                index_col="id")
df2: pd.DataFrame = qpd.read_csv(f"{data_dir}/data-join2.csv",
                                index_col="id")
sdf1: qpd.ShareDataFrame = qmpc.send_to(df1)
sdf2: qpd.ShareDataFrame = qmpc.send_to(df2)

""" Step 3. join"""
print(sdf1.join(sdf2).to_data_frame())

QuickMPCのデプロイ

コード内(Step 1)に記載があるようにQuickMPCでは2台以上の計算サーバを構築する必要があります。

今回は計算サーバとして2台、補助サーバとして1台の計3台のサーバをGKEで構築します。
構築は以下の手順で行います。(細かい構築手順は省きます)

  1. 3台のGKE Standard Clusterを構築する

  2. 各サーバのIPアドレスをQuickMPCの設定ファイルに記載する

  3. QuickMPC構築用のマニフェストを作成し各Clusterにapplyする

上記の手順でデプロイすることができました!…で終わればよかったのですが。

GKEの機能ではNodeに静的IPアドレスを付与できない

先ほどの手順でデプロイが完了し、実際に上に記載のPythonスクリプトが正常に実行できることを確認しました。
しかし、GKEのNodeに付与されているIPアドレスはエフェメラル外部IPアドレスと言われる一時的なIPアドレスであり、Clusterアップデートなど何かしらの原因でNodeが再起動されるとIPアドレスが変更されてしまいます。
すると構築手順のステップ2で設定ファイルに記載していたIPアドレスと異なるため正常に通信が行えなくなってしまいます。
再度動かすためには設定ファイルを更新の上、applyしなおす必要があります。

そのため外部からアクセスできるアドレスを固定化する必要があります。

私が把握しているものでアドレスを固定する方法は以下の3通りあります。

  1. Ingressを使う

  2. LoadBalancerを使う

  3. KubeIPを使う

方法1,2はそれぞれ以下の理由で没にし、"3. KubeIPを使う"で進めることにしました。

  1. QuickMPCはportベース、Ingressはpathベースでのルーティングのため今回は対象外とした

  2. LoadBalancerでは1Serviceにつき1IPが必要になるが、QuickMPCは1台の計算サーバにつき4つのServiceが必要であり、4つのIPを管理する必要があるため今回は対象外とした

KubeIPって何?

KubeIPとはDoiT International社が提供しているOSSで、GKEのNodeのIPアドレスをあらかじめ取得しておいた静的IPアドレスに変更することができます。
KubeIPは常に実行されるため、Nodeが再起動されたとしても再度同じ静的IPアドレスに変更してくれます。
そのため、KubeIPを用いることで上記の問題を解決することができます。

KubeIPの使い方

基本的にREADME.mdに記載の通りです。

※ 私が使用した時点ではKubeIP v1しか公開されていなかったため以下ではv1での使い方を記載します。

事前準備

KubeIPをcloneしてくる

$ git clone https://github.com/doitintl/kubeip
$ cd kubeip
# KubeIP v1のbranchに切り替える
$ git checkout v1-main

環境変数を設定する
構築用の環境変数を設定します。

$ export GCP_REGION=<GKEを立ち上げたregion>
$ export GCP_ZONE=<GKEを立ち上げたzone>
$ export GKE_CLUSTER_NAME=<GKE名>
$ export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
$ export KUBEIP_NODEPOOL=<固定IPを付与したいnodepool名>
$ export KUBEIP_SELF_NODEPOOL=<kubeipを走らせるnodepool名>

必要な権限が付与されたGCPサービスアカウントを作成する
以下のコマンドを実行し必要な権限を付与したGCPサービスアカウントを作成します。

$ gcloud iam service-accounts create kubeip-service-account --display-name "kubeIP"
$ gcloud iam roles create kubeip --project $PROJECT_ID --file roles.yaml
$ gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member=serviceAccount:kubeip-service-account@$PROJECT_ID.iam.gserviceaccount.com \
    --role=projects/$PROJECT_ID/roles/kubeip \
    --condition=None

また以下のコマンドを実行しサービスアカウントキーを取得します。

$ gcloud iam service-accounts keys create key.json \
    --iam-account kubeip-service-account@$PROJECT_ID.iam.gserviceaccount.com

取得したサービスアカウントキーを元にSecretを作成します。

$ kubectl create secret generic kubeip-key --from-file=key.json -n kube-system

静的IPアドレスを取得しラベル付けを行う

以下のコマンドを実行し静的IPアドレスを取得します。

$ gcloud compute addresses create <任意のIPアドレス名> --project=$PROJECT_ID --region=$GCP_REGION

そして以下のコマンドを実行し静的IPアドレスにCluster名をラベル付けします。
※ KubeIPは自身のCluster名のラベルがついたIPアドレスをNodeに付与します。

$ gcloud beta compute addresses update <任意のIPアドレス名> --update-labels kubeip=$GKE_CLUSTER_NAME --region $GCP_REGION

KubeIPの設定ファイルを修正する

KubeIPの設定ファイルを修正します。
以下のコマンドを実行します。

$ sed -i -e "s/reserved/$cluster_name/g; s/default-pool/$KUBEIP_NODEPOOL/g" deploy/kubeip-configmap.yaml
$ sed -i -e "s/pool-kubip/$KUBEIP_SELF_NODEPOOL/g" deploy/kubeip-deployment.yaml

# (任意) KubeIPの処理の実行間隔をKUBEIP_TICKERで指定します。
# defaultでは5分間隔ですが1分間隔に変更しています。
$ sed -i -e "s/KUBEIP_TICKER: \"5\"/KUBEIP_TICKER: \"1\"/g" deploy/kubeip-configmap.yaml

KubeIPを立ち上げる

以下のコマンドでKubeIPを立ち上げます。

$ kubectl apply -f deploy/

静的IPアドレスが紐付けられていることを確認する

上記の手順を行いKUBE_TICKER分後に確認すると静的IPアドレスが紐付けらていることを確認できます。

KubeIP立ち上げ前
KubeIP立ち上げ後
KubeIPにより外部IPアドレスがエフェメラルから静的IPアドレスに変更されています

最後に宣伝

Acompanyはプライバシー保護とデータ活用の両立を追求するデータクリーンルームをベースに、次なるデータ市場を拓くプラットフォームを展開しています!

Acompanyでは一緒に困難を乗り越えてくれる仲間を募集しています!


この記事が気に入ったらサポートをしてみませんか?