東京・大阪のRed Hat OpenShift on IBM CloudをSubmarinerでIPsec VPN接続する

# 目的

KubernetesやOpenShiftクラスターが2つあり、クラスタをまたがってPodどうしが通信したい場合、通常はそれぞれのクラスターでRouterやIngressを使ってServiceを公開し、それを利用してアクセスをすることになります。Submarinerを使うと、クラスタ間でIPsec VPNが張られ、あたかもクラスター内でServiceやPodにアクセスしているかのように、リモートのクラスター内のServiceやPodにアクセスが可能になります。

https://submariner.io/

今回はRed Hat OpenShift on IBM Cloud（ROKS）を東京リージョンと大阪リージョンそれぞれに建てて、Submarinerを検証してみます。

# 手順

## ROKSクラスターのオーダー（東京・大阪）

東京と大阪でROKSクラスターをオーダーします。このときの注意点として、次の3点があります。

* VPCサブネットが重複しないこと
* Podサブネットが重複しないこと
* Serviceサブネットが重複しないこと

VPCサブネットは設定時に東京・大阪のVPCで重複しないようにしてください。

PodサブネットとServiceサブネットは、IBM Cloudコンソールからオーダーするとデフォルト値が適用されて重複する可能性があります。CLIからオーダーするとレンジを明示できますので、少なくとも片方のクラスターはCLIでレンジを指定して重複しないようにしてください。

東京にすでにクラスターが存在している場合、次のコマンドでPodサブネットとServiceサブネットを確認することができます。

```
$ oc get networks.config.openshift.io cluster -o yaml
...
spec:
  clusterNetwork:
  - cidr: 172.17.128.0/18  # Podサブネット
    hostPrefix: 23
  networkType: Calico
  serviceNetwork:
  - 172.21.0.0/16          # Serviceサブネット
...
```

例えば、大阪のクラスターは次のように作成します。

```
$ ibmcloud oc cluster create vpc-gen2 --flavor bx2.16x64 --name ${大阪クラスタ名} --subnet-id ******** --vpc-id ******** --zone jp-osa-1 --cos-instance ********  --pod-subnet 172.17.192.0/18 --service-subnet 172.22.0.0/16 --version 4.8
.11_openshift --workers 2
$ ibmcloud oc zone add vpc-gen2 -c ${大阪クラスタ名} --subnet-id ******** --worker-pool default --zone jp-osa-2
$ ibmcloud oc zone add vpc-gen2 -c ${大阪クラスタ名} --subnet-id ******** --worker-pool default --zone jp-osa-3
$ ibmcloud oc worker-pool resize -c ${大阪クラスタ名} --size-per-zone 1 --worker-pool default
```

> ROKSをCLIでオーダーする場合、各ゾーン最低2台を指定しないとエラーになります。今回は各ゾーン1台*3ゾーンにしたかったので、上記のように一旦2*3=6台構成にした後で1*3=3台構成に縮小しています。

私の環境では次のようになります。

 |東京|大阪
---|---|---
VPCサブネット|10.244.2.0/24|10.248.0.0/24
Podサブネット|172.17.128.0/18|172.17.196.0/18
Serviceサブネット|172.21.0.0/16|172.22.0.0/16


## 東京・大阪間Transit Gatewayの有効化

東京・大阪間のVPCがIBM Cloudのプライベートネットワークで通信できるよう、Transit Gatewayを有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/e65dbce2-b06f-8d4c-bc69-42a5f8f0a91a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/9da8d696-ae92-ba4b-2801-82d52489cfdf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/62098f3f-48c5-5140-3425-441389a9abc7.png)

## 作業用kubeconfigの作成（作業PC）

ここから先は東京・大阪でそれぞれ作業をしますので、自分がどちらのクラスタで作業をしているか間違わないようにする必要があります。それぞれkubeconfigを生成して都度指定しながら作業をすると間違いにくいです。

