AWS中为Kubernetes Pod配置安全组的完整指南

本指南详细介绍了如何在Amazon EKS中实现Pod级别的安全组控制,从集群创建到安全组策略配置,实现精细化的网络访问控制,提升容器安全性。

如何在AWS中创建Kubernetes集群并为Pod配置安全组[完整手册]

Amazon Elastic Kubernetes Service (EKS) Pod安全组是一项强大功能,可在Pod级别实现精细的网络安全控制。本指南将引导您实现此功能,从初始集群设置到测试Pod级别安全组分配。

传统EKS网络与Pod安全组架构

传统EKS网络

在标准EKS网络设置中,安全发生在节点级别而非Pod级别。使用传统模型创建EKS集群时,每个EC2工作节点都会分配一个安全组。该节点上运行的所有Pod都继承来自其宿主节点的相同安全组设置。

这种方法有显著限制。例如,如果一个Pod需要访问数据库而另一个Pod不应该访问,当两个Pod共享节点的安全组时,您无法强制执行此区分。

Pod安全组架构

这种网络模型完全改变了这种范式。启用Pod安全组后,您可以根据Pod的特定需求为其分配专用安全组。某些Pod可以获得自己的弹性网络接口(ENI)和自定义安全组分配,而不是所有Pod都继承节点的安全组。

ENI本质上是AWS中的虚拟网卡。当我们为Pod分配ENI时,该Pod获得与其运行节点分离的专用网络身份。

工作原理

Pod安全组的实现依赖于几个相互连接的机制协同工作。首先,当您通过SecurityGroupPolicy标记Pod进行特殊安全组处理时,系统会自动为该Pod配置专用ENI。

分支网络能力在此至关重要。EC2实例对它们可以支持的ENI数量有限制。VPC CNI插件使用这些额外的ENI插槽为需要自定义安全组的Pod创建分支接口。

基础设施基础

IAM角色和策略设置

EKS集群服务角色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 创建EKS集群服务角色
aws iam create-role \
  --role-name EKSClusterRole \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": "eks.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }
    ]
  }'

EKS集群附加角色策略

1
2
3
4
5
6
7
8
# 附加所需策略
aws iam attach-role-policy \
  --role-name EKSClusterRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy

aws iam attach-role-policy \
  --role-name EKSClusterRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController

EKS节点组角色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 创建节点组角色
aws iam create-role \
  --role-name EKSNodeGroupRole \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": "ec2.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }
    ]
  }'

VPC和网络基础设施

VPC创建和配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 创建VPC
export VPC_ID=$(aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --name 'eks-security-demo'
  --query 'Vpc.VpcId' \
  --output text)

# 创建Internet Gateway
export IGW_ID=$(aws ec2 create-internet-gateway \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)

# 将Internet Gateway附加到VPC
aws ec2 attach-internet-gateway \
  --internet-gateway-id $IGW_ID \
  --vpc-id $VPC_ID

子网架构策略

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 公共子网用于NAT网关和负载均衡器
export PUBLIC_SUBNET_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone eu-west-1a \
  --query 'Subnet.SubnetId' \
  --output text)

export PUBLIC_SUBNET_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone eu-west-1b \
  --query 'Subnet.SubnetId' \
  --output text)

# 私有子网用于工作节点和RDS
export PRIVATE_SUBNET_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.3.0/24 \
  --availability-zone eu-west-1a \
  --query 'Subnet.SubnetId' \
  --output text)

export PRIVATE_SUBNET_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.4.0/24 \
  --availability-zone eu-west-1b \
  --query 'Subnet.SubnetId' \
  --output text)

EKS集群配置

EKS集群创建

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
export CLUSTER_ROLE_ARN=$(aws iam get-role \
  --role-name EKSClusterRole \
  --query 'Role.Arn' \
  --output text)

# 创建EKS集群
aws eks create-cluster \
  --name pod-security-cluster-demo \
  --kubernetes-version 1.33 \
  --role-arn $CLUSTER_ROLE_ARN \
  --access-config authenticationMode=API_AND_CONFIG_MAP \
  --resources-vpc-config subnetIds=$PUBLIC_SUBNET_1,$PUBLIC_SUBNET_2,$PRIVATE_SUBNET_1,$PRIVATE_SUBNET_2

# 等待集群激活
aws eks wait cluster-active --name pod-security-cluster-demo

托管节点组设置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 获取节点组角色的ARN
export NODE_ROLE_ARN=$(aws iam get-role \
  --role-name EKSNodeGroupRole \
  --query 'Role.Arn' \
  --output text)

