高考考试网
当前位置: 首页 高考资讯

kubernetes 查看证书有效期(Kubernetessecrets加密处理的3种方式)

时间:2023-07-30 作者: 小编 阅读量: 4 栏目名: 高考资讯

基于此,本文介绍三种可以加密Kubernetessecret的方式:SealedSecrets、HelmSecrets和Kamus。SealedSecret对象同时又会生成与其名称相同的secret对象,随后就可以按照常规方式使用secret对象了。最后将加密后的文件直接推送至版本控制系统即可,而不用担心敏感信息被泄漏。SealedSecrets和Secret两者的关系与Deployment和Pod之间的关系类似。

前 言

Kubernetes 已经毫无争议地成为了云原生时代的事实标准,在 Kubernetes 上部署应用程序也变得简单起来(无论是采用 kustomize 还是 helm),虽然对于敏感信息(比如用户名、密码、token 和证书等)的处理,Kubernetes 自己提供了 secret 这种方式,但这是一种编码方式,而非加密方式,如果需要用版本控制系统(比如 git)来对所有的文件、内容等进行版本控制时,这种用编码来处理敏感信息的方式就显得很不安全了(即使是采用私有库),这一点在实现 GitOps 时,是一个痛点。

基于此,本文介绍三种可以加密 Kubernetes secret 的方式:Sealed Secrets、Helm Secrets 和 Kamus。

一、Sealed Secrets

Sealed Secrets 充分利用 kuberntes 的高扩展性,通过 CRD 来创建一个 SealedSecret 对象,通过将加密的内容存储在扩展 SealedSecret 对象中,而 SealedSecret 只能够被运行于目标集群上的 controller 解密,其他人员和方式都无法正确解密原始数据。

SealedSecret 对象同时又会生成与其名称相同的 secret 对象,随后就可以按照常规方式使用 secret 对象了。最后将加密后的文件直接推送至版本控制系统即可,而不用担心敏感信息被泄漏。

1.1 原理

Sealed Secrets 加解密的原理简单来说就是:安装的时候 controller 会生成一对用于加密的 key,加密时在客户端 kubeseal 的帮助下,将包含敏感信息的 kubernets secrets 内容加密转变为一个包含有加密信息的 Kubernetes SealedSecrets 对象;解密时在 controller 的帮助下将 Kubernetes SealedSecrets 对象内的内容进行解密,然后生成常规的 kubernetes secret 对象。

1.2 加密(encryption)

kubeseal 使用位于 cluster controller 生成的 public key 来加密,将 secrets 对象的内容加密转变成 SealedSecrets 对象。public key 和 private key 在安装 controller 的时候,以 secret(如下的 sealed-secrets-key217vf)的形成存放,可以在安装 controller 所在的 ns 下面查看。

$ kubectl -n kube-system get secret | grep sealed-secretsealed-secrets-controller-token-qv2n5kubernetes.io/service-account-token36d4hsealed-secrets-key2l7vfkubernetes.io/tls 26d4h

1.3 解密(decryption)

当将加密后生成的 SealedSecrets 对象进行部署时(kubectl apply/create),controller 会先拿 private key 进行解密,然后再生成与 SealedSecrets 同名的 Secret 对象,而此时的 Secret 对象保存的是经过 base64 编码后的信息,随后可以像正常使用 secret 一样使用这些信息。

SealedSecrets 和 Secret 两者的关系与 Deployment 和 Pod 之间的关系类似。

1.4 安装

Sealed Secrets 有两部分组成:

  • 安装于集群侧的 controller
  • 客户端工具 kubeseal

所以安装也分两步,安装 controller 和 kubeseal。可以先安装 controller,执行如下命令即可:

$ kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.14.1/controller.yaml

随后查看 kube-system ns 下面的 controller pod:

$ kubectl -n kube-system get pods | grep sealsealed-secrets-controller-64b74f67b-4wtj71/1Running0153m

接着安装客户端工具 kubeseal。这个可以根据自己的 OS 来选用不同的安装方式,以 MacOs 为例:

$ brew install kubeseal

通过查看 kubeseal 的版本来确定是否安装成功:

$ kubeseal --versionkubeseal version: v0.14.1

此时,两部分均安装成功,下面可以使用了。

1.5 使用

选择一个包含有需要加密的 secret 的文件,内容如下:

apiVersion: v1data:username: eGlhb21hZ2U=password: cGFzc3cwcmQ=token: MWU0ZGdyNWZncmgzcmZmZ3JodG9ubmhyaHI=kind: Secretmetadata:name: seal-test-secretnamespace: testtype: Opaque

将上述内容写入一个 yaml 文件,比如 test-secret.yaml,然后执行如下命令加密:

$ kubeseal < test-secret.yaml > test-seal-secret.yaml

可以查看 test-seal-secret.yaml 文件的内容:

