Kubernetes 에 애플리케이션 배포하기

KubernetesBeginner
지금 연습하기

소개

이 랩에서는 Kubernetes 클러스터에 애플리케이션을 배포하는 방법을 배우게 됩니다. Minikube 를 사용하여 Kubernetes 환경을 설정하는 것부터 시작합니다. 그런 다음 클러스터와 상호 작용하고 Kubernetes 리소스를 관리하기 위한 필수 kubectl 명령어를 탐색합니다. 다음으로 간단한 YAML 매니페스트 파일을 생성하고 클러스터에 적용한 후 배포 상태를 확인합니다. 마지막으로 kubectl proxy를 사용하여 배포된 애플리케이션에 액세스하는 방법을 배웁니다.

이 랩에서는 클러스터 설정, 기본 리소스 관리 및 애플리케이션 배포를 포함한 기본적인 Kubernetes 기술을 다룹니다. 이 랩이 끝나면 Kubernetes 를 사용하여 자체 애플리케이션을 배포하는 방법에 대한 확실한 이해를 갖게 될 것입니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 82%입니다.학습자들로부터 97%의 긍정적인 리뷰율을 받았습니다.

Kubernetes 클러스터 시작하기

이 단계에서는 Minikube 를 사용하여 Kubernetes 클러스터를 시작합니다. Minikube 는 가상화된 환경에서 단일 노드 Kubernetes 클러스터를 실행할 수 있게 해주므로 개발 및 Kubernetes 학습에 훌륭한 도구입니다. 그런 다음 클러스터가 올바르게 실행 중이며 사용할 준비가 되었는지 확인할 것입니다.

먼저 터미널을 엽니다. 이곳에서 컴퓨터와 상호 작용하는 명령을 입력하게 됩니다. Minikube 클러스터를 시작하려면 다음 명령을 입력하고 Enter 키를 누릅니다.

minikube start

이 명령은 Kubernetes 클러스터를 생성하고 시작하는 프로세스를 시작합니다. Minikube 는 필요한 구성 요소를 다운로드하고 클러스터를 구성합니다. Minikube 가 시작됨에 따라 터미널에 출력이 표시됩니다. 다음은 출력 예시입니다.

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

Minikube 가 시작되면 실행 중인지, Kubernetes 클러스터가 준비되었는지 확인해 보겠습니다. 다음 명령을 순서대로 실행하고 각 명령 후에 Enter 키를 누릅니다.

minikube status
kubectl get nodes

minikube status 명령은 Minikube 자체의 상태를 알려줍니다. kubectl get nodes 명령은 Kubernetes 클러스터와 통신하고 클러스터 내 노드 (컴퓨터) 에 대한 정보를 검색합니다. Minikube 는 단일 노드 클러스터이므로 하나의 노드가 나열되어야 합니다.

다음은 볼 수 있는 출력 예시입니다.

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

이 출력이 우리에게 무엇을 말해주는지 분석해 보겠습니다.

  1. minikube 상태는 host, kubelet, apiserver에 대해 Running으로 표시됩니다. 이는 Minikube 의 핵심 구성 요소가 올바르게 실행되고 있음을 나타냅니다.
  2. kubectl get nodesSTATUSReadyminikube라는 노드를 보여줍니다. Ready는 이 노드가 애플리케이션을 실행할 준비가 되었음을 의미합니다. ROLES 아래의 control-plane은 이 노드가 Kubernetes 클러스터의 제어 평면 역할을 하며 클러스터를 관리하고 오케스트레이션함을 나타냅니다.

이러한 명령은 다음을 확인합니다.

  1. Minikube 가 가상 머신 환경에서 실행 중입니다.
  2. Kubernetes 클러스터가 Minikube 에 의해 생성 및 구성되었습니다.
  3. Kubernetes 클러스터는 Ready 상태이며 사용할 준비가 되었습니다.
  4. minikube 노드가 제어 평면 역할을 하는 단일 노드 Kubernetes 클러스터가 있습니다.

기본 kubectl 명령어 및 구문 학습

이 단계에서는 기본적인 kubectl 명령어를 탐색합니다. kubectl은 Kubernetes 클러스터와 상호 작용할 수 있게 해주는 명령줄 도구입니다. Kubernetes 리소스를 관리하는 데 필수적입니다. 리소스를 보고 기본적인 Kubernetes 객체 관리를 이해하기 위해 kubectl을 사용하는 방법을 시연할 것입니다.

먼저 Kubernetes 클러스터 내의 네임스페이스를 탐색해 보겠습니다. 네임스페이스는 Kubernetes 리소스를 구성하는 방법입니다. 기본적으로 Kubernetes 클러스터에는 시스템 구성 요소 및 사용자 리소스를 위한 여러 네임스페이스가 있습니다. 네임스페이스 목록을 보려면 다음 명령을 실행합니다.

kubectl get namespaces

이 명령은 클러스터에서 사용 가능한 모든 네임스페이스를 나열합니다. 예시 출력:

NAME              STATUS   AGE
default           Active   10m
kube-node-lease   Active   10m
kube-public       Active   10m
kube-system       Active   10m

일반적으로 다음과 같은 기본 네임스페이스가 표시됩니다.

  • default: 다른 네임스페이스가 지정되지 않은 경우 사용자 생성 리소스의 기본 네임스페이스입니다.
  • kube-node-lease: 제어 평면이 노드의 상태를 추적하는 데 도움이 되는 노드 임대에 사용됩니다.
  • kube-public: 공개적으로 액세스할 수 있어야 하는 리소스에 사용됩니다 (민감한 정보에는 거의 사용되지 않음).
  • kube-system: 핵심 Kubernetes 구성 요소와 같은 시스템 수준 리소스를 포함합니다.

