五分鐘k8s入門到實戰-應用配置

crossoverJie發表於2023-09-27

ConfigMap.png

背景

在前面三節中已經講到如何將我們的應用部署到 k8s 叢集並提供對外訪問的能力,x現在可以滿足基本的應用開發需求了。

現在我們需要更進一步,使用 k8s 提供的一些其他物件來標準化我的應用開發。
首先就是 ConfigMap,從它的名字也可以看出這是用於管理配置的物件。

ConfigMap

不管我們之前是做 JavaGo 還是 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 這些第三方庫來讀取,所有配置都在一個檔案中也更方便維護。

image.png
ConfigMap 中新增了一個 key:APP 存放了一個 yaml 格式的資料,然後在容器中使用 volumesvolumeMounts 將資料掛載到容器中的指定路徑/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

相關文章