{"kind": "SealedSecret","apiVersion": "bitnami.com/v1alpha1","metadata": {"name": "seal-test-secret","namespace": "test","creationTimestamp": null},"spec": {"template": {"metadata": {"name": "seal-test-secret","namespace": "test","creationTimestamp": null},"type": "Opaque"},"encryptedData": {"password": "AgCHLFSlGFpX2B9QDhWbMTfT83aopXMisR5XnUPZNcbvvnQzqgyG8fBVknT8LCNF5ExtUCCcNLsvWRrZY 9BJqf5dlBl6DkLV1acuPicP0vuGaUQwmc5BY/5Bj53Oj9uMYLNdVHoQ3E6kQgeJPa5v4rvwRXsB0EneYPcT88KyMg tn4OY9JH hpg2XMXZudyyZsocE852J5nfN4P7WZQYaG2eIBqRSQvQXUflQQvZ5wBCkTvmaZYfxz Lxuf3wDWdSlPjcgSVnn5tWNP7u0ErdVy8LwTL5HzJdcoSviDysTq3VVA8W9Nmn0CM3QS0R0Nbi3JfalUdxfBMK yb7t6Z72oJyoxGfCa07iKnkM37SSw4vl1nXiYy3FMWuzDtWLVk6XzjBZR2ChoeClqbGDg8KeSWZg/rO3Xku98vCmCa004OetJKBMc9Db3q gX53ThdU70VvRol9rLPFBPHB8NTjD Bu0Ss4XzIzZzi8J Ov5xE7G8LnPLSZtZQyD/qGZK4n7pU1YNLROJ fz1W5edPdpb5szUOqs1bpFfGleUiPZo1sGA0f1EsDvJShptgtT44YzGRkkgrP1LGp2AVIpnt9meE5WNCoSEPZJVx7wWMV9CHMOyyUi8zi oG/S2NkI3rc2sC8AFp0DqP9m/HaX1GG 6vw9oHAbhxpR4v3mDyBIq /8UEMtkybIEDQGHqyQ5CfRow A80cA4Hw==","token": "AgBRi4NZunaJtHyP5aAoWmGtEXBipbFIb/n4ep8wdg eka5xbDeLZwNCLofbUL u0pP/CHSJeWl62mVPJhZdOKE Su0b8a78im0 xsochaMQf0AI1GGL/Fo08HI8paP8k404gwAtonocIFSis3YooU0nyVD lYH k09FGABI RmVLc2XkuIr96TTL4xsdSM5L0Ks2SFQKcQ42JfFWtNdXz6lr/IODsZop0/xAk6ffbsGGmCUjwusUU3Wp0MR25ntYT8ySuO6W7xkfGozEFzztteBJs28SHLf5HUi6BbYVnsZibrFF3BZP5aNnBg2TIgo3 dbX6EPHM904By3Z9XTBxsQfH6p1VoyUf0EGKZnUnJFezFtN9m2tyKbV/Z/5vCh9kVp6Yn/BE/AwGAH7kqqjPtHTnZiq Xy1UwV4/eHkxGAvSAR3Z6wTQCt/rwqGrQi2eGpIcyjxTwlPYaVjfx3L 1tnBR966lGLnhwX0I6b6whXAm3hRb1AhYFnuyF/CoG/PEmQsMU5GfkroQkb5LL UeCYKbjvMvgCe2hFxfh3dcGJ9E3dad9W0rSKrPd5t/dR1kDtItHau36 G9PSVyqRD1yt0MS2vLLUQu7t2RhiIPrl20fkbnum9JAfmLlgliHIiQPHASL32CXB6EzsgqRX6w8TmWNOSvlR7LU8JZtd4Gmiw9wGBh7JEGodkaH6lc5ndQluykC18RUXtuLft S4dnQCApHX6FoIGZjug==","username": "AgCgBQc/fhGqB0YBGfXzhybC6YXJeLkOZyi7Z7Y HjfnYSg4Q/Zh8Kn7UEbq9CwEl CtagARjKmLfhIcAqFWS8 h8j4A2xNq7gzLnv eCo0vFDPTddDVvdb6ixmRvF5rzD1gZ2vxWzlWVqk7x0wt8wCE90S0yu40j JOaqH35Ir3kb4NgTMXk6Yqlidw06r3P2cqbZ0jBleOFf5eRfiu0ZquU5PJ/J7t9Pecx9S8mlitTtFPlvpVprNPB XPSz2uwcwNW9i5OBUgR3PXsOjILLog8SiWYyk7bHaWnJtZ JVEi9isy4EiwyrDY5kHRK2kB9Nnf6a9zz2krP7W w9a3qXJkv8GP9D2 FN9Pj 2WP4r0hz7JL0i5q9bcc5HgBKP946u87z2lEjv2ioUAghaG/zwol3q tKv0i6pPe0guGRCdpMlXa1Z1deOBJvxJXanTrIwi7dVc/bCsRGMRyYwD6hWhe1JjxgBjc/YbbBj8JJVdHrc2tGYFBU9qG2Kv3cAZMRrMXvKUkTK8JiMVzN0/DHEtdNv1PW4U3hlAqt5b62WahyzdHNVqHycwe Ogz0BfTdohlxftv5qQYx0SEynXaIY WltRnCnYrY1Kg1/DmsWYCGyTO 6cEEwISPe/FM1peidsXVf5S3DCUQWE6aMK/6XDzukZoTjor/8JPkHc56Pk1Paty0yrP YdL5R5m3IERzHoD"}}}

可以看到内容已经得到了加密,接下来就需要创建 SealedSecret 对象了:

$ kubectl -n test apply -f test-seal-secret.yaml

接着查看 SealedSecret 和 secret:

$ kubectl -n test get SealedSecret,secretsealedsecret.bitnami.com/seal-test-secret4ssecret/seal-test-secretOpaque33s

