为了提供安全锁定和擦除的合规性功能,MinIO 使用服务器端加密 (SSE) 在存储层加密对象,以保护对象作为写入操作的一部分。MinIO 以极高的效率做到这一点——基准测试表明 MinIO 能够以接近线速进行加密/解密。
MinIO 使用的秘诀是单指令多数据 (SIMD)。通常,一次只能发送一条 CPU 指令,等待响应后再发送下一条指令。这是非常低效的,尤其是在每秒执行数千条(如果不是数百万条)加密和解密指令时。MinIO 利用 SIMD,因此它可以在单个请求中发送多条指令,由 CPU 处理。我们在 GoLang 中编写了汇编内容,因此我们尽可能靠近硬件层,以充分利用通常未充分利用的 CPU 能力来大规模执行加密操作。
在上一篇文章中,我们向您展示了如何使用 KES 在裸机环境中开始使用 MinIO 和 Vault。在这篇文章中,我们将向您展示如何在 Kubernetes 中以云原生方式使用 KES(密钥加密系统)和 Vault 配置 MinIO Operator。这将使你能够在扩展并使用 Kubernetes 资源来配置它们时自动执行该过程。
先决条件
在开始之前,请确保满足以下先决条件:
-
Kubernetes 集群(在本教程中,我们将使用 kind 创建本地集群)
-
本地计算机上安装的 kubectl 命令行工具
-
git 用于克隆必要的存储库
步骤 1:使用 kind 部署 Kubernetes 集群
首先,我们将使用 kind 创建一个 Kubernetes 集群。这将为我们提供一个本地环境来部署和测试我们的 MinIO 设置。
首先,创建一个使用以下命令命名 kind-config.yaml
的 kind 配置文件:
$ cat > kind-config.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
- role: worker
EOF
$ kind create cluster --config kind-config.yml
步骤 2:部署 MinIO Operator
随着 Kubernetes 集群的启动和运行,我们现在可以使用该 kustomization
插件部署 MinIO Operator。MinIO Operator 简化了 Kubernetes 环境中 MinIO 实例的部署和管理。
执行以下命令,在集群中kind
部署 MinIO Operator:
$ kubectl apply -k github.com/minio/operator
等待所有 Pod 在 minio-operator 命名空间中联机,然后再继续下一步。
第 3 步:设置 HashiCorp Vault
HashiCorp Vault 是一个强大的机密管理工具,我们将使用它来安全地存储和管理我们的加密密钥。要在我们的 Kubernetes 集群中设置 Vault,我们将使用 kubernetes-vault
存储库。
通过运行以下命令克隆存储库:
$ git clone https://github.com/scriptcamp/kubernetes-vault.git
$ cd kubernetes-vault/vault-manifests
接下来,设置必要的 RBAC(基于角色的访问控制)规则,创建 Vault 配置映射,部署 Vault 服务,并设置有状态集:
$ kubectl apply -f rbac.yml
创建 Vault 配置映射
$ kubectl apply -f configmap.yaml
部署 Vault 服务
$ kubectl apply -f services.yaml
由于 Vault 是有状态服务,因此我们需要为其设置一个有状态集。为此执行以下命令
$ kubectl apply -f statefulset.yaml
Vault 设置完成后,解封并初始化 Vault。
$ kubectl exec vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > keys.json
$ VAULT_UNSEAL_KEY=$(cat keys.json | jq -r ".unseal_keys_b64[]")
$ echo $VAULT_UNSEAL_KEY
$ VAULT_ROOT_KEY=$(cat keys.json | jq -r ".root_token")
$ echo $VAULT_ROOT_KEY
$ kubectl exec vault-0 -- vault operator unseal $VAULT_UNSEAL_KEY
现在,输入 vault-0
POS 以执行其他配置:
$ kubectl exec -it vault-0 -- /bin/sh
在容器内,启用 K/V 后端,创建策略,启用 AppRole 身份验证,创建 KES 角色,并生成应用角色 ID 和密钥:
$ vault secrets enable -version=1 kv
创建策略
$ cat > kes-policy.hcl <<EOF
path "kv/*" {
capabilities = [ "create", "read", "delete" ]
}
$ vault policy write kes-policy kes-policy.hcl
启用 AppRole 身份验证
$ vault auth enable approle
创建 KES 角色并向其附加策略
$ vault write auth/approle/role/kes-server token_num_uses=0 secret_id_num_uses=0 period=5m
$ vault write auth/approle/role/kes-server policies=kes-policy
生成应用角色 ID 和机密,并记下值
$ vault read auth/approle/role/kes-server/role-id
Key Value
--- -----
role_id b484633b-8965-08dd-0e24-d6973e6be2d2
$ vault write -f auth/approle/role/kes-server/secret-id
Key Value
--- -----
secret_id 7fd44d44-a3f1-a013-1f40-e1952496c416
secret_id_accessor b5ee0c97-5ffc-b9a7-fe0b-763757fe1033
secret_id_ttl 0s
记下生成的应用角色 ID 和机密,因为我们将在下一步中用到它们。
第 4 步:使用 kustomization 插件部署 KES
要使用 kustomization
插件部署 KES(密钥加密服务),我们首先需要克隆 MinIO 存储库:
$ git clone https://github.com/minio/operator.git
$ cd operator
使用适当的 KES 值更新 examples/kustomization/tenant-kes-encryption/kes-configuration-secret.yaml
文件,包括 Vault 端点、命名空间、前缀以及生成的应用角色 ID 和密钥。
keystore:
## KES configured with fs (File System mode) doesnt work in Kubernetes environments and it's not recommended
## use a real KMS
# fs:
# path: "./keys" # Path to directory. Keys will be stored as files. Not Recommended for Production.
vault:
endpoint: "http://vault.default.svc.cluster.local:8200" # The Vault endpoint
namespace: "default" # An optional Vault namespace. See: https://www.vaultproject.io/docs/enterprise/namespaces/index.html
prefix: "my-minio" # An optional K/V prefix. The server will store keys under this prefix.
approle: # AppRole credentials. See: https://www.vaultproject.io/docs/auth/approle.html
id: "b484633b-8965-08dd-0e24-d6973e6be2d2" # Your AppRole Role ID
secret: "7fd44d44-a3f1-a013-1f40-e1952496c416" # Your AppRole Secret ID
retry: 15s # Duration until the server tries to re-authenticate after connection loss.
tls: # The Vault client TLS configuration for mTLS authentication and certificate verification
key: "" # Path to the TLS client private key for mTLS authentication to Vault
cert: "" # Path to the TLS client certificate for mTLS authentication to Vault
ca: "" # Path to one or multiple PEM root CA certificates
status: # Vault status configuration. The server will periodically reach out to Vault to check its status.
ping: 10s # Duration until the server checks Vault's status again.
现在,将 KES 服务与 MinIO 租户一起部署:
$ kubectl apply -k operator/examples/kustomization/tenant-kes-encryption
这将部署 KES
和 MinIO pod,如下所示
$ kubectl get pods -n tenant-kms-encrypted
NAME READY STATUS RESTARTS AGE
myminio-kes-0 1/1 Running 0 104m
myminio-kes-1 1/1 Running 0 104m
myminio-pool-0-0 2/2 Running 0 101m
myminio-pool-0-1 2/2 Running 0 102m
myminio-pool-0-2 2/2 Running 3 (102m ago) 103m
myminio-pool-0-3 2/2 Running 4 (102m ago) 104m
使用 KES 的 MinIO 部署现已启动并运行。
步骤 5:验证部署
为了确保我们的部署顺利运行,让我们检查一下 MinIO 租户 pod、KES pod 和操作员 pod 的状态:
$ kubectl get pods -n minio-operator NAME READY STATUS RESTARTS AGE
console-6459d44b76-fgwbt 1/1 Running 0 5h29m
minio-operator-5668d46f98-9p2wm 1/1 Running 0 5h29m
minio-operator-5668d46f98-pm98s 1/1 Running 0 5h29m
$ kubectl get pods -n tenant-kms-encrypted
NAME READY STATUS RESTARTS AGE
myminio-kes-0 1/1 Running 0 116m
myminio-kes-1 1/1 Running 0 116m
myminio-pool-0-0 2/2 Running 0 113m
myminio-pool-0-1 2/2 Running 0 114m
myminio-pool-0-2 2/2 Running 3 (114m ago) 115m
myminio-pool-0-3 2/2 Running 4 (114m ago) 116m
$ k get pods -n default
NAME READY STATUS RESTARTS AGE
vault-0 1/1 Running 0 4h39m
验证 KES Pod 日志以确保没有错误,并且 Pod 按预期运行,如下所示:
$ kubectl logs myminio-kes-0 -n tenant-kms-encrypted Copyright MinIO, Inc. https://min.io
License GNU AGPLv3 https://www.gnu.org/licenses/agpl-3.0.html
Version 2023-04-18T19-36-09Z linux/amd64
KMS Hashicorp Vault: http://vault.default.svc.cluster.local:8200
Endpoints https://127.0.0.1:7373
https://10.244.3.55:7373
Admin _ [ disabled ]
Mem Lock off Failed to lock RAM pages. Consider granting CAP_IPC_LOCK
{"time":"2024-03-08T07:51:31.333681336Z","request":{"ip":"10.244.1.47","path":"/v1/key/create/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":400,"time":2871000}}
{"time":"2024-03-08T07:51:32.191375099Z","request":{"ip":"10.244.3.54","path":"/v1/identity/self/describe","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":18000}}
{"time":"2024-03-08T07:51:32.191784146Z","request":{"ip":"10.244.3.54","path":"/v1/key/create/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":400,"time":1739000}}
{"time":"2024-03-08T07:52:01.890935905Z","request":{"ip":"10.244.3.54","path":"/v1/key/generate/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":1888000}}
{"time":"2024-03-08T07:52:02.145905494Z","request":{"ip":"10.244.1.47","path":"/v1/key/generate/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":62000}}
{"time":"2024-03-08T07:52:02.162627602Z","request":{"ip":"10.244.1.47","path":"/v1/key/generate/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":62000}}
{"time":"2024-03-08T07:52:04.850766874Z","request":{"ip":"10.244.3.54","path":"/v1/key/decrypt/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":68000}}
{"time":"2024-03-08T07:52:04.857285115Z","request":{"ip":"10.244.3.54","path":"/v1/key/decrypt/my-minio-key","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":53000}}
{"time":"2024-03-08T07:52:07.753077729Z","request":{"ip":"10.244.2.35","path":"/v1/identity/self/describe","identity":"f9daf353b4bb9bba772a369b621a258c9464322c85d1ac9d2aafd29afdb96ea6"},"response":{"code":200,"time":7000}}
步骤 6:测试部署
为了测试我们的部署,我们将创建一个示例存储桶,并从安装了 mc(MinIO 客户端)的调试 Pod 中加载/检索对象。
首先,启动一个新终端并运行以下命令以执行到调试 pod 中:
kubectl exec -it pod/ubuntu-pod -n default -- bash
在调试 Pod 中,执行以下命令创建存储桶、创建加密密钥、上传文件并验证加密,如下所示:
mc alias ls myminio
mc ls myminio
mc mb myminio/encryptedbucket
mc admin kms key create myminio encrypted-bucket-key
echo "Hello" >> file1.txt
mc cp file1.txt myminio/encryptedbucket
mc ls myminio/encryptedbucket
mc cat myminio/encryptedbucket/file1.txt
mc admin kms key status myminio encrypted-bucket-key
mc stat myminio/encryptedbucket/file1.txt
如果所有设置都正确,您应该会看到上传的文件已加密,并且加密密钥状态有效。
下面演示了此过程,如预期的那样:
$ kubectl exec -it pod/ubuntu-pod -n default -- bash
root@ubuntu-pod:/# mc alias ls myminio
myminio
URL : https://myminio-pool-0-0.myminio-hl.tenant-kms-encrypted.svc.cluster.local:9000
AccessKey : minio
SecretKey : minio123
API : s3v4
Path : auto
root@ubuntu-pod:/# mc ls myminio
root@ubuntu-pod:/# mc mb myminio/encryptedbucket
Bucket created successfully `myminio/encryptedbucket`.
root@ubuntu-pod:/# mc admin kms key create myminio encrypted-bucket-key
Created master key `encrypted-bucket-key` successfully
root@ubuntu-pod:/# echo "Hello" >> file1.txt
root@ubuntu-pod:/# mc cp file1.txt myminio/encryptedbucket
/file1.txt: 6 B / 6 B ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 344 B/s 0sroot@ubuntu-pod:/# mc ls myminio/encryptedbucket
[2024-03-08 10:25:01 UTC] 6B STANDARD file1.txt
root@ubuntu-pod:/# mc cat myminio/encryptedbucket/file1.txt
Hello
root@ubuntu-pod:/# mc admin kms key status myminio encrypted-bucket-key
Key: encrypted-bucket-key
- Encryption ✔
- Decryption ✔
root@ubuntu-pod:/# mc stat myminio/encryptedbucket/file1.txt
Name : file1.txt
Date : 2024-03-08 10:25:01 UTC
Size : 6 B
ETag : 27e775e1a5d22463e4cd39f12ce14ea0
Type : file
Metadata :
Content-Type: text/plain
Encrypted :
X-Amz-Server-Side-Encryption : aws:kms
X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id: arn:aws:kms:encrypted-bucket-key
如果所有设置都正确,您应该会看到上传的文件已加密,并且加密密钥状态为有效,确认对象已加密。
最后的思考
在这篇博文中,我们探讨了如何在 Kubernetes 环境中部署具有 Vault 支持的 KES 的 MinIO Operator,重点关注服务器端加密 (SSE)。通过利用 Kubernetes 和 kustomization
插件的强大功能,我们可以自动化部署过程,并根据需要轻松扩展我们的 MinIO 设置。
我们采用“左移”方法,强调从开发和规划的最初阶段就嵌入安全和数据保护实践的重要性。其意图很明确:将安全性从单纯的考虑提升为基础架构的基本要素。通过强调 SSE 的简单性和可访问性,我们的目标是鼓励将其作为所有 MinIO 部署的标准采用。实现强大安全性的道路既简单又可实现,为更安全、更可靠的数字环境铺平了道路。