SRE兼スクラムマスターのブログ

チーム開発が好きなエンジニアブログです。検証した技術やチームの取り組みを書いていきます。

VSCode の Remote Development を使って開発者体験を上げる

はじめに

Remote Developmentとは

Remote Developmentは, VSCode からServerやWindows Subsystem for Linux (WSL), Containerなどの VSCode を実行しているホスト以とは別の環境に接続し, Server上のワークスペースを開発環境のように扱うことができる. これにより環境構築済みのServerへVSCodeから直接アクセスすることができ,開発者間での環境を簡単に統一できたり, ローカル環境に影響を与えず, 開発環境を構築/削除が容易にできる.

code.visualstudio.com

試してみる

今回はMacを使い, SSHで他のサーバに接続する手順を説明する.

拡張機能インストール

はじめに, Remote Development拡張機能をインストールする. VSCodeRemote Developmentを検索し,インストールする. Remote Development をインストールすると,Remote WSL, Remote SSH, Remote Containers のようにそれぞれに接続するための 拡張機能が自動的にインストールされる. とくにRemote WSL はWSLを利用しているWindowsユーザーにとっては便利機能だと思う.

f:id:JunichiMitsunaga:20201130232217p:plain
Remote Development Extension

SSH接続

サーバへの接続はSSHを用いて行われるため,鍵認証方式でサーバとSSH接続できるようにセットアップしておく必要がある. 今回は, Microsoft Azure 上に仮想マシンを作成してそこに接続する.

docs.microsoft.com

VSCode の左側のRemote Development タブを開くと接続先一覧が表示される.すでにsshで接続するために,~/.ssh/configなどがある場合は読み込まれて設定している接続先一覧が表示される.

configファイルを持っていない場合は,No SSH hosts...のような表示が出ているので,ギアクリックしてSSHのconfigファイルを作成する.

f:id:JunichiMitsunaga:20201201001208p:plain
Remote SSH Extension 1

config ファイルを以下のformatで作成する.

# Read more about SSH config files: https://linux.die.net/man/5/ssh_config
Host host1
    HostName xxx.xxx.xxx.xxx (IPアドレス, DNSなど接続先)
    Port 22
    User hoge (ログインするユーザ名)
    IdentityFile ~/.ssh/sample_rsa (鍵認証に使う鍵ファイルを記述)

configファイルを設定するとconfig のhostが表示されるので選択して接続する.

f:id:JunichiMitsunaga:20201201001501p:plain
Remote SSH Extension 2

f:id:JunichiMitsunaga:20201201110835p:plain
Remote SSH Extension 3

「Continue」を選択する.

f:id:JunichiMitsunaga:20201201111058p:plain
Remote SSH Extension 4

接続が成功したら,「Open Folder」から接続先のフォルダを選択して操作できるようになる.

f:id:JunichiMitsunaga:20201201111250p:plain
Remote SSH Extension 5

Container 接続

接続するために, nginx のimageをpullして起動しておく.

$docker run --name remote-sample -d -p 8080:80 nginx
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
c164ead158ca        nginx               "/docker-entrypoint.…"   15 seconds ago      Up 13 seconds       0.0.0.0:8080->80/tcp   remote-sample

nginx が起動したのを確認して, Remote Development タブを開くと, Containers に nginxが表示される. リアルタイムで表示されなかったが,VSCodeを再起動したら表示された.

f:id:JunichiMitsunaga:20201130235455p:plain
Remote Containers Extension 1

nginx を選択して, 「Attach Container」を選ぶと nginx containerに接続して, container内部の情報をVSCodeで閲覧して修正できる. 添付画像は container 接続後に /etc/nginx 配下のfileを確認している.

f:id:JunichiMitsunaga:20201130235915p:plain
Remote Containers Extension 2

他にもチュートリアル用のContainerが用意されているので,そちらで各開発言語が含まれているContainerに接続できる.

code.visualstudio.com

終わりに

別環境をローカル環境のように扱うことができ,かつ使い慣れたエディタで開発できることは非常に便利になった. 環境構築されたContainerやServerを使うことで初期設定のコストが削減される. またローカル特有の問題に影響を受けることも少ない.

Flux v2 を使った GitOps チュートリアル Flux v1 との比較

Weaveworks社が提唱する kubernetes のベストプラクティスで , Single Source of Truth として Git を採用し,Kubernetes リソースなどを継続的にデリバリーしていく GitOps がある。 今回はそんな GitOpsを実現するツールである Flux のv2が出てきたのでチュートリアルを試し、 v1との比較を行っていく。

なお、 GitOps の説明や過去にv1を検証した内容は以下の記事等に紹介がある。

Get started

今回は Flux v2の動作を確認するために「Get started」の内容に沿って実施していく。 toolkit.fluxcd.io

事前準備

localに kubernetes 環境を構築する。 今回は minikube を使って cluster の構築を行う。 kubernetes.io

$ kubectl version --short
Client Version: v1.19.3
Server Version: v1.19.2

次に Flux を操作するためのクライアントをインストールする。 v1の時は fluxctl だったが、v2からは flux に変更されている。

