您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)如何使用Vault與Kubernetes為密碼提供強(qiáng)有力的保障,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
Kubernetes 已經(jīng)成為了容器編排方案的工業(yè)標(biāo)準(zhǔn),而來(lái)自 HashiCorp 的 Vault 則是密碼管理的工業(yè)標(biāo)準(zhǔn)。那問(wèn)題來(lái)了: 怎樣將這兩項(xiàng)技術(shù)結(jié)合使用從而可以讓你在 Kubernetes 的應(yīng)用程序中使用來(lái)自于 Vault 中心實(shí)例的密碼呢?
一種解決方法是使用AppRole認(rèn)證。Boostport為 AppRoles 在 Kubernetes 上的使用提供了完美的集成。另一個(gè)可行的方法是使用Kubernetes 認(rèn)證。這種認(rèn)證機(jī)制為 Vault 和 Kubernetes 集群創(chuàng)建一個(gè)可信的聯(lián)系因而你可以使用一個(gè)服務(wù)賬號(hào)到 Vault 進(jìn)行認(rèn)證。后期你可以使用Kubernetes 的 Vault 節(jié)點(diǎn)獲取和更新認(rèn)證令牌。
這篇實(shí)踐的文章中,我會(huì)向你展示如何使用一些 Go 助手工具實(shí)現(xiàn)諸如認(rèn)證更新令牌這些相同的工作,并且還會(huì)進(jìn)一步實(shí)現(xiàn)-從 Vault 到 Kubernetes 同步預(yù)定義的密碼子集。
等級(jí): 高級(jí)
簡(jiǎn)單起見(jiàn)我有一些選項(xiàng):
用多種不同的方法啟動(dòng)一個(gè) Kubernetes 集群。通常來(lái)說(shuō),minikube
用來(lái)測(cè)試或者開(kāi)發(fā)。我會(huì)使用kubeadm
因?yàn)樗浅:?jiǎn)單的就可以啟動(dòng)一個(gè)真正的集群。
在 Kubernetes 中,會(huì)使用default
命名空間。
Vault 會(huì)在開(kāi)發(fā)模式下運(yùn)行。_不要像在生產(chǎn)環(huán)境下那樣使用它!_確保在環(huán)境變量中設(shè)置了VAULT_ADDR
。
代碼示例中會(huì)使用 Ubuntu。這些已經(jīng)在 GCE 上配置為 2 vCPU 和 7.5 GB 的 Ubuntu 18.10 VM 上進(jìn)行了測(cè)試。(可以看看 GCP 上 $300 的免費(fèi)套餐,就是說(shuō)說(shuō)而已哈…)
除非另有說(shuō)明,將會(huì)使用 Bash。
讓我們從一個(gè)簡(jiǎn)單的測(cè)試集群開(kāi)始。下面的代碼你會(huì)看到一個(gè)簡(jiǎn)單節(jié)點(diǎn)的安裝步驟是什么樣的。
# 1) Install Kubernetes on a Ubuntu machine sudo -i curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' >> /etc/apt/sources.list.d/kubernetes.list apt update && apt install -y docker.io kubelet kubeadm kubectl sudo systemctl enable docker.service kubeadm init --pod-network-cidr=10.244.0.0/16 # Flannel pod network, see below exit # 2) Prepare kubectl mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config echo "source <(kubectl completion bash); alias k=kubectl; complete -F __start_kubectl k" >> .bashrc && exec $SHELL # 3) Finalize K8s config kubectl cluster-info kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl taint nodes --all node-role.kubernetes.io/master- kubectl get nodes -o wide # For details, see: # - https://kubernetes.io/docs/setup/independent/install-kubeadm/ # - https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/
Vault 的安裝非常的直接: 下載解壓二進(jìn)制包即可:
# Install Vault sudo apt install -y zip curl -OL https://releases.hashicorp.com/vault/1.1.1/vault_1.1.1_linux_amd64.zip unzip vault_1.1.1_linux_amd64.zip sudo mv vault /usr/local/bin/ vault -autocomplete-install && exec $SHELL
我們會(huì)以開(kāi)發(fā)模式運(yùn)行一個(gè) Vault 服務(wù)器。同樣,這也非常的簡(jiǎn)單。請(qǐng)記住,當(dāng)啟動(dòng)一個(gè)開(kāi)發(fā)服務(wù)器的時(shí)候,一個(gè) root 令牌會(huì)被寫(xiě)入到$HOME/.vault-token
中,對(duì) root 用戶來(lái)說(shuō)同樣如此。使用&
符號(hào)會(huì)讓 Vault 進(jìn)程在后臺(tái)運(yùn)行因此我們可以繼續(xù)使用相同的 shell。
$ vault server -dev -dev-listen-address=0.0.0.0:8200 & ==> Vault server configuration: Api Address: http://0.0.0.0:8200 Cgo: disabled Cluster Address: https://0.0.0.0:8201 Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled") Log Level: info Mlock: supported: true, enabled: false Storage: inmem Version: Vault v1.1.1 Version Sha: a3dcd63451cf6da1d04928b601bbe9748d53842e
現(xiàn)在我們必須確保 Kubernetes 可以通過(guò) Kubernetes 認(rèn)證與 Vault 進(jìn)行通信。這將會(huì)在 Kubernetes 和 Vault 之間建立一個(gè)信任的聯(lián)系。預(yù)命名的vault-demo-role
將會(huì)映射策略以及定義一個(gè) TTL。
因?yàn)槲覀兪褂?code>kubeadm啟動(dòng)的 Kubernetes 集群,它非常輕松的就可以找到kubernetes_ca_cert
參數(shù)的證書(shū)頒發(fā)機(jī)構(gòu)(CA)存儲(chǔ)的值。如果使用一個(gè)在云安裝的 Kubernetes 該過(guò)程會(huì)比較困難一些。
# NOTE: You may need to set these addresses differently. export INTERNAL_IP=$(dig +short `hostname -f`) export VAULT_ADDR=http://${INTERNAL_IP}:8200 # Enable and configure the Kubernetes auth method. # For details, see: # - https://www.vaultproject.io/docs/auth/kubernetes.html # - https://www.vaultproject.io/api/auth/kubernetes/index.html vault auth enable kubernetes vault write auth/kubernetes/config \ kubernetes_host=https://${INTERNAL_IP}:6443 \ kubernetes_ca_cert=@/etc/kubernetes/pki/ca.crt vault write auth/kubernetes/role/vault-demo-role \ bound_service_account_names=vault-serviceaccount \ bound_service_account_namespaces=default \ policies=vault-demo-policy \ ttl=1h # Create a policy for demo purposes cat <<EOF | vault policy write vault-demo-policy - path "sys/mounts" { capabilities = ["read"] } path "secret/data/demo/*" { capabilities = ["read"] } path "secret/metadata/demo/*" { capabilities = ["list"] } EOF # Write some demo secret vault kv put secret/demo/most-used-password password=123456 vault kv put secret/demo/first one=1234567890 two=2345678901 vault kv put secret/demo/second green=lantern poison=ivy vault kv put secret/demo/greek/alpha philosopher=plato vault kv put secret/demo/greek/beta god=zeus vault kv put secret/demo/greek/gamma mountain=olympus
在 Kubernetes 這邊,我們現(xiàn)在需要安裝設(shè)置相匹配的 RBAC。首先我們創(chuàng)建一個(gè)名稱為vault-serviceaccount
的服務(wù)賬號(hào)。然后我們會(huì)添加一個(gè)叫做vault-closterrolebinding
的集群角色綁定,因而我們新創(chuàng)建的服務(wù)賬號(hào)可以被允許使用默認(rèn)的集群角色system:auth-delegator
發(fā)送認(rèn)證請(qǐng)求。角色vault-secrectadmin-role
和角色綁定vault-secretadmin-rolebinding
也綁定到了vault-serviceaccount
上這樣我們就可以同步密碼了。
--- apiVersion: v1 kind: ServiceAccount metadata: name: vault-serviceaccount --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: vault-clusterrolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: vault-serviceaccount namespace: default --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: vault-secretadmin-role rules: - apiGroups: [""] resources: ["secrets"] verbs: ["*"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: vault-secretadmin-rolebinding subjects: - kind: ServiceAccount name: vault-serviceaccount roleRef: kind: Role name: vault-secretadmin-role apiGroup: rbac.authorization.k8s.io
讓我們應(yīng)用下面的配置:
$ k apply -f vault-rbac.yaml serviceaccount/vault-serviceaccount created clusterrolebinding.rbac.authorization.k8s.io/vault-clusterrolebinding created role.rbac.authorization.k8s.io/vault-secret-admin-role created rolebinding.rbac.authorization.k8s.io/vault-demo-secret-admin-rolebinding created
準(zhǔn)備工作完成了?,F(xiàn)在我們可以移步到我們的用例上了。
我們將會(huì)覆蓋下面的這三個(gè)用例:
第一個(gè)例子會(huì)演示怎樣認(rèn)證到 Vault 然后使用一個(gè)初始化的容器獲取一個(gè)認(rèn)證令牌。
第二個(gè)例子會(huì)演示怎樣使用 sidecar 容器更新這個(gè)令牌。
第三個(gè)例子將會(huì)演示怎樣從 Vault 到 Kubernetes 同步密碼。
所有這三個(gè)用例均由我在 PostFinance 的同事構(gòu)建的三個(gè) Docker 鏡像上運(yùn)行的。特別感謝 Marc Sauter,他在Seth Vargo工作的啟發(fā)下編纂了最初的實(shí)現(xiàn)方案。創(chuàng)建的這三個(gè)鏡像-在Docker Hub上均可獲取到-包括了一點(diǎn) Go 的助手工具,代碼均可以從GitHub上找到。
第一個(gè)例子會(huì)展示vault-kubernetes-authenticator
(簡(jiǎn)稱 *auther*)鏡像的用法。auther 在一個(gè)初始容器中運(yùn)行,使用服務(wù)賬號(hào)vault-serviceaccount
向 Vault 進(jìn)行認(rèn)證然后將 Vault 的認(rèn)證令牌寫(xiě)入到/home/vault/.vault-token
中。
--- apiVersion: apps/v1 kind: Deployment metadata: name: vault-kubernetes-authenticator-demo labels: appl: vault-kubernetes-authenticator-demo spec: replicas: 1 selector: matchLabels: appl: vault-kubernetes-authenticator-demo template: metadata: labels: appl: vault-kubernetes-authenticator-demo spec: serviceAccountName: vault-serviceaccount volumes: - name: vault-token emptyDir: medium: Memory initContainers: - name: vault-kubernetes-authenticator image: postfinance/vault-kubernetes-authenticator imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token containers: - name: kuard image: gcr.io/kuar-demo/kuard-amd64:blue volumeMounts: - name: vault-token mountPath: /home/vault
我們應(yīng)用這些配置然后執(zhí)行一些測(cè)試來(lái)驗(yàn)證所有配置都能成功運(yùn)行。
$ envsubst < vault-kubernetes-authenticator-demo.yaml | k apply -f - deployment.apps/vault-kubernetes-authenticator-demo created $ k get all NAME READY STATUS RESTARTS AGE pod/vault-kubernetes-authenticator-demo-fc49b957c-b5bnx 1/1 Running 0 81s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/vault-kubernetes-authenticator-demo 1/1 1 1 81s NAME DESIRED CURRENT READY AGE replicaset.apps/vault-kubernetes-authenticator-demo-fc49b957c 1 1 1 81s $ k logs vault-kubernetes-authenticator-demo-fc49b957c-b5bnx -c vault-kubernetes-authenticator 2019/04/16 04:45:23 successfully authenticated to vault 2019/04/16 04:45:23 successfully stored vault token at /home/vault/.vault-token $ k exec vault-kubernetes-authenticator-demo-fc49b957c-b5bnx -- sh -c "VAULT_ADDR=${VAULT_ADDR} sh" ~ $ cat /home/vault/.vault-token; echo s.xrrJoCARIC0Z84vcvcwuH5XG ~ $ wget --header="X-Vault-Token: $(cat /home/vault/.vault-token)" -q -O - ${VAULT_ADDR}/v1/secret/data/demo/most-used-password {"request_id":"12660a6b-7ad0-85bc-8841-d21c7cc8248a","lease_id":"","renewable":false,"lease_duration":0,"data":{"data":{"password":"123456"},"metadata":{"created_time":"2019-04-16T05:11:44.651116748Z","deletion_time":"","destroyed":false,"version":1}},"wrap_info":null,"warnings":null,"auth":null} ~ $ wget --header="X-Vault-Token: $(cat /home/vault/.vault-token)" -q -O - ${VAULT_ADDR}/v1/secret/data/sensitive-password wget: server returned error: HTTP/1.1 403 Forbidden
第二個(gè)例子將向你展示vault-kubernetes-token-renewer
(簡(jiǎn)稱 *renewer*)鏡像的使用。renewer 運(yùn)行在一個(gè) sidecar 容器中,周期性地檢查 TTL 然后根據(jù)檢查的情況更新認(rèn)證令牌。
--- apiVersion: apps/v1 kind: Deployment metadata: name: vault-kubernetes-token-renewer-demo labels: appl: vault-kubernetes-token-renewer-demo spec: replicas: 1 selector: matchLabels: appl: vault-kubernetes-token-renewer-demo template: metadata: labels: appl: vault-kubernetes-token-renewer-demo spec: shareProcessNamespace: true serviceAccountName: vault-serviceaccount volumes: - name: vault-token emptyDir: medium: Memory initContainers: - name: vault-kubernetes-authenticator image: postfinance/vault-kubernetes-authenticator imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token containers: - name: vault-kubernetes-token-renewer image: postfinance/vault-kubernetes-token-renewer imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token - name: kuard image: gcr.io/kuar-demo/kuard-amd64:blue volumeMounts: - name: vault-token mountPath: /home/vault
我們也同樣應(yīng)用一下這些配置然后做一些驗(yàn)證。(我刪除了先前的 deployment。)
$ envsubst < vault-kubernetes-token-renewer-demo.yaml | k apply -f - deployment.apps/vault-kubernetes-token-renewer-demo created $ k get all NAME READY STATUS RESTARTS AGE pod/vault-kubernetes-token-renewer-demo-694cc7dbbd-rkbbs 2/2 Running 0 4s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 31h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/vault-kubernetes-token-renewer-demo 1/1 1 1 4s NAME DESIRED CURRENT READY AGE replicaset.apps/vault-kubernetes-token-renewer-demo-694cc7dbbd 1 1 1 4s $ k logs vault-kubernetes-token-renewer-demo-694cc7dbbd-rkbbs -c vault-kubernetes-authenticator 2019/04/16 15:40:55 successfully authenticated to vault 2019/04/16 15:40:55 successfully stored vault token at /home/vault/.vault-token $ k logs vault-kubernetes-token-renewer-demo-694cc7dbbd-rkbbs -c vault-kubernetes-token-renewer 2019/04/16 15:40:56 start renewer loop 2019/04/16 15:40:56 token renewed
第三個(gè)例子將向你展示vault-kubernetes-synchronizer
(簡(jiǎn)稱 *syncer*)的用法。syncer 可以用在多個(gè)方面。在這個(gè) demo 里面,一個(gè) Kubernetes 任務(wù)將被用來(lái)從預(yù)定義的路徑一次性同步 Vault 密碼。這些 Vault 密碼將會(huì)被寫(xiě)入到相應(yīng)的 Kubernetes 密碼中。
--- apiVersion: batch/v1 kind: Job metadata: name: vault-kubernetes-synchronizer-demo spec: backoffLimit: 0 template: spec: serviceAccountName: vault-serviceaccount restartPolicy: Never volumes: - name: vault-token emptyDir: medium: Memory initContainers: - name: vault-kubernetes-authenticator image: postfinance/vault-kubernetes-authenticator imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token containers: - name: vault-kubernetes-synchronizer image: postfinance/vault-kubernetes-synchronizer imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token - name: VAULT_SECRETS value: secret/demo/first,secret/demo/second,secret/demo/first:third,secret/demo/greek/
同樣,我們也應(yīng)用一下這些配置然后看看所有的配置是否如預(yù)期一樣運(yùn)行正常:
$ envsubst < vault-kubernetes-synchronizer-demo.yaml | k apply -f - job.batch/vault-kubernetes-synchronizer-demo created $ k get all NAME READY STATUS RESTARTS AGE pod/vault-kubernetes-synchronizer-demo-m2xnz 1/1 Running 0 4s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d5h NAME COMPLETIONS DURATION AGE job.batch/vault-kubernetes-synchronizer-demo 0/1 4s 4s $ k logs pod/vault-kubernetes-synchronizer-demo-m2xnz -c vault-kubernetes-authenticator 2019/04/18 14:29:42 successfully authenticated to vault 2019/04/18 14:29:42 successfully stored vault token at /home/vault/.vault-token $ k logs pod/vault-kubernetes-synchronizer-demo-m2xnz 2019/04/18 14:29:43 read secret/demo/first from vault 2019/04/18 14:29:43 update secret third from vault secret secret/demo/first 2019/04/18 14:29:43 read secret/demo/greek/alpha from vault 2019/04/18 14:29:43 update secret alpha from vault secret secret/demo/greek/alpha 2019/04/18 14:29:43 read secret/demo/greek/beta from vault 2019/04/18 14:29:43 update secret beta from vault secret secret/demo/greek/beta 2019/04/18 14:29:43 read secret/demo/greek/gamma from vault 2019/04/18 14:29:43 update secret gamma from vault secret secret/demo/greek/gamma 2019/04/18 14:29:43 read secret/demo/first from vault 2019/04/18 14:29:43 update secret first from vault secret secret/demo/first 2019/04/18 14:29:43 read secret/demo/second from vault 2019/04/18 14:29:43 update secret second from vault secret secret/demo/second 2019/04/18 14:29:44 secrets successfully synchronized $ k get secrets NAME TYPE DATA AGE alpha Opaque 1 2m43s beta Opaque 1 2m43s default-token-ssd7f kubernetes.io/service-account-token 3 3d5h first Opaque 2 2m43s gamma Opaque 1 2m43s second Opaque 2 2m43s third Opaque 2 2m43s vault-serviceaccount-token-f6tnw kubernetes.io/service-account-token 3 2d20h $ k describe secret first Name: first Namespace: default Labels: <none> Annotations: vault-secret: secret/demo/first Type: Opaque Data ==== one: 10 bytes two: 10 bytes $ k describe secret alpha Name: alpha Namespace: default Labels: <none> Annotations: vault-secret: secret/demo/greek/alpha Type: Opaque Data ==== philosopher: 5 bytes
syncer 同樣可以用在 Kubernetes 的 cron 任務(wù)中從 Vault 周期性同步密碼或者同步到另一個(gè) Kubernetes deployment 的初始容器中,這樣密碼就會(huì)保持最新?tīng)顟B(tài)。
需要注意的是 Kubernetes 密碼保護(hù)不是很好。Seth Vargo 在最近的 FOSDEM訪談中指出,默認(rèn)情況下,它們僅做了 base64 編碼和存儲(chǔ),就像在 etcd 中那樣。你應(yīng)該允許數(shù)據(jù)的靜態(tài)加密。也請(qǐng)確保你只同步那些你的 Kubernetes 應(yīng)用程序使用的那些密碼,這些密碼由相應(yīng)的 Vault 策略以及命名角色保護(hù)。除此之外,該方法還允許你以云原生行為使用密碼。你的應(yīng)用程序不能直接訪問(wèn) Vault 密碼可以被注入到環(huán)境變量中。
Kubernetes 和 Vault 這兩項(xiàng)技術(shù)在結(jié)合使用或者集成它們使用時(shí)均是很棒的組合。集成的方案看似不簡(jiǎn)單但是依舊可行。
看完上述內(nèi)容,你們對(duì)如何使用Vault與Kubernetes為密碼提供強(qiáng)有力的保障有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。