EKS 클러스터에 배치 어플리케이션 배포하기

2021-08-16

.

Data_Engineering_TIL(20210816)

[학습자료]

“클라우드 네이티브를 위한 쿠버네티스 실전 프로젝트” 책을 읽고 실습한 내용입니다.

** 동양북스, 아이자와 고지&사토 가즈히코 지음, 박상욱 옮김

참고자료 URL : https://github.com/dybooksIT/k8s-aws-book

[학습내용]

“EKS 클러스터에 프런트앤드 어플리케이션 배포하기”에 이어서 진행을 한 실습을 진행한 내용임

** URL : https://minman2115.github.io/DE_TIL258

  • 실습의 최종 목표

서비스의 최종 구현 목표

architecture3

아키텍처 관점에서 최종목표

architecture2

  • 오늘의 실습목표

배치 어플리케이션을 빌드하고 EKS 클러스터에 배포한다.

  • 실습내용

먼저 ec2 베스천에서 아래와 같이 커맨드를 실행하여 배치 어플리케이션을 빌드하고 컨테이너 이미지를 생성한다.

[ec2-user@ip-10-10-1-181 ~]$ cd k8s-aws-book/batch-app/

[ec2-user@ip-10-10-1-181 batch-app]$ ll
total 28
drwxrwxr-x 9 ec2-user ec2-user  113 Aug 16 07:56 build
-rw-rw-r-- 1 ec2-user ec2-user 2110 Aug 14 07:53 build.gradle
-rw-rw-r-- 1 ec2-user ec2-user  397 Aug 14 07:53 Dockerfile
drwxrwxr-x 3 ec2-user ec2-user   21 Aug 14 07:53 gradle
-rw-rw-r-- 1 ec2-user ec2-user  224 Aug 14 07:53 gradle.properties
-rwxrwxr-x 1 ec2-user ec2-user 5305 Aug 14 07:53 gradlew
-rw-rw-r-- 1 ec2-user ec2-user 2185 Aug 14 07:53 gradlew.bat
drwxrwxr-x 4 ec2-user ec2-user   33 Aug 14 07:53 sample_data
-rw-rw-r-- 1 ec2-user ec2-user   63 Aug 14 07:53 settings.gradle
drwxrwxr-x 4 ec2-user ec2-user   30 Aug 14 07:53 src

[ec2-user@ip-10-10-1-181 batch-app]$ cat Dockerfile
FROM amazoncorretto:11
LABEL maintainer="dybooksIT"

RUN yum install -y glibc-langpack-ko
ENV LANG ko_KR.UTF8
ENV LC_ALL ko_KR.UTF8
RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java", \
 "-verbose:gc", \
 "-Xlog:gc*:stdout:time,uptime,level,tags", \
 "-Djava.security.egd=file:/dev/./urandom", \
 "-jar", \
 "/app.jar"]


[ec2-user@ip-10-10-1-181 batch-app]$ ./gradlew clean build
Starting a Gradle Daemon (subsequent builds will be faster)

BUILD SUCCESSFUL in 1m 24s
14 actionable tasks: 13 executed, 1 up-to-date

[ec2-user@ip-10-10-1-181 batch-app]$ cd build/libs

[ec2-user@ip-10-10-1-181 libs]$ ll
total 40964
-rwxrw-r-- 1 ec2-user ec2-user 41943048 Aug 16 07:56 batch-app-1.0.0.jar

[ec2-user@ip-10-10-1-181 libs]$ cd /home/ec2-user/k8s-aws-book/batch-app

[ec2-user@ip-10-10-1-181 batch-app]$ sudo docker build -t k8sbook/batch-app:1.0.0 --build-arg JAR_FILE=build/libs/batch-app-1.0.0.jar .
Sending build context to Docker daemon   52.7MB
Step 1/10 : FROM amazoncorretto:11
 ---> 2b27f3c83c92
Step 2/10 : LABEL maintainer="dybooksIT"
 ---> Running in bdc41c48fcbf
Removing intermediate container bdc41c48fcbf
 ---> 0e8c9c98175e
