이 연재글은 EKS(Elastic Kubernetes Service) 실습의 3번째 글입니다.

kubernetes cluster를 구동시키면 그 위에 컨테이너화된 애플리케이션을 배포할 수 있습니다. kubectl 명령으로 ECR에 업로드된 Docker Image를 Cluster node에 배포하는 절차를 실습해보겠습니다.

namespace 생성

k8s(kubernetes)에서는 오브젝트들을 논리적으로 구분지을 수 있는 namespace라는 기능을 제공합니다. namespace란 공통적인 성질을 가지고 있는 pod, replicaset, deployment, service등이 묶여있는 가상공간 또는 그룹이라고 생각하면 됩니다. namespace를 지정하지 않고 배포할경우엔 default namespace에 배포가 됩니다.

namespace.yaml 작성

apiVersion: v1
kind: Namespace
metadata:
  name: demo

namespace 생성 및 확인

$ kubectl apply -f namespace.yaml
// 확인
$ kubectl get namespaces
NAME              STATUS    AGE
default           Active    2d23h
demo              Active    6h
kube-node-lease   Active    2d23h
kube-public       Active    2d23h
kube-system       Active    2d23h

deployment

deployment는 k8s가 애플리케이션의 인스턴스를 어떻게 생성하고 업데이트 해야 하는지를 지시합니다. deployment가 만들어지면, k8s 마스터가 해당 deployment에 포함된 애플리케이션 인스턴스가 클러스터의 개별 노드에서 실행되도록 스케줄합니다. 또한 인스턴스를 구동 중인 노드가 다운되거나 삭제되면, deployment 컨트롤러가 인스턴스를 클러스터 내부의 다른 노드의 인스턴스로 교체시켜줍니다.(머신의 장애나 정비에 대응할 수 있는 자동 복구-self-healing 메커니즘을 제공)

deployment.yml 작성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo1-api
  labels:
    app: demo1-api
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo1-api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  template:
    metadata:
      labels:
        app: demo1-api
    spec:
      containers:
      - image: 447157991422.dkr.ecr.ap-southeast-1.amazonaws.com/demo1:0.0.2-SNAPSHOT
        imagePullPolicy: Always
        name: demo1-api
        ports:
            - containerPort: 8080
              protocol: TCP

deployment 적용 및 확인

deployment를 적용하면 선언한 내용에 따라 ecr의 이미지로 2개의 replica를 생성하는 것을 확인할 수 있습니다.

$ kubectl apply -f deployment.yaml
// deployment 확인
$ kubectl get deployment -n demo
NAME        READY     UP-TO-DATE   AVAILABLE   AGE
demo1-api   1/1       1            1           6h4m
// 생성된 pod 확인
$ kubectl get pod -n demo
NAME                         READY     STATUS    RESTARTS   AGE
demo1-api-58c4fbf6cf-j2f8m   1/1       Running   0          5h31m
demo1-api-58c4fbf6cf-wxfpx   1/1       Running   0          5h31m

service

k8s에서 service는 논리적 pod 집합과 이에 접근하는 정책을 정의합니다. service를 정의하여 pod에서 실행 중인 애플리케이션을 cluster 내부에서만 접근하거나 cluster 외부에서 접근할 수 있게 합니다. 아래 내용을 적용하면 생성된 LoadBalancer 주소로 외부에서 접속이 가능하게 됩니다.

service.yml 작성

아래 내용을 적용하면 Classic LoadBalancer가 생성되어 8080 port로 서비스되고 있는 애플리케이션을 외부에서 80 port로 접속할 수 있게 됩니다.

apiVersion: v1
kind: Service
metadata:
  name: demo1-api
  namespace: demo
spec:
  selector:
    app: demo1-api
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

참고로 Network LoadBalancer로 생성하려면 metadata에 annotations를 설정하면 됩니다.

metadata:
  name: demo1-api
  namespace: demo
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"

service 적용 및 확인

$ kubectl apply -f service.yaml
// External ELB 주소 확인
$ kubectl get svc -n demo
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP                                                                  PORT(S)        AGE
kubernetes   ClusterIP      10.100.0.1       <none>                                                                       443/TCP        136m
demo1-api   LoadBalancer   10.100.147.110   a242fc357e640473f930c8b488e5f42f-79225405.ap-southeast-1.elb.amazonaws.com   80:31917/TCP   16m
연재글 이동[이전글] ECR(Elastic Container Registry)에 Docker 이미지 배포하기
[다음글] EKS에 ALB 적용하여 서비스 노출하기(Ingress Application Loadbalancer)