kakakakakku blog

Weekly Tech Blog: Keep on Learning!

モノリス分割はこうやる!「How to break a Monolith into Microservices」を読んだ

研修中に「マイクロサービス」の解説をしていると,たまに「モノリス分割」に関する質問が出てディスカッションをすることがある.当然ながら万能な分割アプローチはないけど,例えば DDD (Domain-driven design) などのアプローチを選択するなど,選択肢はいろいろある.そして最近「モノリス分割」に役立つアプローチを紹介した martinfowler.com の記事「How to break a Monolith into Microservices」を読んだ.

具体的には以下の「計8種類」のアプローチが紹介されている.原著を翻訳するのではなく,あくまで個人的なメモとしてまとめる.なお,日本語も個人的に載せているため,参考程度にしてもらればと!

  1. Warm Up with a Simple and Fairly Decoupled Capability(シンプルかつ分離された機能で準備する)
  2. Minimize Dependency Back to the Monolith(依存関係を最小限に抑えてモノリスに戻す)
  3. Split Sticky Capabilities Early(厄介な機能を早めに分割する)
  4. Decouple Vertically and Release the Data Early(垂直分割でデータを早めに分割する)
  5. Decouple What is Important to the Business and Changes Frequently(ビジネス的に重要で頻繁に変更される機能を分割する)
  6. Decouple Capability and not Code(コードではなく機能を分割する)
  7. Go Macro First, then Micro(まずマクロ,次にマイクロ)
  8. Migrate in Atomic Evolutionary Steps(小さい進化的なステップで移行する)

martinfowler.com

前提

原著は「デリバリーチーム(開発者 / 設計者 / 技術マネージャー)」に対して「モノリス分割に役立つアプローチ」を紹介することを目的にしている.なお,解説を具体的にイメージできるように「オンライン小売アプリケーション (multitier online retail application)」がテーマになっている.そして,マイクロサービスの基礎は書籍「マイクロサービスアーキテクチャ」などを読んで理解していることが前提になる.

マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャ

  • 作者:Sam Newman
  • 発売日: 2016/02/26
  • メディア: 単行本(ソフトカバー)

1. Warm Up with a Simple and Fairly Decoupled Capability(シンプルかつ分離された機能で準備する)

マイクロサービスを実践するためには,デプロイパイプラインを構築したり,分散アプリケーションをモニタリングしたり,最低限の運用準備が必要になる.そこで,第一歩として「モノリスから分離された機能 (capabilities that are fairly decoupled from the monolith)」から着手していく案はどうか?と書いてある.モノリスから分離されていれば,デプロイパイプラインの検証をするなど,影響を少なくできる.またチームメンバーのスキルアップにも繋がり,マイクロサービスの運用を実践できるメリットがある.「オンライン小売アプリケーション」で言えば「エンドユーザー認証サービス」「顧客プロファイルサービス」が例として挙げられている.

やはり,実際に経験することは重要だし,明確に「チームメンバーのスキルアップ」の必要性まで言及されているのは素晴らしい!と同時に「エンドユーザー認証サービス」は第一歩にしては影響が大きすぎるのでは?とも思った.あくまで例ということで!

2. Minimize Dependency Back to the Monolith(依存関係を最小限に抑えてモノリスに戻す)

マイクロサービスのメリットとして「リリースサイクルが独立していること」が挙げられる.しかし,マイクロサービスがモノリスに依存している場合は,モノリスのリリースサイクルに依存し,メリットが失われる可能性がある.例えば「チェックアウト機能」「購入機能」「プロモーション機能」があり,この順番で実行される場合に,1番依存が少ないと言える「プロモーション機能」からマイクロサービスに分割していくと書いてある(原著に載っている図を見るとわかりやすい).もしマイクロサービスからモノリスに依存をしてしまう場合は「腐敗防止層 (Anti-Corruption Layer)」経由でアクセスすれば,モノリスの内部実装を漏れ出さないようにできる.「腐敗防止層」に関しては以下の記事でも紹介されている.

martinfowler.com

3. Split Sticky Capabilities Early(厄介な機能を早めに分割する)

今度はモノリスの中で具体的なドメイン概念として確立されてなく,多くの機能に依存している機能を特定して分割していく.このような機能を早めに分割しないと将来的に苦労することになると書いてある.「オンライン小売アプリケーション」で言えば「セッション機能(ユーザー情報 / アクセス履歴 / ウィッシュリストなど)」が例として挙げられている.ポイントは,単純に「セッションサービス」として分割するのではなく,ドメインを意識して「プロファイルサービス」「ウィッシュリストサービス」などに段階的に分割していく.具体的なテクニックとしては Structure101 を使って,依存度を確認すると書いてあるため,Class 構造まで考慮して,ドメインを特定すると良さそう.

structure101.com