다음으로 kube-system 네임스페이스에서 실행 중인 시스템 구성 요소를 살펴보겠습니다. 많은 핵심 Kubernetes 구성 요소는 이 네임스페이스 내의 파드 (pod) 로 실행됩니다. 특정 네임스페이스의 파드를 보려면 -n 또는 --namespace 플래그 뒤에 네임스페이스 이름을 사용합니다. kube-system 네임스페이스의 파드를 보려면 다음 명령을 실행합니다.

kubectl get pods -n kube-system

이 명령은 kube-system 네임스페이스에서 실행 중인 모든 파드를 나열합니다. 예시 출력:

NAME                               READY   STATUS    RESTARTS   AGE
coredns-787d4945fb-j8rhx           1/1     Running   0          15m
etcd-minikube                       1/1     Running   0          15m
kube-apiserver-minikube             1/1     Running   0          15m
kube-controller-manager-minikube    1/1     Running   0          15m
kube-proxy-xb9rz                    1/1     Running   0          15m
kube-scheduler-minikube             1/1     Running   0          15m
storage-provisioner                 1/1     Running   0          15m

이 출력은 파드의 이름, READY 상태 (전체 컨테이너 중 준비된 컨테이너 수), STATUS(예: Running), RESTARTS 횟수 및 AGE를 보여줍니다. 이것들은 Kubernetes 를 작동시키는 필수 구성 요소입니다.

이제 몇 가지 기본 kubectl 명령어 패턴을 살펴보겠습니다. kubectl 명령어의 일반적인 구문은 다음과 같습니다.

kubectl [command] [TYPE] [NAME] [flags]

이를 분석해 보겠습니다.

  • kubectl: 명령줄 도구 자체입니다.
  • [command]: 수행하려는 작업을 지정합니다. 일반적인 명령어는 다음과 같습니다.
    • get: 하나 이상의 리소스를 표시합니다.
    • describe: 특정 리소스에 대한 세부 정보를 표시합니다.
    • create: 새 리소스를 생성합니다.
    • delete: 리소스를 삭제합니다.
    • apply: 리소스에 구성을 적용합니다. 나중에 이 명령어를 많이 사용하게 될 것입니다.
  • [TYPE]: 상호 작용하려는 Kubernetes 리소스 유형을 지정합니다. 일반적인 리소스 유형은 다음과 같습니다.
    • pods: Kubernetes 에서 가장 작은 배포 가능한 단위입니다.
    • deployments: 확장 및 업데이트를 위해 파드 세트를 관리합니다.
    • services: 파드에서 실행 중인 애플리케이션을 노출합니다.
    • nodes: Kubernetes 클러스터의 작업자 머신입니다.
    • namespaces: 리소스의 논리적 그룹입니다.
  • [NAME]: 특정 리소스의 이름입니다. 선택 사항입니다. 이름을 생략하면 kubectl은 지정된 유형의 모든 리소스에 대해 작동합니다.
  • [flags]: 명령어의 동작을 수정하는 선택적 플래그입니다 (예: -n <namespace>, -o wide).

몇 가지 예를 살펴보겠습니다.

## 기본 네임스페이스의 모든 리소스 가져오기
kubectl get all

## 특정 리소스 유형 설명 ( 'minikube' 노드)
kubectl describe nodes minikube

kubectl get all 명령은 default 네임스페이스의 모든 리소스 유형 (서비스, 배포, 파드 등) 에 대한 정보를 검색합니다. 예시 출력은 다음과 같을 수 있습니다.

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m

이는 default 네임스페이스에 kubernetes라는 service가 있음을 보여줍니다.

kubectl describe nodes minikube 명령은 상태, 용량, 주소 등을 포함하여 minikube 노드에 대한 많은 상세 정보를 제공합니다. 이는 노드의 상태 및 구성을 이해하는 데 유용합니다.

이러한 명령은 다음을 수행하는 데 도움이 됩니다.

  1. Kubernetes 클러스터 내의 리소스를 봅니다.
  2. 클러스터 구성 요소 및 현재 상태에 대한 자세한 정보를 얻습니다.
  3. kubectl의 기본 명령어 구조 및 구문을 이해합니다.

간단한 YAML 매니페스트 생성

첫 번째 YAML 매니페스트를 생성하기 전에, 작업하게 될 주요 Kubernetes 객체에 대해 이해하는 것이 중요합니다. 이러한 객체는 Kubernetes 내에서 애플리케이션을 관리하고 오케스트레이션하는 빌딩 블록입니다.

Kubernetes 객체 이해하기

  • Pod: Kubernetes 의 가장 기본적인 단위입니다. Pod 는 하나 이상의 컨테이너를 담을 수 있는 상자와 같습니다. Pod 내의 이러한 컨테이너는 동일한 네트워크와 스토리지를 공유합니다. Pod 를 애플리케이션의 단일 인스턴스로 생각하십시오.
  • Deployment: Deployment 는 Pod 를 관리하는 데 사용됩니다. 항상 원하는 수의 Pod 복제본이 실행되도록 보장합니다. Pod 가 실패하면 Deployment 가 자동으로 교체합니다. Deployment 는 또한 롤링 업데이트와 같이 제어된 방식으로 애플리케이션 업데이트를 처리합니다.
  • Service: Service 는 Pod 에서 실행 중인 애플리케이션에 액세스할 수 있는 안정적인 방법을 제공합니다. Pod 는 생성 및 삭제될 수 있으므로 IP 주소가 변경될 수 있습니다. Service 는 관리하는 Pod 세트를 항상 가리키는 고정 IP 주소와 DNS 이름을 제공합니다. 이를 통해 애플리케이션의 다른 부분이나 외부 사용자가 개별 Pod IP 를 추적할 필요 없이 애플리케이션에 안정적으로 액세스할 수 있습니다.

