ソフトバンクにおける Java による

クラウドネイティブの実現

Shigeru Tatsuta

2020/09/09 CloudNative Days Tokyo 2020

自己紹介

竜田 茂 (たつた しげる)



ソフトバンク株式会社

テクノロジーユニット IT&ネットワーク統括 IT 本部



前職の日本オラクルでは Java アプリケーションサーバ製品の技術サポートを
担当。



2013 年よりソフトバンクに参画し、Java ミドルウェア製品の全社導入支援、お
よびリアルタイム処理基盤 Chronos-Core プロジェクト、IBM との提携にともな
い IBM Watson のローカライズにも参画。 



現在はプロフェッショナルなテクノロジー集団の実現を目指して、Java での
CloundNative な開発を推進中。 



ソフトバンクの IT 本部について

IT 本部はいわゆる情報システム部門で、主に通信事業に必要な IT
サービスを提供するためシステムを開発・運用しています。

IT 本部のシステムの多くは Java で開発されています。

通信事業を支えるシステム

通信事業のシステムはユーザーの皆さまの生活を支える重要なインフ
ラであるため、これまでは自社のデータセンターでウォーターフォール
で堅牢・堅実なシステム開発がメインでした。

CloudNative への挑戦

事業環境の変化に伴い、事業部門との密なコミュニケーション、および
スピード感が必要等のシステムの特性に応じて、最先端のアジャイル
手法や CloudNative なシステム開発も積極的に取り組んでいます。

Azure 

Kubernetes

Service

Azure/Kubernetes の採用

運用担当者の負荷の低減、若手エンジニアの技術力向上を狙い、
Azure、および Kubernetes を採用。

全国のソフトバンクショップのスマホアドバイザー業務を支援するシステ
ムにおいて、すでに 1 年近く稼働。Kubernetes に起因する大きな障害
はなし。

Azure Kubernetes Service の主な特徴

Azure Kubernetes Service の特徴は以下のとおり。

● コントロールプレーンは Azure で無償で提供され、Kubernetes
ノードの VM に対してのみ課金

● コントロールプレーンの SLA は 99.5% で Uptime SLA を購入する
と、99.9 - 99.95% が保証

● Kubernetes クラスタの構築は Azure CLI でコマンドで簡単に構築
可能

● Azure Application Gateway と連携するための、Application
Gateway Ingress Controller (AGIC)

● Azure Container Instances (ACI) を利用した Virtual Node への
Pod のデプロイ

システムの構成

システムの構成としては、状態は Redis に保持してコンテナはステート
レスに実装するベーシックな構成。Kubernetes のバージョンアップ、万
が一の待機面として、Blue/Green 面の 2 面を用意。

ここが良かったよ Kubernetes

リリース作業の省力化

v1.0.0

v1.1.0

v1.2.0

apiVersion: apps/v1 

kind: Deployment 

metadata:

name: frontend 

namespace: defalt 

spec:

replicas: 20 

strategy:

type: RollingUpdate 

rollingUpdate: 

maxUnavailable: 25% 

maxSurge: 0 

template:

spec:

containers: 

- name: frontend 

image: myregistory.azurecr.io/sample/frontend:1.1.0 

これまでのリリース作業ではアプリケーションサーバごとに war/ear を
デプロイしていたが、Kubernetes ではマニフェストを用意して kubectl
を apply するだけでよくなった。

Azure Container 

Registory

Azure Kubernetes 

Service

Node
 Node
 Node

apply

切り戻しの省力化

リリース作業で問題が発生した場合、最悪は以前のバージョンに切り
戻し作業を実施していたが、Kubernetes では以前のバージョンのコン
テナに戻すだけ。

v1.0.0

v1.1.0

v1.2.0

apiVersion: apps/v1 

kind: Deployment 

metadata:

name: frontend 

namespace: defalt 

spec:

replicas: 20 

strategy:

type: RollingUpdate 

rollingUpdate: 

maxUnavailable: 25% 

maxSurge: 0 

template:

spec:

containers: 

- name: frontend 

image: myregistory.azurecr.io/sample/frontend:1.0.0 

Azure Container 

Registory

Azure Kubernetes 

Service

Node
 Node
 Node

apply

縮退リリースの省力化

