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