```gen-kubeconfig.sh
#!/usr/bin/env bash

export IBMCLOUD_API_KEY=********

TOK_RG=*****
TOK_CLUSTER=********
OSA_RG=*****
OSA_CLUSTER=********

function get-cluster-id {
  ibmcloud oc cluster get -c ${1} --output json | jq -r .id
}

ibmcloud login -r jp-tok -g ${TOK_RG}
KUBECONFIG=./tok.config ibmcloud oc cluster config -c ${TOK_CLUSTER}
KUBECONFIG=./tok.config oc login -u apikey -p ${IBMCLOUD_API_KEY}
KUBECONFIG=./tok.config oc config delete-context ${TOK_CLUSTER}/$(get-cluster-id ${TOK_CLUSTER})

ibmcloud login -r jp-osa -g ${OSA_RG}
KUBECONFIG=./osa.config ibmcloud oc cluster config -c ${OSA_CLUSTER}
KUBECONFIG=./osa.config oc login -u apikey -p ${IBMCLOUD_API_KEY}
KUBECONFIG=./osa.config oc config delete-context ${OSA_CLUSTER}/$(get-cluster-id ${OSA_CLUSTER})
```

## Submarinerのインストールと構成

### Submariner CLIのインストール（作業PC）

作業PCにCLIをインストールします。

```
$ curl -Ls https://get.submariner.io | bash
Installing subctl version latest
  OS detected:           linux
  Architecture detected: amd64
  Download URL:          https://github.com/submariner-io/releases/releases/download/v0.10.1/subctl-v0.10.1-linux-amd64.tar.xz

Downloading...
subctl-v0.10.1-linux-amd64 has been installed as /home/teruq/.local/bin/subctl
This provides subctl version: v0.10.1

$ subctl completion bash | sudo tee /etc/bash_completion.d/subctl >/dev/null
$ source /etc/bash_completion.d/subctl
```

### Calico CLIのインストール（作業PC）

```
$ curl -o calicoctl -O -L  "https://github.com/projectcalico/calicoctl/releases/download/v3.20.2/calicoctl" 
$ sudo cp calicoctl /usr/local/bin/
$ sudo chmod 755 /usr/local/bin/calicoctl
```

## Calico

### IPPoolの作成


https://submariner.io/operations/deployment/calico/

東京と大阪それぞれのIPレンジを下記のように記述します。

```ippool-tok.yaml
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: service-tok
spec:
  cidr: 172.21.0.0/16
  natOutgoing: false
  disabled: true

---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: pod-tok
spec:
  cidr: 172.17.128.0/18
  natOutgoing: false
  disabled: true
```

```ippool-osa.yaml
---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: service-osa
spec:
  cidr: 172.22.0.0/16
  natOutgoing: false
  disabled: true

---
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: pod-osa
spec:
  cidr: 172.17.192.0/18
  natOutgoing: false
  disabled: true
```

それぞれのクラスタに``相手のIPPool``を登録します。つまり、東京のクラスタには大阪のレンジを、大阪のクラスタには東京のレンジを登録します。

```
$ DATASTORE_TYPE=kubernetes KUBECONFIG=./tok.config calicoctl create -f ippool-osa.yaml --allow-version-mismatch
Successfully created 2 'IPPool' resource(s)
```

```
$ DATASTORE_TYPE=kubernetes KUBECONFIG=./osa.config calicoctl create -f ippool-tok.yaml --allow-version-mismatch
Successfully created 2 'IPPool' resource(s)
```

### ノードにラベル付与

> 競合が発生するとsubmariner-operatorに次のログが出力されます。
> E1014 15:09:03.590563       1 submariner_controller.go:204] controller_submariner "msg"="failed to update the Submariner status" "error"="Operation cannot be fulfilled on submariners.submariner.io \"submariner\": the object has been modified; please apply your changes to the latest version and try again" "Request.Name"="submariner" "Request.Namespace"="submariner-operator"

```
$ KUBECONFIG=./tok.config oc label nodes --all submariner.io/gateway=true
node/10.244.130.28 labeled
node/10.244.2.36 labeled
node/10.244.66.34 labeled

$ KUBECONFIG=./osa.config oc label nodes --all submariner.io/gateway=true
node/10.248.0.10 labeled
node/10.248.128.10 labeled
node/10.248.64.11 labeled
```

