Amazon EKS 上有状态服务启用存储加密

news2024/11/25 23:39:10

1.背景

用户通过 Deployment, Replication Controller 可以方便地在 Kubernetes 中部署一套高可用、可扩展的分布式无状态服务。这类应用不在本地存储数据,通过简单的负载均衡策略可实现请求分发。

Deployment 以及 Replication Controller 是为无状态服务而设计的,它们中 Pod 的名称、主机名、存储都是不稳定的,且 Pod 的启动、销毁顺序随机,并不适合数据库这样的有状态应用。

亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏,看到这里请一定不要匆匆划过,点这里让它成为你的技术宝库!

为此,Kubernetes 推出了面向有状态服务的工作负载 StatefulSet,管理的 Pod 具有如下特点:

  • 唯一性 – 对于包含 N 个副本的 StatefulSet,每个 Pod 会被分配一个 [0,N] 范围内的唯一序号。
  • 顺序性 – StatefulSet 中 Pod 的启动、更新、销毁默认都是按顺序进行的。
  • 稳定的网络身份标识 – Pod 的主机名、DNS 地址不会随着 Pod 被重新调度而发生变化。
  • 稳定的持久化存储 – 当 Pod 被重新调度后,仍然能挂载原有的 PersistentVolume,保证了数据的完整性和一致性。

本文针对有状态服务业务场景的数据保护安全需求,旨在从 Amazon EKS 内部结合采用 StatefulSet, Snapshot Controller 的方式实现有状态服务的存储加密启用,并在测试环境下验证了本方案的可行性。

2.场景案例

2.1 场景架构

业务场景:

该业务平台构建在亚马逊云上,服务客群主要为全国各医院,核心业务价值在于简化医院采购结算环节,帮助医院方降本增效。该平台通过结合医院,医院供应商提供的订单、结算单、发票信息,进行三单验证,并集成银行侧银企直连,进而实现医院的快速透明支付结算、有效提升采购效率。

部署架构:

之前客户在本地 IDC 的 Kubernetes 集群中除了部署了无状态的微服务应用外,还部署了有状态的中间件服务,包括 Redis, Kafka, MySQL,存储使用的是本地磁盘。由于自建 Kubernetes 集群的升级、管理、安全等各方面的运维工作复杂,需要耗费大量的运维资源;并且在 Kubernetes 集群中运行有状态的应用,特别是业务数据库,存在很大的潜在风险,因而在迁移至亚马逊云上的过程中,接受我方建议做了相应的架构优化及调整:

  • 自建 Kubernetes 调整为托管的 EKS 服务;
  • 从 Kubernetes 集群中移除关系数据库 MySQL,替换为托管的 RDS Aurora 服务;
  • EKS 中各业务组件采用无状态部署;
  • EKS 中保留 Redis 和 Kafka 等中间件,并采用有状态部署,持久化采用 EBS;
  • EKS 中采用 EFS 作为共享存储,实现存储的安全高可用。

架构示意图:

2.2 问题及解决方案

问题描述:

由于涉及到订单、结算单、发票等敏感数据的传输及存储,在业务上线后不久,客户希望加强云上数据安全保护,结合 KMS 对持久化数据进行自动存储加密。之前有状态服务 Redis, Kafka 等在部署上线时所挂载的 EBS 并未启用加密,由于 EBS 在初始未启用加密的情况下无法直接开启加密(见下面技术约束示意图),那么在对业务的影响降至最低的前提下如何实现 EBS 存储加密的开启及业务的平滑迁移呢?

技术约束示意图:

初始未加密EBS无法直接启用加密,需对未加密 EBS 做快照,再将未加密快照还原成加密 EBS,如下图所示:

解决方案:

  • 方案一:需应用层做数据迁移,EKS 中原 Redis 等有状态服务保持不动,采用 StatefulSet 方式新建 Redis 等有状态服务并启用 EBS 存储加密,在应用层做数据迁移(将敏感数据从原服务未加密 EBS 迁移至新建服务已加密 EBS)后将中间件服务切换至新建 Redis 等有状态服务并下线原服务以实现有状态服务的存储加密;
  • 方案二:不涉及应用层数据迁移,从亚马逊云科技控制台直接对 EBS 进行相关操作,将未加密EBS制作快照后还原成加密 EBS,并将加密 EBS 静态挂载回正确的 Redis 等有状态服务;
  • 方案三:不涉及应用层数据迁移,从 EKS 内部进行相关操作,首先启用 Snapshot Controller,之后通过该 Controller 对未加密 pvc 制作快照后还原成加密pvc,新建 Redis StatefulSet 并挂载加密 pvc,引流至新建 Redis 测试一切正常后做服务迁移;

由于客户不希望应用层做数据迁移,以及从亚马逊云科技控制台操作后如何正确静态挂载回对应的 Pod 存在较大风险,最终采用了方案三进行了相应的测试及部署,并成功启用了 EKS 下 EBS 的存储加密。

3.部署与测试

接下来我们会按照上述方案三进行部署测试,整体的过程如下:

3.1 环境准备

安装 Amazon CLI, eksctl, kubectl 和 helm; 安装并配置 Amazon CLI: https://docs.AWS.amazon.com/cli/latest/userguide/getting-started-install.html 安装eksctl: https://docs.AWS.amazon.com/eks/latest/userguide/eksctl.html 安装kubectl: https://docs.AWS.amazon.com/eks/latest/userguide/install-kubectl.html Helm 安装: https://docs.AWS.amazon.com/eks/latest/userguide/helm.html 运行以下命令创建 EKS 集群,本实验环境中的集群版本为 V1.21

eksctl create cluster --name test-cluster

创建完成后,检查集群连接性,应该会看到两个 Ready 状态的节点;

kubectl get node

安装 EBS CSI Driver 插件,将 arn 中的 111122223333 替换为您的账户 ID;

eksctl utils associate-iam-oidc-provider \
  --cluster test-cluster \
  --approve
eksctl create iamserviceaccount \
  --name ebs-csi-Controller-sa \
  --namespace kube-system \
  --cluster test-cluster \
  --attach-policy-arn arn:AWS:iam::AWS:policy/service-role/AmazonEBSCSIDriverPolicy \
  --approve \
  --role-only \
  --role-name AmazonEKS_EBS_CSI_DriverRole
eksctl create addon --name AWS-ebs-csi-driver --cluster test-cluster --service-account-role-arn arn:AWS:iam::111122223333:role/AmazonEKS_EBS_CSI_DriverRole --force

作为生产环境 EBS 卷加密前的模拟,接下来创建一个 StorageClass,和一个 Redis 的 StatefulSet:

curl -LJO https://raw.githubusercontent.com/henghengha/hello-world/master/sc.yml
curl -LJO https://raw.githubusercontent.com/henghengha/hello-world/master/sts.yml
curl -LJO https://raw.githubusercontent.com/henghengha/hello-world/master/rbac.yml
curl -LJO https://raw.githubusercontent.com/henghengha/hello-world/master/cm.yml
kubectl apply -f sc.yml
kubectl apply -f rbac.yml
kubectl apply -f cm.yml
kubectl apply -f sts.yml

检查部署状态

查看 EBS 卷均未加密

3.2 方案实现

EBS 卷是否加密的属性是在 StorageClass 对象中声明的,通过重建 StorageClass 可以保证重新创建出来的 pv 即 EBS 卷是加密的,但是不会作用到之前已经存在的 EBS 卷。本部分将重点展示针对有状态对象在启用存储加密后,如何将原有 Pod 的数据备份,从而确保所有的 EBS 卷都已加密。操作步骤如下:

安装 Snapshot Controller,默认安装在 kube-system 命名空间,确保运行正常,参考:

Using EBS Snapshots for persistent storage with your EKS cluster | Containers

注意:配置文件中 Snapshot-Controller 使用的镜像地址为 gcr.io/Kubernetes-staging-sig-storage/Snapshot-Controller:v5.0.1,如果在中国区部署,请将该镜像下载下来,可以上传至 ECR,然后修改配置文件中的地址为中国区 ECR 的地址。