4. Decouple Vertically and Release the Data Early(垂直分割でデータを早めに分割する)

次に「データストア」に着目する.モノリス分割を進めたとしても「データストア」に依存してしまうと,本質的には独立しているとは言えず,マイクロサービスの原則も満たせなくなる.そこで「UI / Backend / Data」という水平分割ではなく「Service A (UI / Backend / Data)」「Service B (UI / Backend / Data)」のように垂直分割をしていく.

原著とは関係ないけど「データストア」を分割するときに「共有データ (Shared Data)」の取り扱いが難しいと思う.個人的に以下の「Managing Data in Microservices」というスライドが参考になり,今まで何度も読んでいる(YouTube もある).Synchronous LookupAsync event + local cache など.合わせて読んでもらえると良いかなと!

www.slideshare.net

5. Decouple What is Important to the Business and Changes Frequently(ビジネス的に重要で頻繁に変更される機能を分割する)

闇雲に着手するのではなく,モノリス分割をする「コスト」と得られるメリットと比較しながら継続的に評価していく.もしモノリス分割の目的が「既存機能への変更を加速させること」なら,頻繁に変更されている機能を特定する必要がある.Git リポジトリのコミットを確認したり,プロダクトマネージャーにヒアリングをして,今後頻繁に変更される可能性のある機能を特定することもできる.

「オンライン小売アプリケーション」で言えば「パーソナライゼーション機能」はユーザーに最高の体験を提供するために頻繁に変更が行われるため,例として挙げられている.具体的なテクニックとしては CodeScene を使って,ビジネスと技術を可視化すると書いてある.

codescene.com

6. Decouple Capability and not Code(コードではなく機能を分割する)

モノリス分割をするときに,戦略は大きく「コードを抽出する」「機能を書き換える」に分けられる.コードを抽出する場合,既存の実装をそのまま再利用することも多く,それは「IKEA 効果(自分で組み立てたから愛着が湧くこと)」によるバイアスが含まれていると書いてある.このようなバイアスがあると,モノリス分割の努力を妨げる可能性がある.そこで,機能を書き換えることにより,レガシープロセスや歴史的な仕様を見直すことができ,結果的にシンプルなコードになる.「IKEA 効果」という言葉は今まで知らなかった!

en.wikipedia.org

7. Go Macro First, then Micro(まずマクロ,次にマイクロ)

モノリス分割をするときに「境界」を特定することは「芸術 (art)」でもあり「科学 (science)」でもある.DDD (Domain-driven design) でよく知られた「境界付けられたコンテキスト (Bounded Context)」を見つけることに取り組むべきと書いてある.サービス全体(マクロ)を俯瞰しながら,徐々にサービス個々(マイクロ)に進んでいく.「オンライン小売アプリケーション」で言えば「カート機能」「チェックアウト機能」「購入サービス(カート機能とチェックアウト機能を含む)」として大きくサービス化して,段階的に「カートサービス」「チェックアウトサービス」に移行していくことができる.

martinfowler.com

8. Migrate in Atomic Evolutionary Steps(小さい進化的なステップで移行する)

モノリス分割は長期化するプロジェクトであり,マクロな条件に変化があると再計画が必要になり,資金不足になることもある.継続的にアプローチをするために小さく進化的なステップで移行するべきと書いてある.また「進化的アーキテクチャ」に載っている「適応度関数」を意識するべきという話も載っていた.正直「進化的アーキテクチャ」は1度読んだけど,うまく理解できずに挫折した.「8. Migrate in Atomic Evolutionary Steps」の内容は少し読みにくかった.

進化的アーキテクチャ ―絶え間ない変化を支える

進化的アーキテクチャ ―絶え間ない変化を支える

具体的な例としては「1. Warm Up with a Simple and Fairly Decoupled Capability」にも出てきた「エンドユーザー認証サービス」で,レガシーな認証機能から OAuth 2.0 に移行する例が挙げられている.OAuth 2.0 をデプロイした直後の並行期間はむしろ「機能への変更を加速させること」という目的からは離れてしまうけど,その後 OAuth 2.0 に完全に切り替えて,レガシーな認証機能の実装を削除するなど,小さく移行していく.原著では直接言及されていなかったけど「ストラングラーフィグアプリケーションパターン」も関連している.

martinfowler.com

まとめ

「モノリス分割」に役立つアプローチを紹介した martinfowler.com の記事「How to break a Monolith into Microservices」を読んだ.まだまだ抽象度が高い部分もあるけど,具体的な「計8種類」のアプローチが紹介されているのは参考になった.「モノリス分割」に興味があれば1度読んでみると良いのではないでしょうか!

Argo CD に入門するために「Getting Started」をカスタマイズしながら試した

