阿里云ACK跨集群访问控制:固定Pod IP与LB配置方案

背景

以下方案以UAT环境为例:

为符合安全审计要求,需要对阿里云项目中的ACK集群进行严格的访问控制,具体要求如下:

  1. 生产环境的应用仅能访问生产环境的数据库。

  2. UAT环境的应用仅能访问UAT环境的数据库。

方案及步骤

方案概述

在阿里云环境中,应用(app)和数据库(db)分别部署在两个不同的ACK集群。app集群的生产环境和UAT环境位于同一子网,并且每个Pod都有独立的IP地址,且出集群时不通过节点IP。

当前应用通过db集群的Service(svc)地址连接数据库,实质上是通过负载均衡(LB)进行通信。为了增强安全性,我们计划通过在LB上配置ACL白名单来限制连接源。但是,由于app集群的生产环境和UAT环境处于同一子网,无法通过网段来配置ACL,因此需要采用固定Pod IP地址来进行访问控制。

方案步骤

1. 固定Pod IP地址:

a) 启用ACK Trunk ENI功能,并创建PodNetworking CRD,以固定StatefulSet类型Pod的IP地址。

b) 由于目前的应用是Deployment类型,而不是StatefulSet,因此需要将Deployment类型的Pod动态转换为StatefulSet类型,以便为Pod提供固定IP。

**2.**避免集群内走IPVS表:

a) 在集群内部,默认情况下,使用LB访问时流量会经过ipvs表,这样会导致LB ACL在同集群内无法控制。如果希望流量不经过内部的ipvs表,而是通过集群外部进行负载均衡,必须为Service添加注解,指定外部负载均衡的hostname。通过以下注解,可以确保流量通过集群外部的负载均衡,而不是走集群内部的ipvs表:

复制代码
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname: "${your_service_hostname}"

b) 作用:该注解指定了负载均衡器的外部域名,使流量可以绕过集群内部的ipvs表,直接通过外部负载均衡器进行路由。

**3.**ACL白名单控制:

a) 由于生产和UAT环境在同一子网,无法通过子网网段进行ACL控制。解决方法是通过固定Pod的IP地址,并在LB上配置ACL白名单,只允许特定IP地址(即固定的Pod IP)访问数据库,从而提高安全性。

固定Pod IP地址

查看已有集群是否支持使用Trunk ENI功能

  • 对于ACK专有集群,无需执行此步骤。但是需要额外申请Trunk实例使用权限。请向ECS提交工单申请即可使用Trunk ENI功能。

  • 对于存量ACK托管集群或是由ACK专有集群迁移过来的ACK托管集群,需要查看集群是否支持使用Trunk ENI功能,并修改配置。无需额外申请Trunk实例使用权限。

执行以下命令,检查token配置:

复制代码
kubectl get secret -nkube-system addon.network.token

预期输出如下所示:

|---------------------|--------|------|-----|
| NAME | TYPE | DATA | AGE |
| addon.network.token | Opaque | 1 | 69m |

如果存在token配置,则执行下一步;如果不存在token配置,表明该集群不支持使用Trunk ENI功能,请新建集群支持Trunk ENI功能。

开启terway-eniip并为集群启用Trunk ENI功能

  1. 登录容器服务管理控制台,在左侧导航栏选择集群。

  2. 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择运维管理 > 组件管理。

  3. 在组件管理页面,单击网络页签,找到terway-eniip组件。

  4. 在terway-eniip卡片,单击升级,升级terway-eniip组件到最新版本。

如果卡片上没有升级字样,说明当前组件已经是最新版本,请跳过此步骤。

1.开启terway-enniip。

执行如下命令,编辑eni-config:

复制代码
kubectl edit cm -nkube-system eni-config

编辑YAML文件的eni-config参数:

|---------------------|-------------------------|----------------------------------|
| 参数 | 值 | 说明 |
| enable_eni_trunking | true | 启用Trunk ENI功能。开启后不可关闭。 |
| credential_path | /var/addon/token-config | 对于ACK托管集群,如果YAML文件中不存在该参数,请自行添加。 |

  • 请勿修改其他参数。

  • eni-config内容需要为合法JSON格式。

配置参数示例如下:

复制代码
apiVersion: v1data:  eni_conf: |    {      "min_pool_size": 0,      "enable_eni_trunking": true,      "credential_path": "/var/addon/token-config",      ...    }kind: ConfigMap