在如下的 Deployment 中以环境变量的形式引用上述生成的 secret:

apiVersion: apps/v1kind: Deploymentmetadata:labels:app: devopsname: devopsspec:replicas: 1selector:matchLabels:app: devopstemplate:metadata:labels:app: devopsspec:restartPolicy: Alwayscontainers:- name: devopsimage: dllhb/devopsday:v0.6imagePullPolicy: AlwaysenvFrom:- secretRef:name: test-secretports:- containerPort: 9999name: httpprotocol: TCP

使用下面命令部署:

$ kubectl -n test apply -f test-deploy.yamldeployment.apps/devops created

查看 pod 状态,并查看环境变量(secret 是以环境变量的形式注入 pod 内的):

$ kubectl -n test get podsdevops-b48df6659-gmjtr1/1Running021s$ kubectl -n test exec -it devops-b48df6659-gmjtr shenv | grep -E "username|password|token"username=xiaomagetoken=1e4dgr5fgrh3rffgrhtonnhrhrpassword=passw0rd

说明 secret 注入成功。其他的 secret 类型,比如 tls、dockerconfigjson 等都可以用上面的方式进行使用。

最后就可以将包含 secret 信息且经过加密的文件 test-seal-secret.yaml 推送至版本管理系统,比如 GitHub。

二、Helm Secrets

Helm Secrets 是 Helm 的一个插件,用来对于 Helm Chart 中的敏感信息进行加密。

2.1 原理

Helm Secrets Plugin 可以使用多种加密方式来对敏感信息进行加解密(本文介绍 sops)。加密时使用helm secrets enc 命令对需要加密的文件内容进行加密;解密时helm secrets使用dec将加密内容进行解密,并添加在 values.yaml 文件中,后续的使用直接取用 values.yaml 文件中的值即可。

2.2 加密

使用helm secerts enc 对位于helm_vars目录下的secrets文件加密时,helm secrets plugin会使用 public key 对内容进行加密。

2.3 解密

使用helm secrets install/upgrade命令对应用程序进行安装或更新的过程中,需要指定经过加密后的 secret 文件(-f 指定,通常位于 helm_vars目录下),helm secrets plugin 会选择 private key 对加密的数据进行解密,解密后的数据在 values.yaml 文件中可找到,在 helm chart 的 template 目录下的 secret 文件只需要引用相关的值即可(.Values.xxx)。

2.4 安装

安装的前提条件:

  • helm(>2.3)
  • sops

sops 是一个加密文件的编辑器,支持 YAML、JSON、ENV、INI 和二进制格式,并使用 AWS KMS、GCP KMS、Azure Key Vault 和 PGP 进行加密。

PGP(Pretty Good Privacy)是一种常用的加密方式。在 1990s(1991 年)由 Phil Zimmermann 所开发,现在归属于 Symantec 公司,它是商业软件,需要付费才能使用。而 GPG(GNU Privacy Guard)是一种基于 Open PGP 标准的加密方式。它是开源且免费的。所以本文的演示将使用 GPG 的方式。

由于sops采用非对称加密,所以需要先生成一对key。使用gpg --full-generate-key并输入必要的参数即可生成 key,如下:

$ gpg --full-generate-keygpg (GnuPG) 2.2.12; Copyright (C) 2018 Free Software Foundation, Inc.This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.Please select what kind of key you want:(1) RSA and RSA (default)(2) DSA and Elgamal(3) DSA (sign only)(4) RSA (sign only)Your selection? 1RSA keys may be between 1024 and 4096 bits long.What keysize do you want? (3072) 4096Requested keysize is 4096 bitsPlease specify how long the key should be valid.0 = key does not expire<n>= key expires in n days<n>w = key expires in n weeks<n>m = key expires in n months<n>y = key expires in n yearsKey is valid for? (0) 1yKey expires at Sat Jan8 12:12:10 2022 UTCIs this correct? (y/N) yGnuPG needs to construct a user ID to identify your key.Real name: xiaomageEmail address: devops@xiaomage.comComment: gpg key generationYou selected this USER-ID:"xiaomage (gpg key generation) <devops@xiaomage.com>"Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? OWe need to generate a lot of random bytes. It is a good idea to performsome other action (type on the keyboard, move the mouse, utilize thedisks) during the prime generation; this gives the random numbergenerator a better chance to gain enough entropy.We need to generate a lot of random bytes. It is a good idea to performsome other action (type on the keyboard, move the mouse, utilize thedisks) during the prime generation; this gives the random numbergenerator a better chance to gain enough entropy.gpg: key 8BA2C5716B5C007F marked as ultimately trustedgpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/BCEB5797691E6C95E33A465D8BA2C5716B5C007F.rev'public and secret key created and signed.pubrsa4096 2021-01-08 [SC] [expires: 2022-01-08]BCEB5797691E6C95E33A465D8BA2C5716B5C007Fuidxiaomage (gpg key generation) <devops@xiaomage.com>subrsa4096 2021-01-08 [E] [expires: 2022-01-08]

可以查看生成的private key和public key:

  • private key 查看

gpg -K(gpg --list-secret-keys)/root/.gnupg/pubring.kbx------------------------secrsa4096 2021-01-08 [SC] [expires: 2022-01-08]BCEB5797691E6C95E33A465D8BA2C5716B5C007Fuid [ultimate] xiaomage (gpg key generation) <devops@xiaomage.com>ssbrsa4096 2021-01-08 [E] [expires: 2022-01-08]

  • public key 查看