Step 3/10 : RUN yum install -y glibc-langpack-ko
 ---> Running in 1d491d4b510c
Loaded plugins: ovl, priorities
Resolving Dependencies
--> Running transaction check
---> Package glibc-langpack-ko.x86_64 0:2.26-48.amzn2 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                Arch        Version               Repository       Size
================================================================================
Installing:
 glibc-langpack-ko      x86_64      2.26-48.amzn2         amzn2-core      326 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 326 k
Installed size: 2.5 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : glibc-langpack-ko-2.26-48.amzn2.x86_64                       1/1
  Verifying  : glibc-langpack-ko-2.26-48.amzn2.x86_64                       1/1

Installed:
  glibc-langpack-ko.x86_64 0:2.26-48.amzn2

Complete!
Removing intermediate container 1d491d4b510c
 ---> 5415bd0004fd
Step 4/10 : ENV LANG ko_KR.UTF8
 ---> Running in 3c872fcf8cd2
Removing intermediate container 3c872fcf8cd2
 ---> 1d6600194029
Step 5/10 : ENV LC_ALL ko_KR.UTF8
 ---> Running in c51b5ada7816
Removing intermediate container c51b5ada7816
 ---> 890a25a8dd17
Step 6/10 : RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
 ---> Running in 370741bdb058
Removing intermediate container 370741bdb058
 ---> 6af4dc907215
Step 7/10 : VOLUME /tmp
 ---> Running in a4687dad7f8f
Removing intermediate container a4687dad7f8f
 ---> f6f03018f601
Step 8/10 : ARG JAR_FILE
 ---> Running in ae2fcc7548f9
Removing intermediate container ae2fcc7548f9
 ---> ddf6c9b99326
Step 9/10 : COPY ${JAR_FILE} app.jar
 ---> 5f8f99646ecb
Step 10/10 : ENTRYPOINT ["java",  "-verbose:gc",  "-Xlog:gc*:stdout:time,uptime,level,tags",  "-Djava.security.egd=file:/dev/./urandom",  "-jar",  "/app.jar"]
 ---> Running in 074bfc5a6f87
Removing intermediate container 074bfc5a6f87
 ---> 3b1ba006d80f
Successfully built 3b1ba006d80f
Successfully tagged k8sbook/batch-app:1.0.0


# 그런 다음에 ECR 콘솔로 가서 k8sbook/batch-app 이라는 이름으로 레포지토리를 하나 생성한다.
# 생성한다음에 다시 basion ec2로 넘어와서 아래와 같이 커맨드를 실행한다.

[ec2-user@ip-10-10-1-181 batch-app]$ aws ecr get-login-password --region ap-northeast-2 | sudo docker login --username AWS --password-stdin xxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[ec2-user@ip-10-10-1-181 batch-app]$ sudo docker tag k8sbook/batch-app:1.0.0 xxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/k8sbook/batch-app:1.0.0

[ec2-user@ip-10-10-1-181 batch-app]$ sudo docker push xxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/k8sbook/batch-app:1.0.0
The push refers to repository [xxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/k8sbook/batch-app]
xxxxxxxxx: Pushed
xxxxxxxxx: Pushed
xxxxxxxxx: Pushed
xxxxxxxxx: Pushed
xxxxxxxxx: Pushed
1.0.0: digest: sha256:xxxxxxxxx size: 1374

배치 어플리케이션이 사용할 S3 버킷을 아래와 같이 클라우드를 이용하여 생성한다. 먼저 클라우드 포메이션으로 실행할 yaml 파일 내용을 체크하고 그런 다음에 클라우드 포메이션 콘솔로가서 해당 yaml 파일을 실행한다.

[ec2-user@ip-10-10-1-181 batch-app]$ cd /home/ec2-user/k8s-aws-book/eks-env

[ec2-user@ip-10-10-1-181 eks-env]$ ll
total 60
-rw-rw-r-- 1 ec2-user ec2-user 3135 Aug 14 07:53 01_base_resources_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user  180 Aug 14 07:53 02_nginx_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user 7924 Aug 14 07:53 10_rds_ope_cfn_mysql.yaml
-rw-rw-r-- 1 ec2-user ec2-user 7957 Aug 14 07:53 10_rds_ope_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user   58 Aug 14 07:53 20_create_namespace_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user  153 Aug 14 07:53 21_db_config_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user 1397 Aug 14 07:53 22_deployment_backend-app_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user  190 Aug 14 07:53 23_service_backend-app_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user 1253 Aug 14 07:53 30_s3_cloudfront_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user 1677 Aug 14 07:53 40_s3_batch_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user  195 Aug 14 07:53 41_config_map_batch_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user  158 Aug 14 07:53 42_batch_secrets_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user 1939 Aug 14 07:53 43_cronjob_k8s.yaml.template
drwxrwxr-x 2 ec2-user ec2-user  154 Aug 14 07:53 cloudwatch-yaml

[ec2-user@ip-10-10-1-181 eks-env]$ cat 40_s3_batch_cfn.yaml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  TargetRegion:
    Type: String
    Default: ap-northeast-2

  BucketBaseName:
    Type: String
    Default: eks-work-batch-

  BucketSuffix:
    Type: String

Resources:
  BatchBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Join ["", [!Ref BucketBaseName, !Ref BucketSuffix]]
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false

  BatchUser:
    Type: AWS::IAM::User
    Properties:
      Path: /
      UserName: eks-work-batch-user

  BatchUserAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName: !Ref BatchUser

  BatchBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref BatchBucket
      PolicyDocument:
        Statement:
        - Action:
          - s3:GetObject
          - s3:DeleteObject
          - s3:PutObject
          Effect: Allow
          Principal:
            AWS: !GetAtt BatchUser.Arn
          Resource: !Join ["", [!GetAtt BatchBucket.Arn, "/*"]]
        - Action:
          - s3:ListBucket
          Effect: Allow
          Principal:
            AWS: !GetAtt BatchUser.Arn
          Resource: !GetAtt BatchBucket.Arn

  BatchUserAccessKeyParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: BatchUserAccessKey
      Type: String
      Value: !Ref BatchUserAccessKey

  BatchUserSecretAccessKeyParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: BatchUserSecretAccessKey
      Type: String
      Value: !GetAtt BatchUserAccessKey.SecretAccessKey

[ec2-user@ip-10-10-1-181 eks-env]$

1

그런 다음에 배치 어플리케이션 설정값을 저장하는 configmap을 생성한다. 컨피그맵은 쿠버네티으세어 설정값 등을 보관하기 위한 구조를 말한다. 여기서는 생성한 S3 버킷이름과 S3 디렉토리 이름들을 보관할 컨피그 맵을 등록한다.

컨피그맵은 kubectl 명령어로 설정할수 있지만 버킷 이름의 접미사를 설정해야 하므로 envsubst를 사용한 다음 명령을 실행한다. 명령을 실행하는 디렉터리는 k8s-aws-book/eks-env다.

[ec2-user@ip-10-10-1-181 eks-env]$ cd /home/ec2-user/k8s-aws-book/eks-env

[ec2-user@ip-10-10-1-181 eks-env]$ ll
total 60
-rw-rw-r-- 1 ec2-user ec2-user 3135 Aug 14 07:53 01_base_resources_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user  180 Aug 14 07:53 02_nginx_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user 7924 Aug 14 07:53 10_rds_ope_cfn_mysql.yaml
-rw-rw-r-- 1 ec2-user ec2-user 7957 Aug 14 07:53 10_rds_ope_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user   58 Aug 14 07:53 20_create_namespace_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user  153 Aug 14 07:53 21_db_config_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user 1397 Aug 14 07:53 22_deployment_backend-app_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user  190 Aug 14 07:53 23_service_backend-app_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user 1253 Aug 14 07:53 30_s3_cloudfront_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user 1677 Aug 14 07:53 40_s3_batch_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user  195 Aug 14 07:53 41_config_map_batch_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user  158 Aug 14 07:53 42_batch_secrets_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user 1939 Aug 14 07:53 43_cronjob_k8s.yaml.template
drwxrwxr-x 2 ec2-user ec2-user  154 Aug 14 07:53 cloudwatch-yaml
    
[ec2-user@ip-10-10-1-181 eks-env]$ cat 41_config_map_batch_k8s.yaml.template
apiVersion: v1
kind: ConfigMap
metadata:
  name: batch-app-config
data:
  bucket-name: eks-work-batch-${BUCKET_SUFFIX}
  folder-name: locationData
  batch-run: "true"
  aws-region: ap-northeast-2

[ec2-user@ip-10-10-1-181 eks-env]$ BUCKET_SUFFIX=xxx envsubst < 41_config_map_batch_k8s.yaml.template | kubectl apply -f -
configmap/batch-app-config created

그런 다음에 S3 접속용 액세스 키를 확인하고 시크릿을 생성해야 한다.

배치 어플리케이션에서는 S3에서 파일을 가져와 이용한다. 배치 어플리케이션이 접속할 S3 버킷은 허가된 특정 사용자만 접속할 수 있도록 설정하므로, 배치 어플리케이션에서는 S3에 접속하기 위한 인증 정보를 전달해줘야 한다. API 앱의 경우와 마찬가지로 비밀정보를 관리하기 위해 쿠버네티스 리소스인 시크릿을 이용한다.

아래 그림과 같이 system manager에 파라미터 스토어에서 accesskey와 secretkey를 확인할 수 있다.

2

위에서 확인한 accesskey와 secretkey를 이용햇 시크릿을 생성한다.

[ec2-user@ip-10-10-1-181 eks-env]$ cat 42_batch_secrets_k8s.yaml.template
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: batch-secret-config
stringData:
  aws-accesskey: ${AWS_ACCESSKEY}
  aws-secretkey: ${AWS_SECRETKEY}

[ec2-user@ip-10-10-1-181 eks-env]$ AWS_ACCESSKEY=xxxxxxx AWS_SECRETKEY=yyyyyyy envsubst < 42_batch_secrets_k8s.yaml.template | kubectl apply -f -
secret/batch-secret-config created

AWS CLI를 이용하여 배치 어플리케이션이 사용할 입력파일을 버킷에 업로드한다. 입력 파일로 이용할 CSV 데이터는 깃허브에서 클론한 디렉토리에 포함되어 있다. 아래와 같은 명령을 실행하여 이 파일을 업로드한다.

[ec2-user@ip-10-10-1-181 normal]$ cd /home/ec2-user/k8s-aws-book/batch-app/sample_data/normal

[ec2-user@ip-10-10-1-181 normal]$ ll
total 8
-rw-rw-r-- 1 ec2-user ec2-user 122 Aug 14 07:53 sample_location1.csv
-rw-rw-r-- 1 ec2-user ec2-user  92 Aug 14 07:53 sample_location2.csv

[ec2-user@ip-10-10-1-181 normal]$ aws s3 sync . s3://eks-work-batch-xxx/locationData --delete --include "*" --acl public-read
upload: ./sample_location2.csv to s3://eks-work-batch-xxx/locationData/sample_location2.csv
upload: ./sample_location1.csv to s3://eks-work-batch-xxx/locationData/sample_location1.csv

여기까지 진행을 하면 배치 프로그램을 동작시키기 위한 준비가 끝난것이다. 이제 배치 어플리케이션을 배포해보자. 배포하기 전에는 앱 동작 확인 작업을 위해 배치 어플리케이션 실행 전의 데이터 베이스 내용과 S3 버킷 상태를 확인해야 한다. 또 배치 프로그램 실행 후 다시 데이터베이스와 S3 버킷을 확인하기 위해 해당 페이지를 닫지 말고 그대로 열어두자.

먼저 디비 내용을 확인해보자 시스템 매니저의 세션매니저를 통해 디비에 접속해서 내용을 확인한다.

3

세션매니저에서 아래와 같이 명령을 실행하여 디비 정보를 확인한다.

