Neco は大量の物理サーバーを効率的に管理・運用することを目的とした開発プロジェクトです。 Kubernetes を中心に高度な自律運用の実現を目指しています。
本文書はプロジェクトに参加しているメンバーが身に着けている要素技術を並べたものです。
応募時点ですべてを身に着けている必要はまったくありません。 社内にはチュートリアル資料が多数用意されていますので、必要に応じて学べます。
リストは以下の大項目で分類されています。
Neco プロジェクトではドキュメントを非常に重視しています。 仕様書はもちろん、各種ポリシーやチュートリアル、調査資料などあらゆる場面でドキュメントを作成しています。
ドキュメントはほぼすべて Markdown 形式で書いています。
図の類はほぼ PlantUML で記述して誰でも編集可能にしています。
Neco の成果物はほぼすべて OSS として公開しています。 CI は CircleCI と GitHub Actions を併用しています。
- github.com/cybozu-go - Go 言語製の成果物
- github.com/topolvm - ストレージソフトウェア関係
- github.com/cybozu - 各種 OSS
Neco のテストでは複数の VM が必要になるので、各自が自分専用のテスト環境を持てるよう GCP を活用しています。 GCP の利用は限定的なので、内製のチュートリアル文書に従えば十分です。
Neco の成果物はほぼすべて Go 言語で書かれています。 そのため Go を学ぶことは必須ですし、かなり高度な使いこなしをしています。
他の言語の必要性は薄いです。シェルスクリプトが少々ある程度。
Kubernetes 周辺のコンテナ技術はほぼすべて Go で作られています。 一口に Go といってもいろいろあるので、以下のリストで必要な知識を確認してください。
- Go 言語の基礎知識
- A Tour of Go - やったことがなければ必ずやってください
- Effective Go - 読んだことがなければ必ず読んでください
- Code Review Comments - 従うべきとされている慣習です
- Modules - Go modules で構成管理しているので一読してください
- フレームワークとライブラリ
- context - goroutine 管理には必須の標準ライブラリです。あらゆる場面で利用しています。
- cobra, pflag, viper - サブコマンドがある CLI を作る高機能ライブラリです
- Go database/sql tutorial - Go で SQL データベースを扱う際に必読のチュートリアルです
- https://github.com/jmoiron/sqlx - Go での SQL 操作を楽にしてくれるライブラリ
これ以外に、後述する gRPC や Kubernetes のプログラミングを Go 言語で頻繁に行っています。
Go 言語を使う場合、並列・並行プログラミングは避けられません。 Go は goroutine と channel で手軽さを提供してくれますが、本質的な理解がなければ容易に不具合を生みます。
以下のような知識・経験を持っていることが望ましいです。
- スレッドプログラミングの経験がある
- メモリバリア命令の存在理由を説明できる
- コンパイラのリオーダーを制御する必要性が説明できる
資料:
- Go言語による並行処理 - O'Reilly から最近出版された書籍
- Go Memory Model - メモリモデルの仕様書です
Go は非同期ネットワークサーバーを簡単に作れるのであまりテクニックやライブラリは必要ありません。
自前で API を作るときは、スキーマファーストに開発ができる gRPC や GraphQL を優先しています。
HTTP 処理が必要な場合は、標準ライブラリ net/http を使います。他のライブラリは使っていません。
継続的にデリバリするため、機能の開発は付随する自動テストの実装も合わせて行うことにしています。
テストは実行環境の複雑さによって "single host test", "multi host test", "data center test" と分類されています。 multi host test は mtest, data center test は dctest と略称されます。
go test
で、単独のサーバー上で実行できる試験です。ユニットテストに加えて、etcd
を必要とする一部結合試験も single host test にまとめています。
テスト用に以下のライブラリを使うことがあります。 他のライブラリはあまり使いません。モックを実装するときは基本的に手書きしています。
- google/go-cmp -
reflect.DeepEqual
よりまともな比較をしてくれます - net/http/httptest - 標準の HTTP 用テストライブラリ
Neco の成果物は複数のサーバーで冗長化して動作させるものが非常に多いので、冗長構成に関する機能試験は複数の VM を立てて実行しています。
VM を立てるだけではその上の OS やホストから VM に共有したいファイルや VM 間のネットワーク構成を制御できないので、placemat
というツールを自作して使っています。
テストシナリオの作成には Ginkgo と Gomega というライブラリを使っています。分散システムでは、挙動の確認に一定の時間を要することが多いのですが、「一定時間内に〇〇になるはず」というシナリオを Eventually
で簡単に書くことができるためです。
placemat
- Ginkgo and Gomega
- sabakan/mtest - 上記ツールを用いた mtest の実例
すべての成果物を結合して動かすデータセンター環境も、placemat を利用して仮想的に実装しています。 cybozu-go/neco はそのような仮想データセンターの自動構築および自動更新するプログラムです。
Neco のネットワーク環境で必要になる知識は以下です。
- TCP/IP に関する基本的な知識
- DNS に関する基本的な知識
- BGP 等のルーティングプロトコルに関する基本的な知識
- TLS および PKI に関する基本的な知識
- HTTP や gRPC といったアプリケーションプロトコルの関する知識
- iptables や veth といった Linux ネットワーキングに関する知識
以下、参考資料です。
- マスタリングTCP/IP 入門編 第5版
- データセンター内で使う BGP の基礎知識
- 超入門DNS
- プロフェッショナルSSL/TLS
- Hypertext Transfer Protocol -- HTTP/1.1
Kubernetes による宣言的・自律的なシステム管理は Neco の中心となる構成要素です。 そのため Kubernetes は利用するだけでなく、システムの内部構成とソースコードの調査まで知らないことはないというレベルで習得する必要があります。 必要に応じてどこまでも調べる必要があるのですが、以下はこれまでに調べたりかかわってきたものの一部です。
- kubernetes.io - 公式サイト
- API Overview
- CRI -
kubelet
がコンテナ操作をするのに必要なインタフェースを定めたもの(実装としては cri-o や containerd) - CNI -
kubelet
や Docker がコンテナ用のネットワーク操作をするインタフェースを定めたもの- coil - 自社製 CNI プラグイン
- CSI - Kubernetes のボリュームプラグインのインタフェースを定めたもの
- TopoLVM - 自社製 CSI プラグイン
client-go
- Go 言語から Kubernetes を操作するためのライブラリ- kubebuilder - カスタムコントローラーを作成するツールキット
- controller-runtime: kubebuilder のランライムライブラリ
Kubernetes 上で他のアプリケーションのために以下のミドルウェアを動作させています。
- Argo CD - GitOps で継続的デリバリーするのに利用
- ExternalDNS - AWS Route 53 や GCP Cloud DNS を自動操作
- cert-manager - Let's Encrypt や自己署名証明書を自動発行・更新
- Calico - 拡張された NetworkPolicy を利用
- Contour / Envoy - マネージド HTTP(S) ロードバランサー
- MetalLB - マネージド Layer 3 ロードバランサー
- Prometheus - Kubernetes の標準的なメトリクス監視ソフトウェア
- Grafana - Prometheus のダッシュボードソフトウェア