【参加報告】Kubernetesハッカソン - Azure Kubernetes Serviceでk8s

# はじめに

少し時間が経っていますが、整理も兼ねて2019/2/23、2019/2/24の２日間、日本マイクロソフト 関西支店で開催されたKubernetesハッカソンの参加報告の記載になります。

# 概要

- 日程：2019/2/23,2019/2/24(２日間)
- 場所：日本マイクロソフト 関西支店
- 主催：関ジャバ
- 講師：寺田佳央さん（Microsoft）
- 内容：1日目の午前中は寺田さんよりkubernetes,microserviceなどについての講義。午後よりチーム分けをしてハッカソン。2日目の夕方に結果発表。

# 講義内容

ここでは割愛。
寺田さんのブログにアップされているスライドを見ていただければ、わかりやすくまとまっています。
https://yoshio3.com/category/microsoft-azure/

# チーム分け

講義の最後に付箋が配られ、みんな自分がハッカソンでやりたい技術要素を書き出しました。
その中から希望の多かった４つの要素をピックアップし、チーム分けを行いました。
出来上がったチームは以下の４つ。

- Kubernetes入門
- Micorservice構築
- ログ・監視
- Istio

# Istioハッカソン

私はIstioチームに参加したため、この後はIstioチーム内での報告内容。
なお、ハッカソンは各自ではなくチームごとに１つの環境に対してモブプログラミングで実施。
また、チーム間のコミュニケーションはSlackを利用。

## 2/23 13:00〜 環境構築

### まずは以下のお題でスタート

- クラスタ構築＆踏み台作成
- Istioインストール
- BookInfoアプリのデプロイ

※踏み台は通常必要ないが、全員同じ環境でモブプログラミングを実施するため、kubectlコマンドを踏み台から実行するために用意。

### LinuxにAzureCLIをインストール

https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-apt?view=azure-cli-latest

### ネットワークの作成・クラスタの作成

https://docs.microsoft.com/ja-jp/azure/aks/configure-kubenet

クラスタ作成コマンド

```
az aks create \
   --resource-group istio-rg \
   --name istio-cluster \
   --node-count 3 \
   --enable-addons monitoring \
   --generate-ssh-keys \
   -l japaneast \
   -s Standard_DS2_v2
```

注意点として、無料アカウントだと--node-countは"1"でないとエラーになります。

kubectlインストール

```
https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl
```

### 作成したクラスタへ接続

```
az login
az aks get-credentials --resource-group <リソースグループ名> --name <クラスタ名>
```

### Istioインストール

https://istio.io/docs/setup/kubernetes/quick-start/

Istioをダウンロードして、istio-demoをデプロイする方式で実施

```
kubectl apply -f install/kubernetes/istio-demo.yaml
```

### 自動インジェクション

Istioはnamespace単位でインジェクションの有無を設定できる。
今回はdefaultネームスペースに対してインジェクションを有効にする。

```
kubectl label namespace default istio-injection=enabled
```

### BookInfoアプリのデプロイ

bookinfo.yamlをデプロイすれば、BookInfoアプリすべて（details,ratings,reviews,productpage）のDeployment,Serviceがデプロイされる

```
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
```

デプロイされたPodのYAMLを見てみる（試しにdetails）

```
kubectl get pod/details-xxxxxxxx -o yaml
```

detailsサービスの他にistio(istio-proxy-init,istio-proxy)のコンテナが動いていることが確認できる。

### Gateway,destination-ruleのデプロイ

```
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
```

ここまでできたら、ブラウザからアクセスができる。（IPはAzureで自動に割り振られる）

http://xxx.xxx.xxx.xxx/productpage

## 2/23 16:00〜 可視化

### ServiceGraphで通信内容を可視化

一通りデモアプリのセットアップまで終わったので、初日の最後に簡単に可視化

### ServiceGraph

```
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088
ssh -L8088:localhost:8088 -N istio@xxx.xxx.xxx.xxx
```