gpg -k(gpg --list-keys)gpg: checking the trustdbgpg: marginals needed: 3completes needed: 1trust model: pgpgpg: depth: 0valid:2signed:0trust: 0-, 0q, 0n, 0m, 0f, 2ugpg: next trustdb check due at 2022-01-08/root/.gnupg/pubring.kbx------------------------pubrsa4096 2021-01-08 [SC] [expires: 2022-01-08]BCEB5797691E6C95E33A465D8BA2C5716B5C007Fuid [ultimate] xiaomage (gpg key generation) <devops@xiaomage.com>subrsa4096 2021-01-08 [E] [expires: 2022-01-08]

在用 sops 加密数据之前,先创建一个.sops.yaml文件,写一个加密的规则,比如只加密 key 是 username 和 password 的敏感信息,而且需要指定 gpg 的 fingerprint。

cat << EOF > .sops.yamlcreation_rules:- encrypted_regex: '^(username|password)$'pgp: 'B1C77B2CCF5575FAF0DA6B882CA51446C98C9D85'EOF

接着,将下面的敏感信息写入一个yaml文件:

cat << EOF > secrets.yamlusername: xiaomagepassword: passw0rdEOF

现在就可以用 sops 来加密数据了:

$ sops -e secrets.yamlusername: ENC[AES256_GCM,data:s6pInMY3eGM=,iv:5Q7JsntVoKjseD3ApWcgmYeedmGXj2A1/PyGCNFHGdE=,tag:vInq3NBLxvVWXsoVUD46Rw==,type:str]password: ENC[AES256_GCM,data:Ua7de2w6Jgw=,iv:qYIjTW1D0dh20NA8FGu4XEGI16kvYGAWIk4iu3r/Gdg=,tag:b33tpsP1vCgqlpyCEDP88Q==,type:str]sops:kms: []gcp_kms: []azure_kv: []hc_vault: []lastmodified: '2021-02-06T12:08:57Z'mac: ENC[AES256_GCM,data:QHHDRSO2PyJt0/OA67ex0R39gEjWEnwg0MSnBac8QtLNh3ncY 9D8IZw/WqVnbcaiPta2Pem96yJZTZP4pum9ZX446iRKldsAXNqS4 tmlfowpMWI 1DgOa1QCkhSDH9U/2URA1dzyn3cZLPFzb5Ai6YUEQ93sRjlPI kHXl16c=,iv:jhFM/uJSeChikUv777qgYVDFCHQhQeXlUSjiHx5X8Ow=,tag:6QTo5CsXQoqr0fK1B947ug==,type:str]pgp:-created_at: '2021-02-06T12:08:51Z'enc: |-----BEGIN PGP MESSAGE-----hQIMA/AYjF0OZ4PLAQ/ LRc5vgpRhOez8q9up8t 3OVM5QdnMwSYiuwLvjfInqqkK19jUfUhwXDGGtSMlTotYlTWqWCiSm7sYeqFB0/Lx9lCZY5BhCrVnK7u7m8azpWUosCQNmJehflqqnBmn82nblOGnDjM/FYkcnz4 NHUPNyYV5tWjzw9s8i/WhDeuNrfIPnGKRCGJunWlHDP3yWMo7bnCNU/TmuRiSpf7lQLsp/U71M5t1X8RajatO7DPecqcaq3VZ Ynx0Qcgyt aHugZw5Sw9oFOT4WVqwLlC/NKvrjtY8pCQ1HtY5/agLHrDwHn2Phz1aQ l4EAarphXCiYAFw/LHD2tisbQoApXe5tud9CjiyMu/14qhQalLgQxAyGcMmhEH7Ke4bubaA0ZPo8hBXAkxfdeicSzB/e1IkUP4LtlQiwPldDcDShB6MROHsK3RpELhSaNdfQZxqDVN0CgjRS0/AjboWejjrLQHD1hVcUDAU2WTyfvIaSxKpHIxONo5sTvzYOjU/BRTLn0EujRP414xadOtt 4gEQDrGacYAokuiK2ev0dinHo32EWYj/vsb0o3whNRpBEGMZTUrl9HSkt58FQZsmu5JnL3ZYKiujHFoQS/aOcxD0slUxhCPoCnce6PgmB78RHOLHaXkTrORc 6oMpCGN8/K1hjXE eH/kk4jv8yVLwmbg9XjLSXgFTcQYs6nVTSoWVea62kRN4qlC/XTJ6D91HXRX5UyB3qrZ3k w9TOlM9quYYI/BE0FqbFVSKT3ekPQqF91a7tV01FIxpfr4Mvzy2 8xsXiAQtDm52PSlk9eovkAMqU==nafU-----END PGP MESSAGE-----fp: B1C77B2CCF5575FAF0DA6B882CA51446C98C9D85encrypted_regex: ^(username|password)$version: 3.6.1

可以看到 username 和 password 的值都被加密了。

2.5 安装使用 Helm Secrets plugin

执行以下命令安装 helm-secrets plugin:

$ helm plugin install https://github.com/zendesk/helm-secrets

首先,创建一个演示用的 helm chart,并在根目录下创建一个名为helm_vars的目录,用来存放用来加密的 secret,如下所示:

