kbigwheelのプログラミング・ソフトウェア技術系ブログ

プログラミング・ソフトウェア技術系のことを書きます

エンジニア知識の盲点

Scala, AWS, スクラムマスター, マイクロサービス, KubernetesやDDDなど僕でも多少は知識的に自信がある領域があります。ただ、特にAWSKubernetesのような技術の進歩が早く領域自体もとても広いものはたとえ資格を持っていたとしても思わぬ抜け漏れがたまにあります。 AWSに関して、一応現在の会社ではそこそこ詳しい方だと自負しているのですがそれほどAWSに詳しくない同僚やGCPのほうが得意な同僚に自分の考えや設計の欠点・改善点を指摘されるということが一度ならずありました。それも主にAWSのあるサービス・機能を知っているだけでわかるようなものです。 そういったサービスや機能が自分の選択肢から抜け落ちていた理由を考えるとその領域(例えばAAAやネットワークなどが僕は弱いです)への関心が低かったり実際に使ったことがないため機能のイメージができておらず、new releaseの文章を読んだだけでは実際の利用イメージができていなかったことなどが挙げられます。

このことを僕は「知識の盲点」と呼ぶことにしています。

この概念の面白いところは個々人によって盲点の部分が違い、かつ他の人に盲点部分を指摘してもらえればそれが呼び水となって盲点部分が盲点でなくなる部分です。別の表現をすると、この盲点の部分というのはその人自身もそこが盲点だと気づいていないために盲点であるんですね。自分がわかっていないこと、それ自体に気づいていないわけです。 この状態の対策は簡単で、前述の通り複数人で盲点を補完し合うことです。この場合補完する人はその領域のエキスパートである必要はありません。せいぜい使ったことがあるかもしくは隣接領域のエキスパートなどで十分です1


  1. 例えばAWSの領域に対してサーバレスやGCPなどのエキスパートはよい補完になると思います

DockerベースのGithub Actionsの憂鬱

tl;dr

  • DockerベースのGithub Actionsは僕自身がGithub Actions 8ヶ月使ってみてわかったことまとめ - Qiitaの記事で絶賛した通りポータビリティ・独立性などの点で画期的でした
  • しかしリリースからほぼ1年たった現実ではNodejsベースのGithub Actionsのほうが好まれています
  • 原因はDockerベースのActionの重さにあります
  • CIの開始時に毎回docker pull / buildが走るため1つに付き10 ~ 数十秒かかるため、同じ機能のActionならDockerベースのActionよりセットアップが1~3秒で終わるnodejsベースのActionがよく選ばれます

長めの説明

Dockerベースの再利用可能なCIパーツ、という思想はGithub Actions 8ヶ月使ってみてわかったことまとめ - Qiitaに書いたとおり画期的でした。 僕はこの時点ではDockerが世を席巻したようにDockerベースのCIパーツという思想がCIサービスで多用されるのではないかと想像していました。 しかし、現実にはGithub Actionsサービス内ですらDockerベースのGithub ActionsよりNodejsベースのGithub Actionsの方が好まれており、Terraformの公式ActionsのようにDockerベースだったものをNodejsベースで置き換えるようなケースもちらほら出ています。

なぜDockerベースのGithub Actionsはだめなのか

だめな点1. Action実行の遅さ

NodejsベースのActionと比べてDockerベースのActionは明らかに遅いです。 Docker内での処理実行が遅いというわけではありません。そこは普通のDockerコンテナ実行と同じくほとんどノーペナルティと言って良いです。 遅いのはActionを開始するまでの準備です。 NodejsベースのActionがたかだか数十KBのzipのダウンロードと解凍なのに比べてDockerは数十 ~ 数百MBのDockerイメージをDockerhubその他からダウンロード・解凍する必要があります。 経験にこれは1つに付き数十秒かかります。DockerベースのActionが複数あればその分だけかかることになります。 またこの処理はワークフロー全体の一番最初に必ず実行するため、一連のワークフローの一番最初のAction実行でエラーが発生して以降のステップがまったく実行されない場合でもすべてのDockerベースアクションをダウンロード・解凍する必要があります。

だめな点2. 柔軟性の欠如

DockerベースのActionはActionへの入力(jobs.<job_id>.steps.with)を元に処理を行うことが基本ですが、柔軟性に乏しいと感じることが多いです。また $GITHUB_WORKSPACE のディレクトリもまたdockerコンテナ実行時にカレントディレクトリとしてマウントされるのですが、マウントポイントを $GITHUB_WORKSPACE ではなくそのサブディレクトリにすることなどもできません。 例えばpip installしてくれるDockerベースのGithub Actionsを作ったとすると、requirements.txtがリポジトリルートにあればよいですがサブディレクトリにある場合だと途端にそのGithub Actionsは使えないことになります。

