1 ec2를 만든다. 명령서버에서 쿠버네티스를 만들어야 쿠버네티스 권한을 받게 된다. 그래서 명령서버를 받는다. eksctl도 , cloudformaion도 명령서버에서 쿠버네티스를 만들어야 쿠버네티스 권한을 받게 된다. gui로 쿠버네티스 만들고 권한 주는 법도 있으나 번거롭다. 2 # 클러스터를 만든다. # 클라우드 포메이션으로 만든다. # 프라이빗에 쿠버네티스 설치 Public Subnet 2개: pub-a, pub-b App Private Subnet 2개: app-a, app-b DB Private Subnet 2개: db-a, db-b NAT Gateway 2개 App Private Subnet에 EKS Cluster / NodeGroup 배치 DB Subnet은 격리 라우팅 테이블 유지 파라미터는 VpcCidr, NamePrefix만 사용 Node 타입은 요청 흐름대로 t3.small EKS 버전은 1.34 고정 ------------ # EC2 로그인 1 cat <<'EOF' > eks-full-match-vpc-params-private-ipfixed.yaml AWSTemplateFormatVersion: '2010-09-09' Description: "Full EKS (Private Node) + attached VPC subnet IP scheme (VpcCidr, NamePrefix only)" Parameters: VpcCidr: Type: String Default: 10.0.0.0/20 Description: "VPC CIDR block (example: 10.0.0.0/20)" NamePrefix: Type: String Default: ha-compact Description: "Resource name prefix" Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidr EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub "${NamePrefix}-vpc" IGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub "${NamePrefix}-igw" IGWAttach: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref IGW PublicSubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: !Select [0, !Cidr [!Ref VpcCidr, 16, 8]] AvailabilityZone: !Select [0, !GetAZs ""] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub "${NamePrefix}-pub-a" - Key: kubernetes.io/role/elb Value: '1' - Key: !Sub "kubernetes.io/cluster/${NamePrefix}-eks" Value: shared PublicSubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 16, 8]] AvailabilityZone: !Select [1, !GetAZs ""] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub "${NamePrefix}-pub-b" - Key: kubernetes.io/role/elb Value: '1' - Key: !Sub "kubernetes.io/cluster/${NamePrefix}-eks" Value: shared AppSubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 4, 10]] AvailabilityZone: !Select [0, !GetAZs ""] Tags: - Key: Name Value: !Sub "${NamePrefix}-app-a" - Key: kubernetes.io/role/internal-elb Value: '1' - Key: !Sub "kubernetes.io/cluster/${NamePrefix}-eks" Value: shared AppSubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: !Select [2, !Cidr [!Ref VpcCidr, 4, 10]] AvailabilityZone: !Select [1, !GetAZs ""] Tags: - Key: Name Value: !Sub "${NamePrefix}-app-b" - Key: kubernetes.io/role/internal-elb Value: '1' - Key: !Sub "kubernetes.io/cluster/${NamePrefix}-eks" Value: shared DBSubnetA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: !Select [12, !Cidr [!Ref VpcCidr, 16, 8]] AvailabilityZone: !Select [0, !GetAZs ""] Tags: - Key: Name Value: !Sub "${NamePrefix}-db-a" DBSubnetB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: !Select [13, !Cidr [!Ref VpcCidr, 16, 8]] AvailabilityZone: !Select [1, !GetAZs ""] Tags: - Key: Name Value: !Sub "${NamePrefix}-db-b" NatEipA: Type: AWS::EC2::EIP Properties: Domain: vpc NatEipB: Type: AWS::EC2::EIP Properties: Domain: vpc NatGwA: Type: AWS::EC2::NatGateway DependsOn: IGWAttach Properties: AllocationId: !GetAtt NatEipA.AllocationId SubnetId: !Ref PublicSubnetA Tags: - Key: Name Value: !Sub "${NamePrefix}-nat-a" NatGwB: Type: AWS::EC2::NatGateway DependsOn: IGWAttach Properties: AllocationId: !GetAtt NatEipB.AllocationId SubnetId: !Ref PublicSubnetB Tags: - Key: Name Value: !Sub "${NamePrefix}-nat-b" PublicRT: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${NamePrefix}-rt-public" PublicRoute: Type: AWS::EC2::Route DependsOn: IGWAttach Properties: RouteTableId: !Ref PublicRT DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref IGW PublicAssocA: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetA RouteTableId: !Ref PublicRT PublicAssocB: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnetB RouteTableId: !Ref PublicRT PrivateRTA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${NamePrefix}-rt-app-a" PrivateRouteA: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRTA DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGwA PrivateAssocAppA: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref AppSubnetA RouteTableId: !Ref PrivateRTA PrivateRTB: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${NamePrefix}-rt-app-b" PrivateRouteB: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRTB DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGwB PrivateAssocAppB: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref AppSubnetB RouteTableId: !Ref PrivateRTB DBRTA: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${NamePrefix}-rt-db-a" DBAssocA: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref DBSubnetA RouteTableId: !Ref DBRTA DBRTB: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${NamePrefix}-rt-db-b" DBAssocB: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref DBSubnetB RouteTableId: !Ref DBRTB ClusterRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: eks.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy Tags: - Key: Name Value: !Sub "${NamePrefix}-eks-cluster-role" NodeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy Tags: - Key: Name Value: !Sub "${NamePrefix}-eks-node-role" EKS: Type: AWS::EKS::Cluster DependsOn: - PublicAssocA - PublicAssocB - PrivateAssocAppA - PrivateAssocAppB - ClusterRole Properties: Name: !Sub "${NamePrefix}-eks" Version: "1.34" RoleArn: !GetAtt ClusterRole.Arn AccessConfig: AuthenticationMode: API_AND_CONFIG_MAP BootstrapClusterCreatorAdminPermissions: true ResourcesVpcConfig: SubnetIds: - !Ref PublicSubnetA - !Ref PublicSubnetB - !Ref AppSubnetA - !Ref AppSubnetB EndpointPublicAccess: true EndpointPrivateAccess: false KubernetesNetworkConfig: IpFamily: ipv4 Tags: - Key: Name Value: !Sub "${NamePrefix}-eks" NodeGroup: Type: AWS::EKS::Nodegroup DependsOn: - EKS - NodeRole Properties: ClusterName: !Ref EKS NodegroupName: !Sub "${NamePrefix}-ng-private" NodeRole: !GetAtt NodeRole.Arn AmiType: AL2023_x86_64_STANDARD CapacityType: ON_DEMAND InstanceTypes: - t3.small DiskSize: 20 ScalingConfig: MinSize: 1 DesiredSize: 2 MaxSize: 2 Subnets: - !Ref AppSubnetA - !Ref AppSubnetB Labels: nodegroup-role: private Tags: Name: !Sub "${NamePrefix}-ng-private" Outputs: ClusterName: Value: !Ref EKS VpcId: Value: !Ref VPC PublicSubnetAId: Value: !Ref PublicSubnetA PublicSubnetBId: Value: !Ref PublicSubnetB AppSubnetAId: Value: !Ref AppSubnetA AppSubnetBId: Value: !Ref AppSubnetB DBSubnetAId: Value: !Ref DBSubnetA DBSubnetBId: Value: !Ref DBSubnetB EOF --------------- 2 # pri 배포 aws cloudformation deploy \ --template-file eks-full-match-vpc-params-private-ipfixed.yaml \ --stack-name eks-infrastructure-stack \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides \ VpcCidr=10.0.0.0/20 \ NamePrefix=ha-compact3 \ --region ap-northeast-2 # 접속하기 aws eks update-kubeconfig \ --region ap-northeast-2 \ --name ha-compact3-eks aws sts get-caller-identity kubectl get nodes ---------------- 삭제 aws cloudformation delete-stack \ --stack-name eks-infrastructure-stack \ --region ap-northeast-2 -------------