今回は Argo CD に入門するためにドキュメントに載っている「Getting Started」を試す.任意の Kubernetes クラスターに Argo CD をセットアップして,アプリケーションのデプロイを体験できる.また Argo CD UI を使った画面操作も体験できる.しかし GitOps を実現するには手順が簡単すぎるため,手順を少しカスタマイズしながら進めることにした.

argo-cd.readthedocs.io

GitHub - argoproj/argo-cd: Declarative continuous deployment for Kubernetes. より引用

前提

今回は Docker Desktop for Mac "Edge" を使って,以下の Kubernetes 環境で試す.

$ kubectl version --short
Client Version: v1.18.6
Server Version: v1.18.6

1. Install Argo CD

最初に Argo CD をセットアップする.リソースとしては Namespace / Service / Deployment / ConfigMap など.今回は GitHub に公開されているマニフェスト install.yaml を直接適用する.他には HelmArgo CD Chart を使う選択肢もある.

$ kubectl create namespace argocd

$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
serviceaccount/argocd-application-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-server created
clusterrole.rbac.authorization.k8s.io/argocd-application-controller created
clusterrole.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-server created
clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-gpg-keys-cm created
configmap/argocd-rbac-cm created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-secret created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-redis created
service/argocd-repo-server created
service/argocd-server-metrics created
service/argocd-server created
deployment.apps/argocd-application-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-redis created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created

2. Download Argo CD CLI

次に argocd コマンドをインストールする.今回は Homebrew を使う.

$ brew install argocd

$ argocd version --short
argocd: v1.7.7+33c93ae.dirty

https://argoproj.github.io/argo-cd/cli_installation/argoproj.github.io

3. Access The Argo CD API Server

デフォルト設定だと Argo CD の API に直接アクセスできないため,以下に載せた選択肢を使って API を公開する.今回は1番簡単な「Port Forwarding」を使う.kubectl port-forward コマンドを使って https://localhost:8080/ にアクセスできるようにする.

  • Service Type Load Balancer
  • Ingress
  • Port Forwarding
$ kubectl port-forward svc/argocd-server -n argocd 8080:443

4. Login Using The CLI

Argo CD の API にアクセスする場合,事前に認証が必要になる.ユーザー名は admin で,初期パスワードは Argo CD の Pod 名になっている.kubectl get pods コマンドで初期パスワードを確認したら argocd login コマンドで認証をする.さらに argocd account update-password コマンドを使ってパスワードを更新しておく.

$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
argocd-server-xxxxxxxxxx-yyyyy

$ argocd login localhost:8080
WARNING: server certificate had error: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin' logged in successfully
Context 'localhost:8080' updated

$ argocd account update-password
*** Enter current password:
*** Enter new password:
*** Confirm new password:
Password updated
Context 'localhost:8080' updated

5. Register A Cluster To Deploy Apps To (Optional)

Argo CD をセットアップした Kubernetes クラスター以外にアプリケーションをデプロイする場合は argocd cluster add コマンドを使って登録しておく必要がある.今回は全て Docker Desktop を使っているため,手順としては割愛する.

6. Create An Application From A Git Repository

argocd app create コマンド or Argo CD UI を使ってアプリケーションを登録する.今回は GitHub に公開されている Argo CD のサンプルアプリ guestbook を使う.また今回は少しカスタマイズをするために argoproj/argocd-example-apps リポジトリを kakakakakku/argocd-example-apps リポジトリとして Fork しておく.

github.com

今回は argocd app create コマンドを使う.

$ argocd app create guestbook --repo https://github.com/kakakakakku/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
application 'guestbook' created

7. Sync (Deploy) The Application

argocd app create コマンドを使った後に argocd app get コマンドを使って Sync Status を確認する.すると OutOfSync となり,アプリケーションはまだデプロイされていないことがわかる.

$ argocd app get guestbook
Name:               guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://localhost:8080/applications/guestbook
Repo:               https://github.com/kakakakakku/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        OutOfSync from  (6bed858)
Health Status:      Missing

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  OutOfSync  Missing
apps   Deployment  default    guestbook-ui  OutOfSync  Missing

今回は argocd app sync コマンドを使う.Argo CD は GitHub リポジトリからマニフェストをダウンロードして kubectl を実行する.結果的に Sync StatusSynced になり,アプリケーションのデプロイが完了する.

$ argocd app sync guestbook
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS    HEALTH        HOOK  MESSAGE
2020-10-10T22:00:00+09:00            Service     default          guestbook-ui  OutOfSync  Missing
2020-10-10T22:00:00+09:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing
2020-10-10T22:00:00+09:00            Service     default          guestbook-ui    Synced  Healthy
2020-10-10T22:00:01+09:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing              deployment.apps/guestbook-ui created
2020-10-10T22:00:01+09:00            Service     default          guestbook-ui    Synced   Healthy              service/guestbook-ui created
2020-10-10T22:00:01+09:00   apps  Deployment     default          guestbook-ui    Synced  Progressing              deployment.apps/guestbook-ui created