sh-4.2$ psql -U mywork -h eks-work-db.xxxxxxxxxx.ap-northeast-2.rds.amazonaws.com myworkdb
Password for user mywork:
psql (11.12)
SSL connection (protocol: TLSv1.2, cipher: xxxxxxxxxxxxxxxxxxxxx, bits: 256, compression: off)
Type "help" for help.

myworkdb=> select * from location;
 location_id |  location_name  | region_id |                                         note
-------------+-----------------+-----------+--------------------------------------------------------------------------------------
           1 | 테디베어 뮤지엄 |         9 | 테디베어의 역사는 물론 예술, 세계여행 등의 테마를 제공하는 테마 뮤지엄 브랜드입니다.
           2 | 성산 일출봉     |         9 | 유네스코 세계자연유산에 등재된 제주도의 랜드마크.
(2 rows)

myworkdb=>

ec2 베스천에서 아래와 같은 명령을 실행하여 csv 파일 두개가 있는 것을 확인하고 배치 어플리케이션을 EKS 클러스터에 배포한다.

[ec2-user@ip-10-10-1-181 normal]$ aws s3 ls eks-work-batch-xxx/locationData/
2021-08-16 09:57:00        122 sample_location1.csv
2021-08-16 09:57:00         92 sample_location2.csv
        
[ec2-user@ip-10-10-1-181 eks-env]$ cd /home/ec2-user/k8s-aws-book/eks-env

[ec2-user@ip-10-10-1-181 eks-env]$ ll
total 60
-rw-rw-r-- 1 ec2-user ec2-user 3135 Aug 14 07:53 01_base_resources_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user  180 Aug 14 07:53 02_nginx_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user 7924 Aug 14 07:53 10_rds_ope_cfn_mysql.yaml
-rw-rw-r-- 1 ec2-user ec2-user 7957 Aug 14 07:53 10_rds_ope_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user   58 Aug 14 07:53 20_create_namespace_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user  153 Aug 14 07:53 21_db_config_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user 1397 Aug 14 07:53 22_deployment_backend-app_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user  190 Aug 14 07:53 23_service_backend-app_k8s.yaml
-rw-rw-r-- 1 ec2-user ec2-user 1253 Aug 14 07:53 30_s3_cloudfront_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user 1677 Aug 14 07:53 40_s3_batch_cfn.yaml
-rw-rw-r-- 1 ec2-user ec2-user  195 Aug 14 07:53 41_config_map_batch_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user  158 Aug 14 07:53 42_batch_secrets_k8s.yaml.template
-rw-rw-r-- 1 ec2-user ec2-user 1939 Aug 14 07:53 43_cronjob_k8s.yaml.template
drwxrwxr-x 2 ec2-user ec2-user  154 Aug 14 07:53 cloudwatch-yaml

[ec2-user@ip-10-10-1-181 eks-env]$ cat 43_cronjob_k8s.yaml.template
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: batch-app
spec:
  schedule: "*/5 * * * *" # min hour day-of-month month day-of-week
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: batch-app
            image: ${ECR_HOST}/k8sbook/batch-app:1.0.0
            imagePullPolicy: Always
            env:
            - name: DB_URL
              valueFrom:
                secretKeyRef:
                  key: db-url
                  name: db-config
            - name: DB_USERNAME
              valueFrom:
                secretKeyRef:
                  key: db-username
                  name: db-config
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: db-password
                  name: db-config
            - name: CLOUD_AWS_CREDENTIALS_ACCESSKEY
              valueFrom:
                secretKeyRef:
                  key: aws-accesskey
                  name: batch-secret-config
            - name: CLOUD_AWS_CREDENTIALS_SECRETKEY
              valueFrom:
                secretKeyRef:
                  key: aws-secretkey
                  name: batch-secret-config
            - name: CLOUD_AWS_REGION_STATIC
              valueFrom:
                configMapKeyRef:
                  key: aws-region
                  name: batch-app-config
            - name: SAMPLE_APP_BATCH_BUCKET_NAME
              valueFrom:
                configMapKeyRef:
                  key: bucket-name
                  name: batch-app-config
            - name: SAMPLE_APP_BATCH_FOLDER_NAME
              valueFrom:
                configMapKeyRef:
                  key: folder-name
                  name: batch-app-config
            - name: SAMPLE_APP_BATCH_RUN
              valueFrom:
                configMapKeyRef:
                  key: batch-run
                  name: batch-app-config
          restartPolicy: OnFailure

