原文發佈地址:https://www.cnblogs.com/Detector/p/9348485.html
背景
我們都知道出於安全性考慮,生產環境的權限一般都是要做最小化控制,尤其是數據庫的操作授權,更是重中之重。
博主所在公司使用的是Kubernetes(k8s)進行的集羣容器管理,因爲容器發佈時的IP都是動態分配的,而出於安全性考慮,數據庫的授權又不能全部放開或者針對整個集羣的IP,所以有了動態爲節點進行數據庫授權的需求,所以也就誕生我們今天的主角–數據庫授權組件,Mysql-grant。
當然,我們今天介紹的不是這個組件的開發,而是相關的測試過程記錄。
組件原理
這個數據庫動態授權組件的原理不復雜,每次Kubernetes有節點變化(上線或者下線服務)時,調取Kubernetes相關的API接口獲取已配置的服務改變的對應節點的IP,然後對其進行授權或者權限回收操作(IP+user)。相當於在獲取到信息之後執行下面的命令:
grant select,insert,update on 庫名.表名 to '用戶名'@'IP地址' identified by '密碼' with grant option;
測試設計
在瞭解了具體的需求之後,我很快的確定了測試思路。具體如下:
- 拉起兩個mysql數據庫,每個庫中新建兩個DB,每個DB個新建一張表。
- 寫一個無限循環的腳本,每隔兩秒訪問一次數據庫,插入一條數據,查詢一次數據。
- 把腳本打包到多個不同的鏡像服務中,push到公司的鏡像庫中。
- 然後根據設計的場景使用k8s(Kubernetes)發佈、下線服務、做Mysql-grant相關的配置信息改變來完成相關驗證;
環境
這次主要用的環境如下:
- golang開發環境
- docker環境
- 鏡像運行環境(centos)
測試腳本
考慮到鏡像的大小及Dockerfile的複雜性,本次使用了golang來寫這個腳本,直接編輯成二進制文件,可以不依賴環境執行,具體的腳本如下,把他保存爲mysqlgrant-test.go即可:
package main
import (
"time"
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
count := 0
for{
fmt.Println("====================")
// fmt.Println(count)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
time.Sleep(time.Second * 2)
count++
db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/easytest?charset=utf8")
checkErr(err)
//插入數據
stmt, err := db.Prepare("INSERT base_case SET case_name=?,project_id=?,content=?,description=?")
checkErr(err)
res, err := stmt.Exec(count, "Golang", time.Now(),time.Now())
checkErr(err)
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
//查詢數據
rows, err := db.Query("select * from base_case order by case_id desc limit 1")
checkErr(err)
for rows.Next() {
var content string
var case_id string
var case_name string
var project_id string
var description string
err = rows.Scan(&description, &case_id, &case_name, &project_id, &content)
checkErr(err)
fmt.Println(case_id +":"+ case_name +" "+ project_id +" "+ description +" "+ content)
// fmt.Println(case_id)
// fmt.Println(case_name)
// fmt.Println(project_id)
// fmt.Println(content)
// fmt.Println(description)
}
db.Close()
}
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
腳本build爲linux可執行文件
golang腳本的編譯命令如下:
go build 腳本名稱
但是因爲樓主使用的是windows
,默認的會直接build成 .exe
文件
所以我們要手動設置環境變量,具體命令如下:
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build mysqlgrant-test.go
GOOS:目標平臺的操作系統(darwin、freebsd、linux、windows)
GOARCH:目標平臺的體系架構(386、amd64、arm)
交叉編譯不支持 CGO 所以要禁用它
上面的命令編譯 64 位可執行程序,你當然應該也會使用 386 編譯 32 位可執行程序
鏡像構建
Dockerfile
上面的腳本準備好了之後,接下來要製作鏡像,我們這次試用的是dockerfile,dockerfile內容如下:
FROM centos:6.7
MAINTAINER <"[email protected]">
RUN mkdir -p /usr/local/user-web/mysqlgrant-test
ADD ./mysqlgrant-test /usr/local/user-web/mysqlgrant-test
#ADD ./conf /usr/local/usr-web/mysqlgrant-test/conf
WORKDIR /usr/local/user-web/mysqlgrant-test
CMD ./mysqlgrant-test
Docker build
將上面的信息保存到dockerfile文件之後,切換到文件所在目錄,執行下面命令來進行鏡像的構建:
docker build -t mysqlgrant-test/centos:v1.0 .
參數說明:
-t :指定要創建的目標鏡像名
. :Dockerfile 文件所在目錄,可以指定Dockerfile 的絕對路徑
注意後面的.
不能遺漏,它表示在當前目錄構建的意思
鏡像構建成功之後我們可以通過下面的命令來查看:
root@msxxx:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysqlgrant-test/centos v1.0 70bf1840fd7c 15 seconds ago 158.5 MB
鏡像有效性驗證
我們可以使用新的鏡像來創建容器:
root@msxxx:~$ docker run -it mysqlgrant-test/centos:v1.0 /bin/bash --name mysqlgrant
參數說明:
--name mysqlgrant
表示爲這個容器設置了一個叫mysqlgrant
的別名
-t
:在新容器內指定一個僞終端或終端。
-i
:允許你對容器內的標準輸入 (STDIN) 進行交互。
執行上面的命令後會默認進入mysqlgrant-test目錄,即我們上面在dockerfile中設置的WORKDIR。
當然我們也可以直接執行下面的命令來獲取容器的標準輸出:
docker logs mysqlgrant
這就是腳本輸出的內容:
至此,所有的東西準備完畢,只需要根據準備好的測試用例,做相關業務場景的驗證就可以了。
總結
在新技術應用的過程中難免會遇到一些問題,比如我們今天的介紹的容器化過程中解決數據庫鑑權問題開發的組件。我的感觸是,接觸新的事物我們能學習到更多的東西。此前學習的docker、golang等等,都沒有實戰的基礎,這一次雖然也只是簡單的實踐,但是還是有一種豁然開朗的感覺。