トラブル対応中にエンジニアリーダーとして考えていること

を言葉にしてみようと思った。僕のいる場所での話。ステークホルダーに対する窓口としてプロデューサーがいて、僕が開発チームのリーダーをしてるようなとき。

## 状況を把握する

システムトラブルが発生すると場が混乱してることが多い。色んな情報が混ざるし、色んな人から問い合わせが来たりするし、窓口になってくれているプロデューサーからの説明も省略されていることが多い。このときに一番避けたいのは、ミスコミュニケーションによって本当の問題を見失って無駄な作業をしてしまうこと。

なので、まずは落ち着いて状況を正確に把握する。ちょっとでもはやく解決したいから、その断片的な情報を元に調査に入りたい気持ちになるけど、ぐっとこらえて全体像を把握する。

コミュニケーションで特に気をつけるのは、相手や自分の中にある思い込み。思い込みがあると喋るときには(当然分かってることだよね)と言葉を省略してしまうし、聞くときには曖昧な言葉を自分の思い込みで埋めて(つまりこういうことなんだろうな)と判断してしまって、認識のずれがおきやすい。

なので、喋るときにはできるだけ相手が推測しなくて済むように曖昧な表現を避けて、聞くときには相手の「事実」と「推測」を区別して認識する。「『ボタンをおしたらそうなるんです』というのは、ボタンを押したら実際にそうなったってことですか?それとも、ボタンを押したらそうなるんじゃないかと思っているということですか?」

## 緊急度を判断する

状況を把握したら、プロデューサーと一緒に緊急度を判断する。

プロデューサーはビジネス視点で、僕はエンジニア視点でお互いの意見を共有して判断する。今すぐ修正しないといけないものなのか、明日でもいいのか、来週でも大丈夫なのか。一般ユーザーに影響が出ているのか、社内ユーザーだけに影響がでているのか。

どんな問題だってできるだけ早く解決してほしいとステークホルダーは考えるし、エンジニアとしてもすぐ対応しなきゃと思ってしまうのだけど、問題のレベルに合わせて緊急度を判断することが大切。できるだけ落ち着いて通常の開発フローを通して修正できる方が、プロダクトの品質的にも、チームの健康のためにも良い。

「問題のレベル」については、その場で話をしても揉めるだけなので、事前にステークホルダーと話し合って定義しておく。

## 状況をチームに伝える

状況を把握して、緊急度が高いと判断したら、まずチームの全員がいるチャンネルに状況を共有する。

緊急度が高いからって共有する時間を惜しんで自分が調査に入っちゃうと、場が余計に混乱することが多い。自分が調査に集中してしまうと状況が他の人から見えなくなるし、1人で調査してる途中でメンバーの誰かに聞きたいことがあって突然質問しても相手も「え?何がおこってるの?」ってなるだけだから。

なので、チームの全員に状況を伝える。そうすると何人かのメンバーから「この辺が問題かも」「テストケースチェックしてみる」などの意見がもらえるし、全員がその問題に対して動き出してくれる。このとき、僕は自分では手を動かさないことが多いかな。エンジニアたちの情報をまとめて決断や報告をする役割をする必要があるから。

次に、Zoomを立ち上げて、何人かでそこに集まる(最近はリモートチームで仕事をしてることが多い)。そして根本原因の調査や対応方法の相談をする。対応方法に関しては、いくつかの選択肢があることが多い。その中で良い点や悪い点などを相談しながら、どの対応方法を選ぶかを決断する。

全員の意見がすぐにまとまる場合は良いのだけど、どの方法にもリスクがある場合、決断しきれないことも多い。そういうときは「この対応方法で進めましょう」とリーダーとして決めてしまう。

あとは「誰が何をやるか(何をやらないか)」を取りまとめるかな。それぞれのメンバーが目の前のタスクに集中できるように。

## 状況をプロデューサーに伝える

エンジニアたちの状況をプロデューサーに定期的に伝える。これがあるので、自分はできるだけ手を動かさないようにしている。

エンジニアたちのチャンネルに入ってもらえば全ての情報があるから、それを元に把握してくれたらいいじゃん。って言う人がたまにいるんだけど、それはプロデューサーには難しい。粒度が細かいし、内容が色んな場所に飛んでいったり戻ってきたりするから結局どうなったのかが外から見ただけだと把握できない。それに、プロデューサーは窓口になってステークホルダーとのやり取りをしているため、そこまで細かく追いかけられない。