生产环境中为了尽可能的减少业务受影响的时间,我们后面将使用相同的配置创建一个新的 StatefulSet 对象,命名为 redis1,根据命名规则(该示例 StatefulSet 中的 volumeClaimTemplates 的名字为 data),redis1 生成的 pvc 名字将是 data-redis1-0 和 data-redis1-1。注意这里先不做真正的 StatefulSet 的部署;

删除原有 StorageClass,并使用如下配置重建:

apiVersion: storage.Kubernetes.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.AWS.com
  parameters:
    encrypted: 'true'
volumeBindingMode: WaitForFirstConsumer

本示例使用托管的 Amazon KMS Key aws/ebs 来进行加密,因此在 StorageClass 的配置中未指定具体的 Key ID。如果需要使用自定义 KMS 密钥,可以在 StorageClass 中添加 KMS Key ID 配置。与此同时,遵循最小权限原则,还需要给 EBS CSI Driver 授权 KMS 的对应权限。创建 IAM policy 并关联至 AmazonEKS_EBS_CSI_DriverRole,策略内容可参考官方文档进行配置: Creating the Amazon EBS CSI driver IAM role for service accounts - Amazon EKS

为原有的未加密 EBS 卷创建快照,并进行快照恢复到加密卷。首先,为 pvc data-redis-0 和data-redis-1 创建 Snapshot:

a.创建 Volume Snapshot Class;

cat <<"EOF" > Snapshot-class.yaml
apiVersion: Snapshot.storage.Kubernetes.io/v1
kind: VolumeSnapshotClass
metadata:
  name: test-snapclass
driver: ebs.csi.AWS.com
deletionPolicy: Delete
EOF
kubectl apply -f Snapshot-class.yaml

b.创建 YAML 文件,volume-Snapshot-redis.yaml 内容如下;

注意:VolumeSnapshot 中的 persistentVolumeClaimName 要保证与 Pod 对应的 pvc 名称相同,此处分别为 data-redis-0 和 data-redis-1。部署该文件来创建快照;

cat <<"EOF" > volume-Snapshot-redis.yaml
apiVersion: Snapshot.storage.Kubernetes.io/v1
kind: VolumeSnapshot
metadata:
  name: redis-0-Snapshot
spec:
  volumeSnapshotClassName: test-snapclass
  source:
    persistentVolumeClaimName: data-redis-0
---
apiVersion: Snapshot.storage.Kubernetes.io/v1
kind: VolumeSnapshot
metadata:
  name: redis-1-Snapshot
spec:
  volumeSnapshotClassName: test-snapclass
  source:
    persistentVolumeClaimName: data-redis-1
EOF

kubectl apply -f volume-Snapshot-redis.yaml

c.检查快照信息;

使用快照作为数据源创建 pvc,给下一步新创建的 StatefulSet 中的 Pod 使用:

cat <<"EOF" > volume-from-Snapshot.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-redis1-0
spec:
  storageClassName: ebs-sc
  dataSource:
    name: redis-0-Snapshot
    kind: VolumeSnapshot
    apiGroup: Snapshot.storage.Kubernetes.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-redis1-1
spec:
  storageClassName: ebs-sc
  dataSource:
    name: redis-1-Snapshot
    kind: VolumeSnapshot
    apiGroup: Snapshot.storage.Kubernetes.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
EOF

kubectl apply -f volume-from-Snapshot.yaml

部署新的 StatefulSet redis1,并检查状态:

确认 pv 对应的 EBS 卷已加密,并验证数据备份无误之后可以根据具体的配置情况将连接信息切到新的对象上。

如果确认所有流量都已转移到新的 Pod 上,即可删除原有的 StatefulSet 资源。

3.3 环境清除

删除集群中部署的资源,并删除 pvc 和 pv 对象:

kubectl delete -f sts.yml
kubectl delete -f rbac.yml
kubectl delete -f cm.yml

删除集群:

eksctl delete iamserviceaccount --cluster test-cluster --name ebs-csi-Controller-sa
eksctl delete nodegroup {your-node-group-name} --cluster test-cluster
eksctl delete cluster --name test-cluster

4.参考

Amazon EBS CSI 驱动程序 - Amazon EKS