$curl -s https://toolkit.fluxcd.io/install.sh | sudo bash
$flux --version
flux version 0.2.3

最後にチュートリアルで使う GitHub リポジトリをフォークしておく。 github.com

セットアップ

flux を使って, Flux に対応した環境か確認する。

$ flux check --pre
► checking prerequisites
✔ kubectl 1.19.4 >=1.18.0
✔ Kubernetes 1.19.2 >=1.16.0
✔ prerequisites checks passed

環境の問題はなさそうなので,環境変数GITHUB_TOKEN GITHUB_USER GITHUB_REPOを設定して flux bootstrapコマンドを実行する。

$ export GITHUB_TOKEN=<your-token>
$ export GITHUB_USER=<your-username>
$ export GITHUB_REPO=<repository-name>

$ flux bootstrap github \
    --owner=${GITHUB_USER} \
    --repository=${GITHUB_REPO} \
    --branch=main \
    --personal \
    --path=clusters/staging
► connecting to github.com
✔ repository cloned
✚ generating manifests
✔ components are up to date
► installing components in flux-system namespace

namespace/flux-system created
networkpolicy.networking.k8s.io/allow-scraping created
networkpolicy.networking.k8s.io/allow-webhooks created
networkpolicy.networking.k8s.io/deny-ingress created
role.rbac.authorization.k8s.io/crd-controller-flux-system created
rolebinding.rbac.authorization.k8s.io/crd-controller-flux-system created
clusterrolebinding.rbac.authorization.k8s.io/cluster-reconciler-flux-system created
customresourcedefinition.apiextensions.k8s.io/buckets.source.toolkit.fluxcd.io created
customresourcedefinition.apiextensions.k8s.io/gitrepositories.source.toolkit.fluxcd.io created
customresourcedefinition.apiextensions.k8s.io/helmcharts.source.toolkit.fluxcd.io created
customresourcedefinition.apiextensions.k8s.io/helmrepositories.source.toolkit.fluxcd.io created
service/source-controller created
deployment.apps/source-controller created
customresourcedefinition.apiextensions.k8s.io/kustomizations.kustomize.toolkit.fluxcd.io created
deployment.apps/kustomize-controller created
customresourcedefinition.apiextensions.k8s.io/helmreleases.helm.toolkit.fluxcd.io created
deployment.apps/helm-controller created
customresourcedefinition.apiextensions.k8s.io/alerts.notification.toolkit.fluxcd.io created
customresourcedefinition.apiextensions.k8s.io/providers.notification.toolkit.fluxcd.io created
customresourcedefinition.apiextensions.k8s.io/receivers.notification.toolkit.fluxcd.io created
service/notification-controller created
service/webhook-receiver created
deployment.apps/notification-controller created
Waiting for deployment "source-controller" rollout to finish: 0 of 1 updated replicas are available...
deployment "source-controller" successfully rolled out
Waiting for deployment "kustomize-controller" rollout to finish: 0 of 1 updated replicas are available...
deployment "kustomize-controller" successfully rolled out
deployment "helm-controller" successfully rolled out
Waiting for deployment "notification-controller" rollout to finish: 0 of 1 updated replicas are available...
deployment "notification-controller" successfully rolled out
✔ install completed
► configuring deploy key
✔ deploy key configured
► generating sync manifests
✔ sync manifests pushed
► applying sync manifests
◎ waiting for cluster sync
✔ bootstrap finished

$ kubectl get all -n flux-system

NAME                                           READY   STATUS    RESTARTS   AGE
pod/helm-controller-7fc55767cc-bfzck           1/1     Running   0          4m51s
pod/kustomize-controller-6b85bf79f9-t6qs4      1/1     Running   0          4m51s
pod/notification-controller-7bb8667967-6xqdb   1/1     Running   0          4m48s
pod/source-controller-6cdb6c8889-hpsxx         1/1     Running   0          4m53s

NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/notification-controller   ClusterIP   10.108.140.72    <none>        80/TCP    4m50s
service/source-controller         ClusterIP   10.104.224.8     <none>        80/TCP    4m53s
service/webhook-receiver          ClusterIP   10.103.160.216   <none>        80/TCP    4m48s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/helm-controller           1/1     1            1           4m51s
deployment.apps/kustomize-controller      1/1     1            1           4m53s
deployment.apps/notification-controller   1/1     1            1           4m48s
deployment.apps/source-controller         1/1     1            1           4m53s

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/helm-controller-7fc55767cc           1         1         1       4m51s
replicaset.apps/kustomize-controller-6b85bf79f9      1         1         1       4m52s
replicaset.apps/notification-controller-7bb8667967   1         1         1       4m48s
replicaset.apps/source-controller-6cdb6c8889         1         1         1       4m53s

bootstrap コマンドで flux-system のnamespaceが作成されて, GitOpsを実施するための kustomize , helm のcontrollerが作成されている。 この他にもv2では監視機能が強化されたこともあって notificationのcontrollerが作成されている。 Flux v1flux-agentmemcacheのみだったのに対して役割に応じてcontrollerが増えているようだ。 Flux v2 の全体構成は公式に掲載されている図が非常に分かりやすい。

           Flux v2 構成図 https://toolkit.fluxcd.io/diagrams/gitops-toolkit.png

           Flux v2より引用