なので、僕がエンジニアたちの状況をプロデューサーに伝える役割をする。このときに気をつけるのは、エンジニア視点で把握している情報を伝えるのではなく、プロデューサー視点で必要な情報を伝えるということ。「このモジュールのこの部分のコードに問題がありそうなので修正してプルリクエストを作っているところです」よりも「疑わしい部分を見つけたので20分以内にステージング環境で確認できるようになります。デプロイ後に一緒に確認をお願いしたいです」くらい。

それからプロデューサーからの質問で「いつ修正できそうですか?」に対して、まだ分かっていないときには「まだ分かりません」だけじゃなくて「まだ原因が分かっていないので調査中です。15分後に状況を再度共有します」みたいに、次にいつ情報を共有するか、まで伝えておくとプロデューサーも「まだ原因は分かっていませんか?それとももう修正を始めていますか?」みたいな質問をチームの様子を伺いながらする必要がないし、ステークホルダーにも説明しやすい。

## いま思いつくのは

だいたいそんなところ。

あとは、そのトラブルを引き起こしたバグを埋め込んでしまった人が申し訳ない気持ちになっていたりするので「気にしないでください。誰がこのコードを書いたかというのは全く問題ではないんです。チームとしてレビューをしてテストをして、それでも見つけられなかったということが問題なのです。チームの課題として認識して改善していきましょう」と言ったりするかな。

Istio 1.5.0 のインストールをカスタマイズしてみる

昨日の続き:

bufferings.hatenablog.com

昨日はデフォルトプロファイルでインストールしたので、今日はちょっとカスタマイズしてみたい。

## カスタマイズの方法

これかな:

https://istio.io/docs/setup/install/istioctl/#customizing-the-configuration

### プロファイル

プロファイルはistioctlに組み込まれてるんだけど、それと同じものがインストーラーのinstall/kubernetes/operator/profilesにあるっぽい。それを見たらどんな設定を変更したらいいか分かりそう:

ls -1 install/kubernetes/operator/profiles
default.yaml
demo.yaml
empty.yaml
minimal.yaml
remote.yaml
separate.yaml

Github上はこれかな https://github.com/istio/istio/tree/1.5.0/operator/data/profiles

### 設定の変更方法

で、その設定を次のようにして--setオプションで変更できる:

❯ istioctl manifest apply --set components.telemetry.enabled=false

毎回オプションで指定するのも面倒だなぁと思ってたらやっぱりYAMLで設定できるよねぇ。インストーラーのsamples/operatorにサンプルがある 。

ls -1 samples/operator
default-install.yaml
pilot-advanced-override.yaml
pilot-k8s.yaml
sds-policy-off.yaml
sds.yaml
trafficManagement-namespace.yaml
values-global.yaml
values-pilot.yaml

Github上はこれだな https://github.com/istio/istio/blob/1.5.0/operator/samples

んで、作った設定ファイルをこんな風にして指定できる:

❯ istioctl manifest apply -f bufferings.yaml

マニフェストの適用だけじゃなくて生成もできるのか。それもいいな:

❯ istioctl manifest generate -f bufferings.yaml

なるほど。じゃ、やってみるか。

## 設定ファイルの作成

設定で触りたい主な部分は:

  • kialiを有効にしてみようかな
  • istio-ingressgatewayLoadBalancer じゃなくて NodePort にしてみる
  • Auto mTLSがデフォルトONになったみたいだけど、なんとなくOFFにしてみる
  • outboundTrafficPolicyREGISTRY_ONLY にしてみる

それくらいかな。とか考えながら、ごにょごにょごにょごにょやってみて最終的に bufferings.yaml をこんな感じにしてみた:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  # defaultをベースに
  profile: default

  addonComponents:
    # kialiを有効化する
    kiali:
      enabled: true

  values:
    global:
      # Auto mTLSをオフに
      mtls:
        auto: false
      # 外部へのアクセスは制限する
      outboundTrafficPolicy:
        mode: REGISTRY_ONLY
    gateways:
      # NodePortにする
      istio-ingressgateway:
        type: NodePort
        ports:
          - port: 15020
            targetPort: 15020
            name: status-port
          - port: 80
            targetPort: 80
            nodePort: 31380
            name: http2
          - port: 443
            name: https
            nodePort: 31390
    kiali:
      # テストなのでログインなしにする
      dashboard:
        auth:
          strategy: anonymous

