最近在抽取微服務配置資訊時,調研了 K8s Secrets
物件 ,在此與大家分享。
Kubernetes(以下簡稱 K8s) Secrets
官方文件:
kubernetes.io/docs/user-g…
Secrets
概述
K8s 中 Secrets
是一個包含少量敏感資訊如密碼,令牌,或祕鑰的物件。這些資訊可能被儲存在 pod 定義或者 docker 映象中,把這些資訊儲存在 Secrets
物件中,可以在這些資訊被使用時加以控制,並可以降低資訊洩露的風險。點選 Secret 設計文件 檢視更多資訊。
下面我們以 blog-service
為例,實現把 db
資訊儲存在 K8s Secrets
物件中,並在 blog-service
中讀取 Secrets
物件中的 db
資訊。
1. 建立 K8s secret 物件
K8s Secrets
中儲存的資料都必須經過 base64
加密,我們可以通過 echo
命令為資料加密:
root@ubuntu:~/Carrotzpc/devops/yamls# echo -n "carrot" | base64
Y2Fycm90
root@ubuntu:~/Carrotzpc/devops/yamls# echo -n "192.168.5.1" | base64
MTkyLjE2OC41LjE=
root@ubuntu:~/Carrotzpc/devops/yamls# echo -n "3306" | base64
MzMwNg==複製程式碼
建立如下 secret.yaml
檔案,db
相關配置資訊填寫在 data
欄位中:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: carrot
type: Opaque
data:
# base64
carrot-db-name: Y2Fycm90
carrot-db-username: Y2Fycm90
carrot-db-password: Y2Fycm90
carrot-db-host: MTkyLjE2OC41LjE=
carrot-db-port: MzMwNg==複製程式碼
建立 Secrets
物件 db-secret
:
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl create -f secret.yaml
secret "db-secret" created
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl get secret db-secret --namespace=carrot -o yaml
apiVersion: v1
data:
carrot-db-host: MTkyLjE2OC41LjE=
carrot-db-name: Y2Fycm90
carrot-db-password: Y2Fycm90
carrot-db-port: MzMwNg==
carrot-db-username: Y2Fycm90
kind: Secret
metadata:
creationTimestamp: 2016-08-03T10:45:19Z
name: db-secret
namespace: carrot
resourceVersion: "10186771"
selfLink: /api/v1/namespaces/carrot/secrets/db-secret
uid: 5f11a472-5967-11e6-8bc6-005056852444
type: Opaque複製程式碼
2. 建立 rc
並且在環境變數中引入 Secret
物件
建立 rc.yaml
檔案如下:
kind: ReplicationController
apiVersion: v1
metadata:
name: devops
namespace: carrot
labels:
name: devops
spec:
replicas: 1
selector:
name: devops
template:
metadata:
labels:
name: devops
spec:
containers:
- name: devops
image: 192.168.5.1/carrot/devops:v1
ports:
- containerPort: 8090
protocol: TCP
# 從secret物件中引入資料到環境變數中
env:
- name: SECRET_DB_NAME
valueFrom:
secretKeyRef:
name: db-secret
key: carrot-db-name
- name: SECRET_DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: carrot-db-username
- name: SECRET_DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: carrot-db-password
- name: SECRET_DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: carrot-db-host
- name: SECRET_DB_PORT
valueFrom:
secretKeyRef:
name: db-secret
key: carrot-db-port
resources:
limits:
cpu: 60m
memory: 256Mi
imagePullPolicy: Always
volumeMounts:
- name: tenxcloud-time-zone
mountPath: "/etc/localtime"
readOnly: true
# nodeSelector:
volumes:
- name: tenxcloud-time-zone
hostPath:
path: "/etc/localtime"複製程式碼
從上面 yaml 檔案中可以看出,在宣告環境變數時,引入了 db-secret
物件,並且把 db-secret
物件中每個元素都放在了環境變數中,當然還可以通過引入 volume
等方式引入 db-secret
物件,這裡就不做介紹了,有興趣的童鞋可以看下官方文件。下面建立 rc
devops:
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl create -f rc.yaml
replicationcontroller "devops" created
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl get pod --namespace=carrot
NAME READY STATUS RESTARTS AGE
devops-xws9a 1/1 Running 0 2m
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl exec -it devops-xws9a --namespace=carrot bash
root@devops-xws9a:/opt/nodejs# env
NODE_VERSION=4.2.2
DEVOPS_PORT_8090_TCP_ADDR=10.0.0.117
SECRET_DB_PASSWORD=tenxcloud
HOSTNAME=devops-xws9a
KUBERNETES_PORT=tcp://10.0.0.1:443
KUBERNETES_PORT_443_TCP_PORT=443
DEVOPS_SERVICE_PORT=8090
SECRET_DB_USERNAME=tenxcloud
DEVOPS_PORT_8090_TCP_PORT=8090
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.0.0.1
NPM_CONFIG_LOGLEVEL=info
DEVOPS_PORT_8090_TCP_PROTO=tcp
SECRET_DB_HOST=192.168.5.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/opt/nodejs
SECRET_DB_NAME=tenxcloud
DEVOPS_PORT=tcp://10.0.0.117:8090
DEVOPS_SERVICE_PORT_DEVOPS=8090
SECRET_DB_PORT=3306
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
DEVOPS_PORT_8090_TCP=tcp://10.0.0.117:8090
KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1
DEVOPS_SERVICE_HOST=10.0.0.117
KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443
AUTHORIZED_KEYS=**None**
_=/usr/bin/env複製程式碼
我們使用 exec
命令進入容器內部,可以看到我們宣告的環境變數,說明我們已經成功引入了 Secrets
物件 db-secret
到環境變數中。現在容器還不能被訪問到,下面我們還需要建立一個service
。
3.建立 Service
建立如下 service.yaml 檔案:
kind: Service
apiVersion: v1
metadata:
name: devops
namespace: carrot
labels:
name: devops
annotations:
devops: tcp
spec:
ports:
- name: devops
protocol: TCP
port: 8090
targetPort: 8090
selector:
name: devops
# publicIPs:
# - 192.168.5.2
deprecatedPublicIPs:
- 192.168.5.2
externalIPs:
- 192.168.5.2複製程式碼
建立 Service
物件 devops
:
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl create -f service.yaml
service "devops" created
root@ubuntu:~/Carrotzpc/devops/yamls# kubectl get service devops --namespace=carrot -o yaml
apiVersion: v1
kind: Service
metadata:
annotations:
devops: tcp
creationTimestamp: 2016-08-03T11:07:45Z
labels:
name: devops
name: devops
namespace: carrot
resourceVersion: "10187506"
selfLink: /api/v1/namespaces/carrot/services/devops
uid: 8166f211-596a-11e6-8bc6-005056852444
spec:
clusterIP: 10.0.0.13
deprecatedPublicIPs:
- 192.168.5.2
externalIPs:
- 192.168.5.2
ports:
- name: devops
port: 8090
protocol: TCP
targetPort: 8090
selector:
name: devops
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}複製程式碼
在 blog-service
資料庫配置檔案 db.js 中讀取這些環境變數:
'use strict'
const env = process.env
const database = {
db: env.SECRET_DB_NAME,
username: env.SECRET_DB_USERNAME,
password: env.SECRET_DB_PASSWORD,
}
module.exports = database複製程式碼
小結
這樣一個完整的使用 K8s Secrets
物件儲存 db
配置資訊的 blog-service
就建好了,db-secret
這個Secrets
物件可以同時被多個容器使用,這樣可以解決資料庫在不同服務中的配置問題。當 Secrets
物件被更新,重建使用 Secrets
物件的 pod 後,環境變數裡面的對應資訊會被更新。上面我們提到可以通過引入 volume
的方式引入 Secrets
物件,這樣做有一個好處就是當 Secrets
物件更新後,引入 pod 中的 Secrets
物件也會同步更新,當然更新時間取決於 K8s 的同步週期。
原文請移步我的部落格 noder.xyz/simple-use-…