なお、bootstrapで対象にしたrepository で管理されているmanifestがclusterに展開されていることが分かる。

$ flux get kustomizations --all-namespaces
NAMESPACE       NAME            REVISION                                        SUSPENDED       READY   MESSAGE
flux-system     apps            main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1   False           True    Applied revision: main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1
flux-system     flux-system     main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1   False           True    Applied revision: main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1
flux-system     infrastructure  main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1   False           True    Applied revision: main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1


$ flux get helmreleases --all-namespaces
NAMESPACE       NAME    REVISION        SUSPENDED       READY   MESSAGE
nginx           nginx   5.6.14          False           True    release reconciliation succeeded
podinfo         podinfo 5.0.3           False           True    release reconciliation succeeded
redis           redis   11.3.4          False           True    release reconciliation succeeded

GitOps実践

初期状態の確認

まず, bootstrapでデプロイされた初期のappにアクセスするためにport-forwardする。

$ kubectl -n podinfo port-forward svc/podinfo 9898:9898

Forwarding from 127.0.0.1:9898 -> 9898
Forwarding from [::1]:9898 -> 9898
Handling connection for 9898
Handling connection for 9898

ブラウザからlocalhost:9898にアクセスすると、下記のようなサンプルアプリケーション画面が表示される。なお、初期状態ではv5.0.3と表示される。

サンプルアプリケーション画面初期状態
flux v2 gitops before

マニフェストの修正

GitOps対象のリポジトリ flux2-kustomize-helm-example の中にあるマニフェスト flux2-kustomize-helm-example/workloads/apps/staging/podinfo-values.yamlを修正する。chart.spec.version: ">=1.0.0-alpha"chart.spec.version: "5.0.0"に変更し、repositoryにpushしておく。

podinfoを確認すると変更されたことが確認できる

$ flux get helmreleases --all-namespaces
NAMESPACE       NAME    REVISION        SUSPENDED       READY   MESSAGE
nginx           nginx   5.6.14          False           True    release reconciliation succeeded  
podinfo         podinfo 5.0.0           False           True    release reconciliation succeeded  
redis           redis   11.3.4          False           True    release reconciliation succeeded

再度、ブラウザから確認する

$ kubectl -n podinfo port-forward svc/podinfo 9898:9898
Forwarding from 127.0.0.1:9898 -> 9898
Forwarding from [::1]:9898 -> 9898

versionが 5.0.0に変更していることが分かる これによりgitの結果を正とした GitOpsが実現できている

f:id:JunichiMitsunaga:20201118094212p:plain
flux v2 gitops after

モニタリングを設定

Flux v1では flux agentの監視が困難であり、同期の失敗を検知/修正するまでに時間がかかっていたが、 Flux v2 になってからは Prometheusによる監視と Grafanaダッシュボードが提供された。チュートリアルでは扱っていないが、有用な仕組みなので試してみる。

flux2リポジトリにあるmanifestから作成する

$ flux create source git monitoring \
>   --interval=30m \
>   --url=https://github.com/fluxcd/flux2 \
>   --branch=main
✚ generating GitRepository source
► applying GitRepository source
✔ GitRepository source created
◎ waiting for GitRepository source reconciliation
✔ GitRepository source reconciliation completed
✔ fetched revision: main/37fb0f632b7acd192a314388c8f6bab5a6376764

$ flux create kustomization monitoring \
  --interval=1h \
  --prune=true \
  --source=monitoring \
  --path="./manifests/monitoring" \
  --health-check="Deployment/prometheus.flux-system" \
  --health-check="Deployment/grafana.flux-system"

✚ generating Kustomization
► applying Kustomization
✔ Kustomization created
◎ waiting for Kustomization reconciliation
✔ Kustomization monitoring is ready
✔ applied revision main/37fb0f632b7acd192a314388c8f6bab5a6376764

kubectl -n flux-system port-forward svc/grafana 3000:3000

ブラウザでダッシュボードにアクセスすると GitOps 状態が確認できる。

Control planeのダッシュボード

http://localhost:3000/d/gitops-toolkit-control-plane/gitops-toolkit-control-plane

f:id:JunichiMitsunaga:20201118100432p:plain
control

Cluster reconciliationのダッシュボード

http://localhost:3000/d/flux-cluster/flux-cluster-stats

f:id:JunichiMitsunaga:20201118100354p:plain
cluster

v1との比較

導入のしやすさ

v2になってbootstrap コマンドが追加されたことによって、コマンド1つで設定できるため、v1と比較してnamespaceの準備等がなくなり、簡単に設定できるようになった。

監視

Flux v1 のlogを監視して、errorが発生した場合にトラブルシューティングするなど、泥臭いことをやっていた(少なくとも自分の環境では)。 Flux v2PrometheusGrafanaが提供されたので、metricsの取得やダッシュボードによる可視化が可能になり、保守性が高まった。 また、slackへの通知などの機能も提供されたので、障害発生から検知までの時間短縮に繋がる。

構成