なるほど。Helmよりこっちの方がインストールの設定を管理しやすいな。

## インストール

ということでapply:

❯ istioctl manifest apply -f bufferings.yaml
proto: tag has too few fields: "-"
- Applying manifest for component Base...
✔ Finished applying manifest for component Base.
- Applying manifest for component Pilot...
✔ Finished applying manifest for component Pilot.
- Applying manifest for component IngressGateways...
- Applying manifest for component AddonComponents...
✔ Finished applying manifest for component AddonComponents.
✔ Finished applying manifest for component IngressGateways.


✔ Installation complete

んで、Bookinfoを昨日と同じようにインストールしてみた。

# istio-proxyの自動設定を有効にして
❯ kubectl label namespace default istio-injection=enabled
namespace/default labeled

# アプリケーション群をデプロイ
❯ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
...

# ゲートウェイをデプロイ
❯ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

簡単にチェックしてみよう。

### Kiali

お。デプロイされてる。ポートフォワードしてチェック:

❯ kubectl port-forward -n istio-system svc/kiali 8000:20001

f:id:bufferings:20200309222131p:plain

### NodePort

ちゃんとLoadBalancerじゃなくてNodePortサービスになってる:

❯ kubectl get svc -n istio-system istio-ingressgateway
NAME                   TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)                                      AGE
istio-ingressgateway   NodePort   10.0.5.146   <none>        15020:31147/TCP,80:31380/TCP,443:31390/TCP   2m49s

ポートも指定したものになってる。

### Auto mTLS

は、Kialiで確認したらOFFになってる:

f:id:bufferings:20200309222500p:plain

ちなみにONだとこんな感じ。鍵マークがついてる:

f:id:bufferings:20200309221419p:plain

### outboundTrafficPolicy

も有効になってるみたいだね:

❯ k exec -ti deployment/ratings-v1 bash
Defaulting container name to ratings.
Use 'kubectl describe pod/ratings-v1-f745cf57b-fhd7v -n default' to see all of the containers in this pod.
root@ratings-v1-f745cf57b-fhd7v:/opt/microservices# curl -I google.com
HTTP/1.1 502 Bad Gateway
date: Mon, 09 Mar 2020 13:34:29 GMT
server: envoy
transfer-encoding: chunked

面白かった。

次は

GKEなので、PrometheusじゃなくてStackdriverにログを送りたいな。

Istio 1.5.0 がリリースされたのでとりあえず触ってみるくらいの気持ち

2020-03-05にIstio 1.5.0 がリリースされた。のでとりあえず触ってみる。くらいの気持ち。

Istio / Announcing Istio 1.5

一番大きな変更はIstiod。これまで複数のコンポーネントに分かれてたコントロールプレーンのモノリス化。管理がシンプルになるので良さそう。

カスタムポリシーやテレメトリーみたいなメッシュ拡張の機能はMixerからEnvoyに移ったみたい。これまではMixerで処理してたけど、Envoy Proxyの中でWasmを使って処理することができるようになったということなので、パフォーマンス的にもシンプルさ的にも良さそう。Wasmがどういうものか分かってないから勉強しなきゃだな。

それと istioctl analyze が色々改善されて、experimentalから卒業した。と。使ったことない。

## 試してみる環境

以前にちょっと触ってみたk3dを使ってローカルで試してみてもいいんだけど、なんとなく今日は複数ノードを使ってGKEでやろうかな。こんな感じのを用意した:

❯ kubectl get nodes
NAME                                       STATUS   ROLES    AGE    VERSION
gke-cluster-1-default-pool-d43e77a2-322n   Ready    <none>   105s   v1.14.10-gke.17
gke-cluster-1-default-pool-d43e77a2-mhnr   Ready    <none>   105s   v1.14.10-gke.17
gke-cluster-1-default-pool-d43e77a2-p48p   Ready    <none>   105s   v1.14.10-gke.17

ちなみにk3dで遊んだときの記事はこれ:

ローカルでk8sを試してみたいときはk3dが使えそう。Istioも動きそう。 - Mitsuyuki.Shiiba

あ、全然今回の記事とは関係ないけど、k3dをMacで使うときは --publish オプションでポートをマッピングしてあげないといけないみたいですね。僕はUbuntu使ってるからマッピングしなくても大丈夫でした。