Name:               guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://localhost:8080/applications/guestbook
Repo:               https://github.com/kakakakakku/argocd-example-apps.git
Target:
Path:               guestbook
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        Synced to  (6bed858)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      6bed858de32a0e876ec49dad1a2e3c5840d3fb07
Phase:              Succeeded
Start:              2020-10-10 22:00:00 +0900 JST
Finished:           2020-10-10 22:00:01 +0900 JST
Duration:           1s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME          STATUS  HEALTH       HOOK  MESSAGE
       Service     default    guestbook-ui  Synced  Healthy            service/guestbook-ui created
apps   Deployment  default    guestbook-ui  Synced  Progressing        deployment.apps/guestbook-ui created

今度はデプロイしたアプリケーションを確認するために Argo CD UI にアクセスする.認証情報は「4. Login Using The CLI」と同じ.以下に Argo CD UI のキャプチャを載せておく.特に Deployment / ReplicSet / Pod / Service など,Kubernetes リソースを可視化できる機能は非常に便利だと思う.「Getting Started」の手順としてはここまで.

Argo CD UI : ログイン画面

Argo CD UI : トップ画面

Argo CD UI : アプリケーション詳細画面

追加課題 : Deployment の replicas3 に変更する

「Getting Started」をもう少し試していく.現状では DeploymentAVAILABLE1 になっている.

$ kubectl get deployments.apps
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
guestbook-ui   1/1     1            1           10m

そこで guestbook/guestbook-ui-deployment.yaml を修正して replicas3 にする.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: guestbook-ui
spec:
  replicas: 3

(中略)

「7. Sync (Deploy) The Application」と同じように argocd app sync コマンドを実行するのではなく,push をトリガーにして自動的にデプロイをしたくなる.デフォルトだと Sync Policy<none> になっているため,argocd app set コマンドを使って Sync PolicyAutomated に変更する.

argo-cd.readthedocs.io

$ argocd app get guestbook | egrep '^Sync '
Sync Policy:        <none>
Sync Status:        Synced to  (6ad30c5)

$ argocd app set guestbook --sync-policy automated
 
$ argocd app get guestbook | egrep '^Sync '
Sync Policy:        Automated
Sync Status:        Synced to  (6ad30c5)

少し待つと DeploymentAVAILABLE3 になった.

$ kubectl get deployments.apps
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
guestbook-ui   3/3     3            3           35m

Argo CD UI でも変更を確認できた.

Argo CD UI : アプリケーション詳細画面

リソース削除

手順には載っていなかったけど,最後にリソースを削除しておく.

$ argocd app delete guestbook

$ kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

$ kubectl delete namespace argocd

まとめ

GitOps を実現するツールとして,過去に Flux を試した.今回は最近よく聞く Argo CD に入門した.ドキュメントに載っている「Getting Started」を使えば Argo CD の基礎を学べる.実際に試すと簡単すぎるため,GitHub リポジトリを Fork して,少しカスタマイズすると良いと思う.Argo CD には他にもまだ機能があるため,引き続き試していく!

関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

Kubernetes を網羅的に学ぶなら「Kubernetes 完全ガイド 第2版」を読むべし

「Kubernetes 完全ガイド 第2版」を読んだ.今年6月に「第1版」を読み終わって,書評記事を書こうと思っていたら,タイミング良く今年8月に「第2版」が出版された.出版おめでとうございます!最初は目次を見ながら差分を中心に読んでいたけど,大幅にアップデートされていたため,結果的に最初からもう1度読んだ.Kubernetes そして Kubernetes 関連技術を学ぶのに最適な1冊だと思う.

Kubernetes完全ガイド 第2版 (Top Gear)

Kubernetes完全ガイド 第2版 (Top Gear)

  • 作者:青山 真也
  • 発売日: 2020/08/07
  • メディア: 単行本(ソフトカバー)

目次 🐋

  • 第1章 : Docker の復習と「Hello, Kubernetes」
  • 第2章 : なぜ Kubernetes が必要なのか?
  • 第3章 : Kubernetes 環境の選択肢
  • 第4章 : API リソースと kubectl
  • 第5章 : Workloads APIs カテゴリ
  • 第6章 : Service APIs カテゴリ
  • 第7章 : Config & Storage APIs カテゴリ
  • 第8章 : Cluster APIs カテゴリと Metadata APIs カテゴリ
  • 第9章 : リソース管理とオートスケーリング
  • 第10章 : ヘルスチェックとコンテナのライフサイクル
  • 第11章 : メンテナンスとノードの停止
  • 第12章 : 高度で柔軟なスケジューリング
  • 第13章 : セキュリティ
  • 第14章 : マニフェストの汎用化を行うオープンソースソフトウェア
  • 第15章 : モニタリング
  • 第16章 : コンテナログの集約
  • 第17章 : Kubernetes 環境での CI/CD
  • 第18章 : マイクロサービスアーキテクチャとサービスメッシュ
  • 第19章 : Kubernetes のアーキテクチャを知る
  • 第20章 : Kubernetes とこれから