Flux v1はflux agentが1つだったことに対して、Flux v2では役割毎にcontrol planeが分かれた。個人的には役割が明確になったため、トラブルシューティングが簡単になり、かつ自分たちの環境にマッチした最小構成を構築するのが容易になったと感じた。

まとめ

Flux v2チュートリアルを実施してみたが、Flux v1の時よりも導入は容易になったと感じる。 CLIに関しての変更はv1ユーザーにとっては破壊的変更なため、v2へ移行するには時間がかかりそうだ。しかし、移行した場合は、監視や通知といったこれまで苦戦していた部分が提供されているので、時間をかけてしっかり移行していきたいと思う。

移行の手順は用意されているのでcluserの移行だけなら簡単そう。 pipelineやその他の仕組みでFlux CLIを使っている場合は、考慮が必要そう。

toolkit.fluxcd.io

「ONE TEAM」を目指したが、コラボレーションは簡単じゃない

はじめに

2019年にラグビーワールドカップで「ONE TEAM」という言葉が流行り、ラグビーだけでなく仕事場でも「ONE TEAM」という言葉を使ってチーム作りしている現場もあると思います。 私の現場も「ONE TEAM」というキーワードが出てきてみんな賛同して目指すことになりました。しかし、いざ目指してみるとチーム間でコラボレーションするのがすごく大変だったので解消するためにやったことを残しておきます。

「ONE TEAM」を目指してどうなっていたのか?

「ONE TEAM」を目指そうと話が出たときは、プロジェクト全員が乗り気でかつ自分たちなら達成できると考えていたと思います。しかし、「ONE TEAM」というのはノープランで目指すべきものではないです。

ここではノープランで「ONE TEAM」を目指した結果

  • チーム間で上下関係ができた
  • サイロ化した

の2つの事象が発生しました。

チーム間で上下関係ができた

私たちのプロジェクトはクロスファンクショナルなチームもいれば専門性の高いチームも存在しています。 そんな中、スクラム開発しているチームのスプリントレビュー時に、専門性の高いチームのメンバーが参加すると、 ときどきちゃぶ台返しのような事態も発生します。

サイロ化した

「チーム間で上下関係ができた」ことも原因の1つになると思うのですが、こうして各チームでのサイロ化が急速に進みました。 このころになると、「設計時に困ったら呼んでください」といっても、あまり呼ばれなくなったりとチーム間の交流は少なくなりました。

なぜ「ONE TEAM」にならないのか?

「上下関係ができる」、「サイロ化が進む」で「ONE TEAM」を目指す前は良いペースで進んでいたプロジェクトが徐々に失速しました。 そこでなぜ失敗したかをふりかえっていきます。

なぜ上下関係ができたか

まずはなぜ上下関係ができたかを考えてみます。 個人的には上下関係ができたのはスプリントレビュー時のちゃぶ台返しや「設計時に困ったら呼んでください」などの「困ったら呼んでください」といった発言なのかなぁっと思います。ちゃぶ台を返した時点で建設的なレビュー者ではなく、チームにとってはちゃぶ台を返したメンバーがフェーズゲート(承認者)のように見えていたと思います。そこで、なぜちゃぶ台を返すかをヒアリングしたところ、チームによって達成すべきミッションが異なるからということが分かりました。達成するミッションが異なるので各チームでプロダクトに対する優先順位も異なるのでリリースできる・できないの判断基準が異なったのです。

これ以外にも細かい部分では「困ったら呼んでください」という声かけも「呼んでください」という表現は呼ぶ側と呼ばれる側で心理的に対等にならないとも感じました。

なぜサイロ化したのか

サイロ化したのは「上下関係ができた」ことも原因の1つだと考えていますが、チーム間でコラボレーションする方法を知らなかったことが根本原因だと感じています。プロジェクトでチームが増えてこれまでと同じやり方でうまくいかないのは明白なのに、コラボレーションする仕組みを作ることをしなかったのが問題だと思います。

取り組んだこと

なぜ失敗したかをふりかえり

  • ミッションの違いによる問題
  • 上下関係を感じてしまう心理的な問題

の2つの観点で問題があると考え、これらの問題を解決するための仕組みを作りました。

ミッションの違いによる問題を解決するために

ちゃぶ台返しが良く発生していたのはSREチームとスクラムチームでした。 そこでシステムのSLO(Service-level objective)*1を策定しました。 SLOという明確な基準値を設けることにより各チーム間で基準値内の場合はお互いの自由を許容するというルールにしました。

上下関係を感じてしまう心理的な問題

ミッションの問題と違って明確な数値を設定できるものではないのでコミュニケーションの機会を増やすようにしました。 具体的には

  • 各チームのタスクボードを共有する時間を作る
  • 合同でlearning sessionを実施する
  • 心理的安全性を実現するためにスキルを習得する

の3つに取り組んでいます。

まとめ

ノープランやスキルない「ONE TEAM」は実現しない ミッションが異なるチームでコラボレーションするには?

  • 共通言語を作る
    • 自分たちの場合はSLOを作成する