[ec2-user@ip-10-10-1-181 eks-env]$ ECR_HOST=xxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com | envsubst < 43_cronjob_k8s.yaml.template | kubectl apply -f -
cronjob.batch/batch-app created

[ec2-user@ip-10-10-1-181 eks-env]$ kubectl get all
NAME                              READY   STATUS    RESTARTS   AGE
pod/backend-app-7fb899969-75tr6   1/1     Running   0          2d2h
pod/backend-app-7fb899969-hl5ns   1/1     Running   0          2d2h

NAME                          TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)          AGE
service/backend-app-service   LoadBalancer   10.100.199.40   xxxxxxxxxxx.ap-northeast-2.elb.amazonaws.com   8080:32015/TCP   2d2h

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/backend-app   2/2     2            2           2d2h

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/backend-app-7fb899969   2         2         2       2d2h

NAME                      SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/batch-app   */5 * * * *   False     0        <none>          7s

# 90초 뒤에 다시 실행하면 batch-app과 관련된 파드가 올라오고 5분주기로 completed가 되는 것을 확인할 수 있다.
[ec2-user@ip-10-10-1-181 eks-env]$ kubectl get all
NAME                              READY   STATUS      RESTARTS   AGE
pod/backend-app-7fb899969-75tr6   1/1     Running     0          2d4h
pod/backend-app-7fb899969-hl5ns   1/1     Running     0          2d4h
pod/batch-app-1629116700-mw5cd    0/1     Completed   0          41s

NAME                          TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)          AGE
service/backend-app-service   LoadBalancer   10.100.199.40   a72ae878f670e415e9898a19c7caa073-1835903861.ap-northeast-2.elb.amazonaws.com   8080:32015/TCP   2d4h

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/backend-app   2/2     2            2           2d4h

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/backend-app-7fb899969   2         2         2       2d4h

NAME                             COMPLETIONS   DURATION   AGE
job.batch/batch-app-1629116700   1/1           19s        41s

NAME                      SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/batch-app   */5 * * * *   False     0        42s             3m51s

디비 세션매니저로 가서 아래와 같이 쿼리하면 배치 어플리케이션이 돌면서 데이터가 들어온 것을 확인할 수 있다.

myworkdb=> select * from location;
 location_id |  location_name  | region_id |                                         note
-------------+-----------------+-----------+--------------------------------------------------------------------------------------
           1 | 테디베어 뮤지엄 |         9 | 테디베어의 역사는 물론 예술, 세계여행 등의 테마를 제공하는 테마 뮤지엄 브랜드입니다.
           2 | 성산 일출봉     |         9 | 유네스코 세계자연유산에 등재된 제주도의 랜드마크.
           3 | 국립중앙과학관  |         3 | 국립중앙과학관의 댓글
           4 | 엑스포과학공원  |         3 | 엑스포과학공원의 댓글
           5 | 펭귄마을        |         4 | 펭귄마을의 댓글
           6 | 대구미술관      |         5 | 대구미술관의 댓글
(6 rows)

ec2 베스천에서 배치어플리케이션 s3를 조회했을때 csv 두개가 소비된것을 알 수 있다.

[ec2-user@ip-10-10-1-181 eks-env]$ aws s3 ls eks-work-batch-pms/locationData/

** 실습할때 고생했던 내용

cat 43_cronjob_k8s.yaml.template 을 했을때 image: ${ECR_HOST}/k8sbook/batch-app:1.0.0 와 같이 ECR 호스트 네임을 변수로 받아오게 되어 있다. 그래서 pod을 실행할때도 ECR_HOST=xxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com | envsubst < 43_cronjob_k8s.yaml.template | kubectl apply -f - ECR_HOST를 변수로 받아서 넣게 되는데 이렇게 실행하게 되면 kubectl get all 했을때 InvalidImageName 애러가 발생하였다.