２行目は、踏み台経由でアクセスしているため、各自のPCのローカルホストにポートフォワードするために設定。

http://localhost:8088/force/forcegraph.html
http://localhost:8088/dotviz

### Grafana

```
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:
3000
ssh -L 8088:localhost:3000 -N istio@xxx.xxx.xxx.xxx
```

### Jarger

```
kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 16686:16686
ssh -L 8088:localhost:16686 -N istio@xxx.xxx.xxx.xxx
```

### ... 1日目終了。

## 2/24 10:00〜 前日の疑問点などの整理

昨日はistio-ingressgatewayをLoadBalancerで公開していたのを、今日はまずNodePortにしてクラスタの外側にLBを置くパターンも確認してみる。

### NodePortでデプロイ

```
diff install/kubernetes/istio-demo.yaml{,.orig}
12492c12492
<   type: NodePort
---
>   type: LoadBalancer
```

動作することは確認。
ただベストプラクティスとしてTLSターミネートやバージョン違いのクラスタのスイッチなどをどの層でやるべきなのかが疑問になり、寺田さんを巻き込み議論。

![img_20190224_125948_720.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/a49e36e5-af68-938d-5dc5-cae44d614c57.jpeg)

この時の結果としては、istio-ingressgatewayはLoadBarancerとして、TLSターミネートはGatewayが実施。クラスタのスイッチなどはDNSで行うで決着。

### この時いろいろ話を聞いて、kubernetesやる上でkubernetesの論理的な設定がマネージドサービス上でどのように実装されているかはしっかり意識する必要があることがわかり、大変勉強になりました。

## 2/25 13:00〜 カナリアリリース

### Istioのカナリアリリース機能を確認

カナリアリリースは新機能のリリース時などにごくわずかな通信だけ新バージョンに通信させたり、特定ユーザーなど関係者だけが新バージョンを見えるようにして確認を行う仕組み。
確認して問題なければ新バージョンへの通信割合を増やしていく。

jasonさんだけv1が見える設定

```
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v1
  - route:
    - destination:
        host: reviews
        subset: v2
```

10%のリクエストだけ、v2に割り振る設定

```
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 90
    - destination:
        host: reviews
        subset: v2
      weight: 10
```

## 2/25 15:00〜 サーキットブレーカ

### Istioのサーキットブレーカ機能を確認

サーキットブレーカは呼び出し先のサービスで障害が発生している場合、そのサービスを切り離して呼び出し元が自分でエラーを応答する仕組み。
（ルールで設定した閾値を超えたら呼び出すのをやめエラー応答、また指定した間隔で復旧の確認をして、復旧してたら再接続する）

### 参考

https://docs.microsoft.com/ja-jp/dotnet/standard/microservices-architecture/implement-resilient-applications/implement-circuit-breaker-pattern

### Istioでは下記のように設定

```
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      baseEjectionTime: 180.000s
      consecutiveErrors: 1
      interval: 10m
      maxEjectionPercent: 100
```

### outlierDetectionの仕様（設定できる内容はEnvoyの仕様に準ずる）

https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/cluster/outlier_detection.proto

ただ、仕様通りに設定しても期待通り切り離しが行われず、ここでどハマり。
同じような悩みのissue（ https://github.com/istio/istio/issues/8846 ）も上がっており、Envoyの不具合かもしれないってことでタイムアップになりました。

## まとめ

Azure上でクラスタのセットアップからIstio,サンプルアプリのデプロイを実施、ServiceGraph・Grafana・Jaegerなどを利用した可視化、カナリアリリース、サーキットブレーカなど、Istioを利用したサービスを運用する上で必要な機能を基本的な部分だけですが２日間かけていろいろ触ることができました。結構ボリュームがあり、あっという間の２日間でした。

今回のようなハッカソン形式に参加したのは初めてでしたが、新しい気付きも多く、また寺田さんからも座学だけでは学べないことがいろいろ聞けて大変有意義だったと思います。
また同じような機会があれば参加したいと思います。（次は多少なりとも教えれるようにならないとな・・・）