执行如下命令,重启terway pods,使配置生效:

复制代码
kubectl delete pod -n kube-system -l app=terway-eniip
  1. 请在terway-eniip参数配置完成后,在组件管理页面的网络页签,安装terway-controlplane组件。安装结束后,在terway-controlplane卡片上可以看到已安装字样。

创建网络自定义资源PodNetworking

Terway增加一种名为PodNetworking的自定义资源来描述网络配置。您可以创建多个PodNetworking来规划不同的网络平面。

  1. 登录容器服务管理控制台,在左侧导航栏选择集群。

  2. 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 自定义资源。

  3. 在自定义资源页面,单击使用YAML创建资源。

创建PodNetworking的示例如下:

复制代码
apiVersion: network.alibabacloud.com/v1beta1kind: PodNetworkingmetadata:  name: podnetworking-185spec:  allocationType:    type: Fixed # Pod IP分配的策略,可以取值为Elastic或Fixed。    releaseStrategy: Never # 只有将type配置为Fixed时,releaseStrategy参数才有效;type的配置为Elastic时,无需配置releaseStrategy和releaseAfter参数。    releaseAfter: "1h" # 在releaseStrategy为TTL模式下,releaseAfter参数才有效。  selector:    namespaceSelector:      matchLabels:        appname: "185"status:  status: Ready 

为命名空间添加匹配标签

在部署PodNetworking自定义资源后,需要为指定命名空间增加匹配的标签,确保与PodNetworking的规则相匹配。

复制代码
kubectl label ns abc-185-7db8e  appname="185" 

手动改造deployment创建应用Pod

当创建Pod时,Pod将根据标签与PodNetworking资源进行匹配。如果Pod没有匹配到任何PodNetworking资源,它将默认使用ENI提供的IP。如果有匹配的PodNetworking,Pod将按照该资源定义的配置来分配ENI。

复制代码
apiVersion: apps/v1kind: StatefulSetmetadata:  labels:    log_temp_id: rowBased    projectkey: abc-ba7b5  name: abc-ba7b5  namespace: abc-185-7db8espec:  replicas: 2  revisionHistoryLimit: 10  selector:    matchLabels:      log_temp_id: rowBased      projectkey: abc-ba7b5  template:    metadata:      labels:        log_temp_id: rowBased        projectkey: abc-ba7b5    spec:      affinity:        nodeAffinity:          requiredDuringSchedulingIgnoredDuringExecution:            nodeSelectorTerms:            - matchExpressions:              - key: kubernetes.io/os                operator: In                values:                - linux              - key: nodeGroup                operator: In                values:                - share-pod-uat-49db4      containers:      - env:        - name: CCE_ENV          value: uat        image: cmp-registry.abc.com.cn/library/abc-ba7b5:v10        imagePullPolicy: IfNotPresent        name: abc-ba7b5        resources:          limits:            cpu: "2"            memory: 4Gi          requests:            cpu: 200m            memory: 409Mi        terminationMessagePath: /dev/termination-log        terminationMessagePolicy: File      dnsPolicy: ClusterFirst      restartPolicy: Always      schedulerName: default-scheduler      securityContext: {}      terminationGracePeriodSeconds: 30

改造后将deployment副本改为0:

复制代码
kubectl -n abc-185-7db8e scale deployment abc-ba7b5 --replicas 0

避免集群内走IPVS表

在集群内部,默认情况下,使用LB访问时流量会经过ipvs表,这样会导致LB ACL在同集群内无法控制。如果希望流量不经过内部的ipvs表,而是通过集群外部进行负载均衡,必须为Service添加注解,指定外部负载均衡的hostname。

如下图:如果不添加注解则会出现如下情况

复制代码
kubectl -n abc-185-7db8e edit svc abc-185-mysql-svcapiVersion: v1kind: Servicemetadata:  annotations:    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-hostname: abc-185-mysql-svc...

kubectl -n abc-185-7db8e get svc abc-185-mysql-svckubectl -n abc-185-7db8e describe svc abc-185-mysql-svc

加上此注解后,在k8s层面看不到LB IP地址了,需要通过lb id在阿里云控制台进行查看

ACL白名单控制