이러한 객체 간의 관계를 설명하는 다이어그램은 다음과 같습니다.

graph TD; A[Deployment] -->|Manages| B[Pods] B -->|Contains| C[Containers] B -->|Communicates via| D[Services] D -->|Exposes| E[External Clients]

이러한 객체를 이해하는 것은 YAML 매니페스트를 사용하여 원하는 상태와 구성을 정의할 것이기 때문에 중요합니다.

YAML 매니페스트 개요

Kubernetes 의 YAML 매니페스트는 생성하거나 관리하려는 Kubernetes 객체를 설명하는 YAML 형식으로 작성된 파일입니다. YAML 은 사람이 읽을 수 있는 데이터 직렬화 언어입니다. Kubernetes 매니페스트에 YAML 을 사용하는 것에는 몇 가지 이점이 있습니다.

  1. 선언적 관리: YAML 파일에 리소스의 원하는 상태를 설명합니다 (예: "애플리케이션 복제본 3 개를 실행하고 싶습니다"). 그러면 Kubernetes 는 실제 상태가 원하는 상태와 일치하도록 작동합니다. 이를 선언적 관리라고 합니다.
  2. 버전 관리: YAML 파일은 텍스트 기반이므로 Git 과 같은 버전 관리 시스템에 쉽게 저장할 수 있습니다. 이를 통해 Kubernetes 구성의 변경 사항을 추적하고, 이전 구성으로 롤백하고, 다른 사람과 협업할 수 있습니다.
  3. 재사용성 및 이식성: YAML 매니페스트를 최소한의 변경으로 다른 환경 (개발, 테스트, 프로덕션) 에서 재사용할 수 있습니다. 이를 통해 배포가 더 일관되고 재현 가능해집니다.

Kubernetes 객체 및 YAML 매니페스트의 기본 사항을 이해했으므로 첫 번째 매니페스트를 만들 준비가 되었습니다.

YAML 매니페스트 생성

먼저 프로젝트 디렉토리로 이동합니다. 홈 디렉토리 (~) 에 project 디렉토리가 있다고 가정합니다. 없는 경우 mkdir project를 사용하여 지금 생성합니다. 그런 다음 cd project를 사용하여 현재 디렉토리를 project로 변경합니다.

cd ~/project

다음으로 Kubernetes 매니페스트를 저장할 새 디렉토리를 만듭니다. k8s-manifests라고 이름을 지정합니다. mkdir 명령을 사용하여 디렉토리를 만들고 cd를 사용하여 해당 디렉토리로 이동합니다.

mkdir -p k8s-manifests
cd k8s-manifests

이제 첫 번째 YAML 매니페스트 파일을 만듭니다. 간단한 NGINX Pod 매니페스트부터 시작하겠습니다. NGINX 는 인기 있는 웹 서버입니다. 단일 NGINX 컨테이너를 실행하는 Pod 를 만들 것입니다. nano 텍스트 편집기를 사용하여 nginx-pod.yaml이라는 파일을 만듭니다.

nano nginx-pod.yaml

nano는 터미널에서 실행되는 간단한 텍스트 편집기입니다. nano가 열리면 다음 내용을 파일에 붙여넣습니다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

이 YAML 매니페스트의 각 부분을 이해해 보겠습니다.

  • apiVersion: v1: 이 객체를 생성하는 데 사용할 Kubernetes API 버전을 지정합니다. v1은 핵심 API 그룹이며 Pod, Service 및 네임스페이스와 같은 기본 객체에 사용됩니다.
  • kind: Pod: Pod 리소스를 정의하고 있음을 나타냅니다.
  • metadata:: 이름 및 레이블과 같은 Pod 에 대한 데이터를 포함합니다.
    • name: nginx-pod: Pod 의 이름을 nginx-pod로 설정합니다. 이것이 Kubernetes 내에서 이 Pod 를 참조하는 방법입니다.
    • labels:: 레이블은 객체에 첨부되는 키 - 값 쌍입니다. 객체 하위 집합을 구성하고 선택하는 데 사용됩니다. 여기서는 이 Pod 에 app: nginx 레이블을 추가하고 있습니다.
  • spec:: Pod 의 원하는 상태를 설명합니다.
    • containers:: Pod 내에서 실행할 컨테이너 목록입니다. 이 경우 컨테이너는 하나뿐입니다.
      • - name: nginx: 컨테이너의 이름을 nginx로 설정합니다.
      • image: nginx:latest: 사용할 컨테이너 이미지를 지정합니다. nginx:latest는 Docker Hub 의 NGINX Docker 이미지 최신 버전을 참조합니다.
      • ports:: 이 컨테이너가 노출할 포트 목록입니다.
        • - containerPort: 80: 컨테이너가 포트 80 을 노출함을 지정합니다. 포트 80 은 표준 HTTP 포트입니다.

