kubesql
kubesql(https://github.com/xuxinkun/kubesql)是我最近開發的一個使用sql查詢kubernetes資源的工具。諸如node,pod等kubernetes的資源被處理為table。而后可以使用sql語句對其進行查詢。
例如,所有pod都很容易從apiserver中獲取。但是想要計算每個節點上的pod數量並不容易。但是使用了kubesql,只用一條sql語句可以實現它。
[root@localhost kubesql]# kubesql "select hostIp, count(*) from pods group by hostIp"
+----------+----------------+
| count(*) | hostIP |
+----------+----------------+
| 9 | None |
| 4 | 22.2.22.222 |
| 14 | 11.1.111.11 |
+----------+----------------+
類似的,如果我要查詢有多少處於Pending狀態的容器,也可以使用這樣的語句。
[root@localhost kubesql]# kubesql "select count(*) from pods where phase = 'Pending'"
+----------+
| count(*) |
+----------+
| 29 |
+----------+
kubesql的思路其實就是將一個pod內描述的各個屬性轉化為數據庫中的一行數據。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: 2018-09-28T07:42:35Z
name: watchtest
namespace: wangsiwu
uid: 10b60b8e-c2f2-11e8-8cfe-e0db55138e34
spec:
nodeName: 10.8.64.179
schedulerName: default-scheduler
status:
phase: Pending
[root@f34cee76e36a kubesql]# kubesql "select * from pods where name='watchtest'"
+-------------+-------------------+-------------------+-----------+-----------+--------+-------+-----------+--------+---------+---------------------------+--------------------------------------+
| nodeName | schedulerName | deletionTimestamp | namespace | name | reason | podIP | startTime | hostIP | phase | creationTimestamp | uid |
+-------------+-------------------+-------------------+-----------+-----------+--------+-------+-----------+--------+---------+---------------------------+--------------------------------------+
| 10.8.64.179 | default-scheduler | None | wangsiwu | watchtest | None | None | None | None | Pending | 2018-09-28 07:42:35+00:00 | 10b60b8e-c2f2-11e8-8cfe-e0db55138e34 |
+-------------+-------------------+-------------------+-----------+-----------+--------+-------+-----------+--------+---------+---------------------------+--------------------------------------+
工作原理
kubesql主要由三個組件組成。
- kubesql-watch:始終watch來自kube-apiserver的事件,並將其進行整理為table,然后寫入sqlite3。
- kubesql-server:提供http api進行查詢。接受sql查詢,在sqlite3中執行查詢並返回查詢結果。
- kubesql-client:將查詢sql發送到kubesql-server並獲取結果,然后以表格格式打印結果。
為了增加sqlite3的吞吐量,db文件放在共享內存中,例如放在/dev/shm文件夾。請確保shm超過64MB(如果集群非常大,這里應該對應設置的較大)。
+----------------+ watch +---------------+ +---------+
| kube-apiserver | -------> | kubesql-watch | --> | sqlite3 |
+----------------+ +---------------+ +---------+
^
|
|
+----------------+ http +---------------+ |
| kubesql-client | -------> | kubsql-server | ------+
+----------------+ +---------------+
部署方式
使用docker可以進行方便的部署(我正在編寫使用kubernetes進行部署,很快會更新上去)。
這里假定將kubeconfig放置在物理機的/etc/kubernetes/kubeconfig位置上。
首先部署kubesql-watch和kubesql-server。
docker pull xuxinkun/kubesql
docker run -it -d --name kubesql-watch -v /dev/shm:/dev/shm -v /etc/kubernetes/kubeconfig:/etc/kubeconfig xuxinkun/kubesql kubesql-watch
docker run -it -d --name kubesql-server -v /dev/shm:/dev/shm -v /etc/kubernetes/kubeconfig:/etc/kubeconfig xuxinkun/kubesql kubesql-server
使用方式
執行kubesql命令,使用sql進行相關的查詢。創建一個kubesql的容器用以執行命令。
這里特別注意,如果不修改配置,就要使用
--net=container:kubesql-server
將kubesql的容器和kubesql-server的容器網絡在一起,這樣可以通過127.0.0.1
地址進行訪問。這個地址可以在/etc/kubesql/config
中進行配置。如果配置了這個地址,就不必使用這個--net
的參數了。
[root@localhost kubesql]# docker run -it --rm --name kubesql --net=container:kubesql-server xuxinkun/kubesql bash
[root@d58bbb8c7aa8 kubesql]# kubesql -h
usage: kubesql [-h] [-t TABLE] [-a] [sql]
positional arguments:
sql execte the sql.
optional arguments:
-h, --help show this help message and exit
-t TABLE, --table TABLE
increase output verbosity
-a, --all show all tables
kubesql -a
命令可以查看當前支持的表格。
[root@localhost kubesql]# kubesql -a
+------------+
| table_name |
+------------+
| pods |
| nodes |
+------------+
kubesql -t {table_name}
可以查詢 table_name
表格支持的字段。每個字段對應的是api中的哪個字段,可以在/etc/kubesql/params
中查看。
[root@localhost kubesql]# kubesql -t nodes
+-------------------------+-----+------------+---------+----+-----------+
| name | cid | dflt_value | notnull | pk | type |
+-------------------------+-----+------------+---------+----+-----------+
| name | 0 | None | 0 | 0 | char(200) |
| uid | 1 | None | 0 | 0 | char(200) |
| creationTimestamp | 2 | None | 0 | 0 | datetime |
| deletionTimestamp | 3 | None | 0 | 0 | datetime |
| allocatable_cpu | 5 | None | 0 | 0 | char(200) |
| allocatable_memory | 6 | None | 0 | 0 | char(200) |
| allocatable_pods | 7 | None | 0 | 0 | char(200) |
| capacity_cpu | 8 | None | 0 | 0 | char(200) |
| capacity_memory | 9 | None | 0 | 0 | char(200) |
| capacity_pods | 10 | None | 0 | 0 | char(200) |
| architecture | 11 | None | 0 | 0 | char(200) |
| containerRuntimeVersion | 12 | None | 0 | 0 | char(200) |
| kubeProxyVersion | 13 | None | 0 | 0 | char(200) |
| kubeletVersion | 14 | None | 0 | 0 | char(200) |
| operatingSystem | 15 | None | 0 | 0 | char(200) |
| osImage | 16 | None | 0 | 0 | char(200) |
+-------------------------+-----+------------+---------+----+-----------+
一些樣例
查詢某個節點的pod的名稱和ns。
[root@localhost kubesql]# kubesql "select name, namespace from pods where hostIp = '172.22.160.107'"
+-----------+-----------------------------------------------------------+
| namespace | name |
+-----------+-----------------------------------------------------------+
| default | imagetest1 |
| xutest | dftest-b16f1ac7-0b56c2b9-v2bw2 |
| default | imagetest |
| xutest | dftest-9da529db |
+-----------+-----------------------------------------------------------+
查詢2019-03-12之后創建的容器名稱和創建時間。
[root@localhost kubesql]# kubesql "select name, namespace,creationTimestamp from pods where creationTimestamp > datetime('2019-03-12') order by creationTimestamp desc"
+-----------+---------------------------+------------------+
| namespace | creationTimestamp | name |
+-----------+---------------------------+------------------+
| huck-test | 2019-03-12 07:59:36+00:00 | xxxxlog-v4-hvmsd |
| xutt | 2019-03-12 02:45:40+00:00 | soxcs-a03b8302 |
+-----------+---------------------------+------------------+
查詢docker版本是1.10.3的節點。
[root@localhost kubesql]# kubesql "select name,containerRuntimeVersion from nodes where containerRuntimeVersion = 'docker://1.10.3'"
+----------------+-------------------------+
| name | containerRuntimeVersion |
+----------------+-------------------------+
| 111.22.111.31 | docker://1.10.3 |
| 11.3.22.201 | docker://1.10.3 |
+----------------+-------------------------+
開發的思路歷程
多年前,接觸了facebook開源的項目osquery。關於該項目可以參見我以前的博客資料https://xuxinkun.github.io/tags/#osquery。
osquery使用sql來管理系統信息,進行查詢的思路給了我極深的印象。在我后來使用kubernetes時,我也經常會想,能不能用sql來查詢kubernetes的資源。
在這個思路的啟發下,我做了第一版的kubesql,其主要是將kube-apiserver的數據寫成文件,而后由spark進行讀取,並執行查詢。這個版本的kubesql有很大的一個問題,就是數據不能夠動態更新。而且不太穩定,經常出現spark退出的問題。另外一個弊病是字段難於重命名,比如metadata.name
字段就只能使用這個很長的名字,不方便使用。
因此我在重新開發的時候,重新設計了實現方式和架構,更具有靈活性。而且支持字段重命名。當然,也有很多不完善的地方。還需要開發的。
如果有興趣的同學,也可以一起來參加開發。我的開發計划如下:
- 增加list的支持,可以支持pod中container字段的支持
- 完善出錯處理
- 提高watch性能,減少對sqlite3的壓力
- 增加自定義處理函數,這樣可以將內存等值從字符串處理為數值
- 增加更多的資源支持,如rs,configmap,deployment等