心理的な問題を解消するには?

  • スキルを身につける
  • コミュニケーションの機会を増やす
    • 合同でlearning sessionを実施する
    • 各チームのタスクボードを共有する時間を作る

すぐ取り組めるものから、エンジニアリングが必要なものもありますが、私たちのプロジェクトは仕組みを導入してから以前よりも雰囲気が良くなりました。 チーム間でギクシャクしているなと感じることがあったら、ぜひ立ち止まってふりかえってみてください。その時のアクションプランの参考になれば幸いです。

参考

スキルやサイロ化について学習したときの書籍の一部です。 ここでは紹介しませんが、ファシリテーション系の書籍で得た知識も大変役に立ちました。SLOについてはもともと知っており、SRE本に詳しく書かれています。

amzn.to

amzn.to

*1:サービルレベル目標(service level objective)であり、SLIで計測されるサービスレベルのターゲット値、あるいはターゲットの範囲を指します。

チームサポートするにあたって心掛けていること

はじめに

社内で新しいチームにをサポートしていくことになりました。 チームリーダーの方やマネージャーと「1 on 1」を実施して、抱えている問題や 自分が協力できそうなことを話し合い、7月から本格的にサポートしていくことになりましたが、自戒の念を込めてサポート時に心掛けようとすることをいくつかまとめておこうと思います。

心掛けていること

この内容がすべてではないですが、チームサポートするにあたって、とくに初期段階でおろそかにしないように気をつけたいことになります。

サポートに徹することを明確にする

自分がチームサポートする時に、「チームが、良い方向に進められるように全力を尽くします。しかし、実際に良いチームを作るのは皆さん自身です。」ということを伝えるようにしています。チームメンバー自身に 良いチームを作る意思がなかったり、サポートに参加する自分がすべてを決定するようでは、最終的に自己組織化されたチームが生まれにくいからです。 自己組織化するために必要なチームの対話や、メンバー間のコラボレーションについては、知識やスキルが必要になるので実践の方法やアクティビティについてアウトプットするようにしています。

チームの目標を統一する

チームの目標について共通認識をもつようなプラクティスを実施するようにしています。なぜならば、これまでのチームサポートの経験では、 「目標が人によってバラバラである」 「目標が明確でも達成するための道筋は不明瞭である」 といった状態が多く、総じて同じ方向を向いてることが少ないです。

その場合は「インセプションデッキ」を使って目標、これからの進め方について議論し、理解し、合意するフェーズを設けています。 しかし「インセプションデッキ」は時間のかかるプラクティスで、チームによっては、そのようなイベントに抵抗がある場合も多いです。そういったときは、ふりかえりでも使われる「帆船」を使って自分たちの目標や立ち位置を明確にしていただいてます。

インセプションデッキ」や「帆船」の詳しいやり方は説明しませんので こちらの記事を参照してください。

takaking22.com

note.com

メンバーの価値観を可視化する

同じチームでコラボレーションしてくには、メンバー間で得意なことや 大切にしている価値観を開示していることが大切です。これを実現するために 自分がよく取り入れているのは「ドラッカー風エクササイズ」です。 実践することで 「何に対してモチベーションを感じるのか?」 「どういう部分で協力があると良いのか?」 という点で、メンバーに伝えることもできるし、言語化することで自分自身にも新しい気づきが生まれます。

ドラッカー風エクササイズ」詳しいやり方は説明しませんので こちらの記事を参照してください。

tech.pepabo.com

アジャイル」という言葉を使わない

これも経験談ですが、「アジャイル」という言葉を使わない方が割とうまくいくことが多かったです。これに関しては「アジャイル」のみならず、新しすぎる横文字なども多用しないようにしています。 その理由は、下記の2つではないかと推測しています。 「過去にアジャイル手法だけやって、うまくいかなかった」 「大きな変化を求められているようで抵抗感があった」 前者は、何度か見てきたことがあるのですが人は一度うまくできなったことに対してもう一度チャレンジするのは心理的にハードルが高いからです。 後者は、自分たちのこれまでのやり方が否定されているように感じるからだと思います。 私自身「アジャイルをやろう」というフレーズは、本質を見誤っているようで好きではないです。自分たちが働きやすく、成果を届けられるようにカイゼンを続けた結果「アジャイルな状態」になっていた!くらいがちょうどよいと考えています。

まとめ

久々に新しいチームのサポートをすることになったのでだいぶ緊張しているので サポート時に気をつけたいことまとめました。 まとめていて思ったのはフレームワークやプラクティスを適用する時は チームの成熟度に合わせることが重要ということです。 1つのチームでうまく言った方法が全てのチームでうまくいくと考えると大変なことになるので肝に銘じてやっていこうと思います。 自戒のために心がけをまとめてみましたが、「こういうのも大事だよ!」っていうのがあればコメント頂けると嬉しいです

「1 on 1」ふりかえったら自分のためになっていた

はじめに

去年の9月に新チームが発足し、チームメンバーに何かできることがないかを考えたときに「1 on 1」という選択肢を選択しました。 そこから「1 on 1」を始めて半年以上たちましたので、やってきたことをふりかえり、気づきをまとめようと思います。 これから「1 on 1」を始めてみようという方や迷っている方の参考になればと思います。

