kubernetes從入門到精通系列11-配置信息容器化

kubernetes從入門到精通系列目錄:


kubernetes從入門到精通系列11-配置信息容器化


k8s 提供了 configMap、secret 這兩種特殊類型的存儲卷,多數情況下不是為 POD 提供存儲空間,而是為用戶提供了從集群外部到 POD 內部注入配置信息的方式。

  • 配置信息容器化有哪些方式
  1. 自定義命令行參數,例如:command、args,根據 args 傳遞不同的參數來將容器運行為不同的特性
  2. 直接把配置信息製作為 image 中,但是這種方式非常不靈活,這個鏡像只能適用於一種使用場景,過度耦合
  3. 環境變量,Cloud Native 支持通過環境變量來加載配置,或者使用 ENTRYPOINT 腳本來預處理環境變量為配置信息
  4. 存儲卷,在容器啟動時候掛載一個存儲卷,或者專用的配置存儲卷,掛載到應用程序的配置文件目錄
  • Secret與ConfigMap對比
<code>相同點:
- key / value 的形式

- 屬於某個特定的 namespace
- 可以導出到環境變量
- 可以通過目錄/文件形式掛載(支持掛載所有key和部分key)

不同點:
- Secret 可以被 ServerAccount 關聯(使用)
- Secret 可以存儲 register 的鑑權信息,用在 ImagePullSecret 參數中,用於拉取私有倉庫的鏡像
- Secret 支持 Base64 加密
- Secret 分為 kubernetes.io/Service Account,kubernetes.io/dockerconfigjson,Opaque三種類型, Configmap 不區分類型
- Secret 文件存儲在tmpfs文件系統中,Pod 刪除後 Secret文件也會對應的刪除。
/<code>

11.1 POD 獲取環境變量

  • env,詳見:kubectl explain pods.spec.containers.env
<code>name              <string>  # 變量名稱
value <string> # 變量的值
valueFrom <object> # 引用值,如:configMap 的某個鍵、POD 定義中的字段名,如:metadata.labels
resourceFieldRef <object> # 引用資源限制中的值
secretKeyRef <object> # 引用 secretKey
/<object>/<object>/<object>/<string>/<string>/<code>

11.2 configMap

假如我們現在要啟動一個 POD ,這個 POD 啟動時候,需要讀取不同的配置信息,那麼我們有兩種方式:

  1. 可以將 configMap 資源關聯到當前 POD 上,POD 從 configMap 讀取一個數據,傳遞給 POD 內部容器的一個變量,變量被注入後,可以重啟容器。
  2. 可以將 configMap 資源掛載到當前 POD 上,作為一個文件系統的路徑,這個目錄正好是應用程序讀取配置文件的路徑,容器就可以讀取到配置信息了,當 configMap 修改了,那麼就會通知 POD ,POD 可以進行重載配置。

在每個 configMap 中所有的配置信息都保存為鍵值的配置形式。

  • 清單格式,詳見:kubectl explain configMap
<code>apiVersion  <string>              # 版本號
binaryData # 二進制的數據
data # 鍵值對的數據
kind <string> # 對象類型
metadata <object> # 對象元數據
/<object>/<string>
/<string>/<code>
  • 命令行方式創建
<code># 創建名為 my-config 的 configMap,它的數據來自目錄中的文件,鍵為文件名,值為文件內容
kubectl create configmap my-config --from-file=path/to/dir


# 創建名為 my-config 的 configMap,它的數據來自文件中的鍵值對
kubectl create configmap my-config --from-file=path/to/file

# 創建名為 my-config 的 configMap,也可以手動指定鍵的名稱
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

# 從字面量中創建
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2

# 從env文件中命名 my-config
kubectl create configmap my-config --from-env-file=path/to/bar.env
/<code>

11.2.1 注入 POD ENV

  • 創建 ConfigMap 並在 POD ENV 中使用
<code>apiVersion: v1
kind: ConfigMap # 創建 ConfigMap 對象
metadata:
name: nginx-config
namespace: default
data:
server_name: myapp.kaliarch.com # 鍵值對數據
nginx_port: | # 鍵值對數據,此處為 nginx 配置文件,需要注意換行的寫法
server {
server_name myapp.kaliarch.com;
listen 80;
root /data/web/html;
}

---
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap-demo
namespace: default
labels:

app: myapp
tier: frontend
annotations:
kaliarch.com/created-by: "cluster amdin"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
env:
- name: NGINX_SERVER_PORT # 定義容器內變量的名字,容器需要在啟動的時候使用 ENTRYPOINT 腳本將環境變量轉換為應用的配置文件
valueFrom: # 值來自於 configMap 對象中
configMapKeyRef: # 引用 configMap 對象
name: nginx-config # configMap 對象的名字
key: nginx_port # 引用 configMap 中的哪個 key
optional: true # 相對 POD 啟動是否為可選,如果 configMap 中不存在這個值,true 則不阻塞 POD 啟動
- name: NGINX_SERVER_NAME # 定義容器內變量的名字,使用 exec 進入容器會發現變量已經在啟動容器前注入容器內部了。
valueFrom:
configMapKeyRef:
name: nginx-config
key: server_name
/<code>

11.2.2 掛載為 POD 卷

  • configMap 中的數據可以在容器內掛載為文件,並且當 configMap 中的數據發生變動的時候,容器內的文件相應也會發生變動,但不會重載容器內的進程。