$ tree.└── devsecops├── Chart.yaml├── charts├── helm_vars│├── secrets.yaml│├── tls.crt│└── tls.key├── templates│├── NOTES.txt│├── _helpers.tpl│├── deployment.yaml│├── hpa.yaml│├── ingress.yaml│├── secrets.yaml│├── service.yaml│├── serviceaccount.yaml│└── tests│└── test-connection.yaml└── values.yaml

将需要加密的信息写入secrets.yaml文件里面,比如:

cat << EOF > secrets.yamlsecret_data:username: xiaomagepassword: passw0rdEOF

使用 helm secrets 来加密上述文件:

$ helm secrets enc secrets.test.yamlEncrypting secrets.test.yamlEncrypted secrets.test.yaml

查看加密后的文件内容:

secret_data:username: ENC[AES256_GCM,data:O/1pyNsL3Gc=,iv:HZ0MrGWaBxM37cIkp/JdsA5gRzw6aJFfBR19rno3h5I=,tag:2SiMs46lonnwECc8RHfT/Q==,type:str]password: ENC[AES256_GCM,data:l15XlhZ4CsM=,iv:TMbV6 Rh2wGpMlHi7zJsHWM6IxMK2hBuMKsD82p8LiY=,tag:N4Kbftl//B1U2R9Khsduzg==,type:str]sops:kms: []gcp_kms: []azure_kv: []hc_vault: []lastmodified: '2021-02-07T06:19:15Z'mac: ENC[AES256_GCM,data:dSXjEbKyBXVtqqSqshGXKUwDJcMVZrDf2GxFj0Oor3FDnNeS bTY4Yubv1J0XlzU6yxO0Y87NzVN84unkF/Ph95JJV2opk6a0VTtaxKYOFUVneyY5WQ2glHEntX aEq1lJkW1Sd34i/tvWeSABemIX4M2xcIOdIaCHgzk//vi9w=,iv:febius/ashzpdfKStJnQYVG/3FrVaYw102q87P9 egQ=,tag:/MUXrxhhOk6F8MS5wi7cLQ==,type:str]pgp:-created_at: '2021-02-07T06:19:08Z'enc: |-----BEGIN PGP MESSAGE-----hQIMA7Oc9Dk1ccccARAAk7l23omTBRThnP7YC5AHdqzEO8Lapxc8ycWg5tsbM8eEJaRFn4u3/ dQdpL6xlHv1wu0kmrZUgG8P41WmNDIKb2GtAlHQk bjjV2IU0lCEj79UZXuAyhxHtVjHMBnzjppFh 6L0nH2K5AGaJWATwhO9M6CqmdCFnWJx7vAPfVQZFLi9zqHK/YsbwgEWKs0bVvJ1btB7u4J5olKagYaZhaFaLzwjbtXmEqDUpfmPkooNr7kPSVe8IMv/ MUaJY6uYNTBGWGrije4bY4A hA/dUj4yN0gqqd796oc9GuN1MJSOcAAoiTW2Vrw3OdyP7PIJVuxlS9gXnxtBOjo p/Ij91ELq DnC 6bGS9UIeF Y1RDh4siwx7I7hzk9tp tXmsfdJit usK6raPzYkcBgZVF8woKZsp2/qxloYyIFJ0sbKMO67 dcAg AX0M0/u33t1BAMTt/LJ1V2ZQUl yzjRSKfZ2bCmd/skkE3VZx2ls44LMngWZG7EzE39Onw9PB3ukXD7W X BThc2AJzVotrpDWbSI2/anoM9TMJjYfBjyUxBuTuoviT5ENdm14bGomww9G Ean3dyC2vWoHhY2KfuPlSxZ6mDIDm5zAPkZZl5AQHjtaPT5qymPCpqy2X3yvK76zyJhfWYFIHguOy3JlDxiONC9DH1M6OVWoC69pPzSXgEtII9fTeLXFU5Jy9gJa5nNKEQY87OkSXl3TFAiQ9OmgDbuUHZuvQzlecsKwR2smS7P7Z3Bb eRakQ41Gzw4B7wmOrm2w0t4guVJDNIP/gQB0XBO1XZj4RsbMKn070==yQ2R-----END PGP MESSAGE-----fp: B1C77B2CCF5575FAF0DA6B882CA51446C98C9D85encrypted_regex: ^(data|username|password|.dockerconfigjson|token|token1|key|crt)$version: 3.6.1

需要注意的是,此时只是加密了需要加密的内容,但是这些内容该怎么用呢?其实也比较简单,就是:正常用。

举例来说,在 helm chart 中,正常用 secret 的方式如下:

apiVersion: v1kind: Secretmetadata:name: testlabels:app: devsecopstype: Opaquedata:{{- range $key, $value := .Values.secret_data}}{{ $key }} : {{ $value | b64enc | quote}}{{- end}}

而上面循环中引用的值.Values.secret_data就是来自于上面helm_vars目录下的加密文件。

怎么做到的呢?简单点说,就是执行 helm 的相关命令(install 或者 upgrade)时,会利用 sops 的 private key 将 helm_vars 目录下的加密内容解密,并且“存放在”values.yaml 文件中,接下来的就和正常的 helm chart 使用是一样的了。在 chart中的 deployment.yaml 文件中引用 secret:

......containers:- name: {{ .Chart.Name }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"imagePullPolicy: {{ .Values.image.pullPolicy }}envFrom:- secretRef:name: test......

接下来可以使用下面命令将前文的 chart 进行安装:

$ helm secrets install test . --namespace test -f helm_vars/secrets.yaml -f values.yaml

需要注意的是,在上面的命令中,必须指定helm_vars/secrets.yaml文件。接着查看生成的pod、secret:

$ kubectl -n test get pods,secretpod/test-devsecops-7876ffc8b7-967xr1/1Running06ssecret/testOpaque28s

由于上面的 secret 是以环境变量的形式注入到 pod 里面的,可以查看进行验证:

$ kubectl -n test exec -it test-devsecops-7876ffc8b7-967xr sh$ env | grep -E 'username|password'username=xiaomagepassword=passw0rd

可以看到 secret 解密成功,并成功注入 pod。

最后就可以将加密后的文件上传至源码管理系统了(比如用 git push 至 GitHub)。

三、Kamus

Kamus 是一款开源的采用零信任的 secret 加解密方式为 Kubernetes 应用程序安全处理 secrets 的工具。Kamus 提供两种方式来对 Kubernetes secrets 进行加密,即

  • 使用 init container:将 secrets 加密后存储为 Kubernetes configmap,然后在应用程序的部署中添加一个 init container,通过 init container 将 configmap 中的加密数据解密至指定文件,应用程序再从此文件读取解密后的 secret 信息。
  • 使用 KamusSecret:创建一个 KamusSecret 对象(充分利用了 Kubernetes 的扩展机制),此对象包含了加密之后的数据,在此对象创建的过程中,会创建一个同名的 secret 对象,secret 中的数据是经过 base64 编码之后的数据,可以被 Kubernetes 其他对象引用。

3.1 原理

Kamus 同样是使用客户端工具 kamus-cli 对于需要加密的数据进行加密(区别于 Sealed Secrets 的是,Kamus 的数据需要单独逐一加密,而不是全部存放在 secret 文件里面一次性加密,下面会看到),下面依旧以加解密的方式分别阐述。

3.2 加密

用 kamus-cli 对需要加密的数据逐一加密时,位于集群上的 controller 会选择 public key 并使用 kamus encryptor 对数据进行加密,随后将加密内容保存在 configmap 中(以 init container 的方式使用)或者 KamusSecret 中(以 secret 的方式使用)。

3.3 解密

当将加密后的内容进行部署时(kubectl apply/create),位于集群上的 controller 会选择 private key,并使用 kamus decryptor 对于数据进行解密。

如果是使用 KamusSecret 存储的数据,则 controller 将生成一个与 KamusSecret 对象同名的 Secret 对象,此 Secret 中存放由经过 base64 编码后的信息;

如果是使用 configmap 的形式,则此 configmap 会以 volume 的形式挂载到 pod 内,随后在 pod 中使用 init container 来调用 kamus-decryptor 的 api 将加密信息解密,并存放到指定的文件中,随后 pod 内的应用程序可以通过读取此文件内容来获取敏感信息。

KamusSecret 和 Secret 两者的关系与 Deployment 和 Pod 之间的关系类似。

3.4 安装

kamus 的安装包括 controller 和客户端工具 kamus-cli。

  • 安装 controller

$ helm repo add soluto https://charts.soluto.io$ helm install kamus --namespace kamus soluto/kamus

检查 pod 状态:

$ kubectl -n kamus get podsNAMEREADYSTATUSRESTARTSAGEkamus-controller-55d959895d-hdklf1/1Running09m30skamus-decryptor-5974b6ff47-5pkbr1/1Running07m34skamus-decryptor-5974b6ff47-c4jt41/1Running07m34skamus-encryptor-f75dd457-fwp8r1/1Running09m28skamus-encryptor-f75dd457-p9rnx1/1Running09m29s

  • 安装客户端

$ npm install -g @soluto-asurion/kamus-cli

检查安装是否成功:

$ kamus-cli -V0.3.0

3.5 使用

下面分别以init container和 KamusSecret 的方式来演示使用方式。

1)以init container的方式

首先需要加密 secret。kamus 加密 secret 时需要和一个 service account 关联起来,此 service account 会在后续的应用部署中使用,所以先创建一个 service account(本文所有 demo 均在 test ns 下):

$ kubectl -n test create sa xiaomage

接着使用客户端工具 kamus-cli 来加密 secret(username 的值为 xiaomge,password 的值为 passw0rd):

$ kamus-cli encrypt --secret xiaomage --service-account xiaomage --namespace test --kamus-url http://localhost:9999 --allow-insecure-url[infokamus-cli]: Encryption started...[infokamus-cli]: service account: xiaomage[infokamus-cli]: namespace: test[warnkamus-cli]: Auth options were not provided, will try to encrypt without authentication to kamus[infokamus-cli]: Successfully encrypted data to xiaomage service account in test namespace[infokamus-cli]: Encrypted data:CxujUBK4jgdjt wP5mXyDA==: CoXRDJVtW3EZ2FpterVTA==

返回的CxujUBK4jgdjt wP5mXyDA==: CoXRDJVtW3EZ2FpterVTA== 就是 xiaomage 这个值经过加密后的值,用同样的方法,可以将 passw0rd 进行加密:

$ kamus-cli encrypt --secret passw0rd --service-account xiaomage --namespace test --kamus-url http://localhost:9999 --allow-insecure-url[infokamus-cli]: Encryption started...[infokamus-cli]: service account: xiaomage[infokamus-cli]: namespace: test[warnkamus-cli]: Auth options were not provided, will try to encrypt without authentication to kamus[infokamus-cli]: Successfully encrypted data to xiaomage service account in test namespace[infokamus-cli]: Encrypted data:ChmNEPM8Nj7Huh1YwO5xOA==:r9MHhEyTIEaQ4hw837lA9w==

返回的ChmNEPM8Nj7Huh1YwO5xOA==:r9MHhEyTIEaQ4hw837lA9w== 就是 passw0rd 这个值经过加密后的值,将上述两个加密后的值放在 configmap 中:

apiVersion: v1kind: ConfigMapmetadata:name: kamus-encrypted-secrets-cmnamespace: testdata:username: CxujUBK4jgdjt wP5mXyDA==: CoXRDJVtW3EZ2FpterVTA==password: ChmNEPM8Nj7Huh1YwO5xOA==:r9MHhEyTIEaQ4hw837lA9w==

接下来,将上述 configmap 以 volume 的方式挂在到 pod 中,随后使用 init container 来解密数据,且将数据存放在一个 config.json 文件中:

apiVersion: v1kind: Podmetadata:namespace: testname: kamus-podspec:serviceAccountName: xiaomageautomountServiceAccountToken: trueinitContainers:- name: "kamus-init"image: "soluto/kamus-init-container:latest"imagePullPolicy: IfNotPresentenv:- name: KAMUS_URLvalue: http://kamus-decryptor.kamus.svc.cluster.local/volumeMounts:- name: encrypted-secretsmountPath: /encrypted-secrets- name: decrypted-secretsmountPath: /decrypted-secretsargs: ["-e","/encrypted-secrets","-d","/decrypted-secrets", "-n", "config.json"]containers:- name: kamus-testimage: dllhb/devopsday:v0.6imagePullPolicy: IfNotPresentvolumeMounts:- name: decrypted-secretsmountPath: /secretsvolumes:- name: encrypted-secretsconfigMap:name: kamus-encrypted-secrets-cm- name: decrypted-secretsemptyDir:medium: Memory

需要注意的是,需要指定 kamus 的地址,即 decryptor 的地址,可根据自己的安装情况自行指定。

接下来,部署 configmap 和 pod 并查看:

$ kubectl -n test apply -f configmap.yaml$ kubectl -n test apply -f kamus-deploy.yaml$ kubectl -n test get pods,cmNAMEREADYSTATUSRESTARTSAGEpod/kamus-pods1/1Running04h3mNAMEDATAAGEconfigmap/kamus-encrypted-secrets-cm230s

进入 pod 查看解密后的数据:

$kubectl -n test exec -it kamus-deploy sh$ cat /secrets/config.json{"password":"passw0rd","username":"username"}

可以看到 secet 已经被解密到了 config.json文件中,应用程序只需要读取此文件即可获得 secret 的相关数据。

2)以 KamusSecret 的方式

