EKS
EKS는 Elastic Kubernetes Service 의 약자로 Amazon에서 만든 관리형 Kubernetes 서비스 입니다. EKS를 사용하면 Kubernetes 설치부터 운영까지 맡아서 하지 않아도 되기 때문에 쉽게 Kubernetes를 이용할 수 있습니다. 다만 AWS의 ELB, VPC 등 EKS를 실행하기 위해 여러 서비스가 활용되기 때문에 AWS를 처음 사용하는 분들에게는 다소 어렵게 느껴질 수 있습니다. 그럼에도 불구하고 직접 Kubernetes Cluster를 구성하고 관리하는 것보다는 쉽게 Kubernetes를 사용할 수 있습니다.

Kubernetes 클러스터를 구성하는 머신을 node라고합니다. Kubernetes 클러스터의 node는 물리적이거나 가상 일 수 있습니다. Control Plain을 구성하는 Control-plane-node type은 클러스터의 ‘브레인’역할을 합니다. Data Plain을 구성하는 Worker-node type은 pod를 통해 실제 컨테이너 이미지를 실행합니다.
EKS 작업 환경 구성
AWS 계정 생성
k8s를 관리하기 위한 관리자 권한을 가진 IAM 사용자를 생성합니다. ( AdministratorAccess policy 적용) 이하 작업부터는 새로 생성한 IAM 계정으로 작업을 진행합니다.
IAM – Users – Add user

Next: Permissions – Attach existing policies directly – AdministratorAccess 검색

Next: Tags -> Next: Review -> Create user
Role 생성
workspace용 role 생성
IAM – Roles – CreateRole

Next: Permissions – AdministratorAccess 검색

Next: Tags -> Next: Review -> Role name 작성후 Create Role