全体的に 🐋

まず「第2版」で全体的に良かった点を紹介する.機能面では Kubernetes v1.18 までサポートされている.Kubernetes のライフサイクルを考えると,本書は今後も定期的にアップデートされるのだろうか?次にセクションごとに 1.18 Alpha1.18 Beta など,使えるようになったバージョンが明記されるようになった.Feature Gates を確認することはできるけど,本書を読みながらバージョンも合わせて確認できるのは便利だった.残りは非常に細かいけど,コマンド実行結果のブロック背景色が黒くなって視認しやすくなったり,章ごとの区切りページに「強そうなクジラ🐋」の絵が載るようになってカッコイイ!

kubernetes.io

そして!何と言っても「第1版」に引き続き「網羅性」「図表を含めた解説の充実さ」は素晴らしすぎる!また GitHub に本書で紹介されているマニフェストも公開されているため,試したり,写経したり,無限に学べる.こんな素晴らしい本を日本語で読めることに感謝しかない!

github.com

dive / Trivy / Clair 🐋

第1章「Docker の復習」は,流石にアップデートされていないだろうと思いながら読んでいたら,Docker イメージの種類に DistrolessUniversal Base Image が追加されていて,細かくアップデートされていた.また Docker イメージの最適化(軽量化)ツールとして dive の紹介が追加されていたり,Docker イメージのセキュリティツールとして TrivyClair の紹介も追加されていた.

kind 🐋

第3章「Kubernetes 環境の選択肢」では,ローカル環境に Kubernetes クラスターを構築するツールとして,minikubeDocker Desktop に加えて kind も追加されていた.今まではお手軽な Docker Desktop for Mac "Edge" を使うことが多かったけど,kind を使えば簡単に「マルチノード構成」を構築することもできるため,今後は kind を積極的に使っていきたいと思う.本書を読みながら kind に入門した記事は既に公開してある.他にも MicroK8sK3s の紹介も追加されていた.

kakakakakku.hatenablog.com

Kubernetes リソース 🐋

第5章「Workloads APIs カテゴリ」から続く Kubernetes リソースの解説は「第1版」に引き続き網羅的で,さらにボリュームが増えていた.新機能 (Feature Gates) で言えば,Job の終了後に自動的に履歴を削除する TTLAfterFinished 機能や ConfigMap の更新を防ぐ ImmutableEphemeralVolumes 機能も追加されていた.本書を読みながら CronJobConfigMap を試した記事は既に公開してある.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

Startup Probes 🐋

第10章「ヘルスチェックとコンテナのライフサイクル」では,「第1版」でも紹介されていた Liveness ProbesReadiness Probes に加えて Startup Probes の解説が追加されていた.本書を読むまで Startup Probes は知らなかった.簡単に言えば,起動するまでに時間がかかるコンテナで最初の Probes が実行されるまでの initialDelaySeconds とは別に,起動のみにフォーカスした Probes を設計できるようになる.うまく設計しないと使えなさそうだけど,機能としては覚えておきたいところ.

kubernetes.io

Helm / kustomize 🐋

第14章「マニフェストの汎用化を行うオープンソースソフトウェア」は個人的に嬉しいアップデートだった.なぜなら「第1版」では名前が載っているだけだった kustomize の解説が追加されていたからで,本書を読みながら kustomize を試した記事は既に公開してある.また HelmHelm v3 前提で解説がアップデートされていて良かった.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

GitOps 🐋

第17章「Kubernetes 環境での CI/CD」「第1版」と大きく内容が変わっている.特に GitOps の解説が充実していて「GitOps 基礎」「CIOps との比較」も学べるし,GitOps ツールである Argo CD の解説も追加されている.また CI/CD に関連するツールとして,TelepresenceSkaffoldConftest なども追加されている.

GitOps ツールとして Argo CD と並んで有名な Flux を試した記事は既に公開してある.本書には「Argo CD + Flux = GitOps Engine」というコラムも追加されていた.次は Argo CD を試すぞー!

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

誤植 🐋

今のところは「正誤情報はありません」となっていたけど,気付いた点を残しておく.

  • 第4章 : P.58 vv1.16.6vv1.16.6
  • 第7章 : P.309 AWS Elastic Block StoreAmazon Elastic Block Store (EBS)

book.impress.co.jp

まとめ 🐋

「Kubernetes 完全ガイド 第2版」を読んだ.書評記事では全てを伝えられないほどに素晴らしく,何度も何度も読み直すバイブルにする!Kubernetes では理解すべき知識の幅が広く「読んだ」「使える」の間には大きなギャップがあると思う.本書を読みながら試した記事も多く公開しているけど,まだ試せていない機能もあるため,今後も Kubernetes を楽しく学んでいきたいと思う.

