

 **이 페이지 개선에 도움 주기** 

이 사용자 가이드에 기여하려면 모든 페이지의 오른쪽 창에 있는 **GitHub에서 이 페이지 편집** 링크를 선택합니다.

# Linux에서 샘플 애플리케이션 배포
<a name="sample-deployment"></a>

이 주제에서는 Linux 노드의 클러스터에 샘플 애플리케이션을 배포합니다.

## 사전 조건
<a name="_prerequisites"></a>
+ 노드가 하나 이상 있는 기존 Kubernetes 클러스터. 기존 Amazon EKS 클러스터가 없는 경우 [Amazon EKS 시작하기](getting-started.md) 가이드 중 하나를 사용하여 Amazon EKS 클러스터를 배포할 수 있습니다.
+  컴퓨터에 설치된 `Kubectl`. 자세한 내용은 [`kubectl` 및 `eksctl` 설정](install-kubectl.md) 섹션을 참조하세요.
+  클러스터와 통신하도록 구성된 `Kubectl`. 자세한 내용은 [Kubeconfig 파일을 생성하여 kubectl을 EKS 클러스터에 연결](create-kubeconfig.md) 섹션을 참조하세요.
+ 샘플 워크로드를 Fargate에 배포하려는 경우, 이름을 변경하지 않는 한 이 자습서에서 생성한 것과 동일한 네임스페이스(`eks-sample-app`)를 포함하는 기존 [Fargate 프로필](fargate-profile.md)이 있어야 합니다. [Amazon EKS 시작하기](getting-started.md)에서 gudes 중 하나를 사용하여 클러스터를 만든 경우, 시작 가이드에서 만든 프로필에는 이 자습서에서 사용하는 네임스페이스가 지정되어 있지 않으므로 새 프로필을 만들거나 기존 프로필에 네임스페이스를 추가해야 합니다. 또한 VPC에 프라이빗 서브넷이 하나 이상 있어야 합니다.

다음 단계에서 많은 변수를 변경할 수 있지만 지정된 경우에만 변수 값을 변경하는 것이 좋습니다. Kubernetes 포드, 배포 및 서비스를 더 잘 이해하면 다른 값을 변경해 볼 수 있습니다.

## 네임스페이스 생성
<a name="_create_a_namespace"></a>

네임스페이스를 사용하면 Kubernetes에서 리소스를 그룹화할 수 있습니다. 자세한 내용은 쿠버네티스 문서의 [네임스페이스](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)를 참조하세요. [AWS Fargate로 컴퓨팅 관리를 간소화](fargate.md)하기 위해 샘플 애플리케이션을 배포하려는 경우, 시작할 때 [AWS Fargate를 사용하는 포드 정의](fargate-profile.md)에서 `namespace`의 값이 `eks-sample-app`인지 확인해야 합니다.

```
kubectl create namespace eks-sample-app
```

## Kubernetes 배포를 생성합니다.
<a name="_create_a_kubernetes_deployment"></a>

Kubernetes 배포를 생성합니다. 이 샘플 배포는 퍼블릭 리포지토리에서 컨테이너 이미지를 가져와 클러스터에 3개의 복제본(개별 포드)을 배포합니다. 자세한 내용은 쿠버네티스 문서의 [디플로이먼트](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)를 참조하세요.

