본문 바로가기

개발/DevOps

EKS Application 배포

* 환경 mac m1 


Download

open local terminal 

- aws cli 

brew install awscli

- eks cli

brew install eksctl

- kubectl

brew install kubectl

Aws config

aws configure

* 설정

Access Key: {accessKey}

Secret Access Key: {secretKey}

region name: ap-northest-1

output format: json 

 

* 확인

~/.aws/config
~/.aws/credentials 

 

VPC 세팅 

aws cloudformation create-stack \
  --region ap-northeast-1 \
  --stack-name dev-eks-vpc-stack \
  --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml

 

 

Cluster role생성

export CLUSTER_ROLE_NAME="cluster-dev"
cat << EOF > eks-cluster-role-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "eks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
aws iam create-role \
  --role-name cluster-dev \
  --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"

aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \
--role-name cluster-dev

 

CNI 자격증명 연결

EKS > Clusters > dev-clusters{생성한 클러스터} > Overview > OpenID Connect provider URL 

export CNI_ROLE_NAME="cni-dev"
export ACCOUNT_ID={YOUR_ACCOUND_ID} #ex 123454328901
export OIDC={EKS_OIDC_URL}

cat << EOF > cni-role-trust-policy.json
{"Version": "2012-10-17",
"Statement": [
  {"Effect": "Allow",
  "Principal": {
    "Federated": "arn:aws:iam::$ACCOUNT_ID:oidc-provider/$OIDC"
    },
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringEquals": {
      "oidc.eks.ap-northeast-1.amazonaws.com/id/16DDFF2463227D3A9C84851F564EB337:sub": "system:serviceaccount:kube-system:aws-node"
      }
    }
  }
]}
EOF
aws iam create-role \
--role-name $CNI_ROLE_NAME \
--assume-role-policy-document file://"cni-role-trust-policy.json"

aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
--role-name $CNI_ROLE_NAME

aws eks update-addon \
 --cluster-name dev-clusters \
 --addon-name vpc-cni \
 --service-account-role-arn arn:aws:iam::"$ACCOUNT_ID":role/$CNI_ROLE_NAME

 

Node group role 생성

export NODE_GROUP_ROLE="dev-cluster-node-role"
cat << EOF > node-role-trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

aws iam create-role \
  --role-name dev-cluster-node-role \
  --assume-role-policy-document file://"node-role-trust-policy.json"

  aws iam attach-role-policy \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
  --role-name dev-cluster-node-role
aws iam attach-role-policy \
  --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
  --role-name dev-cluster-node-role
aws iam attach-role-policy \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
  --role-name dev-cluster-node-role

 

AWS cluster 생성

EKS > Clusters > Add cluster

cluster service role : 위에서 생성한 cluster-dev 선택

vpc : 위에서 생성한 vpc 선택

next -> create

 

Node group 추가

EKS > Clusters > dev-clusters(생성한 클러스터) > Compute > Add node group

name, node IAM role설정
instance type설정
scaling size설정

* desired size만큼 node가 생성된다.

 

Instance 생성 확인

위의 설정과는 다른 이미지임.

* instance가 node만큼 생성되는 것을 확인한다.

Ecr create

aws ecr create-repository --repository-name dev-ecr-demo --region ap-northeast-1

 

Ecr image upload 

* application내 build.gradle.kts jib 추가

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "3.0.2"
    id("io.spring.dependency-management") version "1.1.0"
    kotlin("jvm") version "1.7.22"
    kotlin("plugin.spring") version "1.7.22"
    id("com.google.cloud.tools.jib") version "3.1.2"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

jib {
    from {
        image = "eclipse-temurin:17-jre-alpine"
    }
    to {
   		// ECR > Repositories > URI 확인가능
        image = "111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/dev-ecr-demo"
        credHelper = "ecr-login"
        tags = setOf("latest")
    }
    container {
        jvmFlags = listOf("-Xms128m","-Xmx128m")
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-webflux")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("io.projectreactor:reactor-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "17"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

 

gradlew jib

* url 확인

ECR > Repositories > URI

Login

open local terminal 

aws eks --region ap-northeast-1 update-kubeconfig --name dev-clusters && kubectl config set-context --current --namespace=default

 

 

실행

 

deployment.yaml 생성

 

cat << EOF > demo-api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-api
spec:
  replicas: 2
  minReadySeconds: 2
  selector:
    matchLabels:
      app: demo-api
  template:
    metadata:
      name: demo-api-pod
      labels:
        app: demo-api
    spec:
      containers:
      - name: demo-api
        image: 111111111111.dkr.ecr.ap-northeast-2.amazonaws.com/dev-ecr-demo:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
EOF

pod 생성

kubectl apply -f demo-api-deployment.yaml

 

service.yaml 생성 - nlb

cat << EOF > demo-api-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-api
  annotations: #annotations가 없을경우 classic loadbalancer로 생성, but deprecated
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb" 
    #service.beta.kubernetes.io/aws-load-balancer-internal: "true"
spec:
  ports:
   - port: 80
     name: http
     protocol: TCP
     targetPort: 8080
  type: LoadBalancer
  selector:
    app: demo-api
EOF

service 생성

kubectl apply -f demo-api-service.yaml

생성 후 조회

 

결과

service/demo-api 내 external-ip를 호출한다