<code>apiVersion: v1 

kind: ConfigMap # 創建 ConfigMap
metadata:
name: nginx-config-volumes
namespace: default
data: # ConfigMap 中保存了兩個數據,
index: | # 數據1,它可以在 container 中使用 ENV 注入環境變量,也可以在 container 中使用 volumeMounts 掛載成為文件

this is a test page


vhost: | # 數據2,它可以在 container 中使用 ENV 注入環境變量,也可以在 container 中使用 volumeMounts 掛載成為文件
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

location = /hostname.html {
alias /etc/hostname;
}
}
server {
server_name myapp.kaliarch.com;
listen 80;
root /data/web/html;
}

---
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap-volumes-demo
namespace: default
labels:
app: myapp
tier: frontend

annotations:
kaliarch.com/created-by: "cluster amdin"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/conf.d
readOnly: true
- name: nginx-page
mountPath: /data/web/html/
readOnly: true
volumes: # 定義卷
- name: nginx-conf # 定義卷的名字
configMap: # 該卷的類型為 configMap
name: nginx-config-volumes # 從命名空間中讀取哪個名字的 configMap
items: # 定義 configMap 數據到文件的映射,如果不定義則使用 configMap 中的鍵為文件名稱,值為文件內容
- key: vhost # 使用 configMap 哪個鍵
path: www.conf # 將 configMap 中的數據,映射為容器內哪個文件名稱
mode: 644 # 指明文件的權限
- name: nginx-page
configMap:
name: nginx-config-volumes
items:
- key: index
path: index.html
mode: 644

/<code>
  • 啟動後進入容器查看文件是否正常掛載
<code>kubectl exec -it pod-configmap-volumes-demo -c myapp -- /bin/sh 

/<code>
  • 使用 curl 命令驗證,是否能夠正常使用
<code>$ curl 10.244.2.104
Hello MyApp | Version: v1 |

$ curl -H "Host:myapp.kaliarch.com" 10.244.2.104

this is a test page


/<code>

11.3 secret

configMap 是明文存儲數據的,如果需要存儲敏感數據,則需要使用 secret ,secret 與 configMap 的作用基本一致,且 secret 中的數據不是明文存放的,而是 base64 編碼保存的。

  • secret 類型
<code>docker-registry    # 創建一個 Docker registry 使用的 secret
generic # 從本地文件,目錄或字面值創建一個 secret
tls # 創建一個 TLS secret
/<code>
  • 清單格式,詳見:kubectl explain secret
<code>apiVersion  <string>               # API 版本
data # 以鍵值對列出數據,值需要經過 base64 加密
kind <string> # 對象類型

metadata <object> # 元數據
stringData # 明文的數據
type <string> # 數據類型
/<string>
/<object>/<string>
/<string>/<code>

11.3.1 私有倉庫認證1

  • 首先通過命令行創建出來 secret
<code>kubectl create secret docker-registry regsecret --docker-server=registry-vpc.cn-hangzhou.aliyuncs.com --docker-username=admin --docker-password=123456 [email protected]
/<code>
  • 如果想保存為文件可以
<code>kubectl get secret regsecret -o yaml
/<code>
  • POD 創建時候,從 docker hub 拉取鏡像使用的用戶名密碼,kubectl explain pods.spec 的 imagePullSecrets 字段
<code>apiVersion: v1
kind: Pod
metadata:
name: secret-file-pod
spec:
containers:
- name: mypod
image: redis
imagePullSecrets: # 獲取鏡像需要的用戶名密碼
- name: regsecret # secret 對象
/<code>

11.3.2 私有倉庫認證2

  • 首先通過命令行創建出來 secret
<code>kubectl create secret docker-registry regsecret --docker-server=registry-vpc.cn-hangzhou.aliyuncs.com --docker-username=admin --docker-password=123456 [email protected]
/<code>
  • 創建自定義的 serviceaccount 對象,在 serviceaccount 對象上定義 image pull secrets
<code>apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: default
imagePullSecrets:
- name: regsecret # 指定 secret
/<code>
  • 創建 POD 使用指定的 serviceaccount 對象
<code>apiVersion: v1
kind: Pod
metadata:
name: pod-serviceaccount-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
serviceAccountName: admin # 使用 serviceaccount 進行拉取鏡像的認證,這樣更加安全
/<code>

11.3.3 創建 TLS 證書

  • 首先通過命令行創建出來
<code>kubectl create secret tls nginx-secret --cert=tls.crt --key=tls.key
/<code>
  • secret 中的數據可以在容器內掛載為文件,然後在 nginx 容器內使用證書文件
<code>apiVersion: v1
kind: Pod
metadata:
name: pod-configmap-volumes-demo
namespace: default
labels:
app: myapp
tier: frontend
annotations:
kaliarch.com/created-by: "cluster amdin"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/secret
readOnly: true
volumes: # 定義卷
- name: nginx-conf # 定義卷的名字
configMap: # 該卷的類型為 secret
name: nginx-secret # 從命名空間中讀取哪個名字的 secret
items: # 定義 secret 數據到文件的映射,如果不定義則使用 secret 中的鍵為文件名稱,值為文件內容
- key: tls.key # 使用 secret 哪個鍵
path: www.conf # 將 secret 中的數據,映射為容器內哪個文件名稱

mode: 644 # 指明文件的權限
- key: tls.crt
path: index.html
mode: 644
/<code>


分享到:


相關文章: