Cloud Foundry / Pivotal Application Services(PAS)ではコンテナに永続ディスクをアタッチする用途でSMBとNFSのService Brokerが用意されています。
Pivotal Application Servicesは最近リブランドされ、VMware Tanzu Application Service (TAS)にリネームされました。
ただし、SMBやNFSのprovisioningはサポートされておらず既存のサーバーをマウントするのみです。 別途、SMBサーバーを用意したくないので、AzureのManaged ServiceであるAzure Filesを使って試してみます。 Azure FilesはSMB 3.0に対応しています。
SMB Brokerについては次のドキュメントを参照してください。
- https://docs.pivotal.io/platform/application-service/2-8/devguide/services/using-vol-services.html
- https://docs.google.com/presentation/d/1_5px0UB0k7USS71xVnn6XgU1eArZ__Ee_eYmxkj-XcE/edit#slide=id.g5ba1df2c92_0_10
また、PASでSMB Brokerを有効にする方法はこちらを参照してください。
Azure FilesのProvisioning
az
コマンドでAzure Filesリソースを作成します。
export TENANT_ID=....
export CLIENT_ID=....
export CLIENT_SECRET=....
export LOCATION="Japan East"
export RESOURCE_GROUP=azure-files-demo
export STORAGE_ACCOUNT_NAME=makiazurefilesdemo
export SHARE_NAME=demoshare
az login --username ${CLIENT_ID} \
--password ${CLIENT_SECRET} \
--service-principal \
--tenant ${TENANT_ID}
az group create --name ${RESOURCE_GROUP} \
--location "${LOCATION}"
az storage account create --name ${STORAGE_ACCOUNT_NAME} \
--resource-group ${RESOURCE_GROUP} \
--location "${LOCATION}" \
--kind StorageV2 \
--sku Standard_ZRS \
--enable-large-file-share \
--output none
# OR
#
# az storage account create --name ${STORAGE_ACCOUNT_NAME} \
# --resource-group ${RESOURCE_GROUP} \
# --location "${LOCATION}" \
# --kind FileStorage \
# --sku Premium_LRS \
# --output none
STORAGE_ACCOUNT_KEY=$(az storage account keys list \
--resource-group ${RESOURCE_GROUP} \
--account-name ${STORAGE_ACCOUNT_NAME} \
--query "[0].value" | tr -d '"')
az storage share create \
--account-name ${STORAGE_ACCOUNT_NAME} \
--account-key ${STORAGE_ACCOUNT_KEY} \
--name ${SHARE_NAME} \
--quota 1024 \
--output none
Azure PortalでStorage Account:makiazurefilesdemo
のdemoshare
というFile Shareができていることを確認できます。
Demoアプリのデプロイ
Demoアプリとして https://github.com/making/demo-uploader を使います。Spring Bootで実装されたシンプルなFile Uploaderです。
Marketplaceの確認
cf marketplace
でsmb
サービスが利用できることを確認してください。
$ cf marketplace
Getting services from marketplace in org demo / space demo as makingx@gmail.com...
OK
service plans description broker
app-autoscaler standard Scales bound applications in response to load app-autoscaler
smb Existing Existing SMB shares (see: https://code.cloudfoundry.org/smb-volume-release/) smbbroker
TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service.
アプリケーションのビルド
git clone https://github.com/making/demo-uploader
cd demo-uploader
./mvnw clean package -DskipTests=true
アプリケーションのデプロイ
cf push demo-uploader -p target/demo-uploader-0.0.1-SNAPSHOT.jar --no-start
cf create-service smb Existing demo-smb -c "{\"share\": \"//${STORAGE_ACCOUNT_NAME}.file.core.windows.net/${SHARE_NAME}\", \"version\": \"3.0\"}"
cf bind-service demo-uploader demo-smb -c "{\"username\": \"${STORAGE_ACCOUNT_NAME}\", \"password\": \"${STORAGE_ACCOUNT_KEY}\"}"
cf start demo-uploader
cf env demo-uploader
の結果は次のようになります。
環境変数VCAP_SERVICES
の中のsmb
内に次の要素が含まれています。
"volume_mounts": [
{
"container_dir": "/var/vcap/data/b96daab0-24ab-4912-8736-3fabdb82a9c6",
"device_type": "shared",
"mode": "rw"
}
]
container_dir
がコンテナ内にマウントされたSMBのディレクトリです。
アプリケーションがこのディレクトリにファイルを書き込めば、コンテナが再起動してもファイルは失われません。
この値は、
- Spring Boot 2.2以上では
${vcap.services.<SERVICE_INSTANCE_NAME>[volume_mounts][0][container_dir]}
で - Spring Boot 2.1以下では
${vcap.services.<SERVICE_INSTANCE_NAME>.volume_mounts[0].container_dir}
で
参照できます。
Spring Boot以外の場合は、
.profile
内でjq
コマンドを使ったり、echo $VCAP_SERVICES | awk "match(\$0, /\/var\/vcap\/data\/([0-9a-z\-]+)/){print substr(\$0, RSTART,RLENGTH)}"
で取得した値を環境変数で設定することになります。
demo-uploader
では次のように使用しています。
https://github.com/making/demo-uploader/blob/master/src/main/resources/application.properties#L1
demo-uploader
からファイルをアップロードします。
demoshare
File Shareにファイルが出来ていることが確認できます。
cf restart demo-uploader
してもこのファイルは消えません。