내용을 붙여넣은 후 파일을 저장하고 nano를 종료합니다. 이렇게 하려면 Ctrl+X(종료) 를 누르고 Y(저장 확인) 를 입력한 다음 Enter 키를 눌러 파일 이름을 확인하고 저장합니다.

nginx-pod.yaml 파일을 생성했으므로 Pod 를 생성하기 위해 Kubernetes 클러스터에 적용해야 합니다. 매니페스트가 포함된 파일을 지정하는 -f 플래그와 함께 kubectl apply 명령을 사용합니다.

kubectl apply -f nginx-pod.yaml

이 명령은 매니페스트를 Kubernetes 클러스터로 보내고 Kubernetes 는 정의된 대로 Pod 를 생성합니다. 다음과 유사한 출력이 표시됩니다.

pod/nginx-pod created

Pod 가 생성되어 실행 중인지 확인하려면 kubectl get pods 명령을 사용합니다. 이렇게 하면 기본 네임스페이스의 모든 Pod 가 나열됩니다. kubectl describe pod nginx-pod를 사용하여 nginx-pod에 대한 자세한 정보를 얻을 수도 있습니다. 다음 명령을 실행합니다.

kubectl get pods
kubectl describe pod nginx-pod

kubectl get pods에 대한 예시 출력:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

이 출력은 nginx-podREADY (1 개의 컨테이너 중 1 개가 준비됨) 이고 STATUSRunning임을 보여줍니다. 이는 NGINX Pod 가 성공적으로 생성되어 실행 중임을 의미합니다.

이제 더 복잡한 리소스인 Deployment 에 대한 매니페스트를 만들어 보겠습니다. Deployment 는 Pod 세트를 관리하여 원하는 수의 복제본이 실행되도록 보장합니다. nano를 사용하여 nginx-deployment.yaml이라는 새 파일을 만듭니다.

nano nginx-deployment.yaml

nginx-deployment.yaml에 다음 내용을 붙여넣습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

nginx-pod.yaml 매니페스트와 비교하여 주요 차이점과 새로운 부분을 강조해 보겠습니다.

  • apiVersion: apps/v1: Deployment 의 경우 apps API 그룹의 일부이며 상위 수준 애플리케이션 관리 리소스를 처리하는 apps/v1 API 버전을 사용합니다.
  • kind: Deployment: Deployment 리소스를 정의하고 있음을 나타냅니다.
  • spec:: Deployment 의 spec 섹션은 Deployment 가 Pod 를 관리하는 방법을 정의하므로 더 복잡합니다.
    • replicas: 3: 이것이 새로운 부분입니다. 실행하려는 Pod 의 복제본 (사본) 3 개를 원한다고 지정합니다. Deployment 는 template에 정의된 기준과 일치하는 Pod 가 항상 3 개 있도록 보장합니다.
    • selector:: Deployment 가 관리할 Pod 를 식별하는 데 사용되는 선택기입니다.
      • matchLabels:: 이 Deployment 에서 선택하려면 Pod 가 가져야 하는 레이블을 정의합니다. 여기서는 app: nginx 레이블이 있는 Pod 를 선택합니다.
    • template:: template은 Deployment 가 새 Pod 를 생성하는 데 사용할 Pod 사양을 정의합니다. 이는 metadata.labelsspec.containers를 포함하여 nginx-pod.yaml 예제와 본질적으로 동일한 Pod 정의입니다. 중요: 여기서 template.metadata.labels에 정의된 레이블은 Deployment 가 이러한 Pod 를 관리할 수 있도록 selector.matchLabels와 일치해야 합니다.

nano를 저장하고 종료합니다 (Ctrl+X, Y, Enter).

이제 이 Deployment 매니페스트를 클러스터에 적용합니다.

kubectl apply -f nginx-deployment.yaml

다음과 같은 출력이 표시됩니다.

deployment.apps/nginx-deployment created

Deployment 및 생성된 Pod 를 확인합니다. kubectl get deployments를 사용하여 Deployment 상태를 확인하고 kubectl get pods를 사용하여 Pod 를 확인합니다.

kubectl get deployments
kubectl get pods

예시 출력:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m
  • kubectl get deploymentsnginx-deploymentREADY 3/3, UP-TO-DATE 3, AVAILABLE 3 임을 보여줍니다. 이는 Deployment 가 성공적으로 3 개의 Pod 를 생성하고 관리하고 있으며 모두 준비되고 사용 가능한 상태임을 의미합니다.
  • kubectl get pods는 이제 이름이 nginx-deployment-로 시작하는 세 개의 Pod 를 나열합니다. 이것들은 nginx-deployment에 의해 생성되고 관리되는 Pod 입니다.

YAML 매니페스트 적용

이 단계에서는 kubectl apply 명령어를 더 자세히 살펴보고 Kubernetes 매니페스트를 적용하는 다양한 방법을 배웁니다. 이전 단계의 YAML 파일을 기반으로 매니페스트를 적용하는 다양한 기술을 시연할 것입니다.

먼저 올바른 디렉토리에 있는지 확인합니다.

cd ~/project/k8s-manifests

매니페스트를 더 체계적으로 구성하기 위해 새 하위 디렉토리를 만듭니다. manifests라는 디렉토리를 만들고 해당 디렉토리로 이동합니다.

mkdir -p manifests
cd manifests

이제 단일 파일에 Deployment 와 Service 를 모두 포함하는 간단한 웹 애플리케이션에 대한 매니페스트를 만들어 보겠습니다. nano를 사용하여 web-app.yaml이라는 새 파일을 만듭니다.

