Study/Cloud

[AWS]EKS 샘플 애플리케이션 배포

seomj 2023. 10. 29. 14:09

현재 프로젝트를 진행하며 EKS 위에서 Node에 배포를 진행하고 있다. 그 과정에서 PoC로 진행한 샘플 애플리케이션 배포에 대해 기록한다.


앞서 EKS를 구축했다.

 

[AWS]EKS 개념 및 구축

현재 프로젝트를 진행하며 EKS 위에서 Node에 배포를 진행하고 있다. 그 과정에서 학습했던 EKS에 대해 정리하고자 한다. Amazon EKS 컨트롤 플레인을 직접 구성하지 않고서 k8s를 손쉽게 사용할 수 있

seomj74.tistory.com

 

이처럼 구축된 EKS 위에 샘플 애플리케이션을 배포해보는 실습을 진행한다.

 

샘플 애플리케이션을 배포하는 실습 순서

  1. 필요한 도구 설치 - kubectl, aws-cli, eksctl, helm 등
  2. kubeconfig 설정
  3. AWS LBC 설치 및 배포
  4. NS 생성
  5. service, deploy 배포

 

필요한 도구 설치

해당 실습에서 설치되는 도구는 총 4가지이다.

kubectl, aws-cli, eksctl, helm

 

kubectl install

curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.4/2023-08-16/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl

$ kubectl version --client
Client Version: v1.28.2
...

curl을 통해 다운받아 실행하여 설치를 진행한다.

 

aws-cli install

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

$ aws --version
aws-cli/2.13.21 Python/3.11.5 Linux/5.15.0-1036-aws exe/x86_64.ubuntu.20 prompt/off

unzip이 간혹 없는 경우가 있는데, 이때 unzip만 설치하고 진행하면 정상 작동된다.

 

aws-cli의 경우 "apt install awscli"로 설치했다가 버전 문제로 고생한 경험이 있어 그 이후로는 curl로만 설치해서 사용한다.

 

eksctl install

$ ARCH=amd64
$ PLATFORM=$(uname -s)_$ARCH
$ curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
$ tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
$ sudo mv /tmp/eksctl /usr/local/bin

$ eksctl version
0.160.0

 

 

helm install

$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11715  100 11715    0     0  47048      0 --:--:-- --:--:-- --:--:-- 47048
$ chmod 700 get_helm.sh
$ ./get_helm.sh
Downloading https://get.helm.sh/helm-v3.12.3-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm

$ helm version --short | cut -d + -f 1
v3.12.3

 

 

kubeconfig 설정

aws에 존재하는 eks에 배포를 하기 위해서는 해당 eks의 정보를 가지고 있어야 한다. 이는 kubeconfig 파일을 통해 할 수 있다.

kubeconfig를 가져오기 전에 aws configure 설정이 필요하다.

$ aws configure
AWS Access Key ID [None]: asdf
AWS Secret Access Key [None]: asdf
Default region name [None]: ap-northeast-2
Default output format [None]:

각 항목에 알맞게 입력을 해주면 된다. output의 경우 비워둬도 되고 default 값인 json으로 입력해도 된다.

 

해당 항목들은 ~/.aws/ 디렉토리에서 확인할 수 있다.

$ ls ~/.aws/
config  credentials

$ cat ~/.aws/config 
[default]
region = ap-northeast-2
output = json 

$ cat ~/.aws/credentials 
[default]
aws_access_key_id = asdf
aws_secret_access_key = asdf

해당 파일을 직접 작성해줘도 적용이 된다.

 

이제 kubeconfig를 업데이트시켜 적용하자.

$ aws eks update-kubeconfig --region ap-northeast-2 --name seomj-eks
Updated context arn:aws:eks:ap-northeast-2:<account ID>:cluster/seomj-eks in /home/ubuntu/.kube/config

 

 

AWS LBC 설치 및 배포

node에 배포한 애플리케이션에 접근하기 위해 AWS Load Balancer Controller가 필요하다.

AWS Load Balancer Controller를 통해 NLB와 ALB를 구성할 수 있다.

이에 대한 개념 및 내용은 추후 따로 포스팅할 예정이다.

 

우선 여기서 제공하는 배포에서 ALB까지 필요성을 느끼지 못하여 NLB로 구성했다.

NLB(Network Load Balancer)를 구성하기 위해 AWS Load Balancer Controller를 설치하고, Load Balancer type service로 배포했다.

 

IAM 정책을 다운받는다.

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/install/iam_policy.json

