開発チームで、この人が居ないとだめだ!て状況

は過渡期としてはありなんだけど、そこで立ち止まってしまうと、良くなさそうだなぁって思う。

その本人が「自分が居ないとこのチームはダメだ」ってところに居場所を見つけて、心地良いと思いはじめたり。

さらに「自分はこんなに役に立ってるのに、どうしてメンバーは受け身なままで成長してくれないんだろう?」って上から見はじめたり。

そういう感じになると良くない。

チームの次のステップとしては、そういう状況を早く脱出して、誰もがそれをできるようになって、次のレベルの「それぞれが持ち味を発揮する」というところに行けると良いんだけど。

本人は、そこに行けない原因をメンバーのせいにして「自分は問題ないのにメンバーがいけてない」と思ってたりする。「自分は誰にも教わらずにできるようになったのに!」って。

最初はそういう風に「誰にも教わらずに色んな失敗を繰り返しながら知識を得る人」が必要なんだけど、そういう人が居る状態になってしまうと、状況は違って「その人から知識を伝えていく」ことが必要なフェーズになるのかなと。

今日はチョコアイスを買って帰ろうかな-。

KubernetesのLiveness ProbeとReadiness Probeの使い分けを考えたけど結局思いつかなかったや

Liveness ProbeとReadiness Probe

KubernetesにはLiveness ProbeとReadiness Probeってのがある。これの使い分けについて考えてたら混乱したのでメモ。

kubernetes.io

  • Liveness Probeは「コンテナが生きてるかどうか」
  • Readiness Probeは「コンテナがリクエストを受け付けるかどうか」

を示すらしい。

  • Liveness ProbeがNGのときは、コンテナが再起動される。
  • Readiness ProbeがNGのコンテナを持ったPodには、リクエストが送られてこない。

うん。ここまでは理解できる。

んだけど、なんでReadiness Probeだけじゃだめなの?

と思ったので考えてみた。Readiness Probeだけでまかなえるんじゃないの?って。ReadinessがOKの場合って、アプリが生きてるわけだから、それで済むじゃん。って思ったのだ。

f:id:bufferings:20180217171502p:plain

この「オレンジじゃなくて黄色の部分」の意味よなぁ・・・。

と思ったらこんな風に書いてあった

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#when-should-you-use-liveness-or-readiness-probes

  • コンテナに問題があったらクラッシュするんだったら、勝手に再起動されるからLiveness Probeの設定要らない。
  • ProbeがNGのときにコンテナを再起動して欲しいなら、Liveness Probeを設定したら再起動してくれる。
  • ProbeがOKになってからコンテナにトラフィックを送って欲しいなら、Readiness Probeを設定する。Readiness ProbeとLiveness Probeは同じものになるかもしれないけど、Readiness Probeがあるってことは「最初はリクエストを受け付けない状態で起動してReadinessがOKになってからリクエストを受け付けるようになるよ」ってことを表す。
  • メンテナンスとかでリクエストを受け付けるのを停止したい場合にはReadiness Probeを使うことができる。
  • Podが削除されるときにリクエストを受け付けないようにしたいだけならReadiness Probeを使わなくても大丈夫。削除するときにはReadiness Probeに関係なくunready状態になって停止するのを待つから。

起動してるけどまだリクエストを受け付けてない、ってのを分ける必要は、なさそうかなー。メンテナンスかぁ。でも、メンテナンスとかの場合は、k8sのサービス側でコントロールしそうかなー。だから、あんまり区別しなくて良さそうかな。

SpringBoot使ってる人はどんな風にしてるのかなー?

ってぐぐってみたらこんなの見つけた。

zavyn.blogspot.jp

こんな感じに設定してるみたい。

readinessProbe:
httpGet:
  scheme: HTTP
  path: /health
  port: 8080
initialDelaySeconds: 240
periodSeconds: 5
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 10
livenessProbe:
httpGet:
  scheme: HTTP
  path: /health
  port: 8080
initialDelaySeconds: 300
periodSeconds: 60
timeoutSeconds: 10
successThreshold: 1
failureThreshold: 3 

まぁ、やっぱりだいたい同じの設定しておけばいいよねって感じだ。SpringBootアプリの場合は、initialDelaySecondsを長めに設定しとかなきゃなってくらいかなー。