https://github.com/rancher/k3d#exposing-services

## Istioの準備

このページに沿ってやればいいのかな。

Istio / Getting Started

ダウンロードしてきて:

❯ curl -L https://istio.io/downloadIstio | sh -
❯ cd istio-1.5.0export PATH=$PWD/bin:$PATH

デフォルトプロファイルでインストールしてみよう:

Istio / Installation Configuration Profiles

f:id:bufferings:20200307231014p:plain

ん?でもなんで istio-pilotdefault のプロファイルに入ってるんだろう? istiod に統合したから要らなくなったんじゃないのかな?

こんな風に書いてあるんだけどな:

https://istio.io/news/releases/1.5.x/announcing-1.5/upgrade-notes/#pilot

The istio-pilot deployment has been removed in favor of the istiod deployment, which contains all functionality that Pilot once had. For backwards compatibility, there are still some references to Pilot.
(椎葉訳) Pilotが持っていた機能の全てを持った istiod をデプロイすることになったので istio-pilot のデプロイメントは削除されました。後方互換性のため、まだPilotへの参照には残っているものがあります。

ふむ。よく分かってない。まいっか。

## Istioのデプロイ

今までHelmでしかデプロイしたことないけど将来的には非推奨になるみたいだし istioctl でやってみるか。プロファイルを指定しなかったら default が使われるみたいね:

❯ istioctl manifest apply
This will install the default Istio profile into the cluster. Proceed? (y/N) y
- Applying manifest for component Base...
✔ Finished applying manifest for component Base.
- Applying manifest for component Pilot...
✔ Finished applying manifest for component Pilot.
  Waiting for resources to become ready...
  Waiting for resources to become ready...
  Waiting for resources to become ready...
  Waiting for resources to become ready...
  Waiting for resources to become ready...
  Waiting for resources to become ready...
- Applying manifest for component AddonComponents...
- Applying manifest for component IngressGateways...
✔ Finished applying manifest for component AddonComponents.
✔ Finished applying manifest for component IngressGateways.


✔ Installation complete

おー!確かにコントロールプレーンがIstiodだけだしシンプルで素敵:

❯ kubectl get pods -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istio-ingressgateway-598796f4d9-8zfp2   1/1     Running   0          34s
istiod-7d9c7bdd6-74gvm                  1/1     Running   0          54s
prometheus-b47d8c58c-bjjdc              2/2     Running   0          34s

あれ、結局 istio-pilot はデプロイされないのか。

## Bookinfoで確認

恒例のbookinfoサンプルアプリを入れてみる

https://istio.io/docs/examples/bookinfo/

# istio-proxyの自動設定を有効にして
❯ kubectl label namespace default istio-injection=enabled
namespace/default labeled

# アプリケーション群をデプロイ
❯ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

# ゲートウェイをデプロイ
❯ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

# LoadBalancerのIPアドレスを取得export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# ブラウザで開く(Ubuntu)
❯ xdg-open http://$INGRESS_HOST/productpage

普通に動いた。

f:id:bufferings:20200307183012p:plain

Traffic Managementの部分だけ簡単に試してみようかな:

https://istio.io/docs/tasks/traffic-management/request-routing/

まずはDestinationRuleを作っておく:

❯ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created

この時点では、VirtualServiceがないのでreviewサービスに対するリクエストは全部のバージョンに振り分けられている。レビューの星の部分がでなかったり(v1)・黒かったり(v2)・赤かったり(v3)する。

次にVirtualServiceを適用:

❯ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created

これで全部 v1 に流れるようになる。何度リロードしても、星は出なくなった。

次は、jason というユーザーでログインしたときだけ v2 が使用されるようにVirtualServiceを更新:

❯ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews configured

すると jason という名前でログインすると黒い星が出るようになる。それ以外の人や未ログインの場合は星が出ないまま。

ふむ。動いてるっぽいな。よい。

## 次は

インストールをカスタマイズしてみたいな。

