Kubernetes Meetup Tokyo #24  まとめ

# 概要
- 2019年9月24日に開催された[Kubernetes Meetup Tokyo #24](https://k8sjp.connpass.com/event/149872/)の発表内容をまとめたものです
- 映像は[こちら](https://www.youtube.com/watch?v=vwu01bzr-fQ)



# [minne の開発環境の変革と今後](https://speakerdeck.com/shiro16/minne-falsekai-fa-huan-jing-falsebian-ge-tojin-hou-e300f1da-8461-4f94-bbc7-4eacfa193857)
## 登壇者
- 後藤 利博さん([@_shiro16](https://twitter.com/_shiro16))、GMOペパボ株式会社

## minneとは
- ハンドメイドマーケット
- アプリダウンロードは1000万超え

## minneの構成
- AWSとNyAh(GMOペパボのプライベートクラウド)で稼働しており、Route53でアクセスを振り分けている
- それぞれのクラウドでの構成はほぼ同じで、インスタンス上でRailsのWebアプリケーションが稼働している
- マイクロサービス化を進めている

## Kubernetes導入以前の開発環境
### ローカルの開発環境
- ローカルで各サービスのコンテナを立ち上げる
- 人によって異なる環境であった
- 環境が壊れる都度に原因を調査する必要があるといった課題があった
  - コンテナがメモリの問題で起動に失敗
  - tokenが古い

### リモートの開発環境
- EC2相当のサーバーが複数台用意されている
- ミドルウェアは共通

### 開発の流れ
- ローカルの開発環境で稼働確認後、リモートの開発環境にデプロイしてインターネット上で稼働確認を行う
- 人が増えたことで問題発生
  - リモート開発環境の台数が足りなくなり、空いてないと待ちになる
  - 単純に台数を増やせば解決できるが、コストが増えてしまう
- **Kubernetesに移行することで課題を解決**

## Kuberentes移行以後の開発環境

### ローカルの開発環境
- 以前と同じ環境を使用している人もいる
- 新環境の人はTerepresenceを使用して、アクセスをローカルのDockerコンテナに流している
- 各ミドルウェアもリモート環境のものが使えるようになったので、ローカルにコンテナを立てる必要がなくなった
- これによりローカル環境で発生していた問題が解決された
- **個人の環境への依存度が低下**


### リモートの開発環境
- 個人単位でPodを作成し、このPoｄを介してTerepresenceを使用する
- nginx Ingress Contorllerでアクセスを流すsvcをドメイン毎に指定
    - external-dnsの使用は断念(後述)
- 各ミドルウェアは共通
- こちらでも各問題が解決された
- **待ちがなくなったので生産性向上 & コストダウン**
- Skaffold、kaniko、kustomizeを使用してリモートでのイメージビルドや複数環境に対応
- デプロイにはSlackのInteractive Messagesを使用


####  skaffold
- イメージの作成やデプロイを自動化
- KubernetesのマニフェストファイルとDockerfileを使う
  - devモードだとコードに変更があった際に自動でdeploy
- kustomizeやkanikoと組み合わせられる


#### kustomize
- 複数環境のマニフェストファイルを作成できる
  - kustomization.yamlを使う

#### kaniko
- コンテナ内でイメージのビルドをする
- Dockerコマンドが不要

#### exrternal-dns
- IngressやServiceの設定を基にRoute53やGoogle Cloud DNSのDNSレコードを更新する
- Ingressやsvcを消した際の挙動も制御可能
- minneではクラスタの前にrole Serverがあるため使用できず


#### deploy bot
- GMOペパボの方が開発した、Slackのinteractive message を使うbotのフレームワーク
- 最終的にskaffold runを実行する

#### Telepresence
- リモートのKubernetesのトラフィックをローカルのコンテナに流すことができ、ローカルで稼働しているコンテナをKubernetesクラスタの一部のように動作させることができる


## 今後の開発環境
- 課題
  - ローカルでdocker コンテナをいくつも立ち上げる人がいる
  - Telepresenceを使うときはdocker-syncも使うのでメモリ消費が激しい
  - イメージが大きく、ビルドに時間がかかる
  - Kuberenetesのトラブルシューティングに時間がかかる
- 今後と取り組みそうな課題
  - マイクロサービス化が進んだときの個人毎の環境の分け方

## まとめ
- Kuberentesに移行したことで旧環境での課題は解決
- 特にマイクロサービス化が進んだ際には新たな課題が発生する恐れがあり、改善していく必要がある

## QA
- Telepresenceのレイテンシーは気にならないか
  - 開発環境なので気にしていない
- Teleperesenceの使用について
  - 個人のPodはクラスタ上に常に動いていて、そのPodをローカルのコンテナにつなげている
- kanikoのキャッシュでバグがないか
    - 今のところは経験なし

# [Debug application inside Kubernetes using Linux Kernel tools](https://speakerdeck.com/kentatada/debug-application-inside-kubernetes-using-linux-kernel-tools)

## 登壇者
- KENTA TADAさん([@KentaTada](https://github.com/KentaTada))、ソニー株式会社

## Introduction of oci-ftrace-syscall-analyzer which is our system call analyzer for Kubernetes

### 背景
- DockerやKubernetesを使わずにrunCベースのコンテナプラットフォームを使っていた
- セキュリティを考慮し、ftraceベースのsystem call analyzerを開発
- これらをDockerやKubernetesに適用したい
- Kubernetesの既存のデバック方法では追加のパッケージ等が必要になるが、今回はシステムコールについて調査したので、そんなにリッチな機能はいらない
    - **アプリケーションのトレースにカーネルツールを使う**
    - ftraceを採用

### ftraceとは
- Linuxカーネルに関するトレースのフレームワーク
- セットアップが簡単

### ftraceをコンテナにアタッチする方法
- コンテナが起動する前にどのようにftraceの設定を行うか
    - prestartのフェーズでfstartを設定する
- コンテナの中では名前空間が変わってしますため、元々のPIDをどのように取得するか
    - 標準入力の中にJSON形式でコンテナの状態が記載されている
    - ここにPIDの情報が書かれている
- ftraceの設定の内容
    - system call eventを有効化

### Kubernetesから使用する方法
- Kuberentesのレベルではprestartのフェーズがない
- CRI-Oのoci-hooksという機能で実現可能
    - 設定ファイルによって条件などを指定できる

###  関連ツール
- oci-seccomp-bpf-hook
    - システムコールを基にeBPFを使ってseccompのプロファイルを生成する
    - 使用が想定されるケースは
        - 特権ユーザーとして使わせたくないとき
        - eBPFの設定やバージョンに振り回されたくないとき
        - LLVMを使いたくないとき

## How to get process coredumps on Kubernetes

### 抱えている問題
- process coredumpsは特定のパス(/proc/sys/kernel/core_pattern)に記録されるが、コンテナによってそれぞれのnamespaceを保有しているため、ログを適切に取得することができない
    - これをKubernetes上でどのように解決するか
    - [Issue](https://github.com/kubernetes/kubernetes/issues/48787)
    - まだ解決していない


# [Kubernetes 1.16 アルファ機能を先取り！エフェメラルコンテナ](https://speakerdeck.com/superbrothers/kubernetes-1-dot-16-ephemeral-containers-alpha-bf6ff69c-410b-4f89-a7e9-e856db91fb7f)
## 登壇者
- Kazuki Sudaさん([@superbrothers](https://twitter.com/superbrothers))、ゼットラボ株式会社

## デバックで使えるkubectlのサブコマンド
- `kubectl run` Podを作成する
- `kubectl logs` コンテナのログを出力する
- `kubectl exec` コンテナ内で任意のコマンドを実行する
- `kubectl port-forward` コンテナ内のポートをローカルに転送する
- `kubectl cp` コンテナとローカルの間でファイルを転送する
- `kubectl top` Podやノードのリソース状況を確認する

## kubectl execの課題
- コンテナ内のコマンドしか実行できない
    - 開発者としては、軽量で余分なパッケージ等が含まれていないベースイメージを使いたい
    - それ故トラブルシューティングが難しくなる

## エフェメラルコンテナ
- 実行中のPodにトラブルシュートやデバックを目的としたコンテナ
    - エフェメラルとは「儚い」や「一時的」といった意味がある
- 1.16でアルファ機能(実験的機能)として提供されている
    - デフォルトでは無効化されている
- デバック以外の用途で使用できないよう制約がある
    - リソースを確保できる保証がなく、再起動もされない
    - 使用できないフィールドがある
- エフェメラルコンテナを作成するための`kubectl debug`コマンドが提供予定
- デフォルトではbusyboxが使われる

## もっと詳しく
- Podに2つのフィールドを追加する必要がある
- API Serverにサブリソースを追加する必要がある
- Podのspec.ephemeralContainersに変更があればエフェメラルコンテナが起動するよう、kubeletを変更する必要がある


# LT

## [ミニマリストのための CI/CD パイプライン](https://speakerdeck.com/pannpers/cd-pipeline-for-minimalist)

### 登壇者
- Yoshimasa Hamandaさん([@panchan9](https://twitter.com/panchan9))、株式会社Zeals

### CDツールを導入する難しさ
- 選択肢が多い
- 検討コストが高い
- kubernetes自体の導入コストが高い
- しかしツールを導入しないと、間違った環境へのデプロイや、属人化のリスクがある
    - かと言って`kubectl`コマンドをマニュアルで使うのも良くない

### GitOps
- GitOpsが上記の問題を解決するベストプラックティスの１つ


### GitOpsの実現方法
- 原則としては
    - Gitリポジトリで管理しているものが正とする
    - `kubectl`を直接使用してデプロイしない
- しかし、アンチパターンとされているCI Opsを部分的に導入
    - CredentialをCIツールに渡すことにより、強力な権限が付与される
- **GitOpsの恩恵を受けつつ、使い慣れたCIツールを使うことでコストを最小限に**

### ZealsのCI/CDパイプライン
#### Dev環境
- Futureブランチへのプッシュをトリガー
- Featureブランチ専用のNamespaceを作成し、そこにデプロイする
- ローカルからPort-forwardして動作検証

#### Staging環境
- Masterブランチへのマージをトリガー

#### Production環境
- Staging環境で使用したDocker Imageと同じものをPull
    - ここではビルドを行わない

- 詳細はZeals Tech Blogにて
    - [【週刊 Kubernetes 連載】ミニマリストのための CI/CD パイプライン！！](https://tech.zeals.co.jp/entry/kubernetes-cd-pipeline)

## TektonとKanikoで実現するCloudNaticeなCI
- 池田森人さん、慶應義塾大学

### Tekton
- Kuberentes上でCI/CDを構築
- TeKtonの概念
    - Step
        - 基本的な単位
    - Task
        - 複数のStepから成る
    - Pipeline
        - Taskの組み合わせ
        - 並列や順番などの依存関係を定義できる
    - PipelineResource
        - Taskで利用されるInputとOutput
    - それぞれマニフェストファイルで管理される

### Kaniko
- Kubernetes上でコンテナをビルド
- Layer単位でキャッシュをPushできるため、ビルドが早い

### TektonとKaniko
- ソースをGitHubからクローンし、TektonのTask内でKanikoを使用したビルドを実行。その後DockerイメージをPushする。

###  まとめ
- Kuberenetesはコンテナオーケストレーションだけでなく、開発エコシステムの基盤にもなり得る

## [Istio/Envoyによるサービス切り離し時の注意点（v1.3～）](https://www.slideshare.net/SatoshiMunakata1/istioenvoyv13?ref=https://k8sjp.connpass.com/event/149872/presentation/)

### 登壇者
- 宗像聡さん([@mnktsts2](https://github.com/mnktsts2))、株式会社富士通研究所

### Istion・EnvoyのOutlierDetectionの挙動について
- OutlierDetectionとは
    - Gatewayエラーを応答したPodについて、負荷分散対象から一時除外する機能
    
### 〜Istio v1.2
- 全Podを負荷分散対象から除外することはできない(Punic Modeが無効化できない)
- Punic Mode中は、Podのヘルスチェックの結果に関わらず、負荷分散が行われてしまう

### Istio v1.3〜
- 全Podを負荷分散対象から除外できるようになった(Punic Modeが無効化できる)
- UnhealthyのPodのみになった場合は、即時に503が返される

## [kind(Kubernetes IN Docker)でも"type LoadBalancer"を使いたい！~自作コントローラによるLBの実装~](https://speakerdeck.com/uesyn/kubernetes-meetup-tokyo-24-kind-with-type-loadbalancer)

###登壇者
- 上村真也さん([@uesyn](https://twitter.com/uesyn))、ゼットラボ株式会社

### kindとは
- DokcerコンテナをノードとしてKubernetesクラスタを作成できるツール
- 詳しくは[こちら](https://speakerdeck.com/masayaaoyama/cloudnativejp-09-kubernetes-in-docker-kind)を参照
- tyoeをLoadBalancerとしたServiceを作成してもEXTERNAL-IPはPendingのまま
    - kindでは使用できない

### LoadBalancerを諦める場合
1. NodeportとextraPodMappings
    - クラスタの設定ファイルにextraPodMappingsを指定し、Nodeport経由でPodに接続する
2. kubectl port-forward
    - `kubectl port-forward `でPodへ接続する
    

### LoadBalancerを諦めない場合
1. Linux環境であればMetalLBを使用することで実現可能
    - DockerのNetworkへの疎通を考慮する必要があり、お手軽ではない
2. カスタムコントローラを実装
    - LBをPodとして稼働させ、PortForwardを行う
    - ソースは後ほど公開
        - https://github.com/uesyn/k8s-local-loadbalancer

## [Deep-dive KubeVirt](https://speakerdeck.com/takutakahashi/deep-dive-kubevirt)

### 登壇者
- Takuya TAKAHASHIさん([@takutaka1220](https://twitter.com/takutaka1220))、GMOペパボ株式会社

### KubeVirtとは
- Kubernetesのノード上に仮想マシンを起動できる
    - 仮想マシンを管理できるようになる

### Deep Dive Controller
#### 構成要素
- virt-controller(Deployment)
    - CRDをウォッチし、仮想マシンの定義や状態を保持する
    - 関連リソースの変更操作を行う
- virt-handler(Daemonset)
    - controllerから処理を受け取り、launcherに流す
- virt-launcher(Pod)
    - Networkを設定するプロセス
    - VMが起動するコンテナのpid1を担うプロセス

#### VMの起動
- vm01という名前のvm01を作る場合は以下の通り
- `kubectl`の他に、`virtctl`というコマンドラインツールが必要

```
$ kubectl create -f vm01.yaml
$ virtctl start vm01 
```

### Deep Dive Virtual Machine
- CPUやメモリなどのリソース割り当ては、仮想化技術のスタンダードであるQEMU、kvm、libvirtを使用している