どういうケースでこの2つのProbeを使い分けるんだろう?ってのはスッキリしないままだけど、自分の中での使い方は納得したからいっか。

Continuous DeliveryツールのSpinnakerを動かしてみた

今度はSpinnakerに興味を持ったので、ローカルのminikubeでやろうとしたけどできなくて、GKEのチュートリアルでやってみたメモ。さくっと終わるつもりだったのにいつも通り色々あったかな。

Spinnaker

Continuous Deliveryツール。チュートリアルやって動いた、程度なので中身は全然理解してない。

www.spinnaker.io

@deeeetさんの記事見て興味を持ちました。

tech.mercari.com

見た目好き。

f:id:bufferings:20180217110621p:plain

minikubeでやってみよう→失敗

ローカルのminikubeで動かしてみようと思って、ここを見ながらhelm入れるところまでいって、その後Spinnaker入れようとしたらできなかった。もうエラーの内容も覚えてないけど、バージョンの違いとかなんだろうかな。

thenewstack.io

ここで時間かけて原因をチェックするより、とりあえず動かしてみたいので、GKEでやってみることにした。

GKEでやってみよう→できた

GKE + Spinnakerのチュートリアル

Continuous Delivery Pipelines with Spinnaker and Kubernetes Engine  |  Solutions  |  Google Cloud Platform

