EKS構成を把握するためにNeo4j Desktopを使う
k8sは運用するコンポーネントが多く、アプリ開発を続けていくうちに全体像が把握しづらくなりそう...という危機感からNeo4jを使ってk8s構成の可視化を試しました。
この記事ではNeo4j Desktopを使ってAmazon EKSを可視化しています。
Neo4j Desktopについて
Download Neo4j Desktopからインストールできます。
以前はneo4jパッケージをインストールしてサーバをローカル起動して...と言う手順が必要でしたが、Neo4j DesktopによってGUIで簡単にNeo4jサーバを起動できるようになりました。
個人的にはその分、プラグインを有効化したりneo4j.conf
やapoc.conf
の保存ディレクトリを探したり、意外と手間取りました。
今回は名前空間・ポッド・コンテナの構成情報を可視化するため、以下を準備しておきます。
プラグイン有効化
APOC
をインストールしておきます。
コンフィグとデータを管理ディレクトリに配置
Default file locationsを参考にGUIからフォルダを開くと簡単に見つけられます。
-
kubectl
で取得したEKS構成情報- 取得コマンドは
kubectl get namespace -o=json
とkubectl get pod -A -o=json
、これらjsonファイルはImport
ディレクトリに配置します$ ll import total 1584 -rw-r--r--@ 1 ts staff 4203 4 29 14:01 kubectl_namespace.json -rw-r--r--@ 1 ts staff 801081 4 29 14:02 kubectl_pods.json
- 取得コマンドは
-
apoc.load.json
有効化- デフォルト無効のため
apoc.conf
を新規作成してConfiguration
ディレクトリに配置します$ cat conf/apoc.conf apoc.import.file.enabled=true
- デフォルト無効のため
EKS構成のjsonデータをNeo4jにロード
call apoc.load.json("./kubectl_namespace.json")
yield value
with value
unwind value.items as item
merge (namespace:NameSpace {name: item.metadata.name, status: item.status.phase})
return namespace
;
配列の展開はUNWIND
を使いつつ、MERGE
でノードを作成します。
call apoc.load.json("./kubectl_pods.json")
yield value
with value
unwind value.items as item
merge (pod:Pod {name: item.metadata.name, namespace: item.metadata.namespace})
with value
unwind value.items as item
match (pod:Pod {name: item.metadata.name})
set pod.application = item.metadata.labels.app
return pod
;
MERGE
ではnullを許容しない仕様のため、後からSET
で属性を追加しています。
ref: https://community.neo4j.com/t/unwind-with-js-driver-yields-cannot-merge-node-using-null-property/15488
最低限のノードを作成したのでrelationを作成します。
match (n:NameSpace)
match (p:Pod)
where p.namespace = n.name
merge (p)-[:IN]->(n)
;
この時点でグラフは次のようになりました。名前空間ごとにどの程度のPodが存在するかわかります。
Pod内で起動しているコンテナをノード追加
Podでは複数コンテナが起動していることが一般的なため、Pod内の各コンテナをノードとして追加します。
call apoc.load.json("./kubectl_pods.json")
yield value
with value
unwind value.items as item
unwind item.spec.containers as c
match (pod:Pod)
where pod.name = item.metadata.name
merge (con:Container {name: c.name, image: c.image})<-[:RUN]-(pod)
return con, pod
;
再帰的な配列の展開をしたい場合はUNWIND
を複数宣言すれば済み、上記ではコンテナの配列を展開しつつ既存のPod名と一致するコンテナノードを作成しています。
作成済みのノードに任意の属性を追加
検索用途を考えて、Podにkind
属性を追加します。この値はPodのワークロード種別を表しています。
ref: ワークロードのデプロイの概要
call apoc.load.json("./kubectl_pods.json")
yield value
with value
unwind value.items as item
match (pod:Pod {name: item.metadata.name})
set pod.kind = item.metadata.ownerReferences[0].kind
;
クエリ検索いろいろ
全ノード取得
match (n:NameSpace)--(p:Pod)--(c:Container)
return n,p,c
;
ReplicaSetのPod全て
match (n:NameSpace)--(p:Pod)--(c:Container)
where p.kind = "ReplicaSet"
return n,p,c
ECRイメージを使っていないコンテナ
match (n:NameSpace)--(p:Pod)--(c:Container)
where not c.image =~ '.*\.ecr\..*'
return n,p,c
;
今後の課題
まずは内部ツールとして使い始める可能性も有望ですが、Neo4j Desktopは個人利用に限定されているため、チームで使いたい場面ではグラフDBを構築する必要が出てきます。
また、Cypherクエリをチーム内で共有する方法も検討する必要があり、クエリやデータをGitHub管理したい場合はWebアプリを作成することになりそうです。
現段階ではJupyterNotebookでCypherクエリ環境をつくって、チーム開発に対応できないか検証してみたいところです。
Discussion