kamus 对 Kubernetes 进行了扩展,有了自己支持的 KamusSecret 对象,将上述加密后的数据存放在 KamusSecret 中:

apiVersion: "soluto.com/v1alpha2"kind: KamusSecretmetadata:name: kamus-testnamespace: testtype: OpaquestringData:username: CxujUBK4jgdjt wP5mXyDA==: CoXRDJVtW3EZ2FpterVTA==password: ChmNEPM8Nj7Huh1YwO5xOA==:r9MHhEyTIEaQ4hw837lA9w==serviceAccount: xiaomage

创建 KamusSecret 对象:

$ kubectl -n test apply -f kamus-secrets.yaml

查看生成的 KamusSecret 和 Secret:

$ kubectl -n test get KamusSecret,secretNAMEAGEkamussecret.soluto.com/kamus-test60sNAMETYPEDATAAGEsecret/kamus-testOpaque259s

可以看到 KamusSecret 生成了一个和自己同名的 secret,接着查看 secret 的内容:

apiVersion: v1data:password: cGFzc3cwcmQ=username: eGlhb21hZ2U=

解码后为:

password: passw0rdusername: xiaomage

此时,可以像正常方式在 pod 中引用此 secret(像前文的 Sealed Secret 章节所演示的一样,再次不再赘述)。

