k8s配置中心-configmap,Secret
在生產環境中經常會遇到需要修改配置檔案的情況,傳統的修改方式不僅會影響到服務的正常執行,而且操作步驟也很繁瑣。為了解決這個問題,kubernetes專案從1.2版本引入了ConfigMap功能,用於將應用的配置資訊與程式的分離。這種方式不僅可以實現應用程式被的複用,而且還可以通過不同的配置實現更靈活的功能。在建立容器時,使用者可以將應用程式打包為容器映象後,通過環境變數或者外接掛載檔案的方式進行配置注入。ConfigMap && Secret 是K8S中的針對應用的配置中心,它有效的解決了應用掛載的問題,並且支援加密以及熱更新等功能,可以說是一個k8s提供的一件非常好用的功能。
建立ConfigMap
# 建立名稱空間
apiVersion: v1
kind: Namespace
metadata:
name: sg-bs
labels:
app: sg-bs
---
# ConfigMap是名稱空間級資源
apiVersion: v1
kind: ConfigMap
metadata:
name: test-configmap
namespace: sg-bs
data: # 健 : 值
level: debug
使用ConfigMap
## 使用掛載方式,將配置檔案掛載到容器中
# 使用
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx-config
spec:
selector:
matchLabels:
app: nginx-config
template:
metadata:
labels:
app: nginx-config
spec:
containers:
- name: nginx
image: nginx
volumeMounts: # 掛載
- mountPath: /etc/nginx/conf.d # 掛載路徑
name: nginx-config-configmap # 儲存卷名字
volumes:
- name: nginx-config
persistentVolumeClaim:
claimName: nginx-config
- name: nginx-config-configmap
configMap:
name: test-configmap # ConfigMap名字
items:
- key: level
path: level # 最終路徑為:/etc/nginx/conf.d/level
subPath引數
# configmap熱更新
## 修改configmap中的檔案,可以同步到所有的掛載此configmap的容器中(僅僅同步到容器中),但是如果使用subPath引數,則熱更新失效。
## configMap掛載會直接覆蓋原來的目錄,如果不覆蓋則需要使用subPath引數(subPath引數只能夠針對檔案,同時不支援熱更新)
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
listen [::]:80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.php;
}
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
}
index.php: |
<?php
phpinfo();
?>
---
kind: Service
apiVersion: v1
metadata:
name: nginx-config
spec:
ports:
- port: 80
targetPort: 80
nodePort: 30089
selector:
app: nginx-config
type: NodePort
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: nginx-config
spec:
selector:
matchLabels:
app: nginx-config
template:
metadata:
labels:
app: nginx-config
spec:
containers:
- name: php
image: alvinos/php:wordpress-v2
volumeMounts:
- mountPath: /usr/share/nginx/html
name: nginx-config-configmap
- name: nginx
image: alvinos/nginx:wordpress-v2
volumeMounts:
- mountPath: /usr/share/nginx/html/index.php
name: nginx-config-configmap
subPath: index.php
- mountPath: /etc/nginx/conf.d
name: nginx-config-configmap
volumes:
- name: nginx-config-configmap
configMap:
name: nginx-config
items:
- key: index.php
path: index.php
Secret
Secret解決了密碼、token、金鑰等敏感資料的配置問題,而不需要把這些敏感資料暴露到映象或者Pod Spec中。Secret可以以Volume或者環境變數的方式使用。
Secret用來儲存敏感資料,儲存之前就必須將檔案進行base64加密,掛載到pod中,自動解密。
預設使用Opaque型別。
Secret有四種型別:
Service Account :用來訪問Kubernetes API,由Kubernetes自動建立,並且會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中;
Opaque :base64編碼格式的Secret,用來儲存密碼、金鑰等;
kubernetes.io/dockerconfigjson :用來儲存私有docker registry的認證資訊
tls型別:訪問證照
官方文件
https://kubernetes.io/zh/docs/concepts/configuration/secret/
編寫secret清單
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: YWRtaW4xMjMK
username: YWRtaW4K
使用secret
Secret 可以作為資料卷被掛載,或作為環境變數 暴露出來以供 Pod 中的容器使用。它們也可以被系統的其他部分使用,而不直接暴露在 Pod 內。 例如,它們可以儲存憑據,系統的其他部分將用它來代表你與外部系統進行互動。
在 Pod 中使用 Secret 檔案
在 Pod 中使用存放在卷中的 Secret:
- 建立一個 Secret 或者使用已有的 Secret。多個 Pod 可以引用同一個 Secret。
- 修改你的 Pod 定義,在
spec.volumes[]
下增加一個卷。可以給這個卷隨意命名, 它的spec.volumes[].secret.secretName
必須是 Secret 物件的名字。 - 將
spec.containers[].volumeMounts[]
加到需要用到該 Secret 的容器中。 指定spec.containers[].volumeMounts[].readOnly = true
和spec.containers[].volumeMounts[].mountPath
為你想要該 Secret 出現的尚未使用的目錄。 - 修改你的映象並且/或者命令列,讓程式從該目錄下尋找檔案。 Secret 的
data
對映中的每一個鍵都對應mountPath
下的一個檔名。
這是一個在 Pod 中使用存放在掛載卷中 Secret 的例子:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
您想要用的每個 Secret 都需要在 spec.volumes
中引用。
如果 Pod 中有多個容器,每個容器都需要自己的 volumeMounts
配置塊, 但是每個 Secret 只需要一個 spec.volumes
。
您可以打包多個檔案到一個 Secret 中,或者使用的多個 Secret,怎樣方便就怎樣來。
將 Secret 鍵名對映到特定路徑
我們還可以控制 Secret 鍵名在儲存卷中對映的的路徑。 你可以使用 spec.volumes[].secret.items
欄位修改每個鍵對應的目標路徑:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
將會發生什麼呢:
username
Secret 儲存在/etc/foo/my-group/my-username
檔案中而不是/etc/foo/username
中。password
Secret 沒有被對映
如果使用了 spec.volumes[].secret.items
,只有在 items
中指定的鍵會被對映。 要使用 Secret 中所有鍵,就必須將它們都列在 items
欄位中。 所有列出的鍵名必須存在於相應的 Secret 中。否則,不會建立卷。
Secret 檔案許可權
你還可以指定 Secret 將擁有的許可權模式位。如果不指定,預設使用 0644
。 你可以為整個 Secret 卷指定預設模式;如果需要,可以為每個金鑰設定過載值。
例如,您可以指定如下預設模式:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 256
之後,Secret 將被掛載到 /etc/foo
目錄,而所有通過該 Secret 卷掛載 所建立的檔案的許可權都是 0400
。
請注意,JSON 規範不支援八進位制符號,因此使用 256 值作為 0400 許可權。 如果你使用 YAML 而不是 JSON,則可以使用八進位制符號以更自然的方式指定許可權。
注意,如果你通過 kubectl exec
進入到 Pod 中,你需要沿著符號連結來找到 所期望的檔案模式。例如,下面命令檢查 Secret 檔案的訪問模式:
kubectl exec mypod -it sh
cd /etc/foo
ls -l
輸出類似於:
total 0
lrwxrwxrwx 1 root root 15 May 18 00:18 password -> ..data/password
lrwxrwxrwx 1 root root 15 May 18 00:18 username -> ..data/username
沿著符號連結,可以檢視檔案的訪問模式:
cd /etc/foo/..data
ls -l
輸出類似於:
total 8
-r-------- 1 root root 12 May 18 00:18 password
-r-------- 1 root root 5 May 18 00:18 username
你還可以使用對映,如上一個示例,併為不同的檔案指定不同的許可權,如下所示:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 511
在這裡,位於 /etc/foo/my-group/my-username
的檔案的許可權值為 0777
。 由於 JSON 限制,必須以十進位制格式指定模式,即 511
。
請注意,如果稍後讀取此許可權值,可能會以十進位制格式顯示。
使用來自卷中的 Secret 值
在掛載了 Secret 卷的容器內,Secret 鍵名顯示為檔名,並且 Secret 的值 使用 base-64 解碼後儲存在這些檔案中。 這是在上面的示例容器內執行的命令的結果:
ls /etc/foo/
輸出類似於:
username
password
cat /etc/foo/username
輸出類似於:
admin
cat /etc/foo/password
輸出類似於:
1f2d1e2e67df
容器中的程式負責從檔案中讀取 secret。