考えてみるとCIを組む側としてほしかったのは相互に影響しあわない処理環境の独立性がメインであり、実行する処理内容が細かく規定されているのは余計かもしれません。

だめな点3. GitHub公式が別にDockerベースActionを押していない

DockerベースのActionが主流になれば、各種言語インタープリタコンパイラなどは個別のGithub Actionsになり、CIの実行ホストはさながらalpine linuxのようにminimumなOSになると思っていました。 しかし現実にはGithubvirtual-environments/Ubuntu2004-README.md at main · actions/virtual-environmentsを見ればわかるように古今東西あらゆる言語のあらゆるバージョンをインストールしたホストでGithub Actionsを実行しています。 これは最初からインストールされていれば新たにバイナリなどをダウンロードする必要がないからという理屈でこうしているのだと思われますが、この場合インストールされているバージョンや言語・ライブラリはすべてGithub Actions運用側の選択次第ということになります。

もしDockerベースのGithub Actionsに力を入れるのであれば、もっともネックとなっているイメージのダウンロード時間を改善するべくダウンロードしたイメージのデータを一定時間キャッシュできるようにする、直接Dockerhubからダウンロードするのではなくプロキシを通すことでキャッシングするなどの選択肢はあるはずです。そのような改善がいまだ入らず、結果的に全部入りのVMで実行する形が速度を考えると最善になっている今には正直失望を感じます。

ではNodejsベースのActionでいいんじゃないの?

と思われるかもしれませんが、NodejsベースのActionにも欠点はあります。 1つはjavascriptという1つの言語に実装が縛られることです。これはこの言語に慣れ親しんでいない人にとってはかなりのハードルになります。もう1つがnodejsが外部コマンドの呼び出しやファイル操作などいわゆるシェルスクリプト的な処理に向いていないことです。CIの処理というのは基本的にシェルスクリプトがベースになりますが、Nodejsの場合はそれをjavascriptの同等コードに置き換える必要が出てきます。置き換えられる場合はまだましで、現実的にはできないケースも多々あります。

それに対してDockerベースのActionはシェルスクリプトが基本であり、柔軟性も高いです。

まとめ

というわけで、現状DockerベースのGithub ActionsとNodejsベースのGithub Actionsはそれぞれ一長一短あります。ただしよく使われるものはCIの実行時間を短くして使い勝手を良くするためにNodejsベースで実装されるものが多いです。

自分でカスタムアクションを作成する場合は上記の使い勝手と実装のしやすさの間のトレードオフを踏まえてどちらを採用するか決めましょう。

クラウドインフラを構築するときの手順書とInfrasctucture as Codeの間のトレードオフ

tl;dr

インフラを構築するとき、構築方法を手順書で残すかInfrastructure as Codeで残すかの間にはトレードオフがある。

手順書 Infrastructure as Code
学習コスト
利便性

前置き

AWSなどのSaaS/IaaSでサービス基盤を構築するとき、手順書とInfrastructure as Codeのどちらを取るかが最近特に悩ましくなってきました。

手順書とはインフラ構築時の順序やコマンドなどを列挙した文書のことでpuppetやchefすらないときから用いられる由緒正しいインフラ屋の手法です。 一方Infrastructure as Code(IaC)はChef, Terraformなどに代表されるコードで定義されたインフラの定義であり言ってしまえば構築手順書を自動化したものです。 IaCを更に細分化するとMutable Infrastructureの視点によるもの(Chef, Ansible)とImmutable Infrastructureの視点によるもの(Terraform, Packer)に分けられると思います1

法名 手順書 MIaC(Mutable Infrastructure as Code) IIaC(Immutable Infrastructure as Code)
概要 書かれたコマンドを一つ一つTerminalで実行 継続して同じホストに対して自動化された処理を実行 毎回新しいホストに対して自動化された処理を実行 / ホストの元となるイメージを作成
代表的ツール txtファイル
Wiki
Confluence
Chef
Ansible
capistrano
Docker
Packer

上では代表的なツールを挙げましたが実際には各分野のツールもだいたいどれかの属性を帯びていることが多いです。例えばKubernetesの関連ツールであるhelmはそれ単体ですと手順書でしか形式知にできませんが、helmfileやArgo CDなどを使用することでIaCにすることができます。KubernetesやECSのようなコンテナクラスタは使い方によってどれにでもなると言えるでしょう。