最后就可以将加密后的文件上传至源码管理系统了(比如 git push 至 GitHub)。

写在最后

其实,安全处理 Kubernetes secret 的方式不仅仅上面的三种形式,还可以利用诸如 vault 等来管理应用程序部署中的敏感信息。但是不同的工具、不同的方式,其背后的思想和思路都差不太多。

总结起来,差不多有以下几点:

  • 充分利用 Kubernetes 的扩展能力,自定义一个 secret 对象用来存储加密后的数据(诸如 Sealed Secrets 的 SealedSecret 对象;Kamus 的 KamusSecret),让这些扩展的对象生成对应的 secret 对象,再正常使用 secret 对象。
  • 利用外部的敏感信息管理工具(诸如 vault 或者其他云厂商提供的服务)。
  • sops 是一种使用方便的加密工具,也是上述工具实现加密的秘密武器。

没有一劳永逸的安全,只有永不止步的行动。任何改变都是重要的。

参考

  • https://github.com/bitnami-labs/sealed-secrets
  • https://github.com/Soluto/kamus
  • https://kamus.soluto.io/
  • https://blog.solutotlv.com/can-kubernetes-keep-a-secret/
  • https://en.sokube.ch/post/lightweight-kubernetes-gitops-secrets
  • https://github.com/mozilla/sops#showing-diffs-in-cleartext-in-git