AWS GovCloud(미국 동부, 서부) 리전은 '/iam_policy_us-gov.json'으로 다운받아야 한다.

 

이를 토대로 정책을 생성하자.

aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://iam_policy.json

policy name은 변경 가능하다.

 

클러스터에 OIDC 공급자를 등록하고 IAM에 이를 연결하여 kubernetes 클러스터에서 IAM 역할을 통해 AWS자원에 액세스할 수 있도록 하는 작업을 수행한다.

eksctl utils associate-iam-oidc-provider --region=ap-northeast-2 --cluster=seomj-eks --approve

*OIDC란?

더보기

3세대 OpenID 기술인 OpenID Connect

(Open ID: 개방형 표준 및 분산 인증 프로토콜, 인증)

표준화된 방식으로 인증 및 사용자 ID 관리를 가능하게 하는 서비스

웹 애플리케이션 및 API 보안에 사용된다.

OAuth 2.0 위에서 동작하는 얇은 ID 계층

 

참고: https://hudi.blog/open-id/

 

OpenID(OIDC) 개념과 동작원리

등장배경 이전에는 사용자 데이터를 서비스에서 직접 관리하는 경우가 대다수였다. 하지만 해킹, 피싱등으로 인한 개인정보 유출 사건이 끊임없이 발생하자, 서비스에서 직접 사용자 데이터를

hudi.blog

 

AWS Load Balancer Controller를 위한 SA를 생성한다.

해당 SA가 사용할 IAM Role을 생성하며 필요한 정책을 연결하는 작업을 수행한다.

eksctl create iamserviceaccount \
  --cluster=seomj-eks \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::<account ID>:policy/AWSLoadBalancerControllerIAMPolicy \
  --approve

Role과 Policy의 name은 변경 가능하다.

 

이제 helm을 통해서 LBC를 설치해보자.

$ helm repo add eks https://aws.github.io/eks-charts
"eks" has been added to your repositories
$ helm repo update eks
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "eks" chart repository
Update Complete. ⎈Happy Helming!⎈

$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=seomj-eks \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller 
NAME: aws-load-balancer-controller
LAST DEPLOYED: Sat Sep 30 08:32:53 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!

$ kubectl get deployment -n kube-system aws-load-balancer-controller
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
aws-load-balancer-controller   2/2     2            2           85s

제대로 설치되어 배포되어 동작하고 있는 것까지 확인이 가능하다.

 

 

NS 생성

이제 svc와 deploy를 배포하기 위한 namespace를 생성하자.

$ kubectl create namespace eks-test
namespace/eks-test created

$ kubectl get ns | grep eks-test
eks-test          Active   3d5h

 

 

애플리케이션 배포

외부에서 접속할 수 있는 애플리케이션을 배포하는 것이 목적이다.

 

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deploy
  namespace: eks-test
  labels:
    app: eks-sample-linux-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: eks-sample-linux-app
  template:
    metadata:
      labels:
        app: eks-sample-linux-app
    spec:
      containers:
      - name: httpd
        image: httpd:latest
        ports:
        - containerPort: 80

 

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: test-svc
  namespace: eks-test
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
  labels:
    app: eks-sample-linux-app
spec:
  selector:
    app: eks-sample-linux-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

annotation을 통해 NLB를 구성했다.

더보기

aws-load-balancer-type: external

ELB를 사용하여 서비스가 노출되어야 함을 지정

 

aws-load-balancer-nlb-target-type: ip

NLB의 대상 유형을 ip로 설정

이는 pods로 직접 라우팅

 

aws-load-balancer-scheme: internet-facing

NLB가 인터넷 연결인지 내부인지 여부를 결정

 

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/service/annotations/

 

apply 결과

$ kubectl get svc,deploy,pods -n eks-test
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP                                                                        PORT(S)        AGE
service/test-svc   LoadBalancer   172.20.94.88   k8s-ekstest-testsvc-a5036dcbeb-9ba1822e72f801ae.elb.ap-northeast-2.amazonaws.com   80:30898/TCP   36s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/test-deploy   3/3     3            3           35s

NAME                              READY   STATUS    RESTARTS   AGE
pod/test-deploy-6c8bc4567-hbhpg   1/1     Running   0          35s
pod/test-deploy-6c8bc4567-hl9kv   1/1     Running   0          35s
pod/test-deploy-6c8bc4567-kkmkp   1/1     Running   0          35s

 

완료!

 

 

 

참고

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/sample-deployment.html