소개
이 랩에서는 내부 및 외부 서비스를 생성하고, 레이블을 사용하며, Ingress 의 기본 사항을 탐구하는 등 다양한 기술을 사용하여 Kubernetes 애플리케이션을 노출하는 방법을 배우게 됩니다. 먼저 Minikube 를 사용하여 로컬 Kubernetes 클러스터를 설정한 다음, 샘플 NGINX 애플리케이션을 배포하고 내부 및 외부에서 모두 노출합니다. 또한 레이블을 사용하여 리소스를 구성하고 선택하는 방법을 살펴보고, 마지막으로 간단한 예제를 통해 Ingress 에 대한 간략한 소개를 받습니다. Ingress 는 복잡한 주제이므로, 이 랩에서는 개념에 대한 기본적인 소개만 제공합니다.
Kubernetes 클러스터 시작하기
이 단계에서는 Minikube 를 사용하여 로컬 Kubernetes 클러스터를 시작하고 확인하는 방법을 배우게 됩니다. 이는 로컬 머신에서 Kubernetes 애플리케이션을 개발하고 테스트하기 위한 필수적인 첫 번째 단계입니다.
먼저, Minikube 클러스터를 시작합니다:
minikube start
예시 출력:
😄 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 status
kubectl get nodes
minikube status의 예시 출력:
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
kubectl get nodes의 예시 출력:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 1m v1.26.1
이러한 명령은 다음을 확인합니다:
- Minikube 가 성공적으로 실행 중입니다.
- 로컬 Kubernetes 클러스터가 생성되었습니다.
- 클러스터가 사용할 준비가 되었습니다.
- 제어 평면 (control plane) 기능을 갖춘 단일 노드 클러스터가 있습니다.
샘플 애플리케이션 배포
이 단계에서는 YAML 매니페스트를 사용하여 Kubernetes 애플리케이션을 생성하고 배포하는 방법을 배우게 됩니다. Kubernetes 리소스를 정의하고 적용하는 과정을 보여주기 위해 간단한 NGINX 웹 서버 배포를 생성합니다.
먼저, Kubernetes 매니페스트를 위한 디렉토리를 생성합니다:
mkdir -p ~/project/k8s-manifests
cd ~/project/k8s-manifests
NGINX 배포를 위한 YAML 파일을 생성합니다:
nano 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
파일을 저장합니다 (Ctrl+X, Y, Enter).
Kubernetes 클러스터에 배포를 적용합니다:
kubectl apply -f nginx-deployment.yaml
예시 출력:
deployment.apps/nginx-deployment created
배포 및 파드를 확인합니다:
kubectl get deployments
kubectl get pods
kubectl get deployments의 예시 출력:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 1m
kubectl get pods의 예시 출력:
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
파드가 "Running" 상태가 될 때까지 기다린 후 진행합니다.
YAML 매니페스트를 자세히 살펴보겠습니다:
apiVersion: Kubernetes API 버전을 지정합니다.kind: 리소스 유형 (Deployment) 을 정의합니다.metadata: 배포에 대한 이름과 레이블을 제공합니다.spec.replicas: 파드 복제본의 수를 설정합니다.selector: 배포가 올바른 파드를 관리하도록 돕습니다.template: 파드 사양을 정의합니다.containers: 컨테이너 이미지와 포트를 지정합니다.
이 배포는 세 개의 동일한 NGINX 파드를 생성하여 Kubernetes 가 컨테이너화된 애플리케이션을 관리하는 방법을 보여줍니다.
YAML 을 사용하여 내부 또는 외부에서 애플리케이션을 노출하는 서비스 생성
이 단계에서는 NGINX 배포를 내부 및 외부로 노출하기 위해 Kubernetes 서비스를 생성하는 방법을 배우게 됩니다. 두 가지 일반적인 서비스 유형인 ClusterIP 와 NodePort 를 시연합니다.
먼저, 프로젝트 디렉토리로 이동합니다:
cd ~/project/k8s-manifests
ClusterIP 서비스 YAML 파일을 생성합니다:
nano nginx-clusterip-service.yaml
다음 서비스 매니페스트를 추가합니다:
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip-service
spec:
selector:
app: nginx
type: ClusterIP
ports:
- port: 80
targetPort: 80
이제 NodePort 서비스 YAML 파일을 생성합니다:
nano nginx-nodeport-service.yaml
다음 서비스 매니페스트를 추가합니다:
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport-service
spec:
selector:
app: nginx
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080
두 서비스 구성을 적용합니다:
kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml
예시 출력:
service/nginx-clusterip-service created
service/nginx-nodeport-service created
서비스를 확인합니다:
kubectl get services
예시 출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m
nginx-clusterip-service ClusterIP 10.104.xxx.xxx <none> 80/TCP 1m
nginx-nodeport-service NodePort 10.108.yyy.yyy <none> 80:30080/TCP 1m
NodePort 서비스에 액세스하려면 Minikube IP 를 가져옵니다:
minikube ip
예시 출력:
192.168.49.2
서비스 유형 간의 주요 차이점:
- ClusterIP: 내부 클러스터 액세스만 가능
- NodePort: 각 노드의 IP 에서 고정 포트로 서비스를 노출
- NodePort 범위: 30000-32767
서비스 구성 확인
이 단계에서는 kubectl describe service를 사용하여 Kubernetes 서비스의 상세 구성을 검사하고 네트워크 속성을 이해하는 방법을 배우게 됩니다.
먼저, 프로젝트 디렉토리에 있는지 확인합니다:
cd ~/project/k8s-manifests
ClusterIP 서비스를 자세히 설명합니다:
kubectl describe service nginx-clusterip-service
예시 출력:
Name: nginx-clusterip-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.104.xxx.xxx
IPs: 10.104.xxx.xxx
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity: None
Events: <none>
이제 NodePort 서비스를 설명합니다:
kubectl describe service nginx-nodeport-service
예시 출력:
Name: nginx-nodeport-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.108.yyy.yyy
IPs: 10.108.yyy.yyy
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30080/TCP
Endpoints: 10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
네트워크 연결을 확인하기 위해 서비스 엔드포인트를 검사합니다:
kubectl get endpoints
예시 출력:
NAME ENDPOINTS AGE
kubernetes 192.168.49.2:8443 45m
nginx-clusterip-service 10.244.0.7:80,10.244.0.8:80,10.244.0.9:80 15m
nginx-nodeport-service 10.244.0.7:80,10.244.0.8:80,10.244.0.9:80 15m
서비스 설명에서 이해해야 할 주요 정보:
- Selector: 서비스에 속한 파드를 보여줍니다.
- IP: 서비스의 클러스터 내부 IP 주소입니다.
- Endpoints: 서비스를 제공하는 파드 IP 주소 및 포트 목록입니다.
- Port 및 TargetPort: 트래픽 라우팅 방식을 정의합니다.
- NodePort: NodePort 서비스 유형의 외부 포트입니다.
레이블을 사용하여 리소스 구성 및 선택
이 단계에서는 Kubernetes 에서 레이블을 사용하여 리소스를 효율적으로 구성하고 선택하는 방법을 배우게 됩니다. 레이블은 Kubernetes 객체를 관리하고 구성하는 데 도움이 되는 키 - 값 쌍입니다.
먼저, 파드에 현재 레이블이 있는지 확인합니다:
kubectl get pods --show-labels
예시 출력:
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-xxx-yyy 1/1 Running 0 30m app=nginx,pod-template-hash=xxx
nginx-deployment-xxx-zzz 1/1 Running 0 30m app=nginx,pod-template-hash=yyy
nginx-deployment-xxx-www 1/1 Running 0 30m app=nginx,pod-template-hash=zzz
특정 레이블을 사용하여 파드를 선택합니다:
kubectl get pods -l app=nginx
예시 출력:
NAME READY STATUS RESTARTS AGE
nginx-deployment-xxx-yyy 1/1 Running 0 30m
nginx-deployment-xxx-zzz 1/1 Running 0 30m
nginx-deployment-xxx-www 1/1 Running 0 30m
파드 중 하나에 사용자 지정 레이블을 추가해 보겠습니다:
kubectl label pods nginx-deployment-xxx-yyy environment=development
nginx-deployment-xxx-yyy를 파드 중 하나의 이름으로 바꿉니다.
예시 출력:
pod/nginx-deployment-xxx-yyy labeled
이제 여러 레이블 선택기를 사용하여 파드를 선택합니다:
kubectl get pods -l app=nginx,environment=development
예시 출력:
NAME READY STATUS RESTARTS AGE
nginx-deployment-xxx-yyy 1/1 Running 0 30m
파드에서 레이블을 제거합니다:
kubectl label pods nginx-deployment-xxx-yyy environment-
예시 출력:
pod/nginx-deployment-xxx-yyy unlabeled
서비스에서 레이블 선택을 시연합니다:
kubectl describe service nginx-clusterip-service
"Selector" 섹션을 찾아 서비스가 레이블을 사용하여 파드를 식별하는 방법을 확인합니다.
레이블에 대한 주요 사항:
- 레이블은 Kubernetes 객체에 연결된 키 - 값 쌍입니다.
- 리소스를 구성, 선택 및 필터링하는 데 사용됩니다.
- 동적으로 추가, 수정 또는 제거할 수 있습니다.
- 서비스 및 배포는 레이블을 사용하여 관련 파드를 관리합니다.
서비스 삭제 및 관리
이 단계에서는 kubectl 명령을 사용하여 Kubernetes 서비스를 삭제하고 관리하는 방법을 배우게 됩니다. 서비스 관리를 이해하는 것은 Kubernetes 리소스를 유지 관리하고 정리하는 데 매우 중요합니다.
먼저, 현재 서비스를 나열합니다:
kubectl get services
예시 출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
nginx-clusterip-service ClusterIP 10.104.xxx.xxx <none> 80/TCP 45m
nginx-nodeport-service NodePort 10.108.yyy.yyy <none> 80:30080/TCP 45m
kubectl delete를 사용하여 특정 서비스를 삭제합니다:
kubectl delete service nginx-clusterip-service
예시 출력:
service "nginx-clusterip-service" deleted
서비스 삭제를 확인합니다:
kubectl get services
예시 출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
nginx-nodeport-service NodePort 10.108.yyy.yyy <none> 80:30080/TCP 45m
여러 서비스 삭제를 더 명확하게 시연하기 위해 서비스를 다시 생성한 다음 함께 삭제해 보겠습니다:
## Recreate services
kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml
## Delete multiple services at once
kubectl delete service nginx-clusterip-service nginx-nodeport-service
예시 출력:
service "nginx-clusterip-service" deleted
service "nginx-nodeport-service" deleted
모든 서비스가 제거되었는지 확인합니다 (기본 kubernetes 서비스 제외):
kubectl get services
예시 출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
서비스 삭제에 대한 주요 사항:
- 서비스를 삭제하면 네트워크 엔드포인트가 제거됩니다.
- 서비스가 제거될 때 파드는 삭제되지 않습니다.
- 기본 kubernetes 서비스는 삭제할 수 없습니다.
- 이름, YAML 파일 또는 레이블을 사용하여 서비스를 삭제할 수 있습니다.
- 여러 서비스는 나열하거나 레이블 선택기를 사용하여 동시에 삭제할 수 있습니다.
Ingress 기본 소개 및 간단한 Ingress YAML 예시
이 단계에서는 Kubernetes 클러스터에서 서비스에 대한 외부 액세스를 관리하는 강력한 방법인 Kubernetes Ingress 에 대해 배우게 됩니다.
Ingress 란 무엇인가?
Ingress 는 일반적으로 HTTP 인 Kubernetes 클러스터 내 서비스에 대한 외부 액세스를 관리하는 API 객체입니다. Ingress 는 다음을 제공합니다:
- 로드 밸런싱 (Load balancing): 여러 백엔드 서비스로 트래픽을 분산합니다.
- SSL/TLS 종료 (termination): 보안 연결을 처리합니다.
- 이름 기반 가상 호스팅 (Name-based virtual hosting): 호스트 이름을 기반으로 요청을 다른 서비스로 라우팅합니다.
- 경로 기반 라우팅 (Path-based routing): URL 경로를 기반으로 요청을 다른 서비스로 라우팅합니다.
Ingress 는 두 가지 구성 요소로 구성됩니다:
- Ingress 리소스 (Resource): 라우팅 규칙을 정의하는 Kubernetes API 객체
- Ingress 컨트롤러 (Controller): Ingress 리소스에 정의된 규칙을 적용하는 구현
참고: 이 랩에서는 Ingress 에 대한 기본적인 소개만 제공합니다. 프로덕션 환경에서는 Ingress 구성이 고급 라우팅, 인증, 속도 제한 등을 포함하여 훨씬 더 복잡할 수 있습니다.
Minikube 에서 Ingress 애드온을 활성화해 보겠습니다:
minikube addons enable ingress
예시 출력:
💡 ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
🔉 ingress was successfully enabled
두 개의 샘플 애플리케이션에 대한 배포를 생성합니다:
kubectl create deployment web1 --image=nginx:alpine
kubectl create deployment web2 --image=httpd:alpine
이러한 배포를 서비스로 노출합니다:
kubectl expose deployment web1 --port=80 --type=ClusterIP --name=web1-service
kubectl expose deployment web2 --port=80 --type=ClusterIP --name=web2-service
Ingress YAML 파일을 생성합니다:
nano ingress-example.yaml
다음 Ingress 구성을 추가합니다:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /web1
pathType: Prefix
backend:
service:
name: web1-service
port:
number: 80
- path: /web2
pathType: Prefix
backend:
service:
name: web2-service
port:
number: 80
이 Ingress 구성의 주요 구성 요소:
- metadata.annotations: Ingress 컨트롤러에 대한 특정 구성
- spec.rules: 트래픽을 서비스로 라우팅하는 방법 정의
- path: 일치할 URL 경로
- pathType: 경로를 일치시키는 방법 (Prefix, Exact, 또는 ImplementationSpecific)
- backend.service: 트래픽을 라우팅할 서비스 및 포트
Ingress 구성을 적용합니다:
kubectl apply -f ingress-example.yaml
Ingress 리소스를 확인합니다:
kubectl get ingress
예시 출력:
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx * 192.168.49.2 80 1m
Ingress 세부 정보를 확인합니다:
kubectl describe ingress example-ingress
예시 출력은 라우팅 규칙과 백엔드 서비스를 보여줍니다.
Ingress 테스트:
## Get the Minikube IP
minikube ip
## Test access to the services through Ingress
curl $(minikube ip)/web1
curl $(minikube ip)/web2
각 명령은 해당 웹 서버에서 기본 페이지를 반환해야 합니다.
프로덕션 환경에서 Ingress 는 다음과 같이 구성할 수 있습니다:
- 여러 호스트 이름 기반 규칙
- HTTPS 용 TLS 인증서
- 인증 메커니즘
- 속도 제한
- 사용자 지정 시간 초과 구성
- 세션 선호도
- 그리고 더 많은 고급 기능
Ingress 에 대한 보다 포괄적인 내용을 보려면 Kubernetes 문서를 참조하고 NGINX Ingress 또는 Traefik 과 같은 전용 Ingress 컨트롤러 문서를 살펴보십시오.
요약
이 랩에서는 로컬 머신에서 Kubernetes 애플리케이션을 개발하고 테스트하는 데 필수적인 Minikube 를 사용하여 로컬 Kubernetes 클러스터를 시작하고 확인하는 방법을 배웠습니다. 그런 다음 YAML 매니페스트를 사용하여 간단한 NGINX 웹 서버 배포를 생성하고 배포하여 Kubernetes 리소스를 정의하고 적용하는 과정을 시연했습니다.
내부적으로 (ClusterIP 사용) 및 외부적으로 (NodePort 사용) 애플리케이션을 노출하기 위해 Kubernetes 서비스를 생성하는 방법과 레이블을 사용하여 리소스를 효과적으로 구성하고 선택하는 방법을 배웠습니다. 또한 개별 서비스 및 여러 서비스를 삭제하는 것을 포함하여 서비스 관리도 연습했습니다.
마지막으로, Kubernetes Ingress 의 기본 사항을 소개받았고 경로 기반 라우팅의 간단한 예시를 보았습니다. 이 랩에서는 Ingress 에 대한 간략한 소개만 제공했지만, URL 경로를 기반으로 외부 트래픽을 다른 서비스로 라우팅하는 기본적인 개념을 보여주었습니다.
Ingress 및 해당 기능에 대한 더 깊은 이해를 얻으려면 Kubernetes Ingress 컨트롤러 및 구성에 초점을 맞춘 전용 리소스 또는 랩을 탐색해 볼 수 있습니다.