オンライン時間帯にリリースが必要な場合は、LoadBalancer から切り
離してリリース、動作確認してから、LoadBalancer 下に戻すという作業
を実施していたが、Kubernetes の Rolling Update でコマンド一発でよく
なった。

AP Srv
 AP Srv
 AP Srv
 AP Srv
 AP Srv
 AP Srv

deploy

AP Srv
 AP Srv
 AP Srv

LB から切り離し
 デプロイ&動作確認
 LB 下に戻す

FeatureFlag と Kubernetes

Git のブランチ戦略としては、Trunk ベース開発を採用している。メイン
ブランチ一本のため、FeatureFlag でプロダクションに出ていくコードを
制御しています。Kubernetes のマニフェストの環境変数で FeatureFlag
の切り替えが手軽に実現。

############################################## 

# Feature Flag 

############################################## 

feature.searchCustomer=${SEARCH_CUSTOMER_FEATURE_FLAG:true} 

feature.recentUsingSearch=${RECENT_USING_FEATURE_FLAG:true} 

application.properties 

containers:

- name: frontend 

image: myregistory.azurecr.io/spad/frontend:1.0.0 

env:

- name: JAVA_TOOL_OPTIONS 

value: -XX:+UseContainerSupport -XX:InitialRAMPercentage=50 ... 

- name: SPRING_PROFILES_ACTIVE 

value: pr 

- name: SEARCH_CUSTOMER_FEATURE_FLAG 

value: "true" 

- name: RECENT_USING_FEATURE_FLAG 

value: "false" 

kubernetes の yaml 

Full GC による障害

ヒープを激しく消費する処理を実行すると、ヒープが枯渇して Full GC
頻発状態となり、システムは応答不可となり、これまでは大障害となっ
ていたが、Kubernetes では Liveness Probe によってコンテナが再起動
されて自動で復旧される。

restart

Full GC 

頻発

restart
restart

データベースのメンテナンス

クラウドのデータベースを使用しているため、メンテナンス作業でノード
がフェイルオーバーされ、フレームワークのデータソースが使用不可能
になる課題があった。Kubernetes の liveness Probe で再起動させるよ
うに構成することでダウンタイムを最小化。

restart

maintance

ここが苦労したよ Kubernetes

Backend

ヘルスチェックによる高負荷

Readiness Probe に、RDBMS にクエリを投げるようなエンドポイントで
ヘルスチェックを実施していたが、Pod の数が多いと、RDBMS に
DDoS 攻撃をしているような状態になり、却ってアンヘルシーに・・・。

Frontend

日本

東南アジア

アメリカ西海岸

アメリカ東海岸

ヨーロッパ

小さな Java プロセス大きな Java プロセス

JVM チューニングの転換

これまでのアプリケーションサーバ上での可動を前提した大きな Java
プロセスから、アプリケーションをコンテナにパッケージして、
Kubernetes デプロイするため、GC、ヒープサイズ等、JVM のチューニ
ングの転換が必要。

App
 App
 App
 App
 App

App App App App App
many core/big heap 
 few core/small heap 

Direct buffer に起因する OOM

Eden

Survior

From
 To

Tenured

Metaspace

Compressed
Class Space

Code
Cache

Stack

Direct

Buffer

C heap

Java heap
 Native memory

コンテナ化で Java プロセスのヒープが小さくなる一方で、最近のフレー
ムワークでは Netty など Direct Buffer を積極的に使用するものが多
く、Direct buffer に起因する OOM が起きやすい。

まとめ

「本当にあなたのシステムで Kubernetes は必要なのか?」という意見
もあるが、以下の理由でお薦めであった。

1) 開発が開発作業の片手間で運用できるほどに、運用負荷が大きく
軽減される

2) RollingUpdate など、オンライン時間帯の積極的なリリースが可能と
なる。

3) アプリケーションサーバ時代と比べると、コンテナの中の JDK など
の MW のバージョンアップが開発側でコントロールできる。

4) これまでの大障害に繋がっていた障害も Kubernetes によって自動
で復旧できる可能性がある

5) 最新の技術に触れることで、若手エンジニアのやる気の向上

ご清聴ありがとうございました


ソフトバンクにおける Java による クラウドネイティブの実現