nano web-app.yaml

web-app.yaml에 다음 내용을 추가합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

이 매니페스트는 ---로 구분된 단일 파일에 두 개의 Kubernetes 리소스 정의를 포함합니다. 이것은 관련 리소스를 함께 그룹화하는 일반적인 방법입니다. 새로 추가된 부분을 분석해 보겠습니다.

  • 단일 파일의 여러 리소스: web-app.yaml 파일에는 이제 두 개의 별도 Kubernetes 리소스 정의, 즉 Deployment 와 Service 가 포함됩니다. --- 구분 기호는 이들을 구별하는 데 사용됩니다.
  • kind: Service: Service 리소스를 정의합니다.
    • spec.selector.app: web: 이 Service 는 app: web 레이블이 있는 Pod 를 대상으로 합니다. 이는 web-app Deployment 에서 생성된 Pod 에 설정한 레이블과 일치합니다.
    • spec.type: ClusterIP: 서비스 유형을 ClusterIP로 지정합니다. 이는 서비스가 클러스터 내의 내부 IP 주소에 노출되며 일반적으로 클러스터 내 서비스 간 통신에 사용됨을 의미합니다.
    • spec.ports: 서비스가 포트를 대상 Pod 에 매핑하는 방법을 정의합니다.
      • port: 80: 액세스할 Service 자체의 포트입니다.
      • targetPort: 80: 서비스가 트래픽을 전달할 대상 Pod 의 포트입니다.

이제 다양한 방법을 사용하여 이 매니페스트를 적용해 보겠습니다.

방법 1: 전체 파일 적용

이것은 매니페스트를 적용하는 가장 일반적인 방법입니다. kubectl apply -f 뒤에 파일 이름을 사용합니다.

kubectl apply -f web-app.yaml

이 명령은 web-app.yaml에 정의된 Deployment 와 Service 를 모두 생성합니다. 다음과 같은 출력이 표시됩니다.

deployment.apps/web-app created
service/web-service created

방법 2: 디렉토리에서 적용

디렉토리의 모든 매니페스트를 한 번에 적용할 수 있습니다. manifests 디렉토리에 여러 매니페스트 파일이 있는 경우 특정 파일 대신 디렉토리를 지정하여 모두 적용할 수 있습니다.

kubectl apply -f .

.은 현재 디렉토리를 나타냅니다. kubectl은 이 디렉토리에서 YAML 파일을 찾고 모두 적용합니다. 이는 매니페스트를 디렉토리 내의 여러 파일로 구성한 경우 유용합니다.

방법 3: URL 에서 적용 (선택 사항)

kubectl apply는 URL 에서 직접 매니페스트를 적용할 수도 있습니다. 이는 온라인에 호스팅된 예제 애플리케이션 또는 구성을 신속하게 배포하는 데 유용합니다. 예를 들어 Kubernetes 예제 리포지토리에서 Redis 마스터 Deployment 를 배포할 수 있습니다.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml

이렇게 하면 URL 에서 매니페스트를 다운로드하여 클러스터에 적용합니다. 참고: 신뢰할 수 없는 URL 의 매니페스트를 적용할 때는 주의하십시오. 클러스터를 수정할 수 있습니다.

kubectl apply에 대한 몇 가지 추가 옵션을 살펴보겠습니다.

Dry Run

--dry-run=client 플래그를 사용하여 클러스터에 실제로 변경하지 않고 매니페스트를 적용하는 것을 시뮬레이션할 수 있습니다. 이는 매니페스트가 유효한지 확인하고 생성되거나 수정될 리소스를 확인하는 데 유용합니다.

kubectl apply -f web-app.yaml --dry-run=client

이 명령은 생성되거나 변경될 내용을 출력하지만 클러스터에 실제로 변경 사항을 적용하지는 않습니다.

상세 출력

kubectl apply에서 더 자세한 출력을 얻으려면 -v 플래그 뒤에 상세 수준 (예: -v=7) 을 사용할 수 있습니다. 상세 수준이 높을수록 더 자세한 정보가 제공되며 디버깅에 도움이 될 수 있습니다.

kubectl apply -f web-app.yaml -v=7

이렇게 하면 수행되는 API 요청 및 매니페스트 처리와 관련된 훨씬 더 많은 정보가 출력됩니다.

web-app.yaml을 적용하여 생성된 리소스를 확인합니다. kubectl get deploymentskubectl get services를 사용하여 클러스터의 Deployment 및 Service 를 나열합니다.

## 배포 목록 가져오기
kubectl get deployments

## 서비스 목록 가져오기
kubectl get services

## 배포에 대한 자세한 내용을 보려면 설명합니다.
kubectl describe deployment web-app

kubectl get deployments에 대한 예시 출력:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m33s
redis-master       0/1     1            0           23s
web-app            2/2     2            2           42s

kubectl get services에 대한 예시 출력:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   8m28s
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    46s

이제 2/2 READY 복제본이 있는 web-app Deployment 와 ClusterIP 유형의 web-service가 있음을 알 수 있습니다.