### Submariner Brokerのインストール（東京）

東京クラスターにSubmariner Brokerをインストールします。

```
$ subctl deploy-broker --kubeconfig ./tok.config
 ✓ Setting up broker RBAC
 ✓ Deploying the Submariner operator
 ✓ Created operator CRDs
 ✓ Created operator namespace: submariner-operator
 ✓ Created operator service account and role
 ✓ Updated the privileged SCC
 ✓ Created lighthouse service account and role
 ✓ Updated the privileged SCC
 ✓ Created Lighthouse service accounts and roles
 ✓ Deployed the operator successfully
 ✓ Deploying the broker
 ✓ The broker has been deployed
 ✓ Creating broker-info.subm file
 ✓ A new IPsec PSK will be generated for broker-info.subm
```

Podが起動したことを確認します。

```
$ KUBECONFIG=./tok.config oc get pods -n submariner-operator
NAME                                   READY   STATUS    RESTARTS   AGE
submariner-operator-7987f7ccfb-8fdml   1/1     Running   0          49s
[teruz@t14s20 odf]$
```

### クラスターの参加（東京）

東京クラスターをSubmarinerに参加させます。``--clusterid``は``tok``とします。

```
$ subctl join --clusterid tok broker-info.subm --cable-driver vxlan --kubeconfig ./tok.config
* broker-info.subm says broker is at: https://c100-e.jp-tok.containers.cloud.ibm.com:*****
* There are 3 labeled nodes in the cluster:
  - 10.244.130.28
  - 10.244.2.36
  - 10.244.66.34
        Network plugin:  Calico
        Service CIDRs:   [172.21.0.0/16]
        Cluster CIDRs:   [172.17.128.0/18]
 ✓ Discovering network details
 ✓ Validating Globalnet configurations
 ✓ Discovering multi cluster details
 ✓ Deploying the Submariner operator
 ✓ Created Lighthouse service accounts and roles
 ✓ Creating SA for cluster
 ✓ Deploying Submariner
 ✓ Submariner is up and runnin
```

```
$ subctl join --clusterid tok broker-info.subm --kubeconfig ./tok.config
* broker-info.subm says broker is at: https://c100-e.jp-tok.containers.cloud.ibm.com:30677
? Which node should be used as the gateway? 10.244.2.36
        Network plugin:  Calico
        Service CIDRs:   [172.21.0.0/16]
        Cluster CIDRs:   [172.17.128.0/18]
 ✓ Discovering network details
 ✓ Validating Globalnet configurations
 ✓ Discovering multi cluster details
 ✓ Deploying the Submariner operator
 ✓ Created Lighthouse service accounts and roles
 ✓ Creating SA for cluster
 ✓ Deploying Submariner
 ✓ Submariner is up and running
```

Podを確認すると、submariner-lighthouse-agentがErrorになっています。

```
$ KUBECONFIG=./tok.config oc get pods -n submariner-operator
NAME                                             READY   STATUS    RESTARTS   AGE
submariner-gateway-29qtp                         1/1     Running   0          26s
submariner-gateway-9l52q                         1/1     Running   0          26s
submariner-gateway-hcgr5                         1/1     Running   0          26s
submariner-lighthouse-agent-6898c46575-5bssg     0/1     Error     2          22s
submariner-lighthouse-coredns-74bfcb6f65-99njs   1/1     Running   0          19s
submariner-lighthouse-coredns-74bfcb6f65-m2x5p   1/1     Running   0          19s
submariner-operator-7987f7ccfb-2dfb6             1/1     Running   0          74m
submariner-routeagent-4js8k                      1/1     Running   0          22s
submariner-routeagent-9lzg4                      1/1     Running   0          22s
submariner-routeagent-p6fmf                      1/1     Running   0          22s
```

ログを確認すると、APIサーバのTLS証明書の検証に失敗しているようです。