ふりかえり

ふりかえるために、頭の中で考えていたことを「マインドマップ」で表現しています。

ここから各項目について文章でまとめておきます。

※ツールはMiroを使っています。

1 on 1 マインドマップ
マインドマップ

背景

1 on 1をはじめたもっとも大きな理由は「評価」です。 半期に1度メンバーの評価を行うシステムでしたが、感じた課題は「フィードバックが遅い」ことです。 個人的には半年の評価時に「評価低いよ」といわれるのが、誰も幸せにならないと感じていたからです。 評価を受ける人も、「今自分はこう思われているんだな」、「こういうことをやった方が良いな」など 短期でフィードバックされれば、途中からカイゼンできる可能性だってあります。 そういった評価に対するもどかしさを解決したい思いで「1 on 1」を導入しました。

実態

背景で述べたように、モチベーションは「評価」でした。 しかし、実際に「1 on 1」を進めていくと、テーマが徐々に変化したので時系列ごとに書きます。

1~2ヵ月

  • 目標/評価ベース

初めのうちは予定通り、評価するために「1ヵ月」「2ヵ月」「3ヵ月」の目標を立ててもらい定期的にフィードバックしました。 この方法によって定めた目標に対して停滞しているようであればカイゼンのアクションを話し合ったり成果の見える化に注力していた時期です。 いまふりかえると、この時の「1 on 1」は割と自分が発言しており参加メンバーは同意が多かったと思います。 効果として、目標や課題駆動で物事に取り組む習慣がついたように感じます。

2~4ヵ月

  • ふりかえり/アクションベース

目標が明確になったため、「ふりかえり」を中心に進めました。 @viva_tweet_xさんのふりかえり読本にもある ふりかえりの「型」を意識してふりかえりました。 メンバーの抱えている内容によって「学びを最大にする」、「多角的に捉える」、「問題を解消する」などなど 使い分けました。 効果として、立ち止まって考えることで仕事の問題をカイゼンできたことや、メンバーとの信頼関係が気づけました。 このころになると、「1 on 1」では、傾聴が中心になりメンバーの発言がほとんどでした。

4ヵ月~

  • フリーテーマ

メンバーの発言がほとんどなため、とくに「テーマ」を決めず、話したいことを話してもらいました。 変化が表われたと感じたのは、整理できてなくてもどんどん発言してくれることです。 1 on 1の場を自分の考えを整理する場や課題を解決するための場として認識し、トレーニングできるので 会議などでも、考えをまとめて発言したりまとまらないときに困っていることを伝えるなど言語化してつたえる力がついたと思います。

ラクティス

1 on 1をやるにあたって、実施したプラクティスやツールを書いておきます。

  • チェックイン

ふりかえりによくある「場を設定する」方法です。簡単な質問をしてメンバーに答えてもらいます。 たとえば「今の気持ちを一言で答えてください」のように業務に関係ないことでも問題ありません。 1 on 1という場だと、評価する側、評価される側の構図ができやすく発言しにくい空気になるので 気軽に発言できる場を作るために取り入れました。

  • プラス/デルタ

同じくふりかえりである「ふりかえりを終了する」方法です。今回はふりかえりでなく1 on 1です。 1 on 1自体のフィードバックをします。プラス(続けたいこと)デルタ(カイゼンしたいこと)で それぞれ考えてもらいました。自分たちにとってより良い1 on 1をしたいので取り入れました。

  • 5つのなぜ

ふりかえりで行う方法ばかりな気がしますね。。。「アイデアを出す」ための方法です。 課題や悩みに対して、原因が何なのか?どこがボトルネックなのかを明確にするため取り入れました。 主にメンバーが課題解決を望んでいる場合に使っています。4つめ、5つめくらいの「なぜ」を考えるのが難しいです。

  • 1 on 1カード

XP祭りのときに存在を知りました。 1 on 1実施時に会話の引き出しを増やすために使うことがあります。あまりしゃべらない人のときに非常に役立ちます。

  • 外部1 on 1を受ける

私自身が1 on 1を受けたことが無かったので、体験するために外部の方に1 on 1して頂きました。 会社の中で行うのとは別の視点から物事を捉えるので発見が多い場になりました。その時の振り返りはこちらにまとめてあります。

cabi99.hatenablog.com

学び

学びはたくさんありましたが、とくに学びが大きかったことを紹介します。

  • やり方より在り方

人と接する時に効果的にできる「やり方」はもちろん大切です。 とくに1 on 1を始めたころは私自身「やり方」に固執していました。しかし、 1 on 1を実施し体験することで 過去に1 on 1体験したときにも感じたのですが、「自分がどうあるか?」「興味をもっているのか?」など 自分の姿勢は言葉にしなくても相手に伝わることが分かりました。そんな相手がアドバイスしようが、話を聞こうが 相手のアクションに繋がらないし、本音を打ち明けてくれることはありません。 なので、成長や変化を促したい場合は、自分が成長し変化する姿勢を見せることがとても重要だと思います。

さいごに