来源:DevSecOps SIG

作者:小马哥

+“CH050791”可入qun交流~

,
    推荐阅读
  • 备考时什么小零食合适(六个核桃2430一天一罐保持考生极致脑状态)

    而核桃中所含的维生素E可使细胞免受自由基的氧化损害。中国老年保健协会膳食指导专委会名誉会长孙树侠表示大脑补给可以用“71”营养补充法。“71”的“7”是指蛋白质、碳水化合物、脂肪、矿物质、维生素、纤维素和水。其中,脂肪是健脑益智的重要物质,它占人脑的比例高达60%。事实上,核桃营养与大脑记忆力的关系一直是学界重点研究的课题。不少用户都成为了六个核桃2430的忠实粉丝。

  • S开头的火车车次是什么意思(S开头的火车车次是属于什么意思)

    S开头的火车车次是什么意思?我们一起去了解并探讨一下这个问题吧!城郊专运客车,属于旅客列车,目前只有北京,天津存在这种列车。列车运行区间为北京北站~延庆站/沙城站,天津站/北站~宝坻/蓟县。车次的编制和上行下行有关,铁路规定进京方向或是从支线到干线被称为上行,反之离京方向或是从干线到支线被称为下行。例如T11次是从北京开往沈阳北方向,为下行所以是奇数(单数)的。

  • cue是什么英语(的cue在英语里到底是什么意思)

    的cue在英语里到底是什么意思Cue这个词很有意思英文课本里几乎不怎么提,但是日常说话却常常夹在中文里说“最怕老师上课cue我”,“诶,你别cue我,我啥也不知道”等等Cue的动词意思是“给(某人)提示或暗示”,做名词解,就有戏剧。

  • 周末免费体验全脑动漫英语特训体验课

    4月21、22日,东莞科技文化活动中心将在东莞市科技馆举办一期“全脑动漫英语特训”初次免费体验课。体验课程主要针对于东莞地区小学三年级以上和初、高中学生,每次体验课仅限40人,有兴趣的学生可拨打0769—22835210。另外,每个体验课名额还可享受Q版可爱小礼品和一次学生学习品质测评。

  • 白菜猪肉饺子怎么做(白菜猪肉饺子的做法)

    白菜猪肉饺子怎么做材料:标准面粉100克,瘦猪肉50克,白菜200克,酱油5克,香油5克,姜、葱各2克,精盐5克,醋5克,清水适量。先将面用水调成面团,揉匀放置半小时待用。猪肉剁成肉泥,加入香油、酱油,白菜洗净,剁成碎末,挤去水分,姜、葱切成碎末,一同放入肉馅中,加盐调匀即成馅料。食用时可蘸着醋吃。

  • 庖丁解牛的寓意是什么(关于庖丁解牛的寓意介绍)

    庖丁解牛的寓意是什么原来是说一个养生之道的:凡事要顺应自然,不勉强硬碰,还要抱持谨慎小心的态度,收敛锋芒,这样便可以保全生命,保全天性,存养精神,尽享天年。现在比喻经过反复实践,掌握了事物的客观规律,做事得心应手,运用自如。《庖丁解牛》是先秦道家学派代表人物庄子(庄周)创作的一则寓言故事。

  • 翡翠原石皮壳种类(翡翠原石皮壳种类有哪些)

    按皮壳的颜色来划分翡翠原石皮壳种类有:红色、黄色、白色、锈色、黑色和灰色等。按皮壳的外表特征来划分翡翠原石皮壳种类有:沙皮、腊皮、锈皮和油性皮等。

  • 泰州身份证补办条件+材料+地点(泰州市身份证办理地点)

    》》》条件:公民遗失居民身份证的,可向户口所在地公安机关申请遗失补办,未满16周岁的,由监护人携同办理。

  • 落入凡间的温柔句子(适合落入凡间的温柔句子)

    我们一起去了解并探讨一下这个问题吧!落入凡间的温柔句子做一个积极向上的人读温柔的句子见阳光的人眼里全是温柔和笑意。我和口袋里藏着从你城堡里逃跑的星星。你是我惊鸿一瞥的喜欢也是我眼中溢出的光芒。我会披星戴月不远万里抛下世间的一切奔向你。寄给你全宇宙的爱和自太古至永劫的思念。我怀里所有温暖的空气变成风也不敢和你相遇。你是我心里的那个白衬衫男孩我是你的高马尾女孩。你也是我疲惫生活的希望与糖。

  • 服从调剂报志愿可以不报么(服从调剂一定能录取吗)

    服从调剂是指高考分数达到所填报学校的投档线,但未达到所报专业录取分数线,同时该校仍有专业未录满可以录取你,但是这并不代表服从调剂就一定会被录取,也有被退档的风险。如果过了投档线并且选择了服从专业调剂,那么肯定不会被退档的,顶多就是专业并不是所选的那些。但这些完全可以在以后通过转专业的方式实现。也就是说,在平行志愿模式下,如果要避免被退档的风险,大家一定要服从调剂。