Using EBS Snapshots for persistent storage with your EKS cluster | Containers

eksctl

5.小结

本文我们针对 Amazon EKS 上有状态服务的数据保护安全需求,介绍了结合 KMS 服务,在 Amazon EKS 中如何使用 StatefulSet, Snapshot Controller 的方式实现有状态服务的存储加密启用,该方式通过从底层存储解决数据加密存储及迁移,无需应用层介入数据迁移,从而简单有效解决了 Amazon EKS 上有状态服务的存储加密需求。

本篇作者

李锐 亚马逊云科技金融行业资深解决方案架构师,负责基于亚马逊的云计算方案架构咨询和设计,擅长安全领域。曾任职互联网公司,拥有多年金融云产品及架构设计经验。

孙彦巧 亚马逊云科技金融行业解决方案架构师,负责云计算解决方案的架构设计和咨询。有多年亚马逊云科技从业经验,热衷于容器、微服务架构及 Devops 方面的研究和应用。

阅读原文

文章来源:https://dev.amazoncloud.cn/column/article/631478a1323d8e18f89855fd?sc_medium=regulartraffic&amp;sc_campaign=crossplatform&amp;sc_channel=CSDN 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/529670.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于Alibaba开发手册中提到的Manager层解析(对于传统MVC三层架构的改进)

Manager层的理解 MVC三层架构 MVC&#xff08;Model View Controller&#xff09;是软件工程中的一种软件架构模式&#xff0c;它把软件系统分为模型、视图和控制器三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码&#xff0c;将业务逻辑聚集到一个部件里面…

scanf函数的用法

有时候刷题经常遇到如下这种输入&#xff1a; 1 2 3 4 ...... 就是不知道什么时候结束输入&#xff0c;反正就是一直在输入&#xff0c;这个时候怎么写呢&#xff1f;我们知道 scanf()的返回值是成功赋值的变量数量, 发生错误时返回EOF. 看如下代码&#xff1a; #include<st…

mysqlbinlog 生产环境问题排查实践

binlog 简介 MySQL 的二进制日志是通过二进制文件形式记录的&#xff0c;可以通过以下方式设置其格式&#xff1a; 打开 MySQL 配置文件&#xff08;my.cnf&#xff09;&#xff0c;找到 [mysqld] 段&#xff0c;添加以下语句以开启二进制日志功能&#xff1a; log-bin /pat…

Git 工作原理和分支管理

Git是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理 Git工作原理 Git 会把仓库中的每次提交串成一条时间线&#xff0c;这条时间线就是一个分支。在 Git 里&#xff0c;每个仓库都会有一个主分支&#xff0c;即master分支。HEAD…

2023面试自动化测试面试题【含答案】,建议收藏

1、你做了几年的测试、自动化测试&#xff0c;说一下 selenium 的原理是什么&#xff1f; 我做了五年的测试&#xff0c;1年的自动化测试&#xff1b; selenium 它是用 http 协议来连接 webdriver &#xff0c;客户端可以使用 Java 或者 Python 各种编程语言来实现&#xff1b…

路径规划算法:基于蜻蜓算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于蜻蜓优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于蜻蜓优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法蜻蜓…

MyBatis项目的创建和使用

什么是MyBatis? MyBaits是一个更简单的完成程序与数据库交互的工具。MyBatis将复杂的JDBC进行了封装&#xff0c;让使用者可以通过简单的xml和注解对数据库进行记录。 MyBatis的执行流程 创建MyBatis项目 添加依赖 还是SpringBoot的创建流程&#xff1a;SpringBoot项目创建…

SpringMvc笔记-教程-快速回忆

title: SpringMvc笔记 date: 2023-05-14 09:50:02 categories: 后端Java tags:JavaSpring 三层架构&#xff1a; web层主要由servlet来处理&#xff0c;负责页面请求和数据的收集以及响应结果给前端service层主要负责业务逻辑的处理dao层主要负责数据的增删改查操作 MVC设计…

点餐小程序实战教程03-店铺信息展示

