샘플 Linux 워크로드 배포 - Amazon EKS

샘플 Linux 워크로드 배포

이 주제에서는 Kubernetes 매니페스트를 생성하고 클러스터에 배포합니다.

Prerequisites

  • 샘플 애플리케이션을 배포하려면 기존 Kubernetes 클러스터가 있어야 합니다. 기존 클러스터가 없는 경우 Amazon EKS 시작하기 가이드 중 하나를 사용하여 Amazon EKS 클러스터를 배포할 수 있습니다.

  • 컴퓨터에 kubectl을 설치해야 합니다. 자세한 내용은 kubectl 설치 섹션을 참조하세요.

  • kubectl이 클러스터와 통신하도록 구성되어 있어야 합니다. 자세한 내용은 Amazon EKS용 kubeconfig 생성 섹션을 참조하세요.

샘플 애플리케이션을 배포하려면

  1. 샘플 앱에 대한 Kubernetes 네임스페이스를 만듭니다.

    kubectl create namespace <my-namespace>
  2. Kubernetes 서비스 및 배포를 만듭니다.

    1. 다음 콘텐츠를 컴퓨터에 sample-service.yaml이라는 파일에 저장합니다. AWS Fargate 포드에 배포하는 경우 namespace의 값이 AWS Fargate 프로필에 정의한 네임스페이스와 일치해야 합니다. 이 샘플 배포는 퍼블릭 리포지토리에서 컨테이너 이미지를 가져와 클러스터에 3개의 복제본을 배포합니다. 그런 다음 클러스터 내에서만 액세스할 수 있는 자체 IP 주소로 Kubernetes 서비스를 생성합니다. 클러스터 외부에서 서비스에 액세스하려면 네트워크 로드 밸런서 또는 ALB 수신 컨트롤러를 배포합니다.

      이미지는 다중 아키텍처 이미지입니다. 클러스터에 x86 및 Arm 노드가 모두 포함된 경우 두 유형의 하드웨어 아키텍처 중 하나에서 포드를 예약할 수 있습니다. Kubernetes는 포드를 예약하는 노드의 하드웨어 유형에 따라 적절한 하드웨어 이미지를 배포합니다. 또는 특정 하드웨어 아키텍처가 있는 노드에서만 배포를 실행하려는 경우 다음 예에서 amd64 또는 arm64를 제거합니다. 또는 클러스터에 하드웨어 아키텍처가 하나만 포함된 경우에도 동일한 작업을 수행합니다.

      apiVersion: v1 kind: Service metadata: name: my-service namespace: my-namespace labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/arch operator: In values: - amd64 - arm64 containers: - name: nginx image: public.ecr.aws/z9d2n7e1/nginx:1.19.5 ports: - containerPort: 80

      Kubernetes 서비스배포에 대한 자세한 내용은 Kubernetes 설명서를 참조하세요. 샘플 매니페스트의 컨테이너는 네트워크 스토리지를 사용하지 않지만, 사용할 수도 있습니다. 자세한 내용은 Storage 섹션을 참조하세요. 이 예에서는 구현되지 않았지만 포드에 대한 Kubernetes 서비스 계정을 생성하여 AWS IAM 계정에 연결하는 것이 좋습니다. 서비스 계정을 지정하여 포드가 다른 서비스와 상호 작용하는 데 필요한 최소 권한을 가질 수 있습니다. 자세한 내용은 서비스 계정에 대한 IAM 역할 섹션을 참조하세요.

    2. 애플리케이션을 배포합니다.

      kubectl apply -f <sample-service.yaml>
  3. my-namespace 네임스페이스에 있는 모든 리소스를 봅니다.

    kubectl get all -n my-namespace

    출력값은 다음과 같습니다.

    NAME READY STATUS RESTARTS AGE pod/my-deployment-776d8f8fd8-78w66 1/1 Running 0 27m pod/my-deployment-776d8f8fd8-dkjfr 1/1 Running 0 27m pod/my-deployment-776d8f8fd8-wmqj6 1/1 Running 0 27m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-service ClusterIP 10.100.190.12 <none> 80/TCP 32m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-deployment 3/3 3 3 27m NAME DESIRED CURRENT READY AGE replicaset.apps/my-deployment-776d8f8fd8 3 3 3 27m

    이 출력에는 이전 단계에서 배포된 샘플 매니페스트에 지정된 서비스 및 배포가 표시됩니다. 3개의 포드도 확인할 수 있습니다. 동일한 매니페스트에서 replicas에 대해 3을 지정했기 때문입니다. 포드에 대한 자세한 내용은 Kubernetes 문서의 포드를 참조하세요. Kubernetes는 샘플 매니페스트에 지정되지 않은 경우에도 자동으로 replicaset 리소스를 생성합니다. ReplicaSets에 대한 자세한 내용은 Kubernetes 설명서에서 ReplicaSet를 참조하세요.

    참고

    Kubernetes는 매니페스트에 지정된 복제본의 수를 유지합니다. 프로덕션 배포이고 Kubernetes가 복제본의 수를 수평적 또는 수직적으로 조정하여 포드의 컴퓨팅 리소스를 조정하도록 하려는 경우 Horizontal Pod AutoscalerVertical Pod Autoscaler를 사용하세요.

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

    kubectl -n <my-namespace> describe service <my-service>

    간략화된 출력은 다음과 같습니다.

    Name: my-service Namespace: my-namespace Labels: app=my-app Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"my-app"},"name":"my-service","namespace":"my-namespace"}... Selector: app=my-app Type: ClusterIP IP: 10.100.190.12 Port: <unset> 80/TCP TargetPort: 80/TCP ...

    출력에서 IP:의 값은 클러스터 내의 모든 포드에서 연결할 수 있는 고유한 IP 주소입니다.

  5. 배포된 포드 중 하나에 대한 세부 정보를 봅니다.

    kubectl -n <my-namespace> describe pod <my-deployment-776d8f8fd8-78w66>

    간략화된 출력은 다음과 같습니다.

    Name: my-deployment-776d8f8fd8-78w66 Namespace: my-namespace Priority: 0 Node: ip-192-168-9-36.us-west-2.compute.internal/192.168.9.36 ... IP: 192.168.16.57 IPs: IP: 192.168.16.57 Controlled By: ReplicaSet/my-deployment-776d8f8fd8 ... Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 3m20s default-scheduler Successfully assigned my-namespace/my-deployment-776d8f8fd8-78w66 to ip-192-168-9-36.us-west-2.compute.internal ...

    출력에서 IP:의 값은 기본적으로 CIDR 블록에서 포드에 할당되는 고유한 IP입니다. 이 CIDR 블록은 노드가 있는 서브넷에 할당됩니다. 포드에 다른 CIDR 블록의 IP 주소를 할당하려면 기본 동작을 변경할 수 있습니다. 자세한 내용은 CNI 사용자 지정 네트워킹 섹션을 참조하세요. Kubernetes 스케줄러가 IP 주소 192.168.9.36을 사용하여 노드의 포드를 예약했는지 확인할 수도 있습니다.

  6. 아래의 <value>를 3단계의 포드 중 하나에 대해 반환된 값으로 바꾸어 포드 중 하나에서 셸을 실행합니다.

    kubectl exec -it <my-deployment-776d8f8fd8-78w66> -n <my-namespace> -- /bin/bash
  7. DNS 확인자 구성 파일을 봅니다.

    cat /etc/resolv.conf

    출력값은 다음과 같습니다.

    nameserver 10.100.0.10 search my-namespace.svc.cluster.local svc.cluster.local cluster.local us-west-2.compute.internal options ndots:5

    이전 출력에서 nameserver는 클러스터의 이름 서버이며 클러스터에 배포된 포드의 이름 서버로 자동으로 할당됩니다.

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

  9. 샘플 서비스, 배포, 포드 및 네임스페이스를 제거합니다.

    kubectl delete namespace <my-namespace>