Kubernetes 에서 선언적 관리와 명령형 관리의 차이점을 kubectl applykubectl create의 맥락에서 간략하게 논의해 보겠습니다.

  • kubectl apply: 선언적 접근 방식을 사용합니다. 매니페스트 파일에 원하는 상태를 정의하고 kubectl apply는 해당 상태를 달성하려고 시도합니다. 동일한 매니페스트로 kubectl apply를 여러 번 실행하면 매니페스트의 원하는 상태와 클러스터의 현재 상태 간에 차이가 있는 경우에만 Kubernetes 가 변경합니다. kubectl apply는 일반적으로 Kubernetes 리소스를 관리하는 데 권장됩니다. 이는 더 강력하고 시간이 지남에 따라 변경 사항을 관리하기 쉽기 때문입니다. 리소스 구성을 추적하고 점진적인 업데이트를 허용합니다.
  • kubectl create: 명령형 접근 방식을 사용합니다. Kubernetes 에 리소스를 생성하도록 직접 지시합니다. 이미 존재하는 리소스에 대해 kubectl create를 실행하려고 하면 일반적으로 오류가 발생합니다. kubectl createkubectl apply에 비해 업데이트 및 변경 사항을 관리하는 데 유연성이 떨어집니다.

대부분의 경우, 특히 애플리케이션 배포를 관리할 때 kubectl apply가 선호되고 권장되는 방법입니다. 이는 선언적 특성과 업데이트 및 구성 관리를 더 잘 처리하기 때문입니다.

Deployment 상태 확인

이 단계에서는 다양한 kubectl 명령어를 사용하여 Kubernetes 배포 및 기타 리소스의 상태를 검사하고 확인하는 방법을 배웁니다. Kubernetes 클러스터 내에서 실행 중인 애플리케이션 및 해당 상태에 대한 정보를 수집하는 다양한 방법을 탐색할 것입니다.

먼저 프로젝트 내의 manifests 디렉토리에 있는지 확인합니다.

cd ~/project/k8s-manifests/manifests

먼저 현재 네임스페이스 (변경하지 않은 경우 default) 의 모든 배포를 나열하는 것부터 시작하겠습니다. kubectl get deployments를 사용합니다.

kubectl get deployments

이 명령은 배포에 대한 간결한 개요를 제공합니다. 예시 출력:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m44s
redis-master       1/1     1            1           94s
web-app            2/2     2            2           113s

각 열의 의미는 다음과 같습니다.

  • NAME: 배포의 이름입니다.
  • READY: 준비된 복제본 수 대 원하는 복제본 수 (예: 3/3은 원하는 복제본 3 개가 준비되었음을 의미) 를 보여줍니다.
  • UP-TO-DATE: 최신 원하는 상태로 업데이트된 복제본 수를 나타냅니다.
  • AVAILABLE: 현재 트래픽을 처리할 수 있는 복제본 수를 보여줍니다.
  • AGE: 배포가 실행된 시간입니다.

더 넓은 형식으로 더 자세한 정보를 얻으려면 kubectl get deployments-o wide 플래그를 사용할 수 있습니다.

kubectl get deployments -o wide

예시 출력:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                      SELECTOR
nginx-deployment   3/3     3            3           4m58s   nginx        nginx:latest                app=nginx
redis-master       1/1     1            1           108s    master       registry.k8s.io/redis:e2e   app=redis,role=master,tier=backend
web-app            2/2     2            2           2m7s    web          nginx:alpine                app=web

-o wide 출력에는 CONTAINERS, IMAGES, SELECTOR와 같은 추가 열이 포함되어 배포에 대한 더 많은 컨텍스트를 제공합니다.

특정 배포에 포함된 Pod 를 검사하려면 레이블을 사용할 수 있습니다. web-app Deployment 매니페스트에서 Pod 에 app: web 레이블을 설정했음을 기억하십시오. 이 레이블을 사용하여 kubectl get pods -l <label_selector>로 Pod 를 필터링할 수 있습니다. web-app 배포와 관련된 Pod 를 보려면 다음을 실행합니다.

kubectl get pods -l app=web

예시 출력:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          10m
web-app-xxx-zzz           1/1     Running   0          10m

이렇게 하면 app=web 레이블 선택기와 일치하는 Pod, 즉 web-app Deployment 에서 관리하는 Pod 가 나열됩니다.

특정 배포에 대한 심층 정보를 얻으려면 kubectl describe deployment <deployment_name>을 사용합니다. web-app 배포를 설명해 보겠습니다.

kubectl describe deployment web-app

kubectl describe는 다음을 포함하여 배포에 대한 풍부한 정보를 제공합니다.

  • Name, Namespace, CreationTimestamp, Labels, Annotations: 배포에 대한 기본 메타데이터입니다.
  • Selector: 이 배포에서 관리하는 Pod 를 식별하는 데 사용되는 레이블 선택기입니다.
  • Replicas: 원하는, 업데이트된, 총, 사용 가능한 및 사용 불가능한 복제본 수입니다.
  • StrategyType, RollingUpdateStrategy: 업데이트 전략 (예: RollingUpdate) 에 대한 세부 정보입니다.
  • Pod Template: 이 배포에 대한 Pod 를 생성하는 데 사용되는 사양입니다.
  • Conditions: 배포 상태를 나타내는 조건 (예: Available, Progressing) 입니다.
  • Events: 배포와 관련된 이벤트 목록으로, 문제 해결에 도움이 될 수 있습니다.

describe 출력에서 ConditionsEvents 섹션을 살펴보십시오. 이러한 섹션은 배포에 문제가 있는 경우 단서를 제공하는 경우가 많습니다. 예를 들어 배포가 Available 상태가 되지 않으면 Events에 이미지 풀링 오류, Pod 생성 실패 등과 관련된 오류가 표시될 수 있습니다.