```
$ KUBECONFIG=./tok.config oc logs submariner-lighthouse-agent-6898c46575-5bssg -n submariner-operator
I1013 01:31:57.083392       1 main.go:70] Arguments: [/usr/local/bin/lighthouse-agent -alsologtostderr -v=2]
I1013 01:31:57.083442       1 main.go:71] AgentSpec: {tok submariner-operator false}
W1013 01:31:57.083499       1 client_config.go:608] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
I1013 01:31:57.442060       1 main.go:98] Starting submariner-lighthouse-agent {tok submariner-operator false}
F1013 01:31:57.505801       1 main.go:115] Failed to create lighthouse agent: cannot access the API server "https://c100-e.jp-tok.containers.cloud.ibm.com:******": Get "https://c100-e.jp-tok.containers.cloud.ibm.com:30677/apis/multicluster.x-k8s.io/v1alpha1/namespaces/submariner-k8s-broker/serviceimports/any": x509: certificate signed by unknown authority
```

恐らくは2021年10月にLet's Encryptのルート証明書が変更になったことが原因な気がします。仕方がないので今回はPodのCA証明書を手動で差し替えます。

APIサーバの証明書を調べます。issuerがDigiCertのようです。

```
$ openssl s_client -connect c100-e.jp-tok.containers.cloud.ibm.com:****** -showcerts
...
issuer=C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
...
```

DigiCertのサイトで``DigiCert TLS RSA SHA256 2020 CA1``を調べると、ルート証明書が公開されていますので、PEMをダウンロードします。

> https://www.digicert.com/kb/digicert-root-certificates.htm#roots

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/9102f757-c550-e406-eaff-ffe58e3643f9.png)

```
$ wget https://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1-1.crt.pem
```

Base64エンコードします。

```
$ cat DigiCertTLSRSASHA2562020CA1-1.crt.pem | base64 -w 0
LS0tLS1CRUdJTiBDRVJUSUZJ.....
```

CustomResourceのキー``brokerK8sCA``をエンコードした値に書き換えます。

```
$ KUBECONFIG=./tok.config oc edit submariners.submariner.io submariner -n submariner-operator
...
spec:
  broker: k8s
  brokerK8sApiServer: c100-e.jp-tok.containers.cloud.ibm.com:******
  brokerK8sApiServerToken: ********
  brokerK8sCA: LS0tLS1CRUdJTiBDRVJUSUZJ.....（先ほどエンコードしたルート証明書）
...
```

保存すると、Podが無事起動しました。

```
$ KUBECONFIG=./tok.config oc get pods -n submariner-operator | grep lighthouse-agent
submariner-lighthouse-agent-85b9c48df8-rgjbl     1/1     Running   0          33s
```

### クラスターの参加（大阪）

大阪クラスターをSubmarinerに参加させます。``--clusterid``は``osa``とします。

```
$ subctl join --clusterid osa broker-info.subm --kubeconfig ./osa.config
* broker-info.subm says broker is at: https://c100-e.jp-tok.containers.cloud.ibm.com:*****
* There are 3 labeled nodes in the cluster:
  - 10.248.0.10
  - 10.248.128.10
  - 10.248.64.11
        Network plugin:  Calico
        Service CIDRs:   [172.22.0.0/16]
        Cluster CIDRs:   [172.17.192.0/18]
 ✓ Discovering network details
 ✓ Validating Globalnet configurations
 ✓ Discovering multi cluster details
 ✓ Deploying the Submariner operator
 ✓ Created operator CRDs
 ✓ Created operator namespace: submariner-operator
 ✓ Created operator service account and role
 ✓ Updated the privileged SCC
 ✓ Created lighthouse service account and role
 ✓ Updated the privileged SCC
 ✓ Created Lighthouse service accounts and roles
 ✓ Deployed the operator successfully
 ✓ Creating SA for cluster
 ✓ Deploying Submariner
 ✓ Submariner is up and running
```

or 