아래와 같이 kubectl describe pod batch-app 명령어를 날렸을때 애러메세지로 image tag를 제대로 파씽을 못하는걸로 확인했다.

[ec2-user@ip-10-10-1-181 eks-env]$ kubectl describe pod batch-app
Name:         batch-app-1629115200-mkx4x
Namespace:    eks-work
Priority:     0

...
    
Events:
  Type     Reason         Age               From               Message
  ----     ------         ----              ----               -------
  Normal   Scheduled      24s               default-scheduler  Successfully assigned eks-work/batch-app-xxxxxx-mkx4x to ip-192-168-0-177.ap-northeast-2.compute.internal
  Warning  InspectFailed  8s (x3 over 23s)  kubelet            Failed to apply default image tag "/k8sbook/batch-app:1.0.0": couldn't parse image reference "/k8sbook/batch-app:1.0.0": invalid reference format
  Warning  Failed         8s (x3 over 23s)  kubelet            Error: InvalidImageName

# 그래서 아래와 같이 해당 야믈파일을 하드코딩으로 넣어서 수정하였다.
[ec2-user@ip-10-10-1-181 eks-env]$ cat 43_cronjob_k8s.yaml.template
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: batch-app
spec:
  schedule: "*/5 * * * *" # min hour day-of-month month day-of-week
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: batch-app
            image: xxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/k8sbook/batch-app:1.0.0
            imagePullPolicy: Always
            env:
            - name: DB_URL
              valueFrom:
                secretKeyRef:
                  key: db-url
                  name: db-config
            - name: DB_USERNAME
              valueFrom:
                secretKeyRef:
                  key: db-username
                  name: db-config
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  key: db-password
                  name: db-config
            - name: CLOUD_AWS_CREDENTIALS_ACCESSKEY
              valueFrom:
                secretKeyRef:
                  key: aws-accesskey
                  name: batch-secret-config
            - name: CLOUD_AWS_CREDENTIALS_SECRETKEY
              valueFrom:
                secretKeyRef:
                  key: aws-secretkey
                  name: batch-secret-config
            - name: CLOUD_AWS_REGION_STATIC
              valueFrom:
                configMapKeyRef:
                  key: aws-region
                  name: batch-app-config
            - name: SAMPLE_APP_BATCH_BUCKET_NAME
              valueFrom:
                configMapKeyRef:
                  key: bucket-name
                  name: batch-app-config
            - name: SAMPLE_APP_BATCH_FOLDER_NAME
              valueFrom:
                configMapKeyRef:
                  key: folder-name
                  name: batch-app-config
            - name: SAMPLE_APP_BATCH_RUN
              valueFrom:
                configMapKeyRef:
                  key: batch-run
                  name: batch-app-config
          restartPolicy: OnFailure
            
# 그런 다음에 다시 실행하니까 애러가 없이 잘 실행되었다.
[ec2-user@ip-10-10-1-181 eks-env]$ envsubst < 43_cronjob_k8s.yaml.template | kubectl apply -f -
            
[ec2-user@ip-10-10-1-181 eks-env]$ kubectl describe pod batch-app
Name:         batch-app-1629116700-mw5cd
Namespace:    eks-work

...

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  81s   default-scheduler  Successfully assigned eks-work/batch-app-xxxxxx-mw5cd to ip-192-168-1-116.ap-northeast-2.compute.internal
  Normal  Pulling    80s   kubelet            Pulling image "xxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/k8sbook/batch-app:1.0.0"
  Normal  Pulled     72s   kubelet            Successfully pulled image "xxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/k8sbook/batch-app:1.0.0" in 7.440966617s
  Normal  Created    72s   kubelet            Created container batch-app
  Normal  Started    72s   kubelet            Started container batch-app

우리가 원하던 모든 아키텍처의 구현이 완료되었다.

실습이 끝나면 클라우드 포메이션 생성 역순으로 스텍들을 삭제해주면 된다.