서비스 상태를 확인하려면 유사한 명령어를 사용할 수 있습니다. 먼저 모든 서비스를 나열합니다.

kubectl get services

예시 출력:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   10m
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    2m47s

이렇게 하면 web-service와 해당 TYPE (ClusterIP), CLUSTER-IP, 노출된 PORT(S)가 표시됩니다.

서비스에 대한 자세한 내용을 보려면 kubectl describe service <service_name>을 사용합니다.

kubectl describe service web-service

describe service 출력에는 다음이 포함됩니다.

  • Name, Namespace, Labels, Annotations: 기본 메타데이터입니다.
  • Selector: 대상 Pod 를 식별하는 데 사용되는 레이블 선택기입니다.
  • Type: 서비스 유형 (이 경우 ClusterIP) 입니다.
  • IP, IPs: 서비스에 할당된 클러스터 IP 주소입니다.
  • Port, TargetPort: 서비스에 대해 정의된 포트 매핑입니다.
  • Endpoints: 현재 이 서비스를 지원하는 Pod 의 IP 주소와 포트를 보여줍니다. 이것은 매우 중요합니다. 엔드포인트가 보이지 않으면 서비스가 올바르게 Pod 에 연결되지 않은 것이며, 이는 선택기 불일치 때문일 가능성이 높습니다.
  • Session Affinity, Events: 기타 서비스 구성 및 이벤트입니다.

배포 상태를 확인할 때 주요 확인 사항은 다음과 같습니다.

  • Deployment READY 상태: 원하는 복제본 수 (예: web-app의 경우 2/2) 를 표시하는지 확인합니다.
  • Pod STATUS: 모든 Pod 는 Running 상태여야 합니다.
  • Service Endpoints: 서비스에 엔드포인트가 있고 실행 중인 Pod 의 IP 주소에 해당하는지 확인합니다. 엔드포인트가 없으면 서비스의 선택기와 Pod 레이블을 문제 해결합니다.
  • 경고 또는 오류 확인: Events 섹션에서 비정상적인 조건이나 오류가 있는지 kubectl describe deployment <deployment_name>kubectl describe service <service_name>의 출력을 검토합니다.

이러한 kubectl 명령어를 사용하면 Kubernetes 에서 배포 및 서비스의 상태를 효과적으로 모니터링하고 확인할 수 있으며 애플리케이션이 예상대로 실행되도록 보장할 수 있습니다.

kubectl proxy 를 사용하여 애플리케이션 액세스

이 단계에서는 kubectl proxy를 사용하여 Kubernetes 애플리케이션에 액세스하는 방법을 배웁니다. kubectl proxy는 Kubernetes API 서버에 대한 보안 프록시 연결을 생성하여 현재 환경에서 클러스터 서비스 및 Pod 에 액세스할 수 있도록 합니다. 이는 개발 및 디버깅에 매우 유용하며, 특히 외부로 노출되지 않은 서비스에 액세스하려는 경우에 유용합니다.

먼저 프로젝트 디렉토리에 있는지 확인합니다.

cd ~/project/k8s-manifests/manifests

백그라운드에서 kubectl proxy를 시작합니다. 이 명령은 프록시를 별도의 프로세스로 실행하여 터미널을 계속 사용할 수 있도록 합니다.

kubectl proxy --port=8080 &

명령 끝의 &는 백그라운드에서 실행합니다. 다음과 유사한 출력이 표시됩니다.

Starting to serve on 127.0.0.1:8080

이 명령을 실행한 후 터미널이 멈춘 것처럼 보이면 프롬프트로 돌아가기 위해 Ctrl+C를 한 번 눌러야 할 수 있습니다. 프록시는 백그라운드에서 계속 실행되어야 합니다.

이제 web-app 배포의 일부인 Pod 이름을 찾아보겠습니다. kubectl get pods -l app=web을 다시 사용할 수 있습니다.

## 'web-app'에 대한 Pod 이름 가져오기
kubectl get pods -l app=web

예시 출력:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          20m
web-app-xxx-zzz           1/1     Running   0          20m

Pod 이름 중 하나 (예: web-app-xxx-yyy) 를 기록해 둡니다. 이 Pod 이름을 사용하여 해당 Pod 에서 실행 중인 NGINX 웹 서버에 액세스하기 위한 API 경로를 구성합니다.

Kubernetes API 리소스는 특정 경로를 통해 액세스할 수 있습니다. kubectl proxy를 통해 Pod 에 액세스하려면 다음과 같은 URL 을 구성해야 합니다.

http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod_name>/proxy/

이 URL 을 분석해 보겠습니다.

  • http://localhost:8080: kubectl proxy가 실행 중인 주소입니다. 기본적으로 현재 환경의 포트 8080 에서 수신 대기합니다.
  • /api/v1: Kubernetes API 버전 (v1) 을 지정합니다.
  • /namespaces/<namespace>: Pod 가 실행 중인 네임스페이스입니다. 이 경우 default입니다.
  • /pods/<pod_name>: 액세스하려는 Pod 의 이름입니다. <pod_name>을 실제 Pod 이름 (예: web-app-xxx-yyy) 으로 바꿉니다.
  • /proxy/: Pod 에 대한 연결을 프록시하려는 것을 나타냅니다.

URL 에서 Pod 이름을 더 쉽게 사용하기 위해 첫 번째 Pod 의 이름을 셸 변수에 저장해 보겠습니다. kubectl get podsjsonpath를 사용하여 레이블 app=web이 있는 첫 번째 Pod 의 이름을 추출하는 이 명령을 실행합니다.