# 创建托管节点组
aws eks create-nodegroup \
  --cluster-name pod-security-cluster-demo \
  --nodegroup-name workers \
  --subnets $PRIVATE_SUBNET_1 $PRIVATE_SUBNET_2 \
  --node-role $NODE_ROLE_ARN \
  --instance-types m5.large \
  --scaling-config minSize=1,maxSize=3,desiredSize=2 \
  --disk-size 20 \
  --capacity-type ON_DEMAND

安全组配置

Pod级别安全组创建

1
2
3
4
5
6
7
8
9
# 为需要数据库访问的Pod创建安全组
aws ec2 create-security-group \
   --description 'Pod Security Group - Database Access' \
   --group-name 'POD_SG' \
   --vpc-id ${VPC_ID}

export POD_SG=$(aws ec2 describe-security-groups \
   --filters Name=group-name,Values=POD_SG Name=vpc-id,Values=${VPC_ID} \
   --query "SecurityGroups[0].GroupId" --output text)

数据库安全组配置

1
2
3
4
5
6
7
8
9
# 为RDS数据库创建安全组
aws ec2 create-security-group \
   --description 'RDS Security Group - PostgreSQL Database' \
   --group-name 'RDS_SG' \
   --vpc-id ${VPC_ID}

export RDS_SG=$(aws ec2 describe-security-groups \
   --filters Name=group-name,Values=RDS_SG Name=vpc-id,Values=${VPC_ID} \
   --query "SecurityGroups[0].GroupId" --output text)

CNI插件配置

启用Pod ENI支持

1
2
3
4
5
6
# 在AWS VPC CNI上启用Pod ENI功能
kubectl -n kube-system set env daemonset aws-node ENABLE_POD_ENI=true

# 重启CNI Pod以应用配置
kubectl -n kube-system rollout restart daemonset aws-node
kubectl -n kube-system rollout status daemonset aws-node

安全策略实施

SecurityGroupPolicy资源创建

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: allow-rds-access
  namespace: networking
spec:
  podSelector:
    matchLabels:
      app: green-pod
  securityGroups:
    groupIds:
      - ${POD_SG}

测试和验证

绿色Pod(授权数据库访问)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: apps/v1
kind: Deployment
metadata:
  name: green-pod
  namespace: networking
  labels:
    app: green-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: green-pod
  template:
    metadata:
      labels:
        app: green-pod
    spec:
      containers:
      - name: postgres-client
        image: postgres:13-alpine
        env:
        - name: PGHOST
          valueFrom:
            secretKeyRef:
              name: rds
              key: host
        - name: PGPASSWORD
          valueFrom:
            secretKeyRef:
              name: rds
              key: password
        command: ["/bin/sh"]
        args:
        - -c
        - |
          echo "Green pod starting - should have database access..."
          if psql -c "SELECT version();" 2>/dev/null; then
            echo "SUCCESS: Connected to PostgreSQL!"
          else
            echo "ERROR: Could not connect to database"
          fi
          sleep 3600

红色Pod(未授权数据库访问)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: apps/v1
kind: Deployment
metadata:
  name: red-pod
  namespace: networking
  labels:
    app: red-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: red-pod
  template:
    metadata:
      labels:
        app: red-pod
    spec:
      containers:
      - name: postgres-client
        image: postgres:13-alpine
        env:
        - name: PGHOST
          valueFrom:
            secretKeyRef:
              name: rds
              key: host
        - name: PGPASSWORD
          valueFrom:
            secretKeyRef:
              name: rds
              key: password
        command: ["/bin/sh"]
        args:
        - -c
        - |
          echo "Red pod starting - should NOT have database access..."
          if psql -c "SELECT version();" 2>/dev/null; then
            echo "UNEXPECTED: Connected to database!"
          else
            echo "EXPECTED: Could not connect to database"
          fi
          sleep 3600

清理和维护

Kubernetes资源清理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 删除应用部署
kubectl delete -f green-pod.yaml
kubectl delete -f red-pod.yaml

# 删除安全组策略
kubectl delete -f sg-per-pod-policy.yaml

# 删除命名空间
kubectl delete namespace networking

# 禁用Pod ENI功能
kubectl -n kube-system set env daemonset aws-node ENABLE_POD_ENI=false

EKS集群删除

1
2
3
4
5
6
7
# 首先删除托管节点组
aws eks delete-nodegroup \
  --cluster-name pod-security-cluster-demo \
  --nodegroup-name workers

# 删除EKS集群
aws eks delete-cluster --name pod-security-cluster-demo

本综合指南演示了如何在Amazon EKS中实现Pod安全组,在Pod级别提供精细的网络安全控制。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计