目录 1 创建模型应用2 创建用户3 创建自定义应用4 创建页面5 页面搭建6 定义变量7 数据绑定8 绑定事件9 预览发布总结我们上一篇设计了店铺信息数据源,并且录入了测试数据,本篇我们就介绍一下店铺信息展示功能的开发。 1 创建模型应用 我们在上篇讲解的是通过数据源的管理数…

【redis】redis经典五大类型源码及其底层实现

【redis】redis经典五大类型源码及其底层实现 文章目录 【redis】redis经典五大类型源码及其底层实现前言一、面试题redis数据类型的底层数据结构阅读源码的意义 二、在哪找redis的源码&#xff1f;三、SRC下的源码该怎么看&#xff1f;1、redis基本的数据结构&#xff08;骨架…

路径规划算法:基于樽海鞘算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于樽海鞘优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于樽海鞘优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

桂院校园导航小程序 静态项目 二次开发教程 1.0.1

Gitee代码仓库&#xff1a;桂院校园导航小程序 GitHub代码仓库&#xff1a;GLU-Guide 先 假装 大伙都成功安装了静态项目&#xff0c;并能在 微信开发者工具 和 手机 上正确运行。 接着就是 将项目 改成自己的学校。 代码里的注释我就不说明了&#xff0c;有提到 我的学校 …

现代软件测试中的自动化测试工具

自动化测试的重要性和优势 引言&#xff1a;随着软件开发的不断发展&#xff0c;自动化测试工具在现代软件测试中扮演着重要角色。提高效率&#xff1a;自动化测试可以加快测试流程&#xff0c;减少人工测试所需的时间和资源。提升准确性&#xff1a;自动化测试工具可以减少人…

python3 爬虫相关学习3:requests.get(url)的各种属性

目录 1 requests.get(url) 的各种属性 1.1 response.text 1 requests.get(url) 的各种属性&#xff0c;也就是response的各种属性 接触的requests模块的常用功能&#xff1a;一般把 response requests.get(url) requests.get(url)的各种属性 print(response.text)print(…

Flink Watermark 源码分析

随着 flink 的快速发展与 API 的迭代导致新老版本差别巨大遂重拾 flink&#xff0c;在回顾到时间语义时对 watermark 有了不一样的理解。 一、如何生成 在 flink 1.12(第一次学习的版本)时 watermark 生成策略还有两种: punctuated 和 periodic&#xff0c;在 1.17 中 punctua…

基于自建靶场三层网络的内网渗透

注意&#xff1a;一切内容仅用于安全技术的分享&#xff0c;切勿用于其他用途&#xff0c;产生严重的后果与作者无关 前言介绍&#xff1a; 网络拓扑图&#xff1a; 为了方便起见&#xff0c;我在每个服务器放有webshell&#xff0c;这里主要是让我们熟悉sock代理的使用。 这…

修剪二叉搜索树

1题目 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&#xff0c;原有的父代子代关系都应当…

10 常见网站安全攻击手段及防御方法

在某种程度上&#xff0c;互联网上的每个网站都容易遭受安全攻击。从人为失误到网络罪犯团伙发起的复杂攻击均在威胁范围之内。 网络攻击者最主要的动机是求财。无论你运营的是电子商务项目还是简单的小型商业网站&#xff0c;潜在攻击的风险就在那里。 知己知彼百战不殆&…

【一起撸个深度学习框架】6 折与曲的相会——激活函数

CSDN个人主页&#xff1a;清风莫追欢迎关注本专栏&#xff1a;《一起撸个DL框架》GitHub获取源码&#xff1a;https://github.com/flying-forever/OurDLblibli视频合集&#xff1a;https://space.bilibili.com/3493285974772098/channel/series 文章目录 6 折与曲的相会——激活…

史蒂夫·青木主题的 Game Jam

准备好潜入史蒂夫青木的脑海中&#xff0c;创造一个探索他内心思想的游戏吧&#xff01;史蒂夫青木主题 Game Jam 正式推出&#xff0c;这是一场为期两周的游戏制作比赛&#xff0c;鼓励参赛者创造和史蒂夫青木内心世界有关的游戏。 探索这位传奇艺术家和 DJ 潜意识&#xff0c…