Immutable Infrastructure as Codeの利点

時間が無限に使えるという仮定の元であればIIaCがほとんどの場合最良であることはある程度インフラ構築をやったことがある人であればほぼ合意できるかと思います。

手順書の場合、その手順の検証(テスト)のコストが大きくほとんどの場合テストがされません。また実行者の環境へ暗黙的に特定のコマンドがインストールされていることが前提となっているのに(jqなど)それが書かれていないこともよくあります。つまり再現性が低いのです。それに対してIaCでは文字通りコード化されているためテストのコストが圧倒的に低いです。例えばterraformであれば terraform init; terraform apply; terraform destroy で最低限のテストが実行できます。

MIaCについては既存のホストの状態によって実行結果が変わることがネックになります。例えばホスト内から特定のコマンドを削除したりディレクトリを移動することでchefやansibleの実行は失敗する可能性があります。それをカバーしようとして前提チェックや依存コマンド・環境などのレシピを積み上げていくと膨大な量となります。しかもそれでも本当に100%カバーできているかはわかりません。IIaCであれば実行したいアプリケーションの依存物はすべて同梱されており外部からそれを変更することは(それを明確に意図しない限り)できないので再現性が高くなります。

このように、基本的には手順書よりMIaC, MIaCよりIIaCのほうが特に再現性の点で優れていると言えます。 ではIIaCの欠点とはなんでしょうか。

Immutable Infrastructure as Codeの欠点

私が考えるIIaCの主な欠点は2つです。

  1. 計算資源の観点から見たコストの高さ
  2. 学習コストの高さ
1. 計算資源の観点から見たコストの高さ

ここで言う計算資源としては主にストレージ・デプロイ時間のことです。

PackerにしろDockerにしろ、作成したイメージはアプリケーションが依存するものをライブラリだけではなくOSのレイヤーまで含みます。結果的にビルドから実際の実行ホストまでのすべての経路においてMIaCと比べて多くのストレージや通信量がかかります。 実際Packerでビルドをやっていたときはアプリケーションはたかだか数十MBであるにもかかわらず作成したイメージは数GBになる話は珍しくありませんでした。 Dockerになってレイヤー化されたこと、OSのコア部分はホストOS側で担保されることなどによりPackerと比べては劇的に減りましたが結局最初のPull時点ではすべてのレイヤーをダウンロードする必要があるため減ったストレージはDocker Hubが担ってくれている部分のみと言えます。

またデプロイ時間も基本的には増えます。Packerの場合はVMインスタンスを新たに立ち上げる必要がありますし、Dockerの場合でも新たにイメージをpullする必要があります。MIaCによるデプロイはVMインスタンスをそのまま使い回せるため基本的にはIIaCよりも早いです。その仕組みの違い上、MIaCスタイルのデプロイとIIaCスタイルのデプロイそれぞれで最善を尽くすと絶対にIIaCは速度でMIaCスタイルを上回ることはできません。

2. 学習コストの高さ

IIaCという考え方はそれまでの試みや概念を土台としています。 また考え方自体が新しいため世の中に知見やノウハウ・それについて書かれた文書などがまだ多くありません。 IIaCのためのツールもまだ未熟で日本語でのドキュメントが少なかったり単純にバグがまだまだあったり機能が少なかったりします。

これらの欠点に対する私見

個人的に①の欠点はそれほど重大だとは思っていません。 というのは近年のストレージの価格は十分に低下しており、CPUが最も高価なIaaSでは相対的にそれほど気にならないからです2。 またデプロイ時間についてもMIaCスタイルのデプロイ(Capistrano, CodeDeploy)は工程が複雑になりがちで結果的にイメージをダウンロードしてきて実行するだけのIIaCスタイルの方が早くデプロイできるケースが多いです。

②については、確かにコストが高いことがあります。特にKubernetesの関連技術はまだ移り変わりが早く半年や一年で様相が一変しているようなことは少なくありません。

IIaCの覇権は明白

一方で、IIaCの覇権は2020/07現在かなり明白になっています。そもそもIIaCの成り立ちがMIaCなどの既存手法の問題・痛みを解決するものであり、すでに本番環境での採用・実践例も溢れています。 Dockerは本当にプロダクションユースなのか・Dockerのコンテナオーケストレーションツールのデファクトスタンダードはどれかといった業界全体による検証のフェイズはとっくに過ぎており Terraform / Docker / Kubernetes などといったデファクトスタンダードIIaCツールが揃った今、新しくIIaCを始める人にとってもツール選択に迷うことはかなり減りました。 このような背景のためにIIaCの導入は変化に適応する開発組織では確定路線であり、あとはいつ手順書やMIaCなどから移行するかを決めるのみです。


  1. この両方が選択できたりどちらかが曖昧なツールもたくさんあります。前者がAWS CodeDeploy、後者がTerraformなどです

  2. 実際のところはストレージが安くなりネットワークも十分に早くなったからIIaCのような手法が取れるようになった、発達したというのが本当のところだと思います