Kubernetes を網羅的に学ぶなら「Kubernetes 完全ガイド 第2版」を読むべし💡

Kubernetes完全ガイド 第2版 (Top Gear)

Kubernetes完全ガイド 第2版 (Top Gear)

  • 作者:青山 真也
  • 発売日: 2020/08/07
  • メディア: 単行本(ソフトカバー)

kind を使って Feature Gates を有効化した Kubernetes クラスターを構築する

Mac のローカル環境で Kubernetes の検証をするときに,お手軽な Docker Desktop for Mac "Edge" を使っている.Feature Gates を有効化した Kubernetes クラスターで検証をするときは minikube--feature-gates オプションを指定して使うこともある.

kind 🐳

f:id:kakku22:20201001135956p:plain
kubernetes-sigs/kind: Kubernetes IN Docker - local clusters for testing Kubernetes より引用

「Kubernetes 完全ガイド 第2版」を読んでいたら,ローカル環境に Kubernetes クラスターを構築するツールの選択肢として kind が追加されていた.kind を使うと,Docker コンテナを Kubernetes ノードとして Kubernetes クラスターを構築し,簡単に「マルチノード構成」を実現できる.今回は kind を試す.

github.com

今回 kind のベースとして使う Docker Desktop for Mac "Edge" では「Kubernetes 設定」を無効化した.また,ドキュメントには Docker Desktop のメモリを「6GB ~ 8GB」確保すると書いてある.今回は Mac のリソース的に厳しいため,少ないけど「4GB」にした.

Mac に kind をインストールする 🐳

まず Homebrewkind をインストールする.ドキュメントは以下にまとまっている.

$ brew install kind

$ kind version
kind v0.9.0 go1.15.2 darwin/amd64

Kubernetes クラスターを構築する 🐳

kind では kind create cluster コマンドを使えば,簡単に Kubernetes クラスターを構築することができる.さらに「configuration file(設定ファイル)」に Kubernetes クラスター構成を記述することもできる.今回は「1 コントロールプレーン」「3 データプレーン」「マルチノード構成」で構築するため,YAML を以下のように作成した.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker

作成した設定ファイル kind-config.yaml を指定して kind create cluster コマンドを実行すると,以下のように簡単に Kubernetes クラスターを構築できた.今回インストールした kind v0.9.0 を使うと,デフォルトでは Kubernetes v1.19.1 になる.

$ kind create cluster --config kind-config.yaml
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.19.1) 🖼
 ✓ Preparing nodes 📦 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Thanks for using kind! 😊

コンテキストは自動的に kind-kind に切り替わっていた.そして,設定ファイルに記述した通り「マルチノード構成」になっている.便利!

$ kubectl config get-contexts
CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
          docker-desktop   docker-desktop   docker-desktop
*         kind-kind        kind-kind        kind-kind

$ kubectl config current-context
kind-kind

$ kubectl get nodes
NAME                 STATUS   ROLES    AGE   VERSION
kind-control-plane   Ready    master   13m   v1.19.1
kind-worker          Ready    <none>   12m   v1.19.1
kind-worker2         Ready    <none>   12m   v1.19.1
kind-worker3         Ready    <none>   12m   v1.19.1

構築した Kubernetes クラスターを削除する場合は kind delete cluster コマンドを使う.

$ kind delete cluster
Deleting cluster "kind" ...

バージョン指定で Kubernetes クラスターを構築する 🐳

次に Kubernetes v1.19.1 ではなく Kubernetes v1.18.8 で Kubernetes クラスターを構築していく.設定ファイルに image フィールドを追加するとバージョンを指定できる.指定する「イメージ名」「タグ名」は GitHub の Releases に載っている.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
- role: worker
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
- role: worker
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
- role: worker
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb

同じように kind create cluster コマンドを実行すると,今度は Kubernetes v1.18.8 で Kubernetes クラスターを構築できた.

$ kind create cluster --config kind-config.yaml
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.18.8) 🖼
 ✓ Preparing nodes 📦 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a nice day! 👋

$ kubectl get nodes
NAME                 STATUS   ROLES    AGE   VERSION
kind-control-plane   Ready    master   13m   v1.18.8
kind-worker          Ready    <none>   12m   v1.18.8
kind-worker2         Ready    <none>   12m   v1.18.8
kind-worker3         Ready    <none>   12m   v1.18.8

もう1度 Kubernetes クラスターを削除しておく.

$ kind delete cluster
Deleting cluster "kind" ...

Feature Gates を有効化して Kubernetes クラスターを構築する 🐳

最後は Feature Gates を有効化して Kubernetes クラスターを構築する.

