ビビリフクロウの足跡

いつもお世話になっているインターネットへの恩返し

Rancher Submarinerを動かしてみた

3/12にRancher公式ブログで発表された、「Submariner」という新しいOSSを動かしてみましたので、軽く所感を書きます。

Submarinerってなに?

複数のKubernetesクラスタのPodネットワークおよびServiceネットワークを繋げるプロダクトです。NodePortサービスを作って外部公開せずとも、複数Kubernetesクラスタ内のPod同士で通信することが可能になります。

公式では以下の用途にマッチするとしています。

利用手順概要

ここからは私が試した手順の概要を記載いたします。といっても公式GitHubが秀逸なので、特に面白い内容ではないですが。。。

submarinerを試すには最低限3つのKubernetesクラスタが必要です。2つは実際に接続したいクラスタ「west」と「east」、残りの1つは「broker」という、westとeastのネットワーク情報を同期する仲介役として動きます。 クラスタ要件として以下が求められるので、ユーザが自由に制御可能なバニラKubernetesで試すのがおすすめです。

  * 任意のクラスタ間でpodネットワークcidrおよびserviceネットワークcidrおよびcluster local domainが異なること
  * 任意のクラスタ間でインターネットを通じて直接通信できるか、同じネットワークに所属していること
  • brokerクラスタに対し、以下のコマンドを実行
# helmの初期化
kubectl -n kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:tiller
helm init --service-account tiller
helm repo update

# submariner-brokerのインストール
SUBMARINER_BROKER_NS=submariner-k8s-broker
helm install submariner-latest/submariner-k8s-broker \
--name ${SUBMARINER_BROKER_NS} \
--namespace ${SUBMARINER_BROKER_NS}
SUBMARINER_BROKER_URL=$(kubectl -n default get endpoints kubernetes -o jsonpath="{.subsets[0].addresses[0].ip}:{.subsets[0].ports[0].port}")
SUBMARINER_BROKER_CA=$(kubectl -n ${SUBMARINER_BROKER_NS} get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='${SUBMARINER_BROKER_NS}-client')].data['ca\.crt']}")
SUBMARINER_BROKER_TOKEN=$(kubectl -n ${SUBMARINER_BROKER_NS} get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='${SUBMARINER_BROKER_NS}-client')].data.token}"|base64 --decode)
  • IPSec通信するための事前共有キーの作成
SUBMARINER_PSK=$(cat /dev/urandom | LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1)
  • westクラスタに対し、以下のコマンドを実行
# eastクラスタに対する通信のゲートウェイとなるノードにラベル付け
kubectl label node <GATEWAY_NODE> "submariner.io/gateway=true"

# helmの初期化
kubectl -n kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:tiller
helm init --service-account tiller

# submarinerのインストール
helm install submariner-latest/submariner \
--name submariner \
--namespace submariner \
--set ipsec.psk="${SUBMARINER_PSK}" \
--set broker.server="${SUBMARINER_BROKER_URL}" \
--set broker.token="${SUBMARINER_BROKER_TOKEN}" \
--set broker.namespace="${SUBMARINER_BROKER_NS}" \
--set broker.ca="${SUBMARINER_BROKER_CA}" \
--set submariner.clusterId="west-cluster" \
--set submariner.clusterCidr="<westクラスタのpod network cidr>" \
--set submariner.serviceCidr="<westクラスタのservice network cidr>" \
--set submariner.natEnabled="false"
  • eastクラスタに対し、以下のコマンドを実行
# westクラスタに対する通信のゲートウェイとなるノードにラベル付け
kubectl label node <GATEWAY_NODE> "submariner.io/gateway=true"

# helmの初期化
kubectl -n kube-system create serviceaccount tiller
kubectl create clusterrolebinding tiller \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:tiller
helm init --service-account tiller

# submarinerのインストール
helm install submariner-latest/submariner \
--name submariner \
--namespace submariner \
--set ipsec.psk="${SUBMARINER_PSK}" \
--set broker.server="${SUBMARINER_BROKER_URL}" \
--set broker.token="${SUBMARINER_BROKER_TOKEN}" \
--set broker.namespace="${SUBMARINER_BROKER_NS}" \
--set broker.ca="${SUBMARINER_BROKER_CA}" \
--set submariner.clusterId="east-cluster" \
--set submariner.clusterCidr="<eastクラスタのpod network cidr>" \
--set submariner.serviceCidr="<eastクラスタのservice network cidr>" \
--set submariner.natEnabled="false"
  • westクラスタ上にnginx deploymentとserviceを作る(動作確認)
kubectl run nginx --image nginx
kubectl expose deploy nginx --port 80
  • 作成したサービスのIPを取得(動作確認)
NGINX_SERVICE_IP=$(kubectl get svc nginx -o jsonpath="{.spec.clusterIP}")
kubectl run busybox --restart=Never --image busybox:1.28 -- sleep 3600 
kubectl exec -it busybox -- wget -q -O - ${NGINX_SERVICE_IP}

無事、nginxのスタートページが表示されればOKです。

まとめ

submarinerをざっと試してみましたが、そもそもKubernetesクラスタはプロジェクトやチームなど意味あるかたまりで分割されるであろうことから、そもそもpodネットワークやserviceネットワークをつなぎたい需要ってそんなにあるのかな? と疑問に思っています。 Rancherの提示している使い方以外に使えるとすれば、PVのクラスタ間移行なんかには便利に使える気はしますね。

現時点ではクラスタ超えのDNSには対応していないので、クラウドネイティブに使うとなるとちょっと物足りないところ。今後の発展に期待です!