slack知見

某scalikejdbcな人に教えてもらったslack app周りのノウハウ。 アプリを作りたかったので助かる。 以下の記述が間違っていたとしたら僕の書き間違い・理解の間違い。

  • 認証
    • よく読めばわかるがslack appの認証はOAuth
    • 現在の認証はbot tokenとuser tokenだけでよい
    • bot tokenはすべての権限が付与された新bot tokenと等価。逆に言うと新botトークンは権限が選択式になった旧botトーク
    • user tokenは基本的に使わない。user tokenが必要なのはその人自身の権限でしかできないようなアクションをするとき
      • 例としてはその人に成り代わってpostするときや、一部の管理者権限はbotではもたせられないのでworkspace(team)でのadministrativeなアクションをするときはuser tokenである必要あり
    • workspace tokenは従来のbot tokenを更新する目的で作られかけたがうまくいかずdeprecated。ドキュメント上で言及されたり仕様例が残っているところもあるが使わないこと。
    • botトークンは管理者がインストールしてもユーザーがインストールしても機能が変わらない。
    • 基本的にbotトークンで済む場合はbotトークンを推奨
  • スラッシュコマンドは今後推奨されない?
    • 廃止されることはないが、先日発表されたショートカットのほうがGUIがあり便利なのでそちらを今後は推奨
    • ショートカットとスラッシュコマンドの両方を実装するのはあり
  • slackのドキュメントはナラティブに書くという方針があるらしく、英語ネイティブでないと読みづらかったりその方針のために?古い記述がよく残っている

「Kubernetesで実践するクラウドネイティブDevOps」感想・メモ

ソフトウェアエンジニアリングを10年以上やってきて、つまりはその年月の間ずっと技術を学習し続けたのだけど、 最終的に行き着いた学習方法はとりあえずやってみて、必要と感じた部分をピンポイントでググって調べる。 ある程度身についたら入門本やwalkthrough系の本を1冊丸々読んで欠けていたり自学で盲点となりやすいポイントを掬う、というものになった。

というわけでこの本はそのKubernetesのwalkthroughになる。その目的としては非常に優秀で良い本だった。

以下メモ

1章

3つの革命。

  1. クラウド
  2. DEvOps
  3. コンテナ

メインフレームクラウド 一周してきた

P6

一見どう見えようとも、それはつねに人間の問題である。

P14

Kubernetesによる抽象化でクラウド固有の詳細が隠されるため、...

これは嘘。ALBを使うにはalb-ingress-controllerを使う必要があるし、そうでなくてもLBへ証明書を割り当てるためにALB専用のアノテーションをつける必要がある。

Kubernetesが得意としないものもある。例えばデータベース。あとFaaSのほうがよいものもある。

P 18

個々の開発チームでは、チームが提供するシステムやサービスの健全性を担当する運用専門家が少なくとも1名は必要になります。

やっぱそうよなあ。

P 19

開発者生産性光学(Developer Productivity Engineering, DPE)

なるほど、従来の運用専門チームに変わる、分散化した運用者のために共通ツール・ノウハウを作って支援する部署)。

2章

P28

これと比較すると、公式のRubyコンテナイメージはサイズが1.5GiBで、Goイメージの約250倍もあります。

草。その通りだねとしか言えない。

P33

結構minikubeのセットアップには苦労した。特にdriverがvirtualboxkvmとnoneの3種類あって、標準は遅いがbattle proofのあるvirtualboxなのだけど、ubuntuの最新virtualboxが6.x系ナノに対してminikubeの互換バージョンは5x系らしく、結局noneにした(パフォーマンスも良さそうなので)。

macでどうするかはまたひと悶着ありそう。docker for mackubernetes使う手もあるそうだけど、kubernetes公式的にはminikube。なんとなくminikubeのほうが良さそうな気がするが手軽なのはdocker for macか?

3章

P41

何もない状態からKubernetesを本番の設定で運用し始めるためには、エンジニアの給与で約100万ドルが必要になると推定しています(「それでも目的を達成できないかもしれません」)。

これが西海岸のバブル給与だとしても、オンプレでやる場合日本円でも数千万はかかるというのは納得感がある。

P42