1. 다음 콘텐츠를 `eks-sample-deployment.yaml`이라는 파일에 저장합니다. 샘플 애플리케이션의 컨테이너는 네트워크 스토리지를 사용하지 않지만 필요한 애플리케이션이 있을 수 있습니다. 자세한 내용은 [클러스터에 애플리케이션 데이터 스토리지 사용](storage.md) 섹션을 참조하세요.
   + `kubernetes.io/arch` 키 아래의 `amd64` 또는 `arm64` `values`는 애플리케이션을 하드웨어 아키텍처 중 하나에 배포할 수 있음을 의미합니다(클러스터에 둘 다 있는 경우). 이는 이 이미지가 다중 아키텍처 이미지이지만 모두가 그렇지는 않기 때문에 가능합니다. 이미지를 가져오는 리포지토리에서 [이미지 세부 정보](https://gallery.ecr.aws/nginx/nginx)를 확인하여 이미지가 지원되는 하드웨어 아키텍처를 결정할 수 있습니다. 하드웨어 아키텍처 유형을 지원하지 않거나 이미지를 배포하지 않으려는 이미지를 배포하는 경우 매니페스트에서 해당 유형을 제거합니다. 자세한 내용은 쿠버네티스 문서의 [잘 알려진 레이블, 어노테이션, 테인트(Taint)](https://kubernetes.io/docs/reference/labels-annotations-taints/)를 참조하세요.
   + `kubernetes.io/os: linux` `nodeSelector`는 예를 들어, 클러스터에 Linux 및 Windows 노드가 있는 경우 이미지가 Linux 노드에만 배포됨을 의미합니다. 자세한 내용은 쿠버네티스 문서의 [잘 알려진 레이블, 어노테이션, 테인트(Taint)](https://kubernetes.io/docs/reference/labels-annotations-taints/)를 참조하세요.

     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: eks-sample-linux-deployment
       namespace: eks-sample-app
       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:
           affinity:
             nodeAffinity:
               requiredDuringSchedulingIgnoredDuringExecution:
                 nodeSelectorTerms:
                 - matchExpressions:
                   - key: kubernetes.io/arch
                     operator: In
                     values:
                     - amd64
                     - arm64
           containers:
           - name: nginx
             image: public.ecr.aws/nginx/nginx:1.23
             ports:
             - name: http
               containerPort: 80
             imagePullPolicy: IfNotPresent
           nodeSelector:
             kubernetes.io/os: linux
     ```

1. 배포 매니페스트를 클러스터에 적용합니다.

   ```
   kubectl apply -f eks-sample-deployment.yaml
   ```

## 서비스 생성
<a name="_create_a_service"></a>

서비스를 사용하면 단일 IP 주소 또는 이름을 통해 모든 복제본에 액세스할 수 있습니다. 자세한 내용은 쿠버네티스 문서의 [서비스](https://kubernetes.io/docs/concepts/services-networking/service/)를 참조하세요. 샘플 애플리케이션에서는 구현되지 않았지만 다른 AWS 서비스와 상호 작용해야 하는 애플리케이션이 있는 경우 포드에 대한 Kubernetes 서비스 계정을 생성하고 이를 AWS IAM 계정에 연결하는 것이 좋습니다. 서비스 계정을 지정하면 포드가 다른 서비스와 상호 작용하기 위해 지정한 최소 권한만 갖게 됩니다. 자세한 내용은 [서비스 계정에 대한 IAM 역할](iam-roles-for-service-accounts.md) 단원을 참조하십시오.

1. 다음 콘텐츠를 `eks-sample-service.yaml`이라는 파일에 저장합니다. Kubernetes는 클러스터 내에서만 액세스할 수 있는 자체 IP 주소를 서비스에 할당합니다. 클러스터 외부에서 서비스에 액세스하려면 [AWS 로드 밸런서 컨트롤러](aws-load-balancer-controller.md)를 배포하여 [애플리케이션](alb-ingress.md) 또는 [네트워크](network-load-balancing.md) 트래픽을 서비스에 로드 밸런싱합니다.

   ```
   apiVersion: v1
   kind: Service
   metadata:
     name: eks-sample-linux-service
     namespace: eks-sample-app
     labels:
       app: eks-sample-linux-app
   spec:
     selector:
       app: eks-sample-linux-app
     ports:
       - protocol: TCP
         port: 80
         targetPort: 80
   ```

1. 서비스 매니페스트를 클러스터에 적용합니다.

   ```
   kubectl apply -f eks-sample-service.yaml
   ```

## 생성된 리소스 검토
<a name="sample-app-view-namespace"></a>

1. `eks-sample-app` 네임스페이스에 있는 모든 리소스를 봅니다.

   ```
   kubectl get all -n eks-sample-app
   ```

   예제 출력은 다음과 같습니다.

   ```
   NAME                                               READY   STATUS    RESTARTS   AGE
   pod/eks-sample-linux-deployment-65b7669776-m6qxz   1/1     Running   0          27m
   pod/eks-sample-linux-deployment-65b7669776-mmxvd   1/1     Running   0          27m
   pod/eks-sample-linux-deployment-65b7669776-qzn22   1/1     Running   0          27m
   
   NAME                               TYPE         CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
   service/eks-sample-linux-service   ClusterIP    10.100.74.8     <none>        80/TCP    32m
   
   NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
   deployment.apps/eks-sample-linux-deployment 3/3     3            3           27m
   
   NAME                                                      DESIRED   CURRENT   READY   AGE
   replicaset.apps/eks-sample-linux-deployment-776d8f8fd8    3         3         3       27m
   ```

   이 출력에는 이전 단계에서 배포된 샘플 매니페스트에 지정된 서비스 및 배포가 표시됩니다. 3개의 포드도 확인할 수 있습니다. 동일한 매니페스트에 `3` `replicas`가 지정되었기 때문입니다. 포드에 대한 자세한 내용은 쿠버네티스 문서의 [포드](https://kubernetes.io/docs/concepts/workloads/pods/pod/)를 참조하세요. Kubernetes는 샘플 매니페스트에 지정되지 않은 경우에도 자동으로 `replicaset` 리소스를 생성합니다. `ReplicaSets`에 대한 자세한 내용은 Kubernetes 설명서에서 [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/)를 참조하세요.
**참고**  
Kubernetes는 매니페스트에 지정된 복제본의 수를 유지합니다. 프로덕션 배포이고 Kubernetes의 복제본 수 수평적 스케일링 또는 포드의 컴퓨팅 리소스 수직적 스케일링을 원하는 경우 [Horizontal Pod Autoscaler로 포드 배포 확장](horizontal-pod-autoscaler.md) 및 [Vertical Pod Autoscaler로 포드 리소스 조정](vertical-pod-autoscaler.md)을 사용하여 이를 수행할 수 있습니다.

1. 배포된 서비스의 세부 정보를 확인합니다.

   ```
   kubectl -n eks-sample-app describe service eks-sample-linux-service
   ```

   예제 출력은 다음과 같습니다.

   ```
   Name:              eks-sample-linux-service
   Namespace:         eks-sample-app
   Labels:            app=eks-sample-linux-app
   Annotations:       <none>
   Selector:          app=eks-sample-linux-app
   Type:              ClusterIP
   IP Families:       <none>
   IP:                10.100.74.8
   IPs:               10.100.74.8
   Port:              <unset>  80/TCP
   TargetPort:        80/TCP
   Endpoints:         192.168.24.212:80,192.168.50.185:80,192.168.63.93:80
   Session Affinity:  None
   Events:            <none>
   ```

   이전 출력에서 `IP:`의 값은 클러스터 내의 모든 노드 또는 포드에서 도달할 수 있는 고유한 IP 주소이지만 클러스터 외부에서는 도달할 수 없습니다. `Endpoints`의 값은 VPC 내에서 서비스의 일부인 포드에 할당된 IP 주소입니다.

1. 이전 단계에서 [네임스페이스를 볼](#sample-app-view-namespace) 때 출력에 나열된 포드 중 하나의 세부 정보를 봅니다. *776d8f8fd8-78w66*을 포드 중 하나에 대해 반환된 값으로 바꿉니다.

   ```
   kubectl -n eks-sample-app describe pod eks-sample-linux-deployment-65b7669776-m6qxz
   ```

   단축 예제 출력

   ```
   Name:         eks-sample-linux-deployment-65b7669776-m6qxz
   Namespace:    eks-sample-app
   Priority:     0
   Node:         ip-192-168-45-132.us-west-2.compute.internal/192.168.45.132
   [...]
   IP:           192.168.63.93
   IPs:
     IP:           192.168.63.93
   Controlled By:  ReplicaSet/eks-sample-linux-deployment-65b7669776
   [...]
   Conditions:
     Type              Status
     Initialized       True
     Ready             True
     ContainersReady   True
     PodScheduled      True
   [...]
   Events:
     Type    Reason     Age    From                                                 Message
     ----    ------     ----   ----                                                 -------
     Normal  Scheduled  3m20s  default-scheduler                                    Successfully assigned eks-sample-app/eks-sample-linux-deployment-65b7669776-m6qxz to ip-192-168-45-132.us-west-2.compute.internal
   [...]
   ```

   이전 출력에서 `IP:`의 값은 노드가 있는 서브넷에 할당된 CIDR 블록에서 포드에 할당되는 고유한 IP입니다. 포드에 다른 CIDR 블록의 IP 주소를 할당하려면 기본 동작을 변경할 수 있습니다. 자세한 내용은 [사용자 지정 네트워킹을 통해 대체 서브넷에 포드 배포](cni-custom-network.md) 단원을 참조하십시오. Kubernetes 스케줄러가 IP 주소 *192.168.45.132*를 사용하여 `Node`의 포드를 예약했는지 확인할 수도 있습니다.
**작은 정보**  
명령줄을 사용하는 대신 AWS Management Console에서 포드, 서비스, 배포 및 기타 Kubernetes 리소스에 대한 많은 세부 정보를 볼 수 있습니다. 자세한 내용은 [AWS Management Console에서 Kubernetes 리소스 보기](view-kubernetes-resources.md) 단원을 참조하십시오.

## 포드에서 쉘 실행
<a name="_run_a_shell_on_a_pod"></a>

1. 이전 단계에서 설명한 포드에서 셸을 실행하여 *65b7669776-m6qxz*를 포드 중 하나의 ID로 바꿉니다.

   ```
   kubectl exec -it eks-sample-linux-deployment-65b7669776-m6qxz -n eks-sample-app -- /bin/bash
   ```

1. 포드 쉘에서 이전 단계에서 배포와 함께 설치된 웹 서버의 출력을 봅니다. 서비스 이름만 지정하면 됩니다. 기본적으로 Amazon EKS 클러스터와 함께 배포되는 CoreDNS에 의해 서비스의 IP 주소로 확인됩니다.

   ```
   curl eks-sample-linux-service
   ```

   예제 출력은 다음과 같습니다.

   ```
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   [...]
   ```

1. 포드 셸에서 포드의 DNS 서버를 봅니다.

   ```
   cat /etc/resolv.conf
   ```

   예제 출력은 다음과 같습니다.

   ```
   nameserver 10.100.0.10
   search eks-sample-app.svc.cluster.local svc.cluster.local cluster.local us-west-2.compute.internal
   options ndots:5
   ```

   이전 출력에서 `10.100.0.10`은 클러스터에 배포된 모든 포드의 `nameserver`로 자동 할당됩니다.

1. `exit`를 입력하여 포드에서 연결을 해제합니다.

1. 샘플 애플리케이션 사용이 끝나면 다음 명령을 사용하여 샘플 네임스페이스, 서비스 및 배포를 제거할 수 있습니다.

   ```
   kubectl delete namespace eks-sample-app
   ```

## 다음 단계
<a name="sample-deployment-next-steps"></a>

샘플 애플리케이션을 배포한 후 다음 연습 중 일부를 시도해 볼 수 있습니다.
+  [Application Load Balancer를 사용하여 애플리케이션 및 HTTP 트래픽 라우팅](alb-ingress.md) 
+  [Network Load Balancer를 사용하여 TCP 및 UDP 트래픽 라우팅](network-load-balancing.md) 