Kubernetes Meetup Tokyo #27 まとめ

- 2020年1月29日に開催された[Kubernetes Meetup Tokyo #27](https://k8sjp.connpass.com/event/162343/)の参加メモ
- 映像は[こちら](https://www.youtube.com/watch?v=0ZKUMWkjlck&feature=youtu.be)

# [Amazon EKSによるスケーラブルなCTR予測システムを導入した話](https://www.slideshare.net/ToshiyaYoshida3/amazon-eksctr/ToshiyaYoshida3/amazon-eksctr)
- 吉田駿哉さん([ysdtsy](https://www.facebook.com/ysdtsy))、株式会社D2C

## 機会学習 × Kubernetes
### CTR予測について
- ユーザー情報や広告配信ログを基に広告のクリック率を予測
  - CTRを用いて広告のスコアリングを行い、スコアに応じたオークションを行うことで適切な広告をユーザーに表示できる
- 学習に使用したフレームワーク
    - LightGBM
    - Spark(Amazon EMR)
### 今回達成したかったこと
- 日次バッチでCTR予測処理を行う
- 課題
  - 1時間以内に終わらせたい
  - 予測対象レコード数は10億 ± 3億
      - EC2を1台で行うと約10時間かかった
      - 今後増える可能性あり
- **1時間以内で処理を終了させ、かつアーキテクチャを変更せずに対応したい**

### なぜ機械学習にKubernetesなのか
- 機械学習システム特有の問題
  - 環境差異で再現性が損なわれる
    - フレームワークのバージョンなど
  - 継続的な学習やCI/CDが必要
  - 学習と推論でライフサイクルと要求リソースが異なる
    - 学習は週次、推論は日次
    - 学習はGPU、推論はCPU
- なぜ機械学習にKubernetesなのか
    - 上記の問題を解決してくれる
        - コンテナにより再現性担保
        - 学習やCI/CDに関する関連プロダクト(OSS)が豊富
        - リソースの最適化が行える
- **データサイエンティストがModelingの本質的な部分に注力できる**

## 実装について


### システムコンポーネント
- KubernetesクラスタはEKSで構築
    - 推論と学習を同じクラスタで実行させるためクラスタは1つ
- イメージのビルドはCircleCI上で
- AWSのリソースはTerraformで管理
- KubernetesへのデプロイはHelmで

### 推論処理の流れ(学習処理も同じような流れ)
- EMRが特徴量を吐き出し、S3に配置
- S3への配置をトリガーにSNSが起動し、SQSへメッセージを送る
- KubernetesからSQSを監視しており、SQSにメッセージがたまると、SQS Podscaler推論Podを起動(スケールアウト)させる
- Podの起動(PendingのStatus)をトリガーに、Cluster AutoscalerがNodeを起動(スケールアウト)させる
- PodがSQSからメッセージを受信し、ジョブが実行される
- ジョブが終了すると結果をS3にアプロードし、SQSのメッセージを削除する
- SQS PodscalerがPodをスケールインし、Cluster AutoscalerがNodeをスケールインさせる

### 各システムコンポーネントについて
- Node Group
  - ライフサイクル、リソース毎にNode Groupを作成
- KubernetesのJobは不採用
  - クラスタ外(Lambdaなど)からキックする必要があり、管理の手間が増える
  - パラメータの設定が柔軟にできない
- Kubernetes Deploymentの採用
  - Pub/Sub構成でJobのキックが受動的
  - Podがsubscriber
- Kubernetes ワーカー環境
  - SQSのメッセージ数でreplica数を制御
    - 普段は0になっている
  - SQSのメッセージ数をポーリングしてる
  - タスク毎にQueueとNodeGroupを分けることで異なるリソース要求に対応している
- Kubernetes ワーカー環境/リトライ
    - PodがSQSからメッセージを受信すると、そのメッセージはSQS内で処理中のステータスとして扱われる
        - 処理中のメッセージは他のPodから受信されない
    - Podにエラーが発生した場合でもそのメッセージは利用可能なステータスに戻るので、他のPodが再度受信して処理を行う
- コンポーネント
    - Pod Autoscaler
        - k8s-sqs-autoscalerを使用することで、Deploymentのレプリカ数を制御
        - Pod AutoscalerがSQSのメッセージ数をPollingしている
        - スケールイン時は、PodがSIGTERMを受け取り、その後はメッセージを受け付けなくなる
        - Jobの処理時間はTerminated Graceful Period Second以内に収まるよう、チューニングが必要
    - Cluster Autoscaler
        - 普段はDesired Capacityを0
    - Config Injection
        - Helmを使用して環境毎の設定値を管理
        - 学習パラメータの変更毎にビルドし直す必要がなくなった
    - モデル管理
        - 以下の2つの方法がある
           1.  コンテナに含める
                - ソースと紐づけられる
                - 更新の度にビルドが必要になる
            2. 外部ストレージで管理
                - ビルド不要
                - **こちらを採用**
                
        - 特徴量が更新されるとS3のモデルが更新される

## おわりに
- 1時間以内に処理を終わらせるという目標は達成
- max replicaやmax Nodeを変えればいくらでもスケールできる
- リトライ機構のおかげで耐障害性は良い
- リソースを最適化することでコストを削減
- 課題
    - モデルの妥当性を考慮する機能を導入したい

# [Azure Kubernetes Serviceで実現する超低予算＆(ほぼ)フルマネージド＆本格的なWordPress環境](https://speakerdeck.com/noriyukitakei/azure-kubernetes-servicedeshi-xian-suruchao-di-yu-suan-hobo-hurumanezido-ben-ge-de-nawordpresshuan-jing-396aadd0-bd07-4934-9c51-50741ffe6ede)
- 武井 宜行さん([@noriyukitakei](https://twitter.com/noriyukitakei)、[noriyukitakei](https://github.com/noriyukitakei/))、サイオステクノロジー株式会社

- VMで稼働させていた技術ブログのWordpressをKubernetesに移行
- ブログ版は[こちら](https://tech-lab.sios.jp/archives/18794)

## フロントエンド用Nodeとバックエンド用Nodeの振り分け
- フロントエンド
    - 一般的なブログのページ用のPodを稼働させる
- バックエンド
    - PHPの実行やDBアクセスなどがあり負荷の大きい管理画面用のPodを稼働させる
- Nginx Ingressでトラフィックを捌いており、/wp-adminのパスでアクセスすると管理画面用のPodに振り分けれれる
- フロントエンド用Nodeとバックエンド用Nodeに異なるラベルを付与している

## LoadBalancer周り
- Azure Load BalancerとNginx IngressはHelmでインストール

## Pod生成周り
- docker-emtrypoint.shを修正する必要があるためイメージはプライベートレジストリで管理
- ローリングアップデートなど、もろもろのパラメータを指定
- Secretとの連携
- preStopにコマンドを指定することでGraceful Shotdownを実現
- ヘルスチェック用のスクリプトを実装し、livenessProbeとreadinessProbeに指定

## データベース周り

- Azure Database for MYSQLを使用


## ストレージ周り
- 各Podからマウントするストレージを作成
- SMB(Azurefiles)だと、WordPressのプラグイン読み込みに時間がかかりページ読み込みが遅くなった
- NFS(Azure NetApp Files)にしたらレスポンス改善したものの高額
  - 2日で4万円
- VM上にNFSサーバーを構築し、諸所の問題を解決
  - ここがマネージドでない

## 値段
  - 3万5千円/月


## QA
- Application GatewayのIngressを使わなかった理由
  - プレビューじゃなかった
  - Application Gatewayに移したい
- VMで稼働させているNFSの可用性
  - Azureのバックアップ機能(VM丸ごと)を毎日走らせている
- WAFは導入しているか
  - 未導入
  - バージョンをあげれば導入できるが、値段が高い
  - 今後検討

# LT

## [Leader Election in Kubernetes ](https://speakerdeck.com/daikurosawa/leader-election-in-kubernetes-number-k8sjp)
- [@ponde_m](https://twitter.com/ponde_m)さん

- Leader Electionとは分散システム内の1つに特別な権限を与えることで、競合を避けつつ高可用性を保つためのウォームスタンバイの仕組み

- KubernetesではControllerで使われている
    - リソースの作成、更新、削除などの際にControllerのリーダーがAPIを叩く


- ライブラリとして提供されているのでKubernetes上の他のアプリでも使用することができる
    - Leader-for-life
        - Owner ReferenceがリーダーのPodであるConfigMapを作成してロックする
        - Podが削除されると、ガベージコレクションによってConfigMapが削除され、他のPodがリーダーになる
    - Leader-with-lease
        - リーダー以外のControllerはリーダーをwatchしており、リーダーのリースが更新されなかった場合に自分がリーダーになろうとする
        
- 詳細は[こちら](https://d-kuro.github.io/posts/kubernetes-leader-election/)

## [CloudRunが(ちょっと)素敵過ぎる件](https://www.slideshare.net/ssuserf50296/cloudrun?ref=https://k8sjp.connpass.com/event/162343/presentation/)
- 手塚卓也さん
- CloudRunとは、Knativeベースのサーバレス環境
- 良いところ
    - 管理コストが低い
    - デプロイが簡単
    - リクエストに応じたスケーリングができる
    - StackDriverと自動連携できる
- 課題
    - VPCリソースに接続できない
    - コールドスタートに関する問題

## AKSのDisk/IOに関するIssueとChaos-Meshの紹介
- genbokuさん
- Issueの紹介
    - 負荷をかけた状態でIOサチュレーションとスロットリングが起きるために生じる、AKSのレイテンシー及びパフォーマンス/可用性に関する問題
        - いろいろな様相とした障害にみえる(モダンアーキテクチャ的)
- AzureのVMではVMとVMに対してマウントされたストレージのそれぞれにIOPSの上限値が定められており、低い方の上限値がVM全体に適用される
- 上限値は
    - Worker Nodeのデフォルトで500
    - Worker NodeのVMの選択画面だと3200
- つまり、意図せずに500が設定されてしまう
- Worker Node上ではコンテナが起動されるためIOPSは上がりやすく、様々な不具合が起こる
  - ステータスがNorReadyになったり、レイテンシーの発生など
- 本質的な解消方法はなく、監視の仕組みで補うことが推奨されている
- Chaos Meshとは？
    - Kubernetes専用に開発されたカオスエンジニアリングツール
    - Podをわざと落としたり、ネットワークのレイテンシーを発生させたりできる

## [Kubernetes Robotics Distributed System](https://www.slideshare.net/FujitaTomoya/kuberenetes-robotics-distributed-system?ref=https://k8sjp.connpass.com/event/162343/presentation/)
- Fujita Tomoyaさん
- Robotics Operating System
    - OSSで結構活動が盛ん
- 反射行動を扱っている
- 知的処理はEdge側やクラウドで処理していたりする
- スコープとしては
    - 作り込みの部分にコンテナを採用
    - ロボット関で直接通信させたい
- 動的にアプリケーション間の通信を確立する技術を採用している
- 他にやること
    - Node Discovery
        - ロボットは動くためネットワーク内の出入りでクラスタへの参加状況が制御できる仕組みが必要