半年とちょっと続けてきた1 on 1についてふりかえり、まとめました。 はじめはメンバーのために始めたことでしたが、気が付くと1 on 1自体が自分の成長にも大きく影響していました。 コツコツカイゼンを続けていく中でメンバーとの信頼関係も築けるので、迷っている方ははじめてみることをオススメします。

参考

参考にした書籍をいくつか載せておきます。

やり方とあり方についてよく説明されている本です。

1 on 1のみならず普段ファシリテーションする中での心がけになります。

  • アジャイルレトロスペクティブズ 強いチームを育てる「ふりかえり」の手引き

ふりかえりの手法について説明しています。

状況や目的に応じた手法が載っています。

  • NLPで最高の能力が目覚める コーチングハンドブック 知識と経験を最大化するセンスの磨き方

コーチングについての全体像が載っています。

1 on 1を組み立てるうえでヒントにしました。

  • ふりかえり読本 実践編~型からはじめるふりかえりの守破離~ - ふりかえり実践会

ふりかえりについて、「型」ベースに説明しています。

具体的な例や目的をわかりやすく説明しています。 booth.pm

  • 会話の引き出しを増やす 1on1カード と 使いこなしブック

初めに何を話したらよいか?

あまり話が続かないときに使ってみると良いかもしれません。

booth.pm

GitOps Days 2020 参加レポート 2日目

はじめに

2020/5/21(木)開催のGitOps Days 2020のDay2に参加してきましたので、 まとめていきたいと思います!

※1日目と同様に発表者ではなく、ただ聞くだけです。。。

1日目の参加レポートはこちらです。 cabi99.hatenablog.com

印象深かったセッションなど

ここでは印象深かったセッション(など)についてまとめていきます。 Day 1ではGitOpsを実際に導入するための具体的な技術をチームに定着させる方法やGitOpsの今後について説明するなど、 1つ1つのセッションが濃ゆい内容になります。

11:00 – 11:57 am PT: Flux and Helm: Intro and How to teach your teams – Stefan Prodan and Leigh Capili

@stefanprodanさん@capileighさんが従来のCI/CDパイプラインの課題を明確にし、GitOpsに変更する利点と具体的なデプロイの流れを説明しデモを見せてくれました。

従来のCI/CDの課題

従来のCI/CDではビルドとデリバリーを自動化できていましたが ここでの問題提起は監視や復旧といったオペレーション観点となっています。 CI/CDを導入しているチームに共通して抱えている課題のように感じます。

トレーサビリティ

  • クラスターで実行されているアプリのバージョンを確認するか?
  • 複数ビルドを並行して実行するとどうなるのか?

セキュリティ

  • クラスター認証の管理方法をどうするのか?
  • 複数クラスターをターゲットにする方法は?

ディザスターリカバリ

  • インフラ依存関係に対処する方法は?

GitOpsに変更する利点

全体的にGitで宣言的に管理できるようになります。 これにより従来のようにrebuildする機会も減り、Gitのマニフェストを 前バージョンに戻すだけで切り戻しができるようになります。 OPAのようなポリシー適応はまだ実現していないので興味深いです。

  • インフラストラクチャの変更についてPRsとレビューで協力できる
  • 静的分析(OPA)でポリシーを適用できる
  • rollbackとrevertが簡単
  • 平均回復時間を短縮できる

GitOps準備

GitOps実現にあたって必要なものを説明しています。

必須

オペレーション

  • リポジトリ変更を監視し、通知する
  • 設定ドリフトを検出して修正する
  • 設定とドリフトに関するアラート
  • コミッターのバリデーションを行う

flux, helmを利用したGitOpsデモ

デモについては省略します。

fluxの使い方はこちらを参考にしてください。 cabi99.hatenablog.com

所感

2日目は1日目に説明した概念について具体的にデモをする場面が多いです。 これから導入する人や動作のイメージがわかない人向けのような気もしました。 2日間を通してGitOpsは概念であり、実現の方法が1つでないこと、そしてセキュリティに対して利点が多いこと。 これらが参加する前の自分になかった視点なのでとても参考になりました。 また、これらの新しい知識をプロダクトチームにoutputできるのでよりチームのDevOpsが促進することを楽しみにしています。 とても有益なイベントでしたので次回開催もぜひ参加したいと思います。

GitOps Days 2020 参加レポート 1日目

はじめに

2020/5/20(水)開催のGitOps Days 2020に参加してきましたので、 まとめていきたいと思います!

※発表者ではなく、ただ聞くだけです。。。

www.gitopsdays.com

GitOps Daysは、私が知っている限りではGitOpsに関するはじめての大きめイベントです。 はじめてGitOpsについて学びたい人や、GitOpsの利点を理解するようにチームを説得する人向けのようです。 現在のプロダクトでGitOpsを導入しているので世界的にGitOpsがどのように浸透しているのか?今後の展望はどうなっていくのか?などに興味を持ち参加しました。

GitOpsとは?

まずGitOpsとは何ぞや?という疑問もあると思うので説明します。 GitOpsはWeaveworks社が提唱した、Kubernetesの運用ベストプラクティスであり、 宣言的インフラストラクチャとアプリケーションの「Single source of Truth」としてGitを利用し、システム実行環境やアプリケーションの変更を行う方法です。

