k8s_intro_2
쿠버네티스(Kubernetes) 환경에서 Redis 구축 가이드 ②
k3s
☸️ k3s란 무엇인가?
이번 레디스 설치/테스트 환경에서는 CNCF 인증을 받은 경량화된 쿠버네티스 배포판인 'K3s'를 사용했습니다.
k8s(표준 쿠버네티스)와 k3s의 차이점
| 비교 항목 | 표준 쿠버네티스 (k8s) | K3s (Lightweight Kubernetes) |
|---|---|---|
| 목적 | 대규모 엔터프라이즈 데이터센터 | 경량 데이터센터, Edge, IoT, 개발 및 중소규모 폐쇄망 |
| 설치 및 용량 | 설치가 복잡하고 메모리 점유율이 높음 (>2GB RAM) | 단일 바이너리 실행 파일 (<512MB RAM) |
| 데이터스토어 | 기본 etcd 전용 | SQLite(기본), etcd, 외부 DB(MySQL/PostgreSQL) 지원 |
| 기본 스토리지 | 별도 StorageClass (CSI) 설치 필요 | 'local-path' StorageClass 내장 (바로 PVC 사용 가능) |
| 컨테이너 런타임 | containerd, CRI-O 등 별도 설정 | containerd 기본 포함 및 이미지 자동 로딩 지원 |
💡 redisgate's Insight: K3s는 리소스를 아껴야 하는 환경이나 인터넷이 끊긴 폐쇄망 환경에서 Redis를 검증하고 운용하기에 높은 성능과 편의성을 제공합니다.
k3s 설치
containerd 및 kubectl 자동 포함
'StatefulSet', 'Headless Service', 'PVC', 'podAntiAffinity'(가상 노드 테스트) 등
레디스 테스트에 필요한 모든 K8s 기능을 100% 동일하게 제공합니다.
- 1단계: K3s 설치 (root user 사용)
- 1) 설치: # curl -sfL https://get.k3s.io | sh -
- 2) 상태 확인: # k3s kubectl get nodes
- 2단계: 일반(redis) 유저가 'kubectl'을 사용할 수 있도록 권한 부여
K3s가 설치되면 K8s 인증 파일인 'k3s.yaml'이 '/etc/rancher/k3s/' 디렉토리에 생성되는데, 기본적으로 'root'만 읽을 수 있게 되어 있습니다. 이를 redis 유저의 홈 디렉토리로 복사해 오면 sudo 없이도 kubectl 명령어를 바로 사용할 수 있습니다. (sudo 가능한 일반(redis) user 사용)- ① redis 유저의 홈 디렉토리에 .kube 폴더 생성
$ mkdir -p ~/.kube - ② k3s 설정 파일을 redis 유저 홈으로 복사 (sudo 필요)
$ sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config - ③ 복사한 파일의 소유권을 redis 유저로 변경 (sudo 필요)
$ sudo chown $(id -u):$(id -g) ~/.kube/config - ④ 권한 설정 (보안 강화)
$ chmod 600 ~/.kube/config
- ① redis 유저의 홈 디렉토리에 .kube 폴더 생성
- 3단계: redis 유저로 동작 확인
이제 redis 유저 상태에서 sudo 없이 바로 쿠버네티스 클러스터 상태를 조회할 수 있습니다.
$ kubectl get nodes
- 한 걸음 더: kubectl 명령어 자동완성 및 별칭(Alias) 팁
redis 계정의 '~/.bashrc' 파일에 아래 설정을 추가해두면 테스트하실 때 매우 편리합니다.
# redis 유저의 ~/.bashrc 끝에 추가
# 변경사항 적용
$ source ~/.bashrc
이렇게 설정해두시면 'kubectl get pods' 대신 'k get pods'처럼 짧은 명령어로 K3s를 쉽게 조작하실 수 있습니다.
- 스크립트 설명
- 'KUBECONFIG':
'kubectl' 명령어가 K3s 환경에서 실행될 때 기본값으로
'/etc/rancher/k3s/k3s.yaml' 파일을 먼저 바라보도록 K3s 자체 환경변수 또는
래퍼(Wrapper) 스크립트가 설정되어 있습니다. 이것을
복사해두신 '~/.kube/config' 파일을 명시적으로 바라보도록 'KUBECONFIG'
환경변수를 지정해야 합니다.
- 'alias k=kubectl': 'k'도 'kubectl'와 같이 사용할 수 있도록 별칭(alias) 지정
- 'kubectl completion bash' 자동 완성 기능:
쿠버네티스는 'get', 'describe', 'logs', 'statefulset', 'persistentvolumeclaim' 등
외워야 할 보조 명령어와 리소스 종류가 굉장히 길고 많습니다.
'kubectl completion bash' 명령어는 Bash 셸에서 사용할 수 있는 자동완성 규칙 스크립트를 출력해 주는데, 이를 'source' 명령어로 셸에 읽어들여 단어 입력 중 'Tab' 키를 누르면 다음 명령어를 자동으로 추천해주도록 만드는 설정입니다.
* 효과 예시:
- 'kubectl get stat' 입력 후 'Tab' -> 'kubectl get statefulsets'로 자동 완성!
- 'kubectl des' 입력 후 'Tab' -> 'kubectl describe'로 자동 완성!
- 'complete -o default -F __start_kubectl k':
의미: 앞에서 만든 자동완성 기능을 별칭(alias)인 'k'에도 똑같이 연결합니다.
- 'KUBECONFIG':
'kubectl' 명령어가 K3s 환경에서 실행될 때 기본값으로
'/etc/rancher/k3s/k3s.yaml' 파일을 먼저 바라보도록 K3s 자체 환경변수 또는
래퍼(Wrapper) 스크립트가 설정되어 있습니다. 이것을
복사해두신 '~/.kube/config' 파일을 명시적으로 바라보도록 'KUBECONFIG'
환경변수를 지정해야 합니다.
☸️ 유용한 쿠버네티스 명령어 모음
- 파드 정보 조회: kubectl get pods
- 파드 상세 정보 조회(IP, 실행 노드 포함): kubectl get pods -o wide
- 특정 파드의 세부 정보 및 이벤트 확인 (문제 발생 시 원인 분석용): kubectl describe pod redis-0
- 파드 이름과 IP 주소만 깔끔하게 출력:
kubectl get pods -o custom-columns=POD_NAME:.metadata.name,POD_IP:.status.podIP - 디스크 볼륨(PersistentVolumeClaim) 조회: kubectl get pvc
- Linux shell 접속: kubectl exec -it redis-0 -- /bin/bash
kubectl exec -it redis-0 -- /bin/bash -> 일반 이미지: bash로 접속
kubectl exec -it redis-0 -- /bin/sh -> Alpine 이미지: sh로 접속(alpine 이미지 bash가 없음) - 레디스 접속: kubectl exec -it redis-0 -- redis-cli -p 18504 -a password
- 레디스 명령 실행: kubectl exec -it redis-0 -- redis-cli -p 18504 -a password info
- 레디스 로그 보기: kubectl exec -it redis-0 -- tail -f /data/redis.log
- YAML 파일 적용: kubectl apply -f redis-config.yaml
- 파드 삭제: kubectl delete pod redis-0
- redis 파드 모두 삭제: kubectl delete statefulset redis
- 스토리지(pvc) 삭제: kubectl delete pvc redis-data-redis-0
여러 개 지정 가능: kubectl delete pvc redis-data-redis-0 redis-data-redis-1 redis-data-redis-2 - 스토리지(pvc) 모두 삭제: kubectl delete pvc --all
☸️ 레디스 엔지니어가 꼭 알아야 할 쿠버네티스 핵심 개념
- ① StatefulSet (상태 유지를 위한 파드 집합)
일반 웹 서버(Stateless)는 'Deployment'로 관리되지만, Redis 같은 데이터베이스(Stateful)는 반드시 'StatefulSet'으로 관리해야 합니다.- 파드에 'redis-0', 'redis-1', 'redis-2'와 같이 순차적이고 고정된 이름(Ordinal Index)이 부여됩니다.
- 파드가 재시작되면 IP는 변경되지만, 이름과 할당된 디스크(PVC)가 그대로 유지됩니다. 레디스 7.0부터 '이름'통신을 지원하므로 IP가 변경되어도 문제없습니다.
- ② Headless Service ('clusterIP: None')
일반 서비스는 파드 들의 단일 대표 IP(ClusterIP)를 제공하지만, Redis Cluster/Sentinel은 노드 개별 주소를 알아야 합니다.
- 'clusterIP: None' 설정 시 K3s 내부 DNS가 'redis-0.redis-service.default.svc.cluster.local'과 같은 고정 FQDN 도메인 이름을 각 파드의 가상 IP로 자동 매핑해 줍니다.
- ③ initContainers (초기화 컨테이너)
메인 'redis-server' 프로세스가 뜨기 전에 실행되는 일회성 컨테이너입니다.- ConfigMap의 읽기 전용 설정을 쓰기 가능한 '/data' 경로로 복사합니다.
- 파드의 인덱스('redis-0' -> '0')를 추출하여 'replica-priority', 'cluster-announce-hostname', 'replicaof' 등의 옵션을 동적으로 계산 및 주입해 줍니다.
☸️ 도커(Docker), 컨테이너(Container), 파드(Pod)의 개념 및 연관 관계
기존에 베어메탈(Bare-Metal/물리서버)이나 가상 머신(VM) 환경에서 레디스를 다루던 엔지니어가
쿠버네티스 생태계로 진입할 때 가장 먼저 혼란을 겪는 부분이 바로 도커, 컨테이너, 파드의 개념적 차이입니다.
세 기술 개념과 이들이 어떻게 연결되어 작동하는지 체계적으로 정리해 드립니다.
도커와 쿠버네티스는 경쟁 관계가 아니라 역할이 다른 파트너입니다.
도커는 컨테이너를 '만드는' 도구이고, 쿠버네티스는 그 컨테이너를 '관리하는' 도구입니다.
1. 개별 개념 설명
- ① 파드(Pod): 쿠버네티스가 관리하는 '최소 배포 단위'
- 정의: 하나 이상의 컨테이너를 하나로 묶어 쿠버네티스가 스케줄링하고 관리하는 가장 작은 단위.
- 어원: 'Pod'는 식물의 '콩깍지(Bean Pod)'를 의미합니다. 콩깍지 안에 여러 개의 완두콩(컨테이너)이 들어있는 모습을 형상화한 것입니다.
- 역할: 쿠버네티스는 컨테이너 단독으로 관리하지 않고, 반드시 파드(Pod)라는 껍데기로 감싸서 관리합니다. 하나의 파드 내에 속한 컨테이너들은 동일한 Pod IP, 동일한 네트워크(Port는 여러 개 설정 가능) 공간, 동일한 저장소(Volume)를 공유합니다.
- ② 컨테이너(Container): 격리되어 실행되는 '프로세스'
- 정의: 도커 이미지라는 '틀'을 기반으로 Host OS 상에서 독립된 메모리, 파일시스템, 프로세스 공간을 할당받아 격리되어 실행 중인 실제 프로그램(프로세스)입니다.
- 비유: 틀에서 구워져 나온 '진짜 붕어빵' 또는 '실제 화물 박스'
- 역할: Host OS의 커널을 공유하므로 가상 머신(VM)처럼 heavy하지 않고, 수 초 내로 빠르게 켜지고 꺼지는 'Stateless한 실행 객체'입니다. 하지만 스토리지(PVC)를 사용해서 상태를 저장/조회할 수 있고, 원래 상태로 복원할 수 있습니다. 즉, Stateful 가능. ➡ 레디스에서는 redis.conf, sentinel.conf, nodes.conf 파일을 rewrite해서 파드 재시작 시에도 이전 상태로 복원 가능합니다.
- ③ 도커(Docker): 컨테이너를 만드는 '틀'이자 '플랫폼'
- 정의: 애플리케이션과 실행에 필요한 모든 라이브러리/엔진을 '컨테이너 이미지'라는 표준 규격 파일로 패키징하고 실행해 주는 플랫폼(도구)입니다.
- 비유: '붕어빵 틀' 또는 '표준 화물 컨테이너 규격 및 크레인'
- 역할: 'docker build'를 통해 'redis:8.8.2'과 같은 실행 가능한 이미지 파일을 만들고, 이를 중앙 저장소(Docker Hub 등)에 올리거나 당겨오는 역할을 담당합니다.
2. 한눈에 이해하는 쉬운 비유
| 구분 | 비유 (생태계) | 실제 레디스 환경 비유 |
|---|---|---|
| 파드(Pod) | 완두콩들이 담긴 '콩깍지' | [Redis]이 들어있는 'redis-0' 파드 |
| 컨테이너(Container) | 껍질 안의 '완두콩 한 알' | 실행 중인 'redis-server' 프로세스 |
| 도커(Docker) | '완두콩 품종 (씨앗)' | 'redis:8.8.2' 이미지 파일 |
3. 세 기술의 연관 관계 및 계층 구조
세 가지 개념은 독립된 것이 아니라 하위 개념이 상위 개념에 포함되는 포함 관계(Hierarchy)를 가집니다.
[ Docker Image ] ──(실행)──> [ Container ] ──(포장/관리)──> [ Pod ]
(hub.docker.com)
(실제 프로세스)
(k8s가 관리함)
- 1) 이미지 빌드 단계 (Docker의 영역):
• 도커 허브에서 다운 받은 경우: 'https://hub.docker.com/'에서 다운받습니다.
• 직접 만듬: 엔지니어는 도커(Docker)를 사용하여 Redis 소스 코드와 설정 파일(redis.conf)을 묶어 'redis:8.8.2'이라는 도커 이미지를 생성합니다. - 2) 컨테이너 생성 단계 (Runtime의 영역):
도커 이미지를 실행하면 OS 상에 독립된 메모리 공간을 가진 컨테이너가 생성됩니다. 비유하자면 실행 중인 레디스 프로세스 하나가 뜬 것입니다. - 3) 쿠버네티스 파드 구성 단계 (Kubernetes의 영역):
쿠버네티스는 이 컨테이너를 직접 제어하지 않고 파드(Pod)라는 단위로 감쌉니다.
• 단일 컨테이너 파드 (Redis Cluster 등): 1개 Pod = 1개 'redis-server' 컨테이너
• 멀티 컨테이너 파드 (Redis Sentinel Sidecar 패턴 등): 1개 Pod = 1개 'redis-server' 컨테이너 + 1개 'redis-sentinel' 컨테이너 (사이드카)
| << Kubernetes 시작하기 ① | Kubernetes 레디스 준비 ③ >> |
|---|