```
$ subctl join --clusterid osa broker-info.subm --kubeconfig ./osa.config
* broker-info.subm says broker is at: https://c100-e.jp-tok.containers.cloud.ibm.com:30677
? Which node should be used as the gateway? 10.248.0.10
        Network plugin:  Calico
        Service CIDRs:   [172.22.0.0/16]
        Cluster CIDRs:   [172.17.192.0/18]
 ✓ Discovering network details
 ✓ Validating Globalnet configurations
 ✓ Discovering multi cluster details
 ✓ Deploying the Submariner operator
 ✓ Created operator namespace: submariner-operator
 ✓ Created operator service account and role
 ✓ Created lighthouse service account and role
 ✓ Created Lighthouse service accounts and roles
 ✓ Deployed the operator successfully
 ✓ Creating SA for cluster
 ✓ Deploying Submariner
 ✓ Submariner is up and running
```

こちらもlighthouse-agentが起動に失敗するので、CustomResourceを書き換えます。

```
$ KUBECONFIG=./osa.config oc get pods -n submariner-operator | grep lighthouse-agent
submariner-lighthouse-agent-66fc4dfd47-rxswt    0/1     CrashLoopBackOff   1          34s

$ KUBECONFIG=./osa.config oc edit submariners.submariner.io submariner -n submariner-operator
→brokerK8sCAを東京と同じ値に変更

$ KUBECONFIG=./osa.config oc get pods -n submariner-operator | grep lighthouse-agent
submariner-lighthouse-agent-6749795b6f-rw6j5    1/1     Running   0          28s
```

### 接続確認













```
oc edit cm rook-ceph-operator-config -n openshift-storage

CSI_ENABLE_OMAP_GENERATOR", "value": "true"
```

```
apiVersion: v1
data:
  ROOK_CSI_KUBELET_DIR_PATH: /var/data/kubelet
  CSI_ENABLE_OMAP_GENERATOR: "true"
kind: ConfigMap
metadata:
  creationTimestamp: "2021-10-12T14:09:39Z"
  name: rook-ceph-operator-config
  namespace: openshift-storage
  resourceVersion: "22743"
  uid: 4ca20351-9f4f-4be3-b0f6-dea95c37a107
```

```
$ oc get pods -n openshift-storage -l app=csi-rbdplugin-provisioner -o jsonpath={.items[*].spec.containers[*].name}
csi-provisioner csi-resizer csi-attacher csi-snapshotter csi-omap-generator csi-rbdplugin liveness-prometheus csi-provisioner csi-resizer csi-attacher csi-snapshotter csi-omap-generator csi-rbdplugin liveness-prometheus
```


oc get pods -n openshift-storage -l app=csi-rbdplugin-provisioner -o jsonpath={.items[*].spec.containers[*].name}


東京・大阪それぞれで``STATUS``が``connected``になっていることを確認します。

```
$ subctl show connections --kubeconfig ./tok.config
Cluster "c100-e-jp-tok-containers-cloud-ibm-com:30677"
 ✓ Showing Connections
GATEWAY                          CLUSTER  REMOTE IP      NAT  CABLE DRIVER  SUBNETS                         STATUS     RTT avg.
kube-c5j0dfuo0fmosdq1d1pg-roksd  osa      10.248.128.10  no   vxlan         172.22.0.0/16, 172.17.192.0/18  connected  8.455507ms

$ subctl show connections --kubeconfig ./osa.config
Cluster "c101-e-jp-osa-containers-cloud-ibm-com:31014"
 ✓ Showing Connections
GATEWAY                          CLUSTER  REMOTE IP    NAT  CABLE DRIVER  SUBNETS                         STATUS     RTT avg.
kube-c5g3vset0jaip0r1pmkg-rokso  tok      10.244.2.36  no   vxlan         172.21.0.0/16, 172.17.128.0/18  connected  8.395445ms
```

# 動作確認

## サービス公開の仕組み

### ServiceExport

ここまでの手順で東京・大阪のクラスタは接続されていますが、まだお互いのサービスにアクセスすることはできません。公開したいサービスを登録する必要があります。それをServiceExportと呼びます。

ServiceExportはマニフェストで登録します。

```
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
  name: hello       # Service名
  namespace: qiita  # Serviceがあるネームスペース名
```

subctlで登録もできます。

```
$ subctl export service hello -n qiita --kubeconfig ./xxx.config
```