ぐだぐだと中小企業ではKubernetesを運用するのは高コストだからマネージドサービス使えと数ページ使って書かれている。

P43

著者らだけでなく、本書のためにインタビューした多くの人々の経験でも、Kubernetesを実行する最善の方法はマネージドサービスです。以上

P44

GKEのオートスケール

EKSはデフォルトではできない機能で羨ましいところ。

P45

とはいえ、マネージドKubernetes市場では最後発であるため、EKSがGoogleMicrosoftのサービスに追いつくまでにはまだじかんがかかるでしょう。

AWSさんもっと頑張ってくれー (・∀・ )っ/凵⌒☆チンチン

P51

「実行するソフトウェアを減らす」という哲学には3本の柱があり、いずれも時間をうまく使って競争相手に打ち勝つために役立ちます。 1. 標準のテクノロジを選ぶ 2. 差別化につながらない面倒な作業はアウトソーシングする 3. 長続きする競争優位性を生み出す Rich Archbold

これいいね。

P54

それがAzure Container Instances やAWS Fargateなどの、いわゆるクラスタレスサービスです。

この呼称初めて聞いた。いいね。

P63

一般にDeploymentはユーザーが直接触るけどReplica Setを直接触ることは少ない

ほえー確かに。これ言われるまでPod, Replica set, Deploymentは3セットで人に説明していたわ。

P69

実際、ServiceとIngressはどちらも、クラウド型のロードバランサを自動的に作成できます。

この2つが似ているという認識はやっぱり正しいみたい。

P73

helmの辺りはなかなか刺激的だった。これなら自分でもchartを作れそうと思う。

P82

gRPC probe

それが簡単だからと安易にkubernetesの仕様へgRPCのプロトコルなどを組み込まなかったのはさすがの判断。OSSとして抑えなければいけない中立性をよくわかっている。

P83

readiness probeとliveness probeの違いというか使い分けがよくわからない。livenessが生きているか死んでいるかでこれがfalseになるとコンテナをdeleteする、readinessはそのコンテナが受付可能かどうかでserviceから切り離すかどうかを示す、であっているかなあ。

この動作が特に重要となるのはゼロダウンタイムアップグレードの場合です(詳細については13章の「13.2 デプロイ戦略」を参照)。

参照先をみてもreadinessのことが書かれていない。たぶんデプロイ戦略中の切り替えの判断にreadinessを使っているということだろうと思うのだけど。

P88

デフォルトのNamespaceは、間違いを起こしやすいため使用してはなりません。

そうなのか。

Kubernetesのベストプラクティス:名前空間を使用した整理| Google Cloudブログ

たしかにこちらにもそう書いてある。

P88

Serviceのアドレス

なるほど、Serviceだけ?がNamespaceの壁を超えられるのか。 カプセル化、というかインターフェイスtcpに限定しているkubernetesの思想的には一貫している。

P89

ポッドの実行数のハードリミット。ただこれだと問答無用でエラーが発生するのでポッド実行のスロットリング目的としては不適か? いやでもjob経由ならキューに積まれそう。

P92

ほとんどのマネージドKuberentesサービスには、コンテナのCPUおよびメモリ仕様状況を時間の経過に沿って表示する、何らかのダッシュボード機能が用意されています。

みてるかー、AWS EKSチーム見てるかー!!!

P93

Vritical Pod Autoscaler リソース要求の理想的な値を算出するのに役立つ。

単なるオートスケーリングだけじゃなくて実際にリソースを監視してリソースの最適なlimitを決めるのに使えるのか。便利。

P94

優れた経験則として、ノードは典型的なPodを少なくとも5つは実行するのに十分なサイズとする

fmfm

P97

kube-job-cleaner

なるほど、これは便利。

P98

Spot Instanceの利用

これ魅力的なのはわかるけどこれを使う設定がわからない。

[EKS] [request]: Spot instances for managed node groups · Issue #583 · aws/containers-roadmap

Managed Node Groupでもサポートされていないし、これを使うとなるとアンマネージドになるのが辛い。

P102

Descheduler

ポッドの偏りを解消するコントローラ

P109

ベストプラクティスでのシングルテナントの推奨

これには賛成しかねる。 マルチテナントとシングルテナント, kubernetesで検索して出てくるスライド資料参照

P111

ベアメタルサーバ

どっかで聞いたような話だ。

P117

Copper, manifestのlinter

これはCIへ組み込むと良さそう。

P 128

kubectlの--watchコマンド

これ知らずにwhile sleepでループさせてた。参考にしよう。

P129

