Kubernetes應(yīng)用配置管理創(chuàng)建使用詳解
正文
不論什么樣的應(yīng)用,基本都有配置文件,在企業(yè)中,大部分會用到配置中心,比如apollo、nacos等,也有一些公司直接使用Kubernetes自帶的配置管理,主要有:
- Secret
- ConfigMap
Secret
如果把配置信息保存在Secret中,其會被加密存放到Etcd中,Pod可以通過以下兩種種方式使用它:
- 通過環(huán)境變量的方式
- 通過掛載的方式
- 指定拉取鏡像的Secret
一般情況下,通過Secret保存的配置信息都是敏感信息,比如數(shù)據(jù)庫的賬號密碼、認(rèn)證服務(wù)的賬號密碼等,且Secret不宜過大,因?yàn)槿绻褂么蟮腟ecret,則將大量占用API Server和kubelet的內(nèi)存。
創(chuàng)建Secret
創(chuàng)建Secret的方式主要有兩種:
- 使用YAML文件創(chuàng)建
- 使用kubectl命令創(chuàng)建
使用YAML文件創(chuàng)建
使用YAML文件創(chuàng)建,就要熟悉Secret的配置詳情,可以通過kubectl explain secret
去查看。其主要字段有apiVersion,data,kind,metadata,type。
比如創(chuàng)建一個(gè)簡單的Secret如下:
apiVersion: v1 kind: Secret metadata: name: my-secret-volume type: Opaque data: user: cm9vdA== password: UEBzc1cwcmQ=
其中apiVersion、kind和metadata是常用字段,這里就不贅述了。type表示secret的類型,主要有以下幾種:
- Qpaque:可以定義任意數(shù)據(jù)
- kubernetes.io/service-account-token:配置ServiceAccount Token
- kubernetes.io/dockercfg:配置docker認(rèn)證文件
- kubernetes.io/dockerconfigjson:配置docker認(rèn)證文件
- kubernetes.io/basic-auth:配置基礎(chǔ)認(rèn)證
- kubernetes.io/ssh-auth:配置ssh認(rèn)證
- kubernetes.io/tls:配置TLS證書
- bootstrap.kubernetes.io/token:配置bootstrap token
如果在創(chuàng)建Secret的時(shí)候沒有指定類型,默認(rèn)使用Qpaque類型。另外data的數(shù)據(jù)的值是需要base64轉(zhuǎn)碼。
使用kubectl命令創(chuàng)建
在使用kubectl創(chuàng)建的時(shí)候,如果不熟悉子命令信息,可以通過kubectl explain secret查看。
我們使用以下命令創(chuàng)建一個(gè)Secret:
$ kubectl create secret generic secret-auth-test --from-literal=username=joker --from-literal=password=123
創(chuàng)建完成后,可以看到username和password的值被自動加密了,如下:
$ kubectl get secrets secret-auth-test -oyaml apiVersion: v1 data: password: MTIz username: am9rZXI= kind: Secret metadata: creationTimestamp: "2022-07-25T07:44:18Z" name: secret-auth-test namespace: default resourceVersion: "652834" uid: ff1b756a-6b38-4b68-a47c-c51988729b68 type: Opaque
除了直接在命令行輸入數(shù)據(jù),還可以從文件創(chuàng)建,如下:
$ echo -n 'admin' > ./username.txt $ echo -n '1f2d1e2e67df' > ./password.txt
然后通過--from-file引入文件,如下:
$ kubectl create secret generic db-user-pass \ --from-file=./username.txt \ --from-file=./password.txt
創(chuàng)建后的secret值都是加密的,如果要獲取明文信息,通過以下命令即可:
$ kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
默認(rèn)情況下,secret是使用base64加密的,所以解密可以直接使用base64解密。
使用Secret
Secret只是一個(gè)靜態(tài)資源,最終,我們是想使用它,在實(shí)際中,主要通過以下方式使用:
- 通過環(huán)境變量的方式
- 通過掛載的方式
- 指定拉取鏡像的Secret
我們在上面創(chuàng)建了secret-auth-test
的Secret,下面分別使用以上三種方式進(jìn)行使用。
通過環(huán)境變量使用Secret
在Pod的對象中,有spec.containers.env.valueFrom.secretKeyRef字段,該字段可以用來引用Secret字段,如下:
apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: - name: mycontainer image: redis env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: secret-auth-test key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: secret-auth-test key: password
這樣就會把Secret里的信息注入到容器環(huán)境變量里,應(yīng)用可以直接通過讀取環(huán)境變量來使用。
通過掛載的方式使用Secret
可以使用掛載的方式,將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: secret-auth-test
這樣就會把數(shù)據(jù)掛載到/etc/foo這個(gè)目錄里,如下:
$ kubectl exec -it mypod -- /bin/sh # ls -l /etc/foo total 0 lrwxrwxrwx 1 root root 15 Jul 25 08:30 password -> ..data/password lrwxrwxrwx 1 root root 15 Jul 25 08:30 username -> ..data/username
如果Secret里有多個(gè)鍵值,還可以只掛載某一個(gè)數(shù)據(jù),如下:
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: secret-auth-test items: - key: username path: my-group/my-username
上面指定volumes.secret.items.path用來指定username的子目錄,如下:
$ kubectl exec -it mypod-password -- /bin/bash root@mypod-password:/data# cat /etc/foo/my-group/my-username joker
除此之外,還可以指定權(quán)限,如下:
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" volumes: - name: foo secret: secretName: secret-auth-test defaultMode: 0400
然后可以看到被掛載的Secret的權(quán)限如下:
$ kubectl exec -it mypod-permision -- /bin/bash root@mypod-permision:/etc/foo# ls -l total 0 lrwxrwxrwx 1 root root 15 Jul 25 08:38 password -> ..data/password lrwxrwxrwx 1 root root 15 Jul 25 08:38 username -> ..data/username root@mypod-permision:/etc/foo# ls ..data/password -l -r-------- 1 root root 3 Jul 25 08:38 ..data/password
注意:我們進(jìn)/etc/foo目錄直接使用ls -l查看到的權(quán)限是777,但是仔細(xì)的人可以發(fā)現(xiàn)其實(shí)質(zhì)是一個(gè)鏈接文件,我們真正要看的權(quán)限是被鏈接的文件,也就是上面的..data/password。
在拉取鏡像的時(shí)候使用Secret
我們在前面列舉了很多YAML文件,都沒有配置imagePullSecret,主要是那些鏡像都是Dockerhub官方的鏡像,對外是公開的。
然而,在實(shí)際的生產(chǎn)中,不會將自己公司的鏡像對外公開,這非常的不安全。如果鏡像倉庫加密了,在下載鏡像的時(shí)候要docker login,在Kubernetes中,也免不了該操作。
為此,Kubernetes提供了imagePullSecret字段,該字段用來指定拉取鏡像的Secret,這個(gè)Secret會保存鏡像倉庫的認(rèn)證信息。
(1)首先創(chuàng)建鏡像認(rèn)證信息的Secret
kubectl create secret \ docker-registry pull-registry-secret \ --docker-server=registry.test.cn \ --docker-username=ops \ --docker-password=ops123123 \
(2)在Pod中使用
apiVersion: v1 kind: Pod metadata: name: mypod spec: imagePullSecrets: - name: pull-registry-secret containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: "/etc/foo" volumes: - name: foo secret: secretName: secret-auth-test defaultMode: 0400
這樣就可以拉取私有倉庫里的鏡像了。
小結(jié)
綜上,我們可以通過Secret保管其他系統(tǒng)的敏感信息(比如數(shù)據(jù)庫的用戶名和密碼),并以Mount的方式將Secret掛載到Container中,然后通過訪問目錄中文件的方式獲取該敏感信息。當(dāng)Pod被API Server創(chuàng)建時(shí),API Server不會校驗(yàn)該P(yáng)od引用的Secret是否存在。一旦這個(gè)Pod被調(diào)度,則kubelet將試著獲取Secret的值。
如果Secret不存在或暫時(shí)無法連接到API Server,則kubelet按一定的時(shí)間間隔定期重試獲取該Secret,并發(fā)送一個(gè)Event來解釋Pod沒有啟動的原因。一旦Secret被Pod獲取,則kubelet將創(chuàng)建并掛載包含Secret的Volume。只有所有Volume都掛載成功,Pod中的Container才會被啟動。在kubelet啟動Pod中的Container后,Container中和Secret相關(guān)的Volume將不會被改變,即使Secret本身被修改。為了使用更新后的Secret,必須刪除舊Pod,并重新創(chuàng)建一個(gè)新Pod。
ConfigMap
ConfigMap和Serect類似,不同之處在于ConfigMap保存的數(shù)據(jù)信息是不需要加密的,比如一些應(yīng)用的配置信息,其他的用法和Secret一樣。
創(chuàng)建ConfigMap
同樣,我們可以使用兩種方式來創(chuàng)建ConfigMap:
- 通過命令行方式,也就是kubectl create configmap;
- 通過YAML文件方式;
通過命令創(chuàng)建ConfigMap
如果不熟悉ConfigMap對象的字段,可以通過kubectl explain configmap來查看,如果想查看創(chuàng)建configmap的示例,可以通過kubectl create configmap -h查看,如下:
Examples: # Create a new config map named my-config based on folder bar kubectl create configmap my-config --from-file=path/to/bar # Create a new config map named my-config with specified keys instead of file basenames on disk kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt # Create a new config map named my-config with key1=config1 and key2=config2 kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2 # Create a new config map named my-config from the key=value pairs in the file kubectl create configmap my-config --from-file=path/to/bar # Create a new config map named my-config from an env file kubectl create configmap my-config --from-env-file=path/to/foo.env --from-env-file=path/to/bar.env
從上面可以看出,創(chuàng)建ConfigMap可以從給定一個(gè)目錄來創(chuàng)建。例如,我們定義了如下一些配置文件:
$ mkdir configmap-demo $ cd configmap-demo $ ll total 8 -rw-r--r-- 1 root root 25 Sep 6 17:07 mysqld.conf -rw-r--r-- 1 root root 25 Sep 6 17:07 redis.conf $ cat mysqld.conf host=127.0.0.1 port=3306 $ cat redis.conf host=127.0.0.1 port=6379
然后使用一下命令來進(jìn)行創(chuàng)建:
$ kubectl create configmap my-configmap --from-file=../configmap-demo/
然后通過一下命令查看創(chuàng)建完的configmap:
$ kubectl get cm NAME DATA AGE kube-root-ca.crt 1 21d my-configmap 2 9s $ kubectl describe cm my-configmap Name: my-configmap Namespace: default Labels: <none> Annotations: <none> Data ==== mysqld.conf: ---- host=127.0.0.1 port=3306 redis.conf: ---- host=127.0.0.1 port=6379 BinaryData ==== Events: <none>
我們可以看到兩個(gè)key對應(yīng)的是文件的名字,value對應(yīng)的是文件的內(nèi)容。如果要看鍵值的話可以通過如下命令查看:
$ kubectl get configmap my-configmap -o yaml apiVersion: v1 data: mysqld.conf: | host=127.0.0.1 port=3306 redis.conf: | host=127.0.0.1 port=6379 kind: ConfigMap metadata: creationTimestamp: "2022-07-25T09:20:43Z" name: my-configmap namespace: default resourceVersion: "667706" uid: 46cb52e9-0936-4934-9628-ac20efcfd893
當(dāng)然,我們還可以通過文件來創(chuàng)建一個(gè)configmap,比如我們定義一個(gè)如下的配置文件:
$ cat nginx.conf user nobody; worker_processes 1; error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; tcp_nopush on; keepalive_timeout 65; gzip on; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
然后通過如下命令創(chuàng)建一個(gè)nginx的configmap:
$ kubectl create configmap nginx-configmap --from-file=nginx.conf
查看創(chuàng)建后的信息:
$ kubectl get configmap nginx-configmap -o yaml apiVersion: v1 data: nginx.conf: | user nobody; worker_processes 1; error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; tcp_nopush on; keepalive_timeout 65; gzip on; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } kind: ConfigMap metadata: creationTimestamp: "2022-07-25T09:24:29Z" name: nginx-configmap namespace: default resourceVersion: "668283" uid: a025da28-6817-4605-8daf-375b676282c1
注:在一條命令中--from-file可以指定多次。
另外,通過幫助文檔我們可以看到我們還可以直接使用字符串進(jìn)行創(chuàng)建,通過--from-literal參數(shù)傳遞配置信息,同樣的,這個(gè)參數(shù)可以使用多次,格式如下:
$ kubectl create configmap my-cm-daemo --from-literal=db.host=localhost --from-literal=db.port=3306
通過YAML創(chuàng)建ConfigMap
通過YAML文件創(chuàng)建就比較簡單,我們可以參考上面輸出的yaml信息,比如定義如下一個(gè)YAML文件:
apiVersion: v1 kind: ConfigMap metadata: name: my-cm-daemon2 labels: app: cm-daemon data: redis.conf: | host=127.0.0.1 port=6379
然后創(chuàng)建即可。
使用ConfigMap
ConfigMap中的配置數(shù)據(jù)可以通過如下方式進(jìn)行使用:
- 設(shè)置環(huán)境變量值
- 在數(shù)據(jù)卷中創(chuàng)建config文件
通過環(huán)境變量使用ConfigMap
我們直接通過在pod.spec.containers.env.valueFrom.configMapKeyRef中引用ConfigMap即可,如下:
apiVersion: v1 kind: Pod metadata: name: env-configmap labels: app: env-configmap-mysql spec: containers: - name: test-configmap image: busybox command: - "/bin/sh" - "-c" - "env" env: - name: DB_HOST valueFrom: configMapKeyRef: name: my-cm-daemo key: db.host - name: DB_PORT valueFrom: configMapKeyRef: name: my-cm-daemo key: db.port envFrom: - configMapRef: name: my-cm-daemo
創(chuàng)建后,可以通過日志查看環(huán)境變量輸出,如下:
$ kubectl logs env-configmap | grep DB DB_PORT=3306 DB_HOST=localhost
通過數(shù)據(jù)卷使用ConfigMap
基本原理和Secret一樣。
在這里,通過指定pod.spec.volumes.configMap.name來指定ConfigMap,然后掛載到容器里,如下:
apiVersion: v1 kind: Pod metadata: name: volume-configmap-test spec: containers: - name: volume-configmap-test image: busybox command: [ "/bin/sh", "-c", "cat /etc/config/redis.conf" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: my-configmap
我們可以通過日志查看ConfigMap是否掛載進(jìn)去了。
$ kubectl logs volume-configmap-test host=127.0.0.1 port=6379
我們也可以在ConfigMap值被映射的數(shù)據(jù)卷里去控制路徑,如下:
apiVersion: v1 kind: Pod metadata: name: volume-path-configmap spec: containers: - name: volume-path-configmap-test image: busybox command: [ "/bin/sh","-c","cat /etc/config/path/to/msyqld.conf" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: my-configmap items: - key: mysqld.conf path: path/to/msyqld.conf
另外,當(dāng)ConfigMap以數(shù)據(jù)卷的形式掛載進(jìn)Pod的時(shí),這時(shí)更新ConfigMap(或刪掉重建ConfigMap),Pod內(nèi)掛載的配置信息會熱更新。雖然配置信息更新,應(yīng)用到底能不能使用,主要還是依賴應(yīng)用是否也會熱更新。
總結(jié)
ConfigMap在實(shí)際中用的還是比較多,主要都是一些應(yīng)用的配置文件,比如Nginx配置文件,MySQL配置文件,這類配置文件如果想放到私有的配置中心需要額外花費(fèi)更多的精力,而放到ConfigMap,則方便很多,而且多數(shù)都以掛載的方式放進(jìn)容器里。
以上就是Kubernetes應(yīng)用配置管理創(chuàng)建使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Kubernetes應(yīng)用配置管理的資料請關(guān)注腳本之家其它相關(guān)文章!
- Kubernetes ApiServer三大server權(quán)限與數(shù)據(jù)存儲解析
- Kubernetes Visitor設(shè)計(jì)模式及發(fā)送pod創(chuàng)建請求解析
- Kubernetes kubectl中Pod創(chuàng)建流程源碼解析
- Kubernetes?權(quán)限管理認(rèn)證鑒權(quán)詳解
- Kubernetes調(diào)度管理優(yōu)先級和搶占機(jī)制詳解
- Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解
- Kubernetes存儲系統(tǒng)數(shù)據(jù)持久化管理詳解
- Kubernetes scheduler啟動監(jiān)控資源變化解析
相關(guān)文章
Kubernetes中創(chuàng)建命名空間實(shí)現(xiàn)方法
這篇文章主要為大家介紹了Kubernetes中創(chuàng)建命名空間實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11使用k8tz解決pod內(nèi)的時(shí)區(qū)問題(坑的解決)
時(shí)區(qū)的不一致,會帶來很多困擾。即使代碼與時(shí)區(qū)無關(guān),但容器日志與系統(tǒng)日志時(shí)間相關(guān)聯(lián)排查問題也會讓人頭疼,這篇文章主要介紹了使用k8tz優(yōu)雅的解決pod內(nèi)的時(shí)區(qū)問題,需要的朋友可以參考下2022-10-10ES業(yè)務(wù)數(shù)據(jù)遷移遇到的精度問題BUG
這篇文章主要為大家介紹了ES業(yè)務(wù)數(shù)據(jù)遷移遇到的BUG精度問題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06kubernetes k8s 存儲動態(tài)掛載配置詳解
這篇文章主要為大家介紹了kubernetes k8s 存儲動態(tài)掛載配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Linux安裝Kubernetes(k8s)超詳細(xì)教程
Kubernetes是一個(gè)輕便的和可擴(kuò)展的開源平臺,用于管理容器化應(yīng)用和服務(wù),通過Kubernetes能夠進(jìn)行應(yīng)用的自動化部署和擴(kuò)縮容,這篇文章主要給大家介紹了關(guān)于Linux安裝Kubernetes(k8s)的相關(guān)資料,需要的朋友可以參考下2024-07-07