kubernetes cluster용 role 생성
Workspace용 Role 생성과 동일하게 진행합니다. IAM – Roles – CreateRole – EKS – EKS – Cluster 선택후 Permission은 AmazonEKSClusterPolicy, AmazonEKSServicePolicy 선택하여 Role을 생성합니다.
워크 스페이스 생성
EKS cluster에 연결하여 kubernetes에 작업 명령을 내리기 위한 장비(EC2 인스턴스)를 생성합니다.
인스턴스 생성
- EC2 – Launch instance – Amazon Linux 2 AMI – 64-bit (x86) 선택
- Instance Type 선택 – 적당한 사양 선택 후 Next
- Configure Instance Details
- Network: EKS cluster를 생성할 VPC 선택
- Subnet: EKS cluster를 생성할 Subnet 선택
- IAM role: 위에서 생성한 workspace용 role 적용
- Review and Launch
- Launch클릭 – Choose an existing key pair – pem 파일 선택 – 체크박스 체크 후 – Launch Instances
인스턴스 접속
$ ssh -i pem파일 ec2-user@EC2장비PublicIP
k8s 운영 환경 구성
workspace 인스턴스에 터미널로 접속하여 아래 내용을 진행합니다.
aws configure
위에서 생성한 IAM 계정의 credential을 설정합니다.
$ aws configure AWS Access Key ID [None]: IAM AccessKey ID AWS Secret Access Key [None]: IAM Secret Access Key Default region name [ap-southeast-1]: 작업하는 Region Default output format [None]: json
K8S 도구 설치
// kubectl 설정을 저장하기 위한 기본 ~/.kube 디렉터리 생성 $ mkdir -p ~/.kube // kubectl 설치 $ curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" $ chmod +x ./kubectl $ sudo mv ./kubectl /usr/local/bin/kubectl // kubectl 명령어 동작 확인 $ kubectl version --short --client Client Version: v1.19.2 // eksctl 설치 $ curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp $ sudo mv -v /tmp/eksctl /usr/local/bin // eksctl 명령어 동작 확인 $ eksctl version // helm 설치 $ wget https://get.helm.sh/helm-v3.3.1-linux-amd64.tar.gz $ tar -zxvf helm-v3.3.1-linux-amd64.tar.gz $ sudo mv linux-amd64/helm /usr/local/bin/helm $ helm repo add eks https://aws.github.io/eks-charts $ helm repo list | grep eks-charts // JQ 설치 $ sudo yum -y install jq
현재 Region을 기준으로 aws-cli 구성
$ export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region')
echo "export AWS_REGION=${AWS_REGION}" >> ~/.bash_profile
aws configure set default.region ${AWS_REGION}
aws configure get default.region
EKS Worker node에 적용할 Role 생성
role 내용이 많으므로 script 및 명령어로 직접 생성합니다. 본문 내용중 arn:aws:iam::IAM계정번호을 수정 후 실행해야 합니다.
$ cat > eksWorkerNodeRole.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
$ aws iam create-role --role-name eksWorkerNodeRole --assume-role-policy-document file://eksWorkerNodeRole.json
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess
$ cat > EKSAutoscailerPolicy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"ec2:DescribeLaunchTemplateVersions"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
EOF
$ aws iam create-policy --policy-name EKSAutoscailerPolicy --policy-document file://EKSAutoscailerPolicy.json
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::IAM계정번호:policy/EKSAutoscailerPolicy
$ cat > ALBIngressControllerIAMPolicy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:GetCertificate"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DeleteSecurityGroup",
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInternetGateways",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVpcs",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateRule",
"elasticloadbalancing:CreateTargetGroup",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteRule",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:DescribeListenerCertificates",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:ModifyRule",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:SetWebAcl"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:GetServerCertificate",
"iam:ListServerCertificates"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cognito-idp:DescribeUserPoolClient"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"waf-regional:GetWebACLForResource",
"waf-regional:GetWebACL",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"tag:GetResources",
"tag:TagResources"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"waf:GetWebACL"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"wafv2:GetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:AssociateWebACL",
"wafv2:DisassociateWebACL"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"shield:DescribeProtection",
"shield:GetSubscriptionState",
"shield:DeleteProtection",
"shield:CreateProtection",
"shield:DescribeSubscription",
"shield:ListProtections"
],
"Resource": "*"
}
]
}
EOF
$ aws iam create-policy --policy-name ALBIngressControllerIAMPolicy --policy-document file://ALBIngressControllerIAMPolicy.json
aws iam attach-role-policy --role-name eksWorkerNodeRole --policy-arn arn:aws:iam::IAM계정번호:policy/ALBIngressControllerIAMPolicy
K8S Cluster 생성
터미널에서 eksctl 명령어를 이용하거나 aws console을 통하여 k8s cluster를 생성할 수 있습니다.
eksctl을 이용하여 eks cluster 생성
참고
- https://eksctl.io/usage/creating-and-managing-clusters
- https://github.com/weaveworks/eksctl/tree/master/examples
$ eksctl create cluster \ --name eks-cluster-demo-mesh \ --nodes-min 2 \ --nodes-max 3 \ --nodes 2 \ --node-ami=t3.medium \ --region=ap-southeast-1 \ --vpc-private-subnets=subnet-01887582564722d0b,subnet-0cf77158921f1e7a2,subnet-0cf77158921f1e7a2 \ --vpc-public-subnets=subnet-9ac904fc,subnet-5d53a115,subnet-a0f74ff9 \ --auto-kubeconfig \ --full-ecr-access \ --appmesh-access
aws eks console로 eks cluster 생성
Create Cluster
- Name : cluster 이름
- Cluster Service Role : 위에서 생성한 k8s cluster용 role 선택
- vpc, subnes : default 또는 eks용으로 생성한 vpc, subnet 선택
- 생성 시간은 약 15분 소요
K8S Cluster Node Group 생성
- AWS EKS는 Worker Node와 Node Group이라는 것으로 이루어져 있습니다. Worker Node는 실질적인 Pod가 띄워질 인스턴스이고 이 인스턴스들을 그룹으로 묶는 개념이 Node Group입니다.
- Master Node는 AWS가 직접 관리해주고 Worker Node를 프로비저닝하여 사용자가 직접 관리할 수 있도록 Node Group을 통해 Worker Node 머신(EC2)를 생성 합니다.
K8s Cluster 상세 화면 Compute 탭에서 Add Node Group을 클릭합니다.
- name: Node group명 / Node IAM Role : 위에서 생성한 eksWorkerNodeRole을 선택 후 Next
- instanceType: worker node instance 사양을 선택한다.
- Node Group scaling configuration – min/max/desire를 적당한 값으로 세팅 후 Next
- Subnets : default 또는 eks용으로 생성한 vpc, subnet 선택
- Allow remote access to nodes
- 노드에 대한 보안 원격 접속을 허용하려면 ON
- SSH Key pair : 노드 접속을 위한 SSH key pair(pem)을 선택.
- Allow remote access from : 노드에 원격으로 액세스 할 수있는 소스 IP 범위를 설정 후 Next
- 설정 내용 확인 후 Create
워크스페이스 kubeconfig 설정 업데이트
생성한 eks cluster를 사용할 수 있도록 kubeconfig 설정을 업데이트 합니다. 설정이 정상적으로 업데이트 되면 이후부터는 kubernetes cluster에 명령을 내려 작업을 진행할 수 있습니다.
$ aws eks --region ap-southeast-1 update-kubeconfig --name 클러스터명 // 확인 $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 13m