簡単に述べるとgitのcodeと環境面が同期して常にcodeの状態が正になる方法です。 メリットとして、codeですべて管理できる、環境構築が容易になる、セキュリティが向上するなどが挙げられます。

過去にGitOpsを実現するfluxを検証したことがあるので興味がある方はご覧ください。 cabi99.hatenablog.com

印象深かったセッションなど

ここでは印象深かったセッション(など)についてまとめていきます。 Day 1ではGitOpsがどのようなものなのか?概念やメリットを説明しています。 他にも具体的なプラクティスを紹介し、導入企業のエンジニアが事例を紹介しています。

10:00 – 10:27 am PT: GitOps Practitioner Highlight – Palo Alto Networks – Javeria Khan

Javeria KhanさんがGitOpsプラクティスを紹介してくれました。

利用する技術以外にもメリットやオンボーディング時の注意点が興味深かいです。

GitOpsの利点

  1. 可逆性
  2. 監査証跡
  3. 透明性
  4. 反復的なタスクを自動化する
  5. 開発および運用チーム間のコラボレーション

5番以外の利点は認識としてありました。 GitOpsにより環境が同期するため、コード管理時にDevelopとOperationを意識する。 これによりDevとOpsのようにチームが完全分業体制から共通の概念を持つ one teamとして機能しやすいのだと解釈しました。

Layer別の役割と技術

GitOps導入で技術の統一は必須でなく、それぞれの用途に合う仕組みを採用します。 また、環境なのかアプリケーションなのかでオーナシップを持つメンバーが変化します。

インフラ層(IaC)

ステークホルダー

  • SRE
  • Infra Engineers
  • Management

プロビジョニング(例)

  • Terraform → Atlantis
  • Salt → Scheduled states

設定情報(例)

Puppet → code manage Flux, Argo → cluster controllers + config repos

アプリ層

ステークホルダー

  • Developers
  • DevOps, Test Engineers

アプリケーションTemplating, Deployments

  • Helm, Kustomize
  • Flux, Argo: cluster controllers + app manifest
  • Flagger: Blue/Green

オンボーディングで心掛けること

自分たちのチームもGitOpsを導入しているのですが、 オンボーディング時の心掛けはかなり同意です!

  • Dev

    • 時間を先行投資して、仕組みと文化を定着させること
  • Management

    • 個人への依存をなくすこと

12:40 – 1:10 pm PT: GitOps for Cost Efficiency, Compliance, Velocity, Security, Resilience, and more! – Cornelia Davis

@cdavisafcさんによるコスト効率、コンプライアンス、速度などなど良い点をてんこ盛りに説明して頂いてます。

GoogleDevOps Elite performance reportでは、セキュリティについてあまり言及されていないので、ここでGitOpsだよ!と述べています。 システムの可用性、セキュリティを支えるために、必要な要素がGitOpsによりどのようにカイゼンするか?明確になるセッションでした。

GitOpsを支える5つの要素

  • アプリケーションチームの生産性
  • アプリケーションチームの自主性
  • 安全なネットワークの確立
  • 再現性
  • 冗長性

ここは動画が公開されてもう一度視聴してからまとめようと思います。。。

1:10 – 1:17 pm PT: Security and GitOps – Maya Kaczorowski

パズルがアイスクリームと同じくらい大好きな @MayaKaczorowski さんによる GitOpsがもたらすセキュリティの利点の説明です。

個人的には従来のCIOpsのようなpush型デプロイからpull型デプロイへ変更されるため kubernetes clusterのip制御が無くなるので、セキュリティホールのリスクが減る認識でした。 このセッションでは、それ以外にもセキュリティの利点があることを学べました。

セキュリティ利点

管理

さまざまな仕組みが「〇〇 as Code」で実現するため、 バージョニングや不変なものをSingleSourceに集約でき、全体を管理しやすくなる。

監視

デプロイ方法が決まるため、監視しやすい

セキュリティアップデート

デプロイが単純化されるため、セキュリティアップデートに集中する時間が取れる。

軽くまとめてみる?

gitログ、PRコメント、およびレビューポリシーにより、責任を共有しセキュリティの脆弱性の解決に対して協力体制が作れるようです。 同じ指標が持てるようになれば、同じ方向に向かって協力できるようになるのが良いです。 なんだかエンジニアリングでプロジェクトをデザインしている感じが好きです。

GitOps = IaC + Config as Code + Policy as code + Policy as code + thing as code

所感

Day 1は主にGitOpsの抽象的な部分を説明が多かったです。 GitOps自体は哲学であり、それを実現する仕組みは1つでなく、目的に併せて変化するものだと感じました。 実際に導入事例の紹介でも企業によって「GitOps = 〇〇 + △△」の定義が異なることも 多く、各企業が自分たちのモデルにあったものを探して適応している印象です。 もしかすると組織のDevOps習熟度で、この辺は変化していきそうな気がします。

※英語を学習中なので、所々説明している内容と異なるかもしれませんがご了承ください。 むしろ、これはこういうことだよとかフィードバックがあると嬉しいです。