公開したサービスは、``${サービス名}.${ネームスペース名}.svc.clusterset.local``という特殊なFQFNで解決できるようになります。

### サービス名重複時の動作

もし同じ名称同じネームスペースのサービスを複数クラスターが同時に公開した場合は、すこし特殊な動きをします。この状態で例えば``hello.qiita.svc.clusterset.local``にアクセスしようとした場合、次の動きになります。

* 自クラスターにサービスが存在していればそのIPを返す
* 自クラスターにサービスが存在していなければ、他の存在しているクラスターからラウンドロビン的にIPを返す（今回は2クラスタなのでこれはありえないですが、Submarinerは本来は3つ以上のクラスターにも対応しています）

1点目がポイントです。リモートのクラスターにアクセスしているつもりが、実はローカルのクラスターにアクセスしていたという間違いを犯しやすくなります。ですので、明示的に相手のクラスターのサービスにアクセスしたい場合は、サービス名またはネームスペース名を別にする必要があります。

## 大阪のサービスを東京からアクセス

大阪にHelloアプリをデプロイします。

```
$ KUBECONFIG=./osa.config oc new-project qiita
$ KUBECONFIG=./osa.config oc new-app --name hello-osa --docker-image docker.io/ibmcom/hello
$ KUBECONFIG=./osa.config oc get svc hello-osa
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
hello-osa   ClusterIP   172.22.70.152   <none>        8080/TCP   24s
```

サービスを公開します。

```
$ subctl export service hello-osa -n qiita --kubeconfig ./osa.config
Service exported successfully
```

東京から大阪にアクセスします。サービスのIPを指定することも、FQDN名を指定することもできます。

> * Submarinerでは、相手方のサービスを``${サービス名}.${ネームスペース}.svc.clusterset.local``で解決することができます。
> * ServiceのClusterIPで直接アクセスする場合はServiceExportは不要です。が、実運用上現実的ではないでしょう。
> * もし公開側でServiceを作成してClusterIPが変わった場合でも、自動的にServiceImportは新しいIPに変更されます。

```
$ KUBECONFIG=./tok.config oc run centos8 --image centos:8 --command -- tail -f /dev/null
$ KUBECONFIG=./tok.config oc rsh centos8 curl http://hello-osa.qiita.svc.clusterset.local:8080/
Hello World
```

## 東京のサービスを大阪からアクセス

逆も同様です。東京にHelloアプリをデプロイします。

```
$ KUBECONFIG=./tok.config oc new-project qiita
$ KUBECONFIG=./tok.config oc new-app --name hello-tok --docker-image docker.io/ibmcom/hello
$ KUBECONFIG=./tok.config oc get svc hello-tok
NAME    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
hello   ClusterIP   172.21.57.229    <none>        8080/TCP   5s
```

東京のHelloを公開します。subctlで公開することもできます。

```
$ subctl export service hello -n qiita --kubeconfig ./tok.config
Service exported successfully

$ oc get serviceexport hello -n qiita -o yaml
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
  name: hello
  namespace: qiita
...
```

大阪から東京にアクセスします。

```
$ KUBECONFIG=./osa.config oc run centos8 --image centos:8 --command -- tail -f /dev/null

# IP直接
$ KUBECONFIG=./osa.config oc rsh centos8 curl http://172.21.57.229:8080/
Hello World

# サービス名
$ KUBECONFIG=./osa.config oc rsh centos8 curl http://hello.qiita.svc.clusterset.local:8080/
Hello World
```

# クリーンアップ

```
$ KUBECONFIG=./tok.config oc delete ns submariner-k8s-broker submariner-operator
$ KUBECONFIG=./tok.config oc label nodes -l submariner.io/gateway=true submariner.io/gateway-

$ KUBECONFIG=./osa.config oc delete ns submariner-operator
$ KUBECONFIG=./osa.config oc label nodes -l submariner.io/gateway=true submariner.io/gateway-
```

# 残作業

* Transit Gateway断時の挙動
* Gatewayの冗長化検証
* Submarinerのバージョンアップ
* ノードのバージョンアップ、リプレイス時の挙動
* ROKSのエンドポイントのプライベート化