f:id:bufferings:20180217115213p:plain
(Image from: https://cloud.google.com/solutions/continuous-delivery-spinnaker-kubernetes-engine )

この手順でやったら、Spinnakerが動くところまでできた。(∩´∀`)∩ワーイ


そして

勉強の時間を取ることができずにいたら

ということで気を取り直して、最初からやりなおしてみた。

だいたいこんな感じだった:

GCPソースコードリポジトリに"v"で始まるタグをpushすると

ソースコードリポジトリなんてあるんやね。

f:id:bufferings:20180217120816p:plain

GCPのContainer Registoryが検知してイメージを作成すると

トリガーはベータって書いてあるけど、便利。

f:id:bufferings:20180217120957p:plain

Spinnakerが検知してパイプラインが始まる

f:id:bufferings:20180217121228p:plain

まぁ、イメージ作るところまでは、Github -> TravisCI -> DockerHubでいいかなって気がするね。

はまったところ

最初にSpinnakerをデプロイしてから「まだ無料期間中だからいいか」って思ってしばらく放置しておいてから昨日久しぶりに触ったんだけど、そしたらSpinnakerがGCRのタグを取得できないってエラーになってて。ぐぐったらこれっぽい。

github.com

Spinnakerの部品の一つのCloudDriverが起動してから2,3日たつと、認証エラーになるっぽい。ので、とりあえずPodを2日に1回再起動してるーって。ので、Podを落として勝手に再起動されるのを待ってたらタグとってこれて動いたや。(∩´∀`)∩ワーイ

デプロイメントパイプライン

パイプラインの流れは、イメージのpushをトリガーにして→機能テストを実施→問題なければカナリア環境にデプロイ。

んで、動作確認がOKだったら手動で本番化するかどうかを選ぶ。って感じ。(下側の赤いところが中断を選んだ場合。)

f:id:bufferings:20180217122456p:plain

カナリアリリース

チュートリアルの本番環境には本番Podが8個、カナリアPodが1個デプロイされるようになってるから、8:1の割合でカナリアPodにリクエストが流れる。

問題なければ、本番化すると本番Podが新しいバージョンになるっぽい。

面白かったー

次はもう少し詳しくSpinnakerを見ていこうかな。クッキーでカナリア環境に振り分けたりとかとか。

おとーさんを。プログラミング!

Macの電池が切れそうだから、部屋まで行ってアダプターを取ってくるおとーさんプログラムを書いて!」って娘達と遊んだ。結果はこんな感じ。

f:id:bufferings:20180202165930j:plain

娘1(8歳)と話をしたのは次の2つ。

右を向く

立ち上がったあと「右を向く」という命令があったのだけど、僕が斜めに座ってたので右に90度回転すると壁にぶつかってしまった。ので、「右を向く」じゃなくて何か目印を使ってみようかって話をした。「テレビに背を向ける」になった。

5歩進む。もしランドセルを通り過ぎてたら1歩戻る。

繰り返しが使えるね。という話をした。「ランドセルまで1歩進むを繰り返す」になった。

そしたらあとは

壁にぶつかって止まったり、目的地を通り過ぎたりしたんだけど、自分で考えてやってくれたのであった。

面白かったー

その間ずっと娘2(5歳)は僕の後ろをついてきてました。

できあがったプログラム

1. 立ちあがる
2. テレビに背を向ける
3. ランドセルの前まで1歩すすむをくりかえす
4. ランドセルがある方を向く
5. ドアの1歩手前まで1歩すすむをくりかえす
6. ドアをあけてパパのへやの前まで1歩すすむをくりかえす
7. パパのへやの方を向く
8. クローゼットの前まですすむ
9. 黒いいすの方を向いて黒いイスの前まで1歩すすむをくりかえす
10. カバンの中からコンセントをとる

「(∩´∀`)∩ワーイ アダプターゲットー!帰るぞー!」

11. ドアがあいてるほうのまん中らへんを向く
12. パパのへやを出るまで1歩すすむ
13. きいろのたわしの方をむく
14. ちゃいろのマクラがおいてあるところまで1歩すすむをくりかえす
15. うしろをむく
16. ドアをしめる
17. きいろのたわしの方を向く
18. テーブルの前まで1歩すすむをくりかえす
19. パソコンの方を向く
20. パソコンの前まで1歩すすむをくりかえす
21. パソコンの方を向く
22. すわる
23. おわり

「(∩´∀`)∩ワーイ電源つなげて助かったー」

娘1の感想「人間ってこれだけのことを『あれ取ってきて!』でできるのすごいね」

ついでに

「フィズバズってプログラムがあるんやけどやってみる?」

娘1「うんー」

「それだと15のときにフィズ!って言うよ?」

娘1「あー。こっちが先?」

「そうね。で、ここに『1から100まで以下の処理を繰り返す』って書いたら完璧だよ!」

f:id:bufferings:20180202172806j:plain

Istioのルーティングをごにょごにょやってみる。雰囲気で。

昨日はこんな感じでIstioとそのサンプルプロジェクトであるBookinfoをGKE上にデプロイしたので、それを使って今日はIstioのルーティングをごにょごにょやってみる。雰囲気で。

bufferings.hatenablog.com

やること

Istio / Intelligent Routing に書いてある3つのタスクをやる。

  1. Istio / Configuring Request Routing
  2. Istio / Fault Injection
  3. Istio / Traffic Shifting

Bookinfoのつくり

サンプルプロジェクトのBookinfoの画面はこんな感じ。

f:id:bufferings:20180130081528p:plain

つくりは https://istio.io/docs/guides/bookinfo.html に説明があるんだけどこんな感じ。Envoyってのがサイドカーコンテナとしてアプリの隣にデプロイされてて、そいつをプロキシとしてサービス同士が通信することでルートをコントロールする。

f:id:bufferings:20180130081420p:plain

マイクロサービス的なつくりになってて、Reviewsサービスに3つのバージョンが用意されてる。それぞれのバージョンはこんな感じ。

  • v1: レーティングなし
  • v2: 黒い星(★★★)
  • v3: 赤い星(★★★)

今回のチュートリアルでは、このReviewsサービスの周りのルーティングをごにょごにょして遊ぶ。

最初はラウンドロビン

プロジェクトをデプロイした初期の状態では、ProductPageからReviewsサービスのルートがラウンドロビンなので、3つのバージョンが順番にでてくる。

Task 1. Configuring Request Routing

reviews:v1だけ

に流す設定を適用

$ istioctl create -f samples/bookinfo/kube/route-rule-all-v1.yaml

こんな風にして設定を確認すると

$ istioctl get routerule reviews-default -o yaml

こうなってる

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  creationTimestamp: null
  name: reviews-default
  namespace: default
  resourceVersion: "201910"
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v1
---

各項目の意味は分かってないけど、reviewsサービスへの通信は全てv1になってる雰囲気ある。

f:id:bufferings:20180130203910p:plain

ので何回リロードしてもこの表示(レビューの部分だけ切り取った)。おぉ。

f:id:bufferings:20180130203049p:plain

jasonさんだけv2

にする設定を適用して

$ istioctl create -f samples/bookinfo/kube/route-rule-reviews-test-v2.yaml

取得

$ istioctl get routerule reviews-test-v2 -o yaml

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  creationTimestamp: null
  name: reviews-test-v2
  namespace: default
  resourceVersion: "275044"
spec:
  destination:
    name: reviews
  match:
    request:
      headers:
        cookie:
          regex: ^(.*?;)?(user=jason)(;.*)?$
  precedence: 2
  route:
  - labels:
      version: v2
---

Cookieuser=jason ってあったらv2に流す雰囲気。こういう感じ。

f:id:bufferings:20180130205015p:plain

普通に表示するとさっきと何も変わらず星が出ないんだけど、右上にあるSign inから"jason"でサインインすると(パスワードはなんでもいい)黒い星になった。おぉ。

f:id:bufferings:20180130205401p:plain

これでTask 1終了!

Task 2. Fault Injection

f:id:bufferings:20180130210034p:plain

Reviews-v2からRatingsサービスの呼び出しのタイムアウトは10sに設定してるので、7sのdelayを挿入して動作を確認してみる。

$ istioctl create -f samples/bookinfo/kube/route-rule-ratings-test-delay.yaml

設定確認

$ istioctl get routerule ratings-test-delay -o yaml

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  creationTimestamp: null
  name: ratings-test-delay
  namespace: default
  resourceVersion: "277806"
spec:
  destination:
    name: ratings
  httpFault:
    delay:
      fixedDelay: 7.000s
      percent: 100
  match:
    request:
      headers:
        cookie:
          regex: ^(.*?;)?(user=jason)(;.*)?$
  precedence: 2
  route:
  - labels:
      version: v1
---

jasonさんのrating呼び出しが100%の割合で7秒遅延する雰囲気だね。

jasonさんでログインした状態なので、そのままリロードして7秒待つ・・・

f:id:bufferings:20180130211006p:plain

(´・ω・`)ショボーン

どゆこと?

実は、ReviewsサービスからRatingsサービスへの呼び出しは正しく10sが設定されてるんだけど、その前のProductPageからReviewsサービスの呼び出しのタイムアウトが3秒になってるのだった。1回リトライするから合計6秒でエラーメッセージが表示される。

っていうふうに

サービス呼び出しの設定が意図通りの動作をするかを確認したりするのに使えるよってことみたい。ほほー。

Task 2しゅーりょー。

Task 3. Traffic Shifting

始める前に

jasonさん用のルーティング設定を削除して、全部v1に流れるとこまで戻しておくかな。(チュートリアルにはネームスペースオプションがなかったけど、それだと「ネームスペース指定してね」って怒られた)

$ istioctl delete routerule reviews-test-v2 -n default

$ istioctl delete routerule ratings-test-delay -n default

reviews:v1とreviews:v3に50%ずつ流す設定

を適用する

$ istioctl replace -f samples/bookinfo/kube/route-rule-reviews-50-v3.yaml

今回は元々あった設定を上書きするから create じゃなくて replace

f:id:bufferings:20180130213249p:plain

確認

$ istioctl get routerule reviews-default -o yaml

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  creationTimestamp: null
  name: reviews-default
  namespace: default
  resourceVersion: "279870"
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v1
    weight: 50
  - labels:
      version: v3
    weight: 50
---

いつも通り雰囲気で。そっか50%ずつね。ふむふむ。という感じ。実際にリロードを繰り返してみると、v1(星なし)とv3(赤い星)が半々くらいで出てくる。

f:id:bufferings:20180130212733p:plain

v3大丈夫そうねってなったら

全部v3に流す設定を適用

$ istioctl replace -f samples/bookinfo/kube/route-rule-reviews-v3.yaml

f:id:bufferings:20180130213332p:plain

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
  creationTimestamp: null
  name: reviews-default
  namespace: default
  resourceVersion: "280349"
spec:
  destination:
    name: reviews
  precedence: 1
  route:
  - labels:
      version: v3
    weight: 100
---

リロードしたら常に赤い星になってる。(∩´∀`)∩ワーイ

たのしかった。

IstioのGKEクイックスタートができなかったので心を込めてひとつずつ手でデプロイ

最近はKubernetesに興味があって、GKE(Google Kubernetes Engine)でごにょごにょしてて、折角ならカナリアリリースしたいなーと思って、Istioというものを触ろうとしてる。

Istioは、マイクロサービス間のサービスメッシュをコントロールするプロダクト。と言えばいいのかな。

んで、ほんとに軽い気持ちで「IstioにGKE用のクイックスタートあるじゃん。これやってみよー」って思って、ここを見ながらやってみた。ら、色々つまづいたので共有。(主に数カ月後の自分に向けて)

Deploymentのテンプレートは基本的にデフォルトのままにして、Istioのバージョンだけ0.3.0じゃなくて0.4.0に変更してデプロイした。

istio.io

結論から言っておくと、GKEクイックスタートを使うのを諦めて、いっこずつ手でやった。

Pilotが起動しない・・・

最初は、IstioのコアコンポーネントのひとつのPilotが起動しなくてずっとリスタートしてて「???」ってなった。んだけど、僕が注意書きを読んでなかっただけだった。ごめんなさい。

f:id:bufferings:20180128234211p:plain

GoogleのCloud ConsoleからIAMを開いてデフォルトのコンピュートサービスアカウントを見ると、デフォルトではEditorロールが設定されてるけど、そこにKubernetes Engine Adminを追加してね」って書いてた。

ので、追加してクラスタを作りなおしたら無事Pilotが起動した。(∩´∀`)∩ワーイ

productpageを開くことができない・・・

IstioのGKEクイックスタートを使ってデプロイをすると、サンプルプロジェクトも一緒にデプロイされる。ので、よーし!productpageを開くぞー!ってアクセスしてみたら。

productpage upstream connect error or disconnect/reset before headers

と表示されて503だったかな(もうあんまり覚えてない)。

つまり、・・・何かがおかしいみたいだ!(GKEもk8sもIstioもよく分かってないので本当にこれくらいの語彙)

mutualTLS authenticationをDisableに

適当に調べてみたら、どうも証明書周りっぽい?感じだったので、デプロイのテンプレートの「Enable mutualTLS authentication」の部分のチェックを外して、クラスタを再作成してみた。

f:id:bufferings:20180128235912p:plain

ら、productpageにつながった!(∩´∀`)∩ワーイ

違和感があるような・・・

ところで、productpageの部分で悩んでるときに、Deployment周りのソースがgithubにあることに気づいて見てたんだけど、この部分に違和感。

kubectl apply -f install/kubernetes/istio-sidecar-injector.yaml (https://github.com/istio/istio/blob/2deef884f6e36e0ce76c287b59771bff820a759b/install/gcp/deployment_manager/istio-cluster.jinja#L100)

って書いてあるんだけど、これを生成するには updateVersion.sh (https://github.com/istio/istio/blob/2deef884f6e36e0ce76c287b59771bff820a759b/install/updateVersion.sh)を呼び出さないといけないように見える。でも、呼び出してなさそう。

んで、GKE用じゃない方のクイックスタートを見てみたら、同じことをするのに kubectl apply -f install/kubernetes/istio-initializer.yaml を使ってるの。あれ?GKE用のと違うファイル?ま、僕がまだ全然仕組みを分かってないからかな。どっかでごにょごにょやってるんだろうな。気にせずに続けよう!と、先に進んでみたのだけど・・・

サンプルアプリ以外が動いてない・・・

クイックスタートはサンプルのアプリ以外にも、GrafanaとかPrometheusとかもデプロイされるようになってる。のだけど、そいつらが画面は開けるけど、データが見えない。どうもサービスとうまく通信できてないっぽい。

んー。さっきの違和感の部分は、やっぱり怪しい・・・のかな?

GKEクイックスタート諦めた

ということで、もうGKE用のクイックスタートを諦めて、他のクイックスタート( Istio / Quick Start )を見ながら自分で作ってみることにした。ら、全部ちゃんと動いた。

1. GKEでクラスタを作る

vCPU x 2 を4台用意。自動的にEnvoyをインストールするために、アルファ版の機能を有効にする。

f:id:bufferings:20180129003247p:plain

2. ローカルからの接続設定

そのクラスターに繋げられるようにして、現在のユーザーに管理者権限をつける

gcloud container clusters get-credentials <cluster-name> --zone <zone> --project <project-name>
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value core/account)

3. Istioをダウンロード

Istioをダウンロードしてきて、そこに移動してbinにパスを通す

curl -L https://git.io/getLatestIstio | sh -
cd istio-0.4.0
export PATH=$PWD/bin:$PATH

4. Istioをデプロイ

折角だから、さっきはオフにしちゃった「mutual TLS authentication」を今回は試してみることにした。

kubectl apply -f install/kubernetes/istio-auth.yaml

さっき違和感あるって言ってた、サイドカーの自動挿入の部分ね

kubectl apply -f install/kubernetes/istio-initializer.yaml

5. Bookinfo(サンプルアプリ)をデプロイ

クイックスタートのページはそこまでで終わりなので、次はこのページ( Istio / Bookinfo )を参考にBookinfoアプリをデプロイ。

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

6. その他のツールをデプロイ

今度は Istio / Metrics, Logs, and Traces を参考に

Prometheus

kubectl apply -f install/kubernetes/addons/prometheus.yaml

Grafana

kubectl apply -f install/kubernetes/addons/grafana.yaml

Zipkin

kubectl apply -f install/kubernetes/addons/zipkin.yaml

Servicegraph

kubectl apply -f install/kubernetes/addons/servicegraph.yaml

7. productpageにアクセス

ということで、デプロイが終わったのでGKEクイックスタートの続きをやってみる。・・・遠かった。

https://istio.io/docs/setup/kubernetes/quick-start-gke-dm.html#access-the-bookinfo-sample

IPアドレスを取得して

export GATEWAY_URL=$(kubectl get ingress --no-headers | awk '{print $3}')

ブラウザで http://${GATEWAY_URL}/productpage にアクセス

f:id:bufferings:20180129004723p:plain

(∩´∀`)∩ワーイ

8. ツール群にアクセス

適当にトラフィックを生成しておいて

for i in {1..100}; do curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage; done

Grafana + Prometheus

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 &

してから

http://localhost:3000/dashboard/db/istio-dashboard

f:id:bufferings:20180129005537p:plain

Zipkin

kubectl port-forward -n istio-system $(kubectl get pod -n istio-system -l app=zipkin -o jsonpath='{.items[0].metadata.name}') 9411:9411 &
http://localhost:9411

f:id:bufferings:20180129005636p:plain

ServiceGraph

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=servicegraph -o jsonpath='{.items[0].metadata.name}') 8088:8088 &
http://localhost:8088/dotviz

f:id:bufferings:20180129005951p:plain

ということで

一歩前進かな。疲れた。

「まず公式のドキュメントを読め」というのは分かってるんだけど・・・

サービスやライブラリーやフレームワークを触るときは「まず公式のドキュメントを読め」というのは分かってるんだけど。なんだかつらいときが多くて。僕の順番的にはこういう感じだなーって思ったメモ。

1. 公式ドキュメントを読もうとする

雰囲気だけパラパラと。特に英語の場合は、中身を読もうとしてもすぐに挫折する。

後で倒しに来るために、いちどボスの姿を見ておこう。みたいな気持ち。

2. ググる:ブログとかキータとか

Stack Overflowは、まだはやいので、ブログとかキータとかみたいにまとめられた情報を漁る。日本語の情報が少なければ英語のブログとかも。

みんなが使ってみた感じとか、どんな風に使ってるか、困ったかとかを知る感じ。

3. 手を動かす

とりあえず、細かいことはいいから手を動かしてみようか。って。全く理解せずにチュートリアルとかをやってみる。

そしたら、自分が興味ある部分とかツールの使いかたが分かってくる。

4. 公式ドキュメントを読む

自分が興味ある部分だけに絞って読む。

5. ちゃんと作ってみる

そしたら「あれ?この部分はどうなってるんだろう?」って細かいところが気になりだす。

6. Stack Overflowや公式ドキュメントを読む

細かい部分が気になってくると、Stack Overflowが色々教えてくれる感じになる。今まで目に入ってなかった公式ドキュメントのNoteとかも理解できはじめる。

7. 適当に公式ドキュメントを読む

自分がちゃんと読んだところ以外も、面白そうなところを読んでみる。何かが気になった時に「確か公式のあの辺に書いてあったな」って戻ってこれる程度に。

こんな感じの繰り返しをしてるっぽい。

あと、ブログに書く

と、自分の考えを整理しながら色々気づくことができて良いですね。