本書ではずっと、コードとしての宣言的インフラを使用する重要性を強調してきました。そのため、「命令的なkubectlコマンドの使用は推奨しない」という主張が驚かれることはないでしょう。

なるほど。たしかにcreateやdeleteはローカル環境でやる時以外は控えたほうが良いかも。

P134

コンテナへのアタッチ

用途がよくわからない。dockerなどと一緒だとしたら標準入力などを与える場合はこれが必要?

kubespy

リソースの変更を監視できるツール。 kubectl get --watch もよいがこれも便利そう。 ただkubernetesの手頃なdashboardがあれば不要?

P136

kubernetesクラスタトラブルシューティング(主にネットワークなど)のための便利コマンド

kubectl run nslookup --image=busybox:1.28 --rm -it --restart=Never --command -- nslookup demo

P140

コンテキストはクラスタ、ユーザー、ネームスペースの組み合わせのこと

P155

本番環境でコンテナをデプロイするときは、latestタグの使用を避けるべきです。実行中のイメージのバージョンを把握することが難しく、また適切なロールバックが困難になるためです。

ああ、よく知ってる。

P163前後

ポッドのセキュリティ。非常に面倒くさいことだけはよくわかった。

P166

永続化ボリューム

そういえばeksでefsって使えるのかなと思って調べてみたら、この永続ボリュームの機能で使えるっぽい。

P175

Labelは内部的にも酷使されるためかなり厳しい制限がある。 具体的にはlabel名は63文字まで、ただしdnsサブドメイン形式での最大256文字までのprefixが認められる。 prefixとlabel名本体は/で区切られう。 labelの名前と値に使える文字は-_.alphanumのみ。

P176

こうした Affinity にはハードとソフトの 2 種類があります。残念ながらソフトウェアエンジニア は必ずしも命名の才に恵まれているわけではないため、 Kubernetes の場合、これらは次のように 呼ばれています。

● requiredDuringSchedulingIgnoredDuringExecution (ハード)

● preferredDuringSchedulingIgnoredDuringExecution (ソフト)

P184

StatefulSet

名前に反してDeploymentの各Podへindexがついただけのような微妙なリソースタイプ。

StatefulSet では、 PersistentVolumeClaim を自動的に作成する VolumeClaimTemplates を使用 して、紐づく一連の Pod のディスクストレージも管理できます

と思ったらやっぱり永続化に関する機能というかデフォルトの振る舞いもあるっぽい。

P186