## 레이블 'app=web'이 있는 첫 번째 Pod의 이름 가져오기
POD_NAME=$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
echo $POD_NAME ## 선택 사항: Pod 이름을 출력하여 확인

이제 curl 명령에서 $POD_NAME 변수를 사용하여 Pod 에서 제공하는 NGINX 기본 페이지에 액세스할 수 있습니다. curl을 사용하여 프록시 URL 로 HTTP 요청을 보냅니다. URL 에서 ${POD_NAME}을 방금 설정한 변수로 바꿉니다.

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}/proxy/

모든 것이 올바르게 작동하면 이 명령은 기본 NGINX 환영 페이지의 HTML 콘텐츠를 반환해야 합니다. 예시 출력은 다음과 같은 HTML 콘텐츠입니다.

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    ...
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    ...
  </body>
</html>

이 출력은 kubectl proxy를 통해 Pod 내부에서 실행 중인 NGINX 웹 서버에 성공적으로 액세스했음을 확인합니다.

kubectl proxy로 할 수 있는 몇 가지 추가 사항을 살펴보겠습니다.

프록시를 통해 기본 네임스페이스의 모든 Pod 나열:

프록시를 통해 Kubernetes API 에 직접 액세스할 수 있습니다. 예를 들어 default 네임스페이스의 모든 Pod 를 나열하려면 이 URL 을 사용할 수 있습니다.

curl http://localhost:8080/api/v1/namespaces/default/pods/

이렇게 하면 default 네임스페이스의 모든 Pod 에 대한 정보가 포함된 JSON 응답이 반환됩니다.

프록시를 통해 특정 Pod 에 대한 자세한 정보 가져오기:

특정 Pod 에 대한 자세한 정보 ( kubectl describe pod와 유사) 를 얻으려면 Pod 의 API 엔드포인트에 직접 액세스할 수 있습니다.

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}

이렇게 하면 지정된 Pod 에 대한 자세한 정보가 포함된 JSON 응답이 반환됩니다.

kubectl proxy 중지:

kubectl proxy 사용을 마치면 중지해야 합니다. 백그라운드에서 시작했으므로 프로세스 ID(PID) 를 찾아 종료해야 합니다. jobs 명령을 사용하여 백그라운드 프로세스를 나열할 수 있습니다.

jobs

이렇게 하면 현재 터미널 세션에서 실행 중인 백그라운드 프로세스가 나열됩니다. kubectl proxy가 나열된 것을 볼 수 있습니다. 중지하려면 kill 명령 다음에 프로세스 ID 를 사용합니다. 예를 들어 jobs[1] Running kubectl proxy --port=8080 &를 표시하면 프로세스 ID 는 1입니다. 다음을 사용합니다.

kill %1

jobs 명령에서 표시된 작업 ID 로 %1을 바꿉니다. 또는 ps aux | grep kubectl proxy를 사용하여 프로세스 ID 를 찾은 다음 kill <PID>를 사용할 수 있습니다.

kubectl proxy에 대해 기억해야 할 주요 사항:

  • kubectl proxy는 Kubernetes API 서버에 대한 안전하고 인증된 연결을 생성합니다.
  • 클러스터 네트워크 내부에 있는 것처럼 현재 환경에서 클러스터 리소스 (Pod, 서비스 등) 에 액세스할 수 있습니다.
  • 디버깅, 개발 및 Kubernetes API 탐색에 매우 유용합니다.
  • 보안상의 이유로 kubectl proxylocalhost(127.0.0.1) 에서만 액세스할 수 있습니다. 서비스를 공개적으로 노출하는 데 사용하도록 만들어지지 않았습니다.

요약

이 실습에서는 Minikube 를 사용하여 Kubernetes 클러스터에 애플리케이션을 배포하는 방법을 성공적으로 배웠습니다. Minikube 로 Kubernetes 클러스터를 설정하고 상태를 확인하는 것부터 시작했습니다. 그런 다음 클러스터와 상호 작용하고 리소스를 관리하기 위한 필수 kubectl 명령을 탐색했습니다. 네임스페이스를 나열하고, 노드 및 Pod 에 대한 세부 정보를 가져오고, kubectl의 기본 명령 구조를 이해하는 방법을 배웠습니다. 이러한 단계를 통해 Kubernetes 작업을 위한 견고한 기반을 마련했습니다.

Pod 및 Deployment 에 대한 간단한 YAML 매니페스트를 생성하고, kubectl apply를 사용하여 클러스터에 적용하고, getdescribe와 같은 다양한 kubectl 명령을 사용하여 배포 상태를 확인했습니다. 이러한 실습 경험을 통해 Kubernetes 에서 애플리케이션을 배포하는 선언적 접근 방식과 클러스터와 효과적으로 상호 작용하는 방법을 이해할 수 있었습니다.

마지막으로 kubectl proxy를 사용하여 배포된 애플리케이션에 액세스하는 방법을 배웠습니다. 이는 클러스터의 API 와 상호 작용하고 현재 환경에서 서비스 및 Pod 에 액세스하는 안전한 방법을 제공합니다. 이는 개발, 디버깅 및 Kubernetes 환경 탐색에 유용한 기술입니다.

이 실습을 완료함으로써 필수적인 Kubernetes 개념 및 도구에 대한 실용적인 경험을 쌓았으며, Kubernetes 에서 더 복잡한 애플리케이션을 배포하고 관리하는 경로를 설정했습니다.