由于生产和UAT环境在同一子网,无法通过子网网段进行ACL控制。解决方法是通过固定Pod的IP地址,并在LB上配置ACL白名单,只允许特定IP地址(即固定的Pod IP)访问数据库,从而提高安全性。

查看uat环境app pod ip

设置访问控制策略组

设置访问控制白名单

扩展

同集群内LB ACL不生效,我们是通过在LB添加注解方式实现,如果要真正限制住db集群的pod访问,可以通过k8s networkpolicy实现。这样不仅限制住LB的访问,pod的访问也被限制住。

启用ACK集群网络策略

前提条件:已创建ACK托管集群或ACK专有集群,且集群网络插件为Terway。

  1. 登录容器服务管理控制台,在左侧导航栏选择集群。

  2. 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择运维管理 > 组件管理。

  3. 单击网络页签,定位terway-eniip组件并单击右下角的配置,勾选启用 NetworkPolicy,然后单击确定。

对没有启用DataPath V2的集群,开启NetwokPolicy功能对已有节点不能立即生效,您需要重启节点才能生效。

通过网络策略限制指定IP列表可以访问特定标签下namespace的所有pod

这条策略和LB ACL的白名单保持一致

复制代码
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: allow-specific-ip-only  namespace: abc-185-7db8e  # 目标命名空间spec:  policyTypes:    - Ingress  ingress:    - from:        - ipBlock:            cidr: 10.X.X.14/32        - ipBlock:            cidr: 10.X.X.15/32        - ipBlock:            cidr: 10.X.X.16/32  podSelector: {}  # 选择该命名空间下所有的 Pod 

下面这条策略是拒绝所有浏览访问,可以用来debug:

复制代码
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: default-deny-all  namespace: abc-185-7db8espec:  podSelector: {}  # 选择命名空间中的所有 Pod  policyTypes:- Ingress

参考资料

为Pod配置固定IP及独立虚拟交换机、安全组

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/configure-a-static-ip-address-a-separate-vswitch-and-a-separate-security-group-for-each-pod?spm=5176.28426678.J_HeJR_wZokYt378dwP-lLl.1.5d015181XM6aHU\&scm=20140722.S_help@@文档@@443632.S_BB2@bl+RQW@ag0+BB1@ag0+os0.ID_443632-RL_为pod配置固定ip-LOC_search\~UND\~helpdoc\~UND\~item-OR_ser-V_4-P0_0 #8433b7ada0byo

通过Annotation配置传统型负载均衡CLB

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/add-annotations-to-the-yaml-file-of-a-service-to-configure-clb-instances

一次网络不通"争吵"引发的思考

https://www.cnblogs.com/alisystemsoftware/p/17637749.html

CLB访问控制

https://help.aliyun.com/zh/slb/classic-load-balancer/user-guide/overview-3?spm=a2c4g.11174283.0.0.6d02de53td6uwK

在ACK集群使用网络策略

https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/use-network-policies?spm=a2c4g.11186623.0.0.2dd51109Ol3fEO #585e3173083do

相关推荐
聪明的笨猪猪12 小时前
企业知识库AI架构选型:落地导向的架构决策与组件清单
经验分享·面试·架构·embedding·数据库架构
Go Work13 小时前
两个等值条件摆着,MySQL 偏要全表扫
经验分享·笔记
深圳智根网络程序开发18 小时前
WordPress固定链接怎么设?改不对谷歌收录直接崩
经验分享
德思特18 小时前
如何提升 5G 移动性切换验证效率?德思特 Amarisoft Callbox 新增 NR SA LTM 测试功能详解
经验分享·无线通信·车载通信
虹科数字化与AR21 小时前
农业机械AR质检ROI怎么算?从搬运、测量、返工和交付成本入手
经验分享·ar·质检·农业机械
聪明的笨猪猪1 天前
Java 工程案例:AI 生成 @Async 异步线程池踩坑
java·经验分享·面试·ai编程
仓库日记2 天前
Excel进销存何时该换?用3项检查判断是否需要软件
经验分享·excel·进销存·开单软件
AI工具挖掘机2 天前
开源!2个Skill复刻带货视频、图文和Live,做百号矩阵
经验分享
虹科网络安全2 天前
Redis Radar:在统一视图中掌握 Redis 部署、健康与容量
经验分享·redis·艾体宝·艾体宝it·艾体宝redis
聪明的笨猪猪2 天前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程