CronJob マ ニ フ ェ ス ト で 注 目 す べ き 重 要 な フ ィ ー ル ド は 、 spec.schedule と spec.job Template の 2 つです。 schedule フィールドはジョブが実行されるタイミングを指定するも ので、 Unix の cron ユーティリティと同じ形式( https://en.wikipedia.org/wiki/Cron )を使用し ます † 4 。

本書く人ですらWikipediaを参照する程度にcronのフォーマットの仕様はwebに明記されていないんよな。 man結果を安定的にホスティングするセミオフィシャルなサイトとかあったらいいんだけど。

P190

監訳注: 2016 年に Operator を提唱した CoreOS 社(現在は IBM 社の一部)は、ブログ( https://coreos.com/blog/introd ucing-operators.html )で Operator を「アプリケーション固有の運用ナレッジがプログラミングされたカスタムコントロー ラ」と言っています。そのため、このサンプルは Operator ではなく Kubernetes コントローラと呼ぶほうが一般的かもしれ ません。

P192

証明書ってIngressで設定できたんだへーと思ったら

tls.secretNameからACMに証明書をインポート・問題#1084・kubernetes-sigs / aws-alb-ingress-controller

ACMでもできるようになりつつあるらしい。 これでalb-ingress-controllerがちゃんと取り込まれたらAWSでもKubernetesクラウドサービスの結合度はかなり高くなるなあ

P204

envFromを使用することで、COnfigMapからすべてのキーを取り込んで環境変数に変換するための簡単な方法が用意されています。

これは便利。

P205

configMapからコンテナ上のファイルへそのまま書き出す方法が書かれている

P215

SOPS

現状parameter storeとexternal-secretsで同期しているから不要? でもhelm-secretsを使う利点もあるかもしれない。

SOPS、読み進めるとこれ12 factors appに反しているな。 あとterraformからのパラメータの引き渡しも難しい。やっぱりSOPSは微妙な気がする。

P222

マルチテナントについて これはたしかに最も安全なアプローチですが、クラスタを追加していくことにはトレードオフもあしります。どのクラスタもパッチ適用や監視の対象とする必要があり、多数の小さなクラスタは少数の大きなクラスタに比べて実行効率が劣る傾向もあります。

うん。だからterraformのmoduleを使用してなるべく一つのアプローチで一気に管理できるようにしようとしている。

P223

viewロール

これいいね。readonlyロール

P249

values.yaml

なるほど、これがあればhelm-install.shはもっとよく書けそう。

P255

helmfile

これ、argo cdと競合するので使うべきか悩む。

P257

ksonnetの最も重要な点は、プロトタイプという概念を導入していることです。これは Kubernetes リソースのあらかじめ記述された組み合わせで、よく使われるマニフェストのパ ターンを、スタンプで押すように手軽に利用できるようになります。

これは魅力的。

P 260

kubeval

これ読む限り、こいつがやってくれるvalidationはkubectlがやってくれるものと完全に等価? ユーザーグラウンドでこのプロパティの値はこの範囲、のような指定はできないのかも。 そういうのはconftestか。

P263

13章開発ワークフローはローカル環境で高速に開発サイクルを回したいときのツールらしい。 なかなか難しいトピックになってきた。

Draft, Skaffold, Telepresence

この辺り、部内でk8sを広めていくためには必要になってくるかー。

P269

BGデプロイをlabelでする

これをなんらかのツールなどで支援できないとなかなかつらい。オペミス発生しそう。

カナリアデプロイにはIstioが必要

P270

Helmのフック機能

これいいなー。

P276

14.2 おすすめのCDツール

weave fluxもargo cdも書かれていない? 時期が2年近く前であることを考えると必然か?

P279

と思ったらfluxはこっちにあった。

P294

ユーザがハッピーでなければ 9 の数に意味はありません。 ―― Charity Majors ( https://red.ht/2FMZcMZ )

いい言葉だ。

15章、16章は流してしまった。 また興味が湧いたら読み直す。

すぐやること

  • インスタンスサイズは4つより2つのほうが良さげ
  • defaultのネームスペースは危険なので使わない
  • Copper - manifestのlinter
  • envFromで変数の羅列をやめる
  • deschedulerは大定番っぽいので基本入れる
  • conftest, kubevalは基本入れる(これはkubernetes meetup #29から)
  • 管理者以外にviewロールで権限を付与する
  • velero - これもmeetup #29からでもあるけど、とりあえずsnapshotを取っておくだけでもかなり有用

「OKR(オーケーアール) シリコンバレー式で大胆な目標を達成する方法」感想

OKR(オーケーアール) シリコンバレー式で大胆な目標を達成する方法 | クリスティーナ・ウォドキー, 及川 卓也(解説), 二木 夢子 |本 | 通販 | Amazon

死ぬほどひどいタイトルにドン引きしてこれがおおよそcannonicalな本であることはわかっていたにも関わらず別の本に逃げていた。

今、どんなタイトルからこんなひどいタイトルの本にしてしまったのか原書を調べていたのだけど原書のタイトルは大きく違った。

Amazon.com: Radical Focus: Achieving Your Most Important Goals with Objectives and Key Results ( OKRs ) eBook: Christina Wodtke: Kindle Store

Radical Focus, 徹底的な集中。たしかにこのほうがこの本で言いたいことの本質を捉えている気がする。 これにOKRとタイトルを付けるのはわかりやすいかもしれないけどまさに目的より手段を優先することを冗長していないだろうか。

閑話休題、結論から言うとけして悪くはないと思う。 序盤の小説仕立てのところは触りとしては悪くない。 もうちょっと間間に挟んでくれるともっと読みやすかった気もするが、そこまでするほどでもない気はする。

後半を非常に駆け足で読んだのでそこは再度読み直したほうがよいかも。

あと、このOKRをボトムアップでやるのはあんまり有効ではないなと思った。 この中で説明されているように基本的にOKRはトップダウンだと思うので1チームで導入しようとしてもひとつ上の枠組みで目指すものとの整合性が取りにくい。 もしひとつ上の枠組みでOKRではなくMVVのようなものが設定されている場合、MVVからOKRへ落とすような工夫が必要になると思う。

4セルでキープする項目を書くのは良いと思った。 OKRやKPIで、じゃあ目標だけおっていればいいのか、他のことは後回しでいいのかっていう話に良くなったので。

bastionを廃してRDSのパブリックアクセス可能(publicly accessible)を有効にしてはどうか提言

tl;dr

  • Site to Site VPN, Direct Connect, Client VPNなどでオフィスネットワークとVPCがつながっていない前提
  • 従来Bastionインスタンスをおいていたがモダンな設計ではもはやRDS以外で使われない
  • publicly accessibleがtrueでもセキュリティを担保しやすくなっておりメリットも多いのでそうしたらどうだろうか

BastionがもはやEC2インスタンス用でいらない背景

elpy1/ssh-over-ssmやEC2 instance connect, そもそもECSやEKSの場合は個別のノードへログインする必要性がない、などの背景でモダンなAWSアーキテクチャではEC2インスタンスへのログインのためにbastionはほぼほぼ不要になりつつある。

bastionを使うとbastionに秘密鍵をおいてしまったり退職者のユーザーアカウントがなかなか削除されなかったりいつの間にかそこからデプロイされるようになる = immutableではなくなり作り直しができなくなる、などの問題があるためむしろ積極的に避けたい。

public accessibleをtrueにする利点

  • メリット
    • 設計がシンプル
      • RDSを知っている人なら誰でも接続方法がわかる
      • 部署やシステムごとに接続方法が変わったりしない
        • 接続方法のドキュメントをメンテナンスしたりその場所を考慮したりする必要がない
    • 余計な経路がないので可用性が高まる
      • bastionの可用性を担保しようとすると冗長化などでかなり構成が複雑になる
    • bastionで余計なコストが掛からない
    • mysqlクライアントから接続するときにssh port forwardingなどの設定が不要
      • 設定が難解で動作確認も難しいので非エンジニアにもやってもらうのがキビシイ
    • ssh port forwardingやbastionサーバをサポートしていないmysqlクライアントでも接続可能

publicly accessibleを有効にするリスクは幽霊では?

RDSでpublicly accessibleがtrueであることがセキュリティリスクである、ということはAWSを使う者にとってある程度の共通認識である。 しかし、これがどうにも疑わしい。 bastionを経由しようが結局public IPアドレスが振られるのがRDSインスタンスからbastionへ変わっただけで実態的なセキュリティリスクは減っていない。 確かにMySQLなどはプロトコルがセキュアでなかったりsshより比較的簡単なIDパスワードが使われる傾向がある。しかしIAMデータベース認証ではセキュアプロトコルが強制されるしセキュリティグループなどで接続元を絞れば十分安全である。またパスワードはそもそも十分セキュアな文字列にするべきだ。

これは個人的な推測なのだがどうにもpublicly accessible有効が危険だという認識は極めてずさんな設定のRDSへ攻撃された事例や話から生まれている気がする。実際の事例を聞くと安易にpublicly accessibleを有効にしたRDSインスタンスでsecureでないrootアカウントを設定してrootアカウントのユーザー名も"root"のままにしていたような、そのような話しかない。 確かにpublicly accessibleをfalseにすれば攻撃の難易度は上がるがDBインスタンスへのアクセシビリティを犠牲にしているので一概にやるべきとは思えない。

上記を踏まえてのpublicly accessible: trueでのおすすめ設定

  • (must) publicly accessibleをtrueにする
  • (must) セキュリティグループでingressをオフィスゲートウェイ(+ VPC)に絞る
  • (must) アプリケーション用パスワードは十分セキュアな文字列にする(パスワードジェネレータなど推奨)
  • (must) インターネットを経由する接続には必ずSSLプロトコルを利用する
  • (should) 開発者の接続はIAM データベース認証 - Amazon Auroraを使う
    • 必然的にプロトコルSSLになるためインターネット経由の接続でも通信内容が漏れる心配がない
  • (may) 接続ポートをデフォルトから変える1
    • 安易な攻撃からの防御手段になるがポートスキャンなどで無意味化される。本質的な対策ではないかも。

残タスク

publicly accessibleを有効にした場合、果たしてもはやprivate subnetは必要なのかという疑問が湧いてくる。 現段階ではもはや必要ない気がする2。ここについては追加調査が必要。

2020/06/19 追記

AWSのサポートに本件について問い合わせたところ、Publicly AccessibleのON/OFFとセキュリティについてはどちらとも言えないという返答が返ってきた。 Publicly AccessibleをONにしてもSecurity Groupなどを使えばセキュアにできるし、 Publicly AccessibleをOFFにしても踏み台サーバのセキュリティが弱かったりすればRDSへ侵入される危険があると。 道理だ。


  1. 変える場合は変更先のポート番号などに特にコンベンションなどなさそうなので(TCPやUDPにおけるポート番号の一覧 - Wikipedia)雑だが1万番代のポート番号からランダムで選択などでいいと思う。特にRDSは独立したインスタンスなのでポート番号がかぶる心配はない

  2. GCPとかそもそもVPC概念薄いが運用上問題になる話はほぼない。あっても既存の運用を変えずにGCPへ持っていきたいというケースしか聞かない