容器化应用程序经常需要访问外部 AWS 服务,例如RDS, ElastiCache。在 AWS 上,控制服务之间的网络访问通常是通过安全组 。
在发布此新功能之前,只能在节点级别分配安全组。由于节点组内的所有节点共享安全组,因此通过将访问 RDS 实例的安全组附加到节点组,这些节点上运行的所有 pod 都可以访问数据库,即使只有绿色 pod 应该具有访问权限。
Pod 的安全组 将EC2 安全组与 Kubernetes Pod 集成,可以使用EC2 安全组定义规则来控制进出 Pod 的入站和出站网络流量
本节内容:
SecurityGroupPolicy
,它自动将 POD_SG 安全组附加到具有正确元数据的 pod。大多数基于 Nitro 的 Amazon EC2 实例系列都支持 Pod 安全组,包括m5
、c5
、r5
、p3
、m6g
、c6g
和r6g
实例系列,但t3不支持。因此如果当前nodegroup是t3的话,需要使用Nitro实例创建第二个 NodeGroup:
mkdir ${HOME}/environment/sg-per-pod
cat << EoF > ${HOME}/environment/sg-per-pod/nodegroup-sec-group.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ${EKS_CLUSTER}
region: ${AWS_REGION}
managedNodeGroups:
- name: nodegroup-sec-group
desiredCapacity: 1
instanceType: m5.large
EoF
eksctl create nodegroup -f ${HOME}/environment/sg-per-pod/nodegroup-sec-group.yaml
kubectl get nodes \
--selector node.kubernetes.io/instance-type=m5.large
首先创建 RDS 安全组 (RDS_SG)。 Amazon RDS 实例将使用它来控制网络访问。
export VPC_ID=$(aws eks describe-cluster \
--name $EKS_CLUSTER \
--query "cluster.resourcesVpcConfig.vpcId" \
--output text)
# create RDS security group
aws ec2 create-security-group \
--description 'RDS SG' \
--group-name 'RDS_SG' \
--vpc-id ${VPC_ID}
# save the security group ID for future use
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)
echo "RDS security group ID: ${RDS_SG}"
创建 Pod 安全组 (POD_SG):
# create the POD security group
aws ec2 create-security-group \
--description 'POD SG' \
--group-name 'POD_SG' \
--vpc-id ${VPC_ID}
# save the security group ID for future use
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)
echo "POD security group ID: ${POD_SG}"
Pod 需要与其所在Node进行通信以进行 DNS 解析,因此我们将相应地更新 Node Group 安全组:
export NODE_GROUP_SG=$(aws ec2 describe-security-groups \
--filters Name=tag:Name,Values=eks-cluster-sg-${EKS_CLUSTER}-* Name=vpc-id,Values=${VPC_ID} \
--query "SecurityGroups[0].GroupId" \
--output text)
echo "Node Group security group ID: ${NODE_GROUP_SG}"
# allow POD_SG to connect to NODE_GROUP_SG using TCP 53
aws ec2 authorize-security-group-ingress \
--group-id ${NODE_GROUP_SG} \
--protocol tcp \
--port 53 \
--source-group ${POD_SG}
# allow POD_SG to connect to NODE_GROUP_SG using UDP 53
aws ec2 authorize-security-group-ingress \
--group-id ${NODE_GROUP_SG} \
--protocol udp \
--port 53 \
--source-group ${POD_SG}
最后,我们添加两个入站流量(ingress)规则到 RDS_SG 安全组:
# Cloud9 IP
export C9_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)
# allow Cloud9 to connect to RDS
aws ec2 authorize-security-group-ingress \
--group-id ${RDS_SG} \
--protocol tcp \
--port 5432 \
--cidr ${C9_IP}/32
# Allow POD_SG to connect to the RDS
aws ec2 authorize-security-group-ingress \
--group-id ${RDS_SG} \
--protocol tcp \
--port 5432 \
--source-group ${POD_SG}
现在安全组已准备就绪,现在创建RDS for PostgreSQL 数据库。
首先需要创建一个subnet group, 我们将使用与 EKS 集群相同的子网。
export PUBLIC_SUBNETS_ID=$(aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$VPC_ID" "Name=tag:Name,Values=eksctl-${EKS_CLUSTER}-cluster/SubnetPublic*" \
--query 'Subnets[*].SubnetId' \
--output json | jq -c .)
echo $PUBLIC_SUBNETS_ID
# create a db subnet group
aws rds create-db-subnet-group \
--db-subnet-group-name rds-eksworkshop \
--db-subnet-group-description rds-eksworkshop \
--subnet-ids ${PUBLIC_SUBNETS_ID}
创建数据库:
# get RDS SG 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)
# generate a password for RDS
export RDS_PASSWORD="$(date | md5sum |cut -f1 -d' ')"
echo ${RDS_PASSWORD} # 记下来这个密码
# create RDS Postgresql instance
aws rds create-db-instance \
--db-instance-identifier rds-eksworkshop \
--db-name eksworkshop \
--db-instance-class db.t3.micro \
--engine postgres \
--db-subnet-group-name rds-eksworkshop \
--vpc-security-group-ids $RDS_SG \
--master-username eksworkshop \
--publicly-accessible \
--master-user-password ${RDS_PASSWORD} \
--backup-retention-period 0 \
--allocated-storage 20
创建数据库最多需要 4 分钟,可以使用此命令验证它是否可用:
aws rds describe-db-instances \
--db-instance-identifier rds-eksworkshop \
--query "DBInstances[].DBInstanceStatus" \
--output text
等待数据库状态变成available
获取数据库端点:
# get RDS endpoint
export RDS_ENDPOINT=$(aws rds describe-db-instances \
--db-instance-identifier rds-eksworkshop \
--query 'DBInstances[0].Endpoint.Address' \
--output text)
echo "RDS endpoint: ${RDS_ENDPOINT}"
连接到数据库:
PGPASSWORD=${RDS_PASSWORD} psql -h ${RDS_ENDPOINT} -U eksworkshop -d eksworkshop
在数据库中创建一些内容:
CREATE TABLE welcome (column1 TEXT);
insert into welcome values ('--------------------------');
insert into welcome values ('Welcome to the eksworkshop');
insert into welcome values ('--------------------------');