RSGTの精神( #RSGT2020 でお話をしてきました)

RSGT2020に参加しました。楽しかった。

2020.scrumgatheringtokyo.org

色々なことがあって、沢山の人とお話できて、何から書いたら良いか分からないので、思いついたものをざーっと書いてみます。

## 発表した

f:id:bufferings:20200112081020j:plain

Photo by あらたさん(ありがとうございます!)

スライドはこちら

色んな人に「よかったよ」って言ってもらえたし、見られなかった人も「話聞きたい」って質問してくれたし、Twitterでも色んな人が「いいね」って言ってくれてて、嬉しい。

当日は、小野さんが部屋担当で「いつもの感じっすか?」ってやってくれたのでありがたかったし、知ってる人たちが最前列で見てくれてて安心したし、真ん中らへんや後ろの方でセッション中にうなずきながら見てくれてる人がいたので喋りやすかったです。ありがとうございます。

## ポジティブ

プレゼンのヒントにと思ってこの本を読んだのでした。

books.rakuten.co.jp

「聴いた人がハッピーになる」ってあって、あぁ、これまでメッセージを届けることは意識してたけど、ハッピーになるかどうかまでは考えてなかったな。確かにそうだな。と思って「ポジティブな一歩」を意識してつくりました。

「あぁ、いいな。明日からこういうこと考えてみようかな」と前向きな気持ちで思えるようなセッションになってたかなぁ?もし、そんな風にちょっとでもポジティブな気持ちのきっかけにしてもらえてたらいいなぁ。

## すごくあたたかい

色んな人に「よかったよ」って言ってもらえてとても嬉しい。でも、勘違いしないようにしたいのは、それって自分がすごいんじゃなくて、僕のセッションから何かを感じてくれようとしてくれる人たちがすごいってことです。

いつでも、自分がなんかすごいんじゃないかな?と思うときは、自分がすごいんじゃなくて、周りにいる人たちがそういう風に思わせてくれてたり、それを支えてくれる動きをしてくれてるからで、あたたかい。

## 正解はない。自分で考える。

突然RSGT自体の話になりますが、2つの対象的なキーノートが印象的でした。1日目はコープさんのスクラムの精神のお話。2日目はサホタさんの誰も見捨てずに前に進むお話。2日目のキーノートを聞きながらニヤニヤしてしまった。これはRSGTの主催者からのメッセージだなと。

どちらか一方だけだと「自分は全くスクラムから遠いところにいるなぁ」と思ったかまたは「スクラムはいいけど、目の前の一歩を踏み出そうかな」と思いそうだけど、その2つを見せつけられることで「正解はない。両方を受け入れて自分で考えてください」というメッセージだなと僕は受け取りました。

そう。セッションを聞いてると「この人が言ってるからこれが正解なんだ」と思ってしまう自分がいて。それと違うことをしてたら「自分は間違ったことをしているんじゃないか?」と悩んだりするんですけど。そういうのを減らしていきたいな。自分の目で確認しながら進みたい。

## コミュニティ

3日目の高橋さんのクロージングキーノートを聞いてて、そっかそんな風にして試行錯誤を繰り返してこのコミュニティは大きくなってきたんだなぁと感慨深かった。僕にとってのチームはコミュニティだなということも再確認できた。

## セッション

いくつか印象的だったセッションを。

CI&Tさんのセッションで「テスターからスクラムマスターに昇進しました」って話を嬉しそうにしてて「この会社はいい会社なんだなぁ」と感じました。テストエンジニアは高いスキルが必要なので上下の話ではないとは思うけど、入り口としてテスターというロールを用意していて、その次のステップの1つとしてSMがある、というのを明確に定義しているんだろうなぁと。楽しそうに仕事をしてるのが伝わってきて、良いな。

あらたさんのセッションはしくじりのお話だったんですけど、しくじる前の成功のお話もとても勉強になりそうだったので今度ゆっくりそっちも聞いてみたいです。しくじり自体も、そうやるとよくなさそうな気はしてたけど、実際にそうやるとそんなことになるのか・・・というのを学べて良かったし、最後のメッセージもとても勇気づけられたし、この人にしかあんなことできないなーと思ってみてました。相変わらずすごい。

きょんさんのセッションは、チームがばらばらになったというのが衝撃でした。だけど、それでもあきらめずに、今まで培ってきた知見を活用しながら自分たちにしかできない形で新しい形でチームを形作っているのが、優しいなと思いました。優しすぎて少し心配。内容とは別に勉強になったのが、スライドの構成やセリフの入れ方、歩くタイミングや目線、ねのさんとのタイミングの合わせ方、などすごいなぁと思いながら見てました。

後輩のキムさんの軍隊の話は自分が全く知らない世界の話だったので興味津々で面白かったし、半谷さんの話は、同じ会社で仕事をしてる人として尊敬しかない動きで、あれはとても人間力が必要だし、実現させてるのが単純にすごいなぁと思いました。

およべさんのセッションは聞けなかったんですけど、会って少し話をするだけで、相変わらずすごく勇気を僕にくれました。こんなところに僕がいていいんだろうか?と思うときがあるんだけど、およべさんと話をしていると「いいんだよ!」って言ってもらえる感じがして、安心する。

## RSGTの精神

色々な人たちとお話をする中で、考え方や目指すものは違うけど、自社サービスだからとか、受託だからとか、SIerだからとか、Web系だからとか、組み込みだからとか、大企業だからとか、スタートアップだからとか、そういうの関係なく、その場を改善しようとして頑張ってる人たちとお互いに支えあいながら敬意を払いながら歩いていきたいなと思いました。

## 成長のベクトル

RSGT2019でおよべさんと素晴らしい後輩たちが投げかけてきてくれたメッセージ「成長のベクトル」をこの一年間たまに思い出しながら取り組んできました。自分は自分が全力でやってきたことを信頼しているし、それで成長のベクトルも後輩たちにも負けないようにやってきたと思うので、そういう気持ちでまたここに戻ってこれて良かった。

英語圏の人たちと話をするのにまだ勇気が出ないので、今年は英語を頑張ろうかな。と思い中。そもそも日本語でも勇気がかなり必要とされているので別な問題の気もするけど。

まとまりないけどこの辺で。今年こそは少し手を抜いてがんばるー。スタッフのみなさん、参加者のみなさん、最高でした!ありがとうございました!

#kanjava で Micronaut の紹介をしました。そのときに使ったアプリのコードを公開しました。

関ジャバでお話する機会をいただき、Micronautの紹介をしてきました。Java最新フレームワーク特集ということで、Quarkusのお話を聞くことができてとても面白かったです。

kanjava.connpass.com

当日は、GKEにサンプルアプリをデプロイして、Stackdriverで状況を見たのですが、ローカルで動かせるほうがいいかな?と思ったので、先日少しだけ触ってたk3dで動かせるようにして

bufferings.hatenablog.com

コードを公開しておきました。READMEに書いてある通りにやったらローカルでIstioとアプリが動くと思います。CPUとメモリを結構使うかも。

github.com

Istioのbookinfoサンプルをバージョン切り替えをなくして、Micronautで簡単に書き直しただけのアプリなんですけど、こんな感じ

https://github.com/bufferings/kanjava201911/raw/master/image/bookstore.png

Istioの上で動くようにしてあるので、kialiでServiceGraphを見てみたり

https://github.com/bufferings/kanjava201911/raw/master/image/kiali.png

Grafanaのダッシュボードもいっこ作って、Istioのインストールスクリプトの中に入れておいたので、こんな風に確認したりできます

https://github.com/bufferings/kanjava201911/raw/master/image/grafana.png

普通のJAR実行と、ネイティブイメージの両方のDockerコンテナを用意したのですが、比較するところまではいけませんでした。

また、確認していきたいな。それとGraalVMの19.3が関ジャバが終わったその日くらいにリリースされて

GraalVM 19.3.x

Native Image周りも変わったっぽいので、そのあたりも触ってみたいなと思ってます。ありがとうございました。

Javaのコンテナのメモリ割り当ての考え方をまきさんに教えていただいたので記録

何度か教えていただいているので、今度こそしっかり覚えておきたくて、まきさんからのコメントを記録。

## メモリサイズの考え方

SpringBootのアプリをコンテナとして動かす場合には768MB以上必要で、1GBくらいは割り当てる必要があるのではないかという僕のコメントに対していただいたコメント。

## Build Pack

上記のようなメモリサイズの計算をやってくれるツールも教えてもらった。

ありがとうございます!

ローカルでk8sを試してみたいときはk3dが使えそう。Istioも動きそう。

## ローカルでk8s

ちょっと試してみたいときとかに、ローカルでk8sを動かしたくて。以前だとMinikubeとかDockerについてくるk8sとかを使ったことがあるけど、今だとまた何か出てるかな?と思ってたらこういうスレッドを見つけた。

K3s, minikube or microk8s? : kubernetes

  • Minikube
  • Microk8s
  • K3s
  • Kind
  • Desktop Docker
  • K3d
  • Kubeadm

が紹介されてた。へー。と思って、なんとなくk3dが面白そうかなと思ったので試してみた。

## k3d

https://github.com/rancher/k3d

紹介されている一覧の中にあるk3sをDockerで動かしてくれるのがk3dということみたい。Dockerを動かすプラットフォームをDockerの中で動か・・・す?こんがらがる。

僕はUbuntu使ってるんだけど、Dockerで動くならWindowsでもMacでも動きそうで良さそうね。

READMEに書いてある通りにインストールして(brewも対応してるみたい)

$ curl -s https://raw.githubusercontent.com/rancher/k3d/master/install.sh | bash

READMEに書いてある通りにクラスターを生成してからConfigを設定したら

$ k3d create
$ export KUBECONFIG=$(k3d get-kubeconfig)

へー。ほんとに動いてる。

$ kubectl get pods -A
NAMESPACE     NAME                                      READY   STATUS      RESTARTS   AGE
kube-system   local-path-provisioner-58fb86bdfd-kvmdh   1/1     Running     0          3m40s
kube-system   coredns-57d8bbb86-grbbr                   1/1     Running     0          3m40s
kube-system   helm-install-traefik-4qr7t                0/1     Completed   0          3m40s
kube-system   svclb-traefik-j8c49                       3/3     Running     0          3m5s
kube-system   traefik-65bccdc4bd-vtk9r                  1/1     Running     0          3m5s

$ kubectl get svc -A                                                                                                                                                                                   
NAMESPACE     NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                                     AGE                                                                                
default       kubernetes   ClusterIP      10.43.0.1      <none>         443/TCP                                     5m57s                                                                              
kube-system   kube-dns     ClusterIP      10.43.0.10     <none>         53/UDP,53/TCP,9153/TCP                      5m56s                                                                              
kube-system   traefik      LoadBalancer   10.43.80.235   192.168.48.2   80:30107/TCP,443:31822/TCP,8080:31373/TCP   5m5s   

traefikをLoadBalancerサービスとして使ってるってことなのかな。ふむふむ。

## Istio?

ふと。k3dでIstio動くんかな?と思って見てみたら

[HELP] 1 node(s) didn't have free ports for the requested pod ports · Issue #104 · rancher/k3d · GitHub

どうやらこの人はtraefikとIstioのポートがぶつかってたからtraefikを使わないようにしたらIstioが動いたっぽい。へー。

やってみるか。

### traefik抜きでk3dクラスターを生成

# さっきのクラスターを削除して
$ k3d delete

# traefik抜きのクラスターを作成
$ k3d create --server-arg --no-deploy --server-arg traefik

# 設定を生成して
$ export KUBECONFIG=$(k3d get-kubeconfig)

# チェック
$ kubectl get pod,svc -A
NAMESPACE     NAME                                          READY   STATUS    RESTARTS   AGE
kube-system   pod/local-path-provisioner-58fb86bdfd-h6npn   1/1     Running   0          13m
kube-system   pod/coredns-57d8bbb86-zkjkq                   1/1     Running   0          13m

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP                  13m
kube-system   service/kube-dns     ClusterIP   10.43.0.10   <none>        53/UDP,53/TCP,9153/TCP   13m

これでIstio入れてみるかな。

### Istioのインストール

・・・ってもうバージョン1.4か。こ、今月出たばっかりだし、1.3使っとこうかな。なんとなく。

https://github.com/istio/istio/releases/tag/1.3.5

からダウンロードしてきて、このページを見ながらインストールする。helm templateを使う方で入れる。Helmは既に入れてある。

https://istio.io/docs/setup/install/helm/

# Istio用のネームスペース作って
$ kubectl create namespace istio-system

# CRD入れて
$ helm template install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | kubectl apply -f -

# CRDの生成が終わるのを待つ
$ kubectl -n istio-system wait --for=condition=complete job --all

あw。これまではwcコマンドつかって23個になるのを待ってたのに、wait使うようになってる。良い。で、Istioのインストール。

$ helm template install/kubernetes/helm/istio --name istio --namespace istio-system | kubectl apply -f -

ありゃ。さくっと入ったっぽい。

kubectl get svc,pod -n istio-system
NAME                             TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                                                                                                                                      AGE
service/istio-galley             ClusterIP      10.43.10.191    <none>         443/TCP,15014/TCP,9901/TCP                                                                                                                   2m21s
service/istio-policy             ClusterIP      10.43.86.131    <none>         9091/TCP,15004/TCP,15014/TCP                                                                                                                 2m21s
service/istio-telemetry          ClusterIP      10.43.11.107    <none>         9091/TCP,15004/TCP,15014/TCP,42422/TCP                                                                                                       2m21s
service/istio-pilot              ClusterIP      10.43.126.19    <none>         15010/TCP,15011/TCP,8080/TCP,15014/TCP                                                                                                       2m21s
service/prometheus               ClusterIP      10.43.41.148    <none>         9090/TCP                                                                                                                                     2m21s
service/istio-citadel            ClusterIP      10.43.91.217    <none>         8060/TCP,15014/TCP                                                                                                                           2m21s
service/istio-sidecar-injector   ClusterIP      10.43.117.133   <none>         443/TCP,15014/TCP                                                                                                                            2m21s
service/istio-ingressgateway     LoadBalancer   10.43.69.0      192.168.96.2   15020:30845/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:31842/TCP,15030:32247/TCP,15031:32685/TCP,15032:31093/TCP,15443:30499/TCP   2m21s

NAME                                          READY   STATUS      RESTARTS   AGE
pod/istio-init-crd-10-1.3.5-28hj7             0/1     Completed   0          5m40s
pod/istio-init-crd-11-1.3.5-vmwmw             0/1     Completed   0          5m40s
pod/istio-init-crd-12-1.3.5-84q77             0/1     Completed   0          5m40s
pod/istio-security-post-install-1.3.5-jb66j   0/1     Completed   0          2m21s
pod/svclb-istio-ingressgateway-ww22d          9/9     Running     0          2m21s
pod/istio-citadel-5c67db5cb-hmhvb             1/1     Running     0          2m20s
pod/prometheus-6f74d6f76d-tpjpc               1/1     Running     0          2m20s
pod/istio-policy-66d87c756b-hf4wx             2/2     Running     3          2m21s
pod/istio-galley-56b9fb859d-7jmsq             1/1     Running     0          2m21s
pod/istio-sidecar-injector-5d65cfcd79-lhh6k   1/1     Running     0          2m20s
pod/istio-pilot-64478c6886-9xm7b              2/2     Running     0          2m20s
pod/istio-telemetry-5d4c4bfbbf-g4ccz          2/2     Running     4          2m20s
pod/istio-ingressgateway-7b766b6685-5vwg5     1/1     Running     0          2m21s

こんなにスムーズに進むなんて・・・(疑い

サンプルアプリ動かしてみるか。

### bookinfoサンプルアプリをデプロイ

動作確認のために、Istioについてくるbookinfoサンプルアプリをデプロイしてみる。

https://istio.io/docs/examples/bookinfo/

# サイドカーの自動インジェクションを有効にして
$ kubectl label namespace default istio-injection=enabled

# デプロイして
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

# watchでもしながらしばらく待つ
$ kubectl get pods -w
NAME                              READY   STATUS            RESTARTS   AGE
details-v1-78d78fbddf-5db8b       0/2     PodInitializing   0          37s
reviews-v1-7bb8ffd9b6-rdgjc       0/2     PodInitializing   0          37s
ratings-v1-6c9dbf6b45-p7567       0/2     PodInitializing   0          36s
productpage-v1-596598f447-nj6wx   0/2     PodInitializing   0          36s
reviews-v3-68964bc4c8-qrhc4       0/2     PodInitializing   0          37s
reviews-v2-d7d75fff8-65f4q        0/2     PodInitializing   0          37s

# bookinfo用のIngressGatewayを作成
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

LoadBalanerサービスのExternal IPを確認して

$ kubectl get svc  -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
192.168.96.2

それをブラウザで開いたら・・・ありゃ。動いた。

http://{そのIPアドレス}/productpage

f:id:bufferings:20191117113617p:plain

メモリ使用量はbookinfoをデプロイしただけだと2GiBくらい。

$ docker stats --no-stream
CONTAINER ID        NAME                     CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
598bd6d07c85        k3d-k3s-default-server   52.24%              1.909GiB / 15.4GiB   12.40%              819MB / 21.7MB      1.41MB / 818MB      899

何か起こったときの問題解決は難しそうだけど、ローカルでちょこっとためすのにはお手軽で良さそう。