背景
在前面三節中已經講到如何將我們的應用部署到 k8s 集羣並提供對外訪問的能力,x現在可以滿足基本的應用開發需求了。
現在我們需要更進一步,使用 k8s 提供的一些其他對象來標準化我的應用開發。
首先就是 ConfigMap
,從它的名字也可以看出這是用於管理配置的對象。
ConfigMap
不管我們之前是做 Java
、Go
還是 Python
開發都會使用到配置文件,而 ConfigMap
的作用可以將我們原本寫在配置文件裏的內容轉存到 k8s
中,然後和我們的 Container
進行綁定。
存儲到環境變量
綁定的第一種方式就是將配置直接寫入到環境變量,這裏我先定義一個 ConfigMap
:
apiVersion: v1
kind: ConfigMap
metadata:
name: k8s-combat-configmap
data:
PG_URL: "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"
重點是 data
部分,存儲的是一個 KV
結構的數據,這裏存儲的是一個數據庫連接。
需要注意,KV 的大小不能超過 1MB
接着可以在容器定義中綁定這個 ConfigMap
的所有 KV
到容器的環境變量:
# Define all the ConfigMap's data as container environment variables
envFrom:
- configMapRef:
name: k8s-combat-configmap
我將 ConfigMap
的定義也放在了同一個 deployment 中,直接 apply:
❯ k apply -f deployment/deployment.yaml
deployment.apps/k8s-combat created
configmap/k8s-combat-configmap created
此時 ConfigMap
也會被創建,我們可以使用
❯ k get configmap
NAME DATA AGE
k8s-combat-configmap 1 3m17s
❯ k describe configmap k8s-combat-configmap
Data
====
PG_URL:
----
postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable
拿到剛纔聲明的配置信息。
同時我在代碼中也讀取了這個環境變量:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
name, _ := os.Hostname()
url := os.Getenv("PG_URL")
fmt.Fprint(w, fmt.Sprintf("%s-%s", name, url))
})
訪問這個接口便能拿到這個環境變量:
root@k8s-combat-7b987bb496-pqt9s:/# curl http://127.0.0.1:8081
k8s-combat-7b987bb496-pqt9s-postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable
root@k8s-combat-7b987bb496-pqt9s:/# echo $PG_URL
postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable
存儲到文件
有些時候我們也需要將這些配置存儲到一個文件中,比如在 Java 中可以使用 spring
讀取,Go
也可以使用 configor
這些第三方庫來讀取,所有配置都在一個文件中也更方便維護。
在 ConfigMap
中新增了一個 key:APP
存放了一個 yaml
格式的數據,然後在容器中使用 volumes
和 volumeMounts
將數據掛載到容器中的指定路徑/go/bin/app.yaml
apply 之後我們可以在容器中查看這個文件是否存在:
root@k8s-combat-7b987bb496-pqt9s:/# cat /go/bin/app.yaml
name: k8s-combat
pulsar:
url: "pulsar://localhost:6650"
token: "abc"
配置已經成功掛載到了這個路徑,我們便可以在代碼中讀取這些數據。
Secret
可以看到 ConfigMap
中是明文存儲數據的;
k describe configmap k8s-combat-configmap
可以直接查看。
對一些敏感數據就不夠用了,這時我們可以使用 Secret
:
apiVersion: v1
kind: Secret
metadata:
name: k8s-combat-secret
type: Opaque
data:
PWD: YWJjCg==
---
env:
- name: PG_PWD
valueFrom:
secretKeyRef:
name: k8s-combat-secret
key: PWD
這裏我新增了一個 Secret
用於存儲密碼,並在 container
中也將這個 key
寫入到環境變量中。
❯ echo 'abc' | base64
YWJjCg==
Secret
中的數據需要使用 base64
進行編碼,所以我這裏存儲的是 abc.
apply 之後我們再查看這個 Secret
是不能直接查看原始數據的。
❯ k describe secret k8s-combat-secret
Name: k8s-combat-secret
Type: Opaque
Data
====
PWD: 4 bytes
Secret
相比 ConfigMap
多了一個 Type
選項。
我們現階段在應用中用的最多的就是這裏的 Opaque
,其他的暫時還用不上。
總結
在實際開發過程中研發人員基本上是不會直接接觸 ConfigMap
,一般會給開發者在管理臺提供維護配置的頁面進行 CRUD。
由於 ConfigMap
依賴於 k8s 與我們應用的語言無關,所以一些高級特性,比如實時更新就無法實現,每次修改後都得重啓應用才能生效。
類似於 Java 中常見的配置中心:Apollo,Nacos
使用上會有不小的區別,但這些是應用語言強綁定的,如果業務對這些配置中心特性有強烈需求的話也是可以使用的。
但如果團隊本身就是多語言研發,想要降低運維複雜度 ConfigMap
還是不二的選擇。
下一章節會更新大家都很感興趣的服務網格 Istio
,感興趣的朋友多多點贊轉發🙏🏻。
本文的所有源碼和資源文件在這裏可以訪問:
https://github.com/crossoverJie/k8s-combat