kubernetes.io

今回は Kubernetes v1.18 (Alpha) で使えるようになった「Immutable ConfigMaps 機能(ConfigMap の値を更新できなくする)」を試す.

kubernetes.io

Feature Gates を有効化する場合,以下のように設定ファイルに featureGates を記述して ImmutableEphemeralVolumes など「Feature Gates 名」true にする.簡単!サンプルを検索すると kubeadmConfigPatches を記述する例も載っていたけど,今はもっと簡単に記述できるようになっていた.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
- role: worker
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
- role: worker
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
- role: worker
  image: kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb
featureGates:
  ImmutableEphemeralVolumes: true

Feature Gates を有効化して,もう1度 Kubernetes クラスターを構築する.

$ kind create cluster --config kind-config.yaml
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.18.8) 🖼
 ✓ Preparing nodes 📦 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a nice day! 👋

次に immutable フィールドを含めた ConfigMap マニフェストを作成する.

apiVersion: v1
kind: ConfigMap
metadata:
  name: immutable-configmap
data:
  name: kakakakakku
immutable: true

マニフェストを適用する.

$ kubectl apply -f immutable-configmap.yaml
configmap/immutable-configmap created

今度はマニフェストを修正して kakakakakkuKAKAKAKAKKU にする.

apiVersion: v1
kind: ConfigMap
metadata:
  name: immutable-configmap
data:
  name: KAKAKAKAKKU
immutable: true

もう1度マニフェストを適用しようとすると,immutable フィールドによってエラーになった.Kubernetes v1.18ImmutableEphemeralVolumesFeature Gates が適切に有効化されていることが確認できた.

$ kubectl apply -f immutable-configmap.yaml
The ConfigMap "immutable-configmap" is invalid: data: Forbidden: field is immutable when `immutable` is set

まとめ 🐳

「Kubernetes 完全ガイド 第2版」に載っていた kind を使って,Kubernetes クラスターを構築してみた.簡単に「マルチノード構成」を実現できるし,設定ファイルに Kubernetes クラスター構成を記述できるのも便利だった.今後は kind を使っていく!

Kubernetes完全ガイド 第2版 impress top gearシリーズ

Kubernetes完全ガイド 第2版 impress top gearシリーズ

  • 作者:青山真也
  • 発売日: 2020/08/17
  • メディア: Kindle版

入門から実践まで CircleCI のノウハウが凝縮された「CircleCI 実践入門」を読んだ

9月に出版された「CircleCI 実践入門」を読んだ.素晴らしかった!なぜ CI/CD が必要なのか?という背景から,CircleCI 入門,CircleCI 実践まで,網羅的に解説されている.ボリュームは多く,読みごたえはあるけど,必要な箇所から読むこともできる.また「継続的デリバリー」「継続的デプロイ」の違いが明確に解説されているのも良かった.今回は著者の1人である CircleCI の Kim さん (@kimhirokuni) に献本をいただいた.ありがとうございます!出版おめでとうございます!

目次

  • 第1章「なぜ CI/CD が必要か」
  • 第2章「CircleCI の基本」
  • 第3章「環境構築」
  • 第4章「ワークフローでジョブを組み合わせる」
  • 第5章「実践的な活用方法」
  • 第6章「テストの基本と最適化」
  • 第7章「継続的デプロイの実践」
  • 第8章「Web アプリケーション開発,インフラでの活用」
  • 第9章「モバイルアプリ開発での活用」
  • 第10章「デスクトップ/ネイティブアプリ開発での活用」
  • 第11章「さまざまなタスクの自動化」
  • 第12章「Orbs の作成」

以下のサイトに正誤表が公開されている.他にも数点気付いたところは,記事の最後にメモ程度に残しておく.

gihyo.jp

前提

僕自身は CircleCI を2016年頃から使っている.プロダクション環境で使っていて,2018年頃には CircleCI 1.0 から 2.0 への移行も経験した.2019年頃からは,個人プロジェクトのみで使っている.よって,直近2年ほどはプロダクション環境で使っていないこともあり,本書を読みながら,キャッチアップできていなかった機能を知ることもできた.

次世代コンビニエンスイメージ (Next-generation Convenience Images)

今まで,お手軽にジョブを作るときは CircleCI の公式イメージ circleci/* を使っていた.本書を読んでいたら,第2章「CircleCI の基本」のコラムに「次世代コンビニエンスイメージ」と言われる cimg/* が紹介されていた.イメージサイズが軽くなり,キャッシュヒット率が高くなり,ダウンロード時間も短くなる.今後は積極的に使っていく.これは知らなかった!

  • cimg/base:stable
  • cimg/go:1.15
  • cimg/ruby:2.7
  • etc

なお,英語のドキュメントには cimg/* の紹介が載っているけど,日本語のドキュメントには載ってなく,翻訳されていなく残念だった.また画面左下の言語設定を押すと「該当ページ」ではなく「トップページ」に遷移してしまうのも残念だと思う.改善に期待!

永続化(ワークスペースとキャッシュ)

第4章「ワークフローでジョブを組み合わせる」には「ワークスペース」「キャッシュ」など,CircleCI をよく使っていても個人的に理解が曖昧になりがちだった機能の解説があって良かった.特に永続化のライフサイクルと範囲,そして上書きの可否など,ドキュメントに書いてあるとしても,わかりやすく解説されているのはとても嬉しい!

Docker イメージキャッシュ

第6章「テストの基本と最適化」には「Docker イメージキャッシュ」の解説もある.Docker イメージのビルドを高速化する戦略として,Docker Layer Caching (DLC) 機能も紹介されていて,実践的に学べる.有料プランで利用可能になるため,個人プロジェクトでは試すことができないけど,機能は覚えておきたいと思う.

サンプルプロジェクトの多さ

本書を読んで驚いたのは,多くのプログラミング言語やランタイムの解説をサポートしていることだった.TypeScript に Android に Windows まである.以下にリストを載せた.サンプルプロジェクトは全て GitHub に公開されているため,すぐに試せるし,データベースにマイグレーションを実行するなど,実践的な .circleci/config.yml は CircleCI を実戦投入するときの参考になる.

  • 第8章「Web アプリケーション開発,インフラでの活用」
    • 8.1 TypeScript
    • 8.2 Ruby (Ruby on Rails)
    • 8.3 PHP (Laravel)
    • 8.4 Java (Spring Boot)
    • 8.5 Docker
    • 8.6 Terraform
  • 第9章「モバイルアプリ開発での活用」
    • 9.1 Android
    • 9.2 iOS (macOS)
  • 第10章「デスクトップ/ネイティブアプリ開発での活用」
    • 10.1 Windows
    • 10.2 クロスプラットフォーム
    • 10.3 Unity

github.com

また個人的に少し前から Spring Boot に入門したいと思っていた.本書に「Java (Spring Boot)」のサンプルもあった.Mac で動かすなら PostgreSQL と組み合わせて ./gradlew bootRun を実行すると,簡単に Spring Boot を起動できた.

github.com

Quote として任意の文字列を登録するアプリケーションにアクセスできるようになる.今回はタイトルのところに「😃」を追加してみた.そのまま GitHub に push をすると CircleCI も正常に動く.

f:id:kakku22:20200928115607p:plain

また検証のために,JUnit で実装されたテストコードに確実にエラーになる Assert を追加して,GitHub に push してみる.すると,期待した通りに CircleCI でエラーになる.今回のように新しくフレームワークを学ぶときに,継続的インテグレーション環境まで揃っていると,実戦投入しやすく素振りできるように思う.便利!

f:id:kakku22:20200928115623p:plain

ブロガーに役立つ textlint 連携

第11章「さまざまなタスクの自動化」では,textlintreviewdog を組み合わせて自動的にドキュメント校正をするサンプルが紹介されていた.CircleCI はプロダクション環境じゃなくても使うことができ,ブロガーにも役立つ内容だった.うまく読者層を広げているように感じた.

Orb 公開

第12章「Orbs の作成」は良かった.今まで Orb を使うことはあっても,自分で作る機会はなく,試したいと思っていた.本書では,Orb 解説だけではなく,サンプル Orb を実際に公開できるように紹介されている.詳細は本書を読んでもらうとして,以下のように circleci CLI を使って,簡単に公開できる.

$ circleci setup
$ circleci namespace create kakakakakku github kakakakakku
$ circleci orb create kakakakakku/sample
$ circleci orb publish orb.yml kakakakakku/sample@0.0.1

公開した Orb は原則削除できないという仕様を理解してなく,今思えば「開発用 Orb」として公開すれば良かったと思う...😇個人プロジェクトで似たような YAML を書いているため,Orb 化を検討しながら,Orb 開発でも CI/CD を実現したり,もっと深く学びたくなった.

f:id:kakku22:20200928115652p:plain

誤植

  • 第7章 P.187 AWS ECRAmazon ECR
  • 第7章 P.187 AWS ECSAmazon ECS
  • 第12章 P.327 AWS S3Amazon S3

まとめ

9月に出版された「CircleCI 実践入門」を読んだ.CircleCI 初学者でも読めるし,実際に CircleCI を使っている人でも新しい学びがあると思う.それほどに網羅的に解説されている1冊だった.読みながら付箋だらけになってしまったし,今回紹介したポイント以外にもたくさん学べた.少しでも CI/CD や CircleCI に興味を持っていたら読んでみると良いと思う💡

関連記事

本書を読みながらすぐに試したくなった「Slack Orb」の検証記事は既に公開してある!

kakakakakku.hatenablog.com