1. 쿠버네티스 소개
- 2014년 Google 내부 Borg 에서 발전하여 2015년에 오픈소스로 공개함
- 컨테이너를 쉽고 빠르게 배포하고 확장해주는 컨테이너 관리 자동화 오픈소스 플랫폼
- 컨테이너 오케스트레이션 (조율, 관리)
- k8s
- 조타수 등을 뜻하는 그리스어에서 유래
- 쿠버네티스에 올라가는 많은 도구들은 바다와 관련된 용어와 아이콘이 많음
- control-plane(master)
- node, worker node - 컨테이너 파드가 올라가는 서버들
- kubectl : 큐브컨트롤
- etcd: 저장소 역할
- 퀴즈 : etcd 라는 이름으로 하게 된 이유는?
- 답 : 리눅스 시스템 설정 파일이 /etc에 있고, 여기에 분산(distributed)의 의미로 ‘d’를 더해서
쿠버네티스 필요성
- 컨테이너는 클라우드 네이티브 애플리케이션의 표준 컴퓨팅 단위
- 운영 환경에서 도커(컨테이너)를 단독으로 사용 시 확장이 어려움
- 쿠버네티스를 통해 애플리케이션 확장과 장애 조치를 처리하고 배포 패턴 등을 제공
- (가용성을 위해서 서비스 컨테이너 100개를 각각 이중화 해서 배포할 건데 직접 Docker CLI (Docker run) 를 통해서 배포할래?? 갑자기 트래픽이 많아져서 100대가 더 필요하면 언제 배포할래??)
쿠버네티스 핵심 개념
- 애완동물 vs 가축 (쿠버네티스는 가축에 가깝다)
- 사용자가 바라는 환경 (Desired State)
- 원하는 상태를 YAML 파일로 작성해 놓으면 쿠버네티스가 현재 상태(Current state)를 지속적으로 확인, 바라는 환경을 유지하려고 작업을 실시
- 선언형 커맨드
- 서버에게 직접 동작을 명령하지 않고 내가 원하는 상태를 선언하는 명령어
- vs 명령형 커맨드 (docker run)
- YAML 문법 예시
# Nginx Deployment 형식
apiVersion: apps/v1
kind: Deployment # 리소스 선언
metadata:
name: nginx-deployment # 해당 리소스의 이름
labels: # 해당 리소스의 Label - Label 은 Kubernetes 의 Metadata
app: nginx
spec:
replicas: 3 # 파드 개수
selector:
matchLabels: # Deployment 를 적용할 Pod 를 선택
app: nginx
template: # Pod 템플릿 선언
metadata:
labels:
app: nginx # Pod 의 Label
spec:
containers: # 컨테이너 정의
- name: nginx # Pod Container 이름
image: nginx:1.14.2 # Pod Container Image 정의
ports:
- containerPort: 80 # Pod Container Port
apiVersion: v1
kind: Service # 리소스 선언
metadata:
name: my-service # 해당 리소스 이름
spec:
selector:
app: nginx # Service 와 연결할 Deployment Pod Label
ports:
- port: 80 # Service 연결 포트
targetPort: 8080 # Pod 포트
쿠버네티스 아키텍처
- Control Plane(마스터)와 Node(노드)로 구성
- Control Plane(마스터 노드) 핵심 컴포넌트
- 마스터는 단일 서버 혹은 고가용성을 위한 클러스터 마스터 (3대 이상)로 구축
- Control Plane : Kubernetes 관리 서버
- kube-apiserver
- 마스터로 전달되는 모든 요청을 받아들이는 API 서버
- etcd
- 클러스터내 모든 메타 정보를 저장하는 Key-Value 형태의 분산 데이터 저장소
- 오직 API Server 와 통신, 다른 모듈(스케쥴러, 컨트롤러 등)은 API Server 를 통해 ETCD 접근
- kube-scheduler
- 사용자의 요청에 따라 적절하게 컨테이너를 워커 노드에 배치하는 스케줄러
- 스케줄러가 파드를 배포하는 건 아닌데, 어떤 노드에 배포할지를 골라준다.
- controller-manager
- 선언형 커맨드(현재 상태와 바라는 상태)를 지속적으로 확인하며 특정 이벤트에 따라 특정 동작을 수행하는 컨트롤러
- 쿠버네티스 리소스 상태 변화를 감지하고 클러스터에 적용
- ETCD 의 Desired State 와 쿠버네티스의 Current State 비교
- Kube-Controller-Manager : 대부분의 쿠버네티스 오브젝트 상태 관리
- Cloud-Controller-Manager : 클라우드 플랫폼(AWS, GCP, Azure 등)에 특화된 리소스를 제어하는 클라우드 컨트롤러. EC2 Node 추가/삭제, 로드밸런서 연결, Volume 장착 등
- 마스터는 단일 서버 혹은 고가용성을 위한 클러스터 마스터 (3대 이상)로 구축
- Worker Node(워커 노드)
- Control Plane 과 통신하며 필요한 Pod와 볼륨을 생성하는 서버
- 실제 컨테이너가 동작하는 서버
- 더 많은 컨테이너 배포를 위해서는 워커 노드를 확장
- Kubelet
- Control Plane 명령에 따라 노드에 할당된 Pod 의 생명 주기(Life-Cycle)를 관리
- Pod 생성 / Node Pod 에 이상이 없는 지 주기적으로 확인하면서 Control Plane (API Server) 에 현재 상태(Current State) 전달
- API Server 의 요청을 받아 Container Log 전달, 특정 명령 수행 등
- kube-proxy
- 컨테이너의 네트워킹을 책임지는 프록시, 네트워크 규칙 유지 관리
- Pod 로 연결된 네트워크 관리 (Overlay Network)
- Proxy 서버 → iptable 설정 방식(병목이 생겨서) → IPVS 지원
- Container Runtime
- 실제 컨테이너를 실행하는 컨테이너 실행 환경 (컨테이너 엔진)
- (
Docker& containerD & CRI-O) - Docker 지원 중단 - 쿠버네티스 1.24 버전부터 Dockershim 이 제거되면서 완전히 결별
- 초창기 쿠버네티스는 특정 컨테이너 런타임인 도커 엔진에서만 동작 했는데, 이후 OCI 표준을 준수하는 다른 컨테이너 런타임과 연동함
- 하지만 기존 도커 엔진은 OCI 표준을 준수하지 않아 쿠버네티스 개발 과정에서 지속적으로 추가 공수가 필요하게 됨 (추가 공수의 결과 : Dockershim)
- 해당 부분을 제거함으로써 다른 영역에 개발 공수를 투자하려는 목적
- Pod 배포 명령어 수행 시 전체 동작 과정
- kubectl apply (API Server 호출)
- Control Plane (API Server) → ETCD : Unscheduled Pod 상태 저장
- Scheduler : API Server 를 감시하고 있다가 Unscheduled Pod 이벤트 감지, 노드 리소스 및 레이블을 확인하여 적절한 노드 선택 후 API Server 호출 (Patch 요청)
- API Server : ETCD 에 Pod 노드 저장
- Kubelet : API Server 를 감시하다가 자신의 노드에 할당되지 않은 Pod 가 있는 지 체크 후 Pod 생성, 생성 후 API Server 에 상태 전달
- API Server : 상태 업데이트
- Deployment, ReplicaSet 등은 2-3 사이에 해당 리소스 Controller 동작이 포함
- Add on
- CNI : Container Network Interface 는 k8s 네트워크 환경을 구성해준다.
- DNS : 쿠버네티스 서비스를 위해 DNS 레코드를 제공해주며, Service Discovery 기능을 제공을 한다. 대표적으로 CoreDNS 가 있다.
- CSI : Container Storage Interface
- 컨테이너 볼륨 저장
2. 쿠버네티스 설치
- 다양한 쿠버네티스 운영환경 배포 도구들
- kubeadm
- kubespray
- kops
- 개발/테스트용
- minikube
- k3d
- kind
- 경량 개발 및 테스트 용
- getdeck
- kwok
kind
- docker in docker로 쿠버네티스 클러스터 환경을 구성
- 도커 컨테이너가 하나 뜨고 그 안에서 쿠버네티스 클러스터를 만든다.
설치 Windows Docker 설치 (WSL2) - (+Kind)
# Windows WSL2 (Ubuntu) - PowerShell / CMD (관리자 권한)
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
wsl --list -o
wsl --install -d ubuntu
# 위 명령은 WSL2와 Ubuntu를 설치하기 위한 것 이미 설치되어 있으면 생략하기
#(특히 wsl --install -d ubuntu는 Ubuntu를 처음 설치할 때만!)
# 아래 명령부터는 우분투 터미널에서 실행
# WSL2 Ubuntu
sudo snap install docker
sudo groupadd docker
sudo usermod -aG docker $USER
docker --version
# Kind 설치
[ $(uname -m) = x86_64 ] && curl -Lo ./kind <https://kind.sigs.k8s.io/dl/v0.27.0/kind-linux-amd64>
sudo chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# Kind Cluster 생성
kind create cluster
[참고] kind create cluster 명령어 실행 시 오류 발생
ERROR: failed to create cluster: failed to get docker info: command "docker info --format '{{json .}}'" failed with error: exit status 1
Command Output:
The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.
For details about using Docker Desktop with WSL 2, visit:
<https://docs.docker.com/go/wsl2/>
위 오류 발생 시 도커 데스크톱을 최신 버전으로 업데이트한 후 Resources > WSL Integration 의 Ubuntu 활성화하고 restart한 후 다시 명령어를 실행하면 된다.
[참고]
kubectl & krew
# Installation for kubectl & krew
$ sudo snap install kubectl --classic
# 설치 후 kubectl get pods -A 했을 때 무언가 뜨면 세팅 성공
$ wget <https://github.com/kubernetes-sigs/krew/releases/download/v0.4.5/krew-linux_amd64.tar.gz>
$ tar zxvf krew-linux_amd64
$ ./krew-linux_amd64 install krew
$ vi ~/.bashrc
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
$ kubectl krew
[kubectl get pods -A 명령어 실행 후 화면]
# Installation for k9s
$ wget <https://github.com/derailed/k9s/releases/download/v0.50.4/k9s_linux_amd64.deb>
$ sudo dpkg -i k9s_linux_amd64.deb
$ sudo apt-get install -f
$ k9s
# Installation for helm
$ sudo snap install helm --classic
요약
- 다수의 컨테이너를 운영해야 될 때 발생하는 도커의 부족한 점을 해결하기 위해 컨테이너 오케스트레이션이 나오게 되었다!
- 쿠버네티스는 컨트롤 플레인와 노드(워커)로 구성되어 있다.
- 쿠버네티스는 컨테이너 애플리케이션의 기본 단위를 파드(Pod)라고 부르며, 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합입니다.
Kubectl
- 큐브컨트롤, 큐브시티엘
- 쿠버네티스를 제어하는 명령을 컨트롤플레인의 API Server 로 전달
kubectl api-resources
# 대표적인 쿠버네티스 리소스 약어
# pods - po
kubectl api-resources | grep pods
# deployments - deploy
kubectl api-resources | grep deployments
# namespaces - ns
kubectl api-resources | grep namespaces
# configmaps - cm
kubectl api-resources | grep configmaps
****
kubectl api-resources 실행 시 긴 명령어의 경우 약어(SHORTNAMES)를 가지고 있는 것을 확인할 수 있다.
- 예 : namespaces 는 ns
- kubectl get <리소스>
- 쿠버네티스 클러스터 내부 리소스에 대한 조회 명령어
# 노드 조회
kubectl get node
kubectl get node -o wide # 정보를 더 상세히 보여줌
# 파드 조회
kubectl get pods
kubectl get pods -A # ALL 모든 네임스페이스의 파드를 조회한다.
# 디플로이먼트 조회
kubectl get deployment
kubectl get deployment -A
# 네임스페이스 조회
kubectl get namespace
- 노드 조회 시
- 지금은 단일 노드로 배포했기 때문에 컨트롤 플레인 1대만 뜬다.
- kind는 멀티노드도 지원한다.
- 파드 조회 시
- A 옵션으로 하면 kube-system 네임스페이스의 파드들을 조회할 수 있다.
- 디플로이먼트 조회 시
- A 옵션으로 조회 시 kube-system에 coredns, local-path-storage에는 local-path-provisioner라는 Name이 조회됨
- kubectl describe <리소스>
쿠버네티스 클러스터 내부 리소스에 대한 상세 정보 조회
# 파드 상세 조회
kubectl describe pod -n kube-system coredns-6f6b679f8f-krwfh
# 디플로이먼트 조회
kubectl describe deployment -n kube-system coredns
# 네임스페이스 조회
kubectl describe namespace kube-system
[실습] 파드 상세 조회하기
create, start가 잘 되었음을 확인할 수 있다.
디플로이먼트 조회하기
- describe 명령어로 kube-system의 coredns 조회하기create, start가 잘 되었음을 확인할 수 있다.
- describe 명령어로 kube-system의 coredns 조회하기
- 디플로이먼트 조회하기
- Replicas에 2개가 필요하다고 선언되어 있다.
- 그렇기 때문에 kubectl get pods -A로 조회했을 때 coredns가 2개 조회되는 것이다.
쿠버네티스 컨텍스트
- Context
- kubectl 명령어를 수행할 때 어떤 클러스터, 어떤 사용자, 어떤 네임스페이스를 대상으로 동작할 지 지정하는 설정
- 컨텍스트를 통해 쿠버네티스에 접근하는 과정을 인증(Authentication) 이라고 지칭
- (쿠버네티스에는 인증/인가가 있는데 컨텍스트는 인증)
- 멀티 클러스터를 다룰 때 유용
- Context 구성 요소
- Cluster : 연결할 쿠버네티스 클러스터
- User: 클러스터 인증에 사용할 사용자 정보 (토큰, 인증서)
- Namespace: 기본으로 사용할 네임스페이스
- Context 확인
# 현재 설정된 컨텍스트 확인
kubectl config current-context # 현재 사용하는 컨텍스트는 kind-kind
# 모든 컨텍스트 확인
kubectl config get-contexts
# 다른 컨텍스트 전환
kubectl config use-context <Context Name>
# 컨텍스트 삭제
kubectl config delete-context <Context Name>
- [참고] 현재 사용하는 컨텍스트는 *로 표시됨 (kind-kind)
- 실습 환경 상 하나밖에 없기 때문에 전환, 삭제는 실습 생략
- 컨텍스트 정보는 어디서 가져오는 걸까?
- ~/.kube/config 에 저장
# Config 정보 확인
cat ~/.kube/config
apiVersion: v1
clusters:
- cluster: # API Server 정보
certificate-authority-data: LS0tLS1CRUdS0tCk1JSURC # API Server 인증서
server: <https://127.0.0.1:63718> # API Server URL
name: kind-kind # Cluster 명칭
contexts:
- context:
cluster: kind-kind
user: kind-kind # Cluster 접근 유저
name: kind-kind
current-context: kind-kind
kind: Config
preferences: {}
users:
- name: kind-kind # Cluster 접근 유저에 대한
user:
client-certificate-data: LS0tLS1CRUdJS0K # Client 인증서
client-key-data: LS0tLJVkFURSBLRVktLS0tLQo= # Client Key
docker ps
- 외부에 API Server 포트가 열려있으면 외부에서 호출할 수 있다!
- 쿠버네티스의 API 서버는 기본적으로 6443 포트를 사용한다.
Namespace
- 쿠버네티스 클러스터 내에서 리소스를 격리하는 논리적 단위
- 리소스를 구분하는 가장 기초적인 컴포넌트
- kube- 접두사는 k8s 시스템용으로 예약되어 있기에 Namespace 로 생성할 수 없음
- 모든 Object 가 Namespace 에 속하지는 않음 → 전체 클러스터 수준
# Namespace 에 속하는 리소스
kubectl api-resources --namespaced=true
# Namespace 에 속하지 않는 리소스
kubectl api-resources --namespaced=false # 전체 클러스터 수준에 적용되는 리소스
k8s 초기 네임스페이스
- *default : 다른 Namespace가 없는 Object를 위한 기본 Namespace
- *kube-system : k8s system 에서 생성한 Object를 위한 Namespace (쿠버네티스 동작을 위한 파드들이 배포되는 네임스페이스)
namespace 활용
# 네임스페이스 조회
kubectl get ns
# 네임스페이스 생성
kubectl create namespace knou
kubectl get ns
# 파드 생성
kubectl run nginx --image=nginx:alpine
#
kubectl get pods
kubectl describe pod nginx
kubectl describe pod nginx | grep Namespace
# knou 네임스페이스에 파드 생성
kubectl run nginx --image=nginx:alpine -n knou
#
kubectl get pods -n knou # knou 네임스페이스에 있는 파드를 조회하는 명령어
kubectl get pods -A
# knou 네임스페이스에 다시 한 번 파드 배포
kubectl run nginx --image=nginx:alpine -n knou
Error from server (AlreadyExists): pods "nginx" already exists
# 논리적으로 격리되어 있기 때문에 다른 네임스페이스에는 동일한 이름의 파드를 배포할 수 있지만,
# 같은 네임스페이스에는 동일한 파드를 배포할 수 없다!
# -> 쿠버네티스 사용 시 가장 많이 하는 실수 중 하나. 다른 네임스페이스에 배포하는 것
# 테스트 파드 삭제
kubectl delete pods nginx
kubectl delete pods nginx -n knou
[실습] knou라는 네임스페이스 만들고 파드 배포하기
네임스페이스를 따로 지정하지 않으면 default 네임스페이스로 배포가 된다.
-n으로 이름을 지정할 수 있다.
- kubectl run 은 명령형 커맨드일까 선언형 커맨드일까??
- → 명령형 커맨드
기본 네임스페이스 변경
# 기본 네임스페이스 변경
## 현재 네임스페이스 정보 조회 (빈값: default)
kubectl config get-contexts
kubectl config view --minify
kubectl config view --minify --output 'jsonpath={..namespace}'
## 네임스페이스 변경
kubectl config set-context --current --namespace=knou
kubectl config get-contexts
kubectl config view --minify
kubectl config view --minify --output 'jsonpath={..namespace}'
# 네임스페이스 지정 없이 파드 배포
kubectl run nginx2 --image=nginx:alpine
kubectl get pods -n knou
# 테스트 파드 삭제
kubectl delete pods nginx2
네임스페이스를 지정하지 않아도 디폴트로 knou 네임스페이스를 사용하도록 설정했기 때문에, 현재 나의 컨텍스트는 knou를 기본으로 사용하고 있다.
Pod
- k8s 에서 애플리케이션을 생성하고 관리할 수 있는 배포 가능한 가장 작은 단위
- 1개 이상의 컨테이너로 구성 (2, 3, 4개 등의 컨테이너로 구성된 파드 존재)
- 동일한 파드 내의 컨테이너는 Storage, Network 를 공유
- 동일한 파드 내의 컨테이너는 항상 함께 실행
- 파드는 프로세스가 아닌 컨테이너를 실행하기 위한 환경
- 파드는 직접 생성하지 않는다! - Bare Pod
Pod 배포하기
# 선언형 커맨드
apiVersion: v1
kind: Pod # Pod 리소스 선언
metadata:
name: nginx # **Pod Name**
spec:
containers:
- name: nginx # **Container Name**
image: nginx:alpine # Container Image
ports: # Container Port
- containerPort: 80
touch pod.yaml
# 위 yaml 파일 복사 붙여넣기
vim pod.yaml
cat pod.yaml
# 현재 pod 상태 확인
kubectl get pods -A
# pod 배포
kubectl apply -f pod.yaml
#
kubectl get pods
kubectl describe pods nginx
# 삭제
kubectl delete -f pod.yaml
- kubectl apply 는 선언형 커맨드일까??
- → 선언형 커맨드
Pod 로그 확인하기
apiVersion: v1
kind: Pod
metadata:
name: knou
namespace: knou
spec:
containers:
- name: knou
image: busybox
env: # Pod 내부 변수 선언
- name: NAME # 변수 Key
value: "yeonsu oh" # 변수 Value
command: ["/bin/sh"]
args: ["-c", "while true; do echo \\"Hello My Name is $(NAME)\\"; date; sleep 2; done"]
touch pod2.yaml
# 위 yaml 파일 복사 붙여넣기
vim pod2.yaml
cat pod2.yaml
# 현재 pod 상태 확인
kubectl get pods -A
# pod 배포
kubectl apply -f pod2.yaml
#
kubectl get pods
kubectl describe pods knou
# 로그 조회
kubectl logs knou
kubectl logs knou -f # 실시간으로 볼 수 있다.
# 삭제
kubectl delete -f pod2.yaml --force
[참고] 로그 조회 실행 결과
Sidecar 패턴 활용
apiVersion: v1
kind: Pod
metadata:
name: knou-mart
spec:
volumes:
- emptyDir: {}
name: varlog
containers:
- name: knou-mart
image: busybox
command:
- /bin/sh
- -c
- 'i=1; while :;do echo -e "$i: Price: $((RANDOM % 10000 + 1))" >> /var/log/knou-mart.log; i=$((i+1)); sleep 2; done'
volumeMounts:
- mountPath: /var/log
name: varlog
- name: price
image: busybox
args: [/bin/sh, "-c", 'tail -n+1 -f /var/log/knou-mart.log']
volumeMounts:
- mountPath: /var/log
name: varlog
- knou-mart라는 컨테이너와 price 라는 컨테이너 2개가 뜬다.
- knou-mart에서는 2초마다 price에 랜덤 값을 심어서 knou-mart라는 파일로 떨군다.
- price는 knou-mart.log를 읽어서 tail로 출력한다.
touch sidecar.yaml
# 위 yaml 파일 복사 붙여넣기
vim sidecar.yaml
cat sidecar.yaml
# 현재 pod 상태 확인
kubectl get pods -A
# pod 배포
kubectl apply -f sidecar.yaml
#
kubectl get pods
kubectl describe pods knou-mart
# price 컨테이너 로그 조회
kubectl logs knou-mart -c price -f
#
kubectl delete -f sidecar.yaml
# 사이드카 패턴을 사용하는 대표적인 서비스가 Istio
## Envoy Proxy 가 Side Car 로 동작하여 Container 의 모든 네트워크 패킷을 감시하고 제어
- kubectl get pods를 해보면 2/2로 되어있다. 원하는 상태가 2개이고 현재 2개가 떠있는 상태라는 것을 의미한다.
- 컨테이너가 여러 개일 때는 -c 옵션으로 어떤 컨테이너의 로그를 조회할지 지정해야 한다.
- 조회해보면 2초마다 랜덤 값을 출력한다.
Pod 단점
- 왜 직접 배포하면 안될까?
# 앞에서 배포했던 파드 1개 선언
kubectl apply -f pod.yaml
#
kubectl get pods
# kubectl 명령으로 파드 삭제
kubectl delete pods nginx
#
kubectl get pods
# 파드가 사라졌다?
# 서비스 장애 발생!
- Pod 단독 사용 시 고가용성 및 자가 치유가 불가
- → 다른 배포 방식 사용 ⇒ 주로 Deployment
- Pod를 배포하는 다양한 방법
- Deployment : Pod 를 배포하는 기본적인 방법, 다양한 배포 전략 사용 가능
- StatefulSets : 실행 순서 보장, Host Name & Volume 을 일정하게 사용 가능, 순서 & 데이터가 중요한 경우
- DaemonSet : 현재 클러스터의 모든 노드에 배포, Log & Monitoring 등 모든 노드에 배포가 되어야 하는 경우
- Job, CronJob : 배치성 작업
Deployment 기본 사용
Deployment
- 파드와 레플리카셋에 대한 선언적 업데이트 제공
- 레플리카셋 : 명시된 파드 개수에 대한 가용성 보장 (ex. pod 2개, 3개)
- 디플로이먼트가 관리하는 레플리카셋은 건드리지 말아야함
- 레플리카셋은 그냥은 사용하지 않음 (디플로이먼트를 통해서만 사용함)
- 파드 배포에 대한 다양한 전략 설정 (롤아웃, 배포 전략)
- 파드 배포 핵심 리소스
- Deployment 안에는 PodTemplate 포함
- 배포하고자 하는 Pod 정보
Deployment 사용하기
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v1
spec:
selector:
matchLabels: # PodTemplate 에 선언된 Label 을 지정하여 Deployment 적용
app: nginx
replicas: 2 # Pod 개수
template: # PodTemplate 시작
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
env:
- name: APP_MODE
value: "v1"
ports:
- containerPort: 80 # PodTemplate 종료
touch deploy.yaml
# 위 yaml 파일 복사 붙여넣기
vim deploy.yaml
cat deploy.yaml
# 현재 pod 상태 확인
kubectl get pods -A
# pod 배포
kubectl apply -f deploy.yaml
# Pod, ReplicaSet, Deployment 조회
kubectl get deploy,rs,pods
#
kubectl delete -f deploy.yaml
[실습]
- 레플리카셋은 디플로이먼트에 해시값이 붙음
- 파드는 레플리카셋의 이름에 해시값이 붙음 - 파드는 레플리카 셋이 관리
- 사용자가 디플로이먼트를 삭제하지 않는 한 디플로이먼트는 파드 2개에 대한 가용성을 보장한다.
pod 업데이트
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v1
spec:
selector:
matchLabels: # PodTemplate 에 선언된 Label 을 지정하여 Deployment 적용
app: nginx
replicas: 2 # Pod 개수
template: # PodTemplate 시작
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
env:
**- name: APP_MODE
value: "v2" # v1 -> v2 변경**
ports:
- containerPort: 80 # PodTemplate 종료
# 터미널 2
while true; do kubectl get pods -o wide; sleep 1; done
# 터미널 1
kubectl apply -f deploy.yaml
# 동작 방식 (기본 Rolling Update)
# 신규 pod 배포 -> 배포 완료 -> 기존 pod 1대 제거 -> 제거 완료 -> 신규 Pod 배포 -> 배포 완료 -> 기존 Pod 제거 -> 제거 완료 -> N번 반복
Qos (Quality of Service)
- 노드 자원이 부족할 때, 어떤 파드를 먼저 죽일 지 결정 (BestEffort → Bustable → Guaranteed 순)
분류 우선 순위 상세
Guaranteed | 상 | Limit, Request 동일 |
Burstable | 중 | Limit, Request 다름 |
BestEffort | 하 | Limit, Request 없음 |
BestEffort 파드
# Request, Limit 없는 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: qos-besteffort
spec:
replicas: 1
selector:
matchLabels:
app: qos-besteffort
template:
metadata:
labels:
app: qos-besteffort
spec:
containers:
- name: nginx
image: nginx:alpine
touch besteffort.yaml
vim besteffort.yaml
# 배포
kubectl apply -f besteffort.yaml
kubectl get pods
BEST_EFFORT=$(kubectl get pods --no-headers -o custom-columns=":metadata.name" | grep qos-besteffort)
# QoS 확인
kubectl get pod ${BEST_EFFORT} -o jsonpath='{.status.qosClass}'
kubectl describe pod ${BEST_EFFORT}
BestEffort
Burstable 파드
# Request, Limit 존재하지만 값이 다름
apiVersion: apps/v1
kind: Deployment
metadata:
name: qos-burstable
spec:
replicas: 1
selector:
matchLabels:
app: qos-burstable
template:
metadata:
labels:
app: qos-burstable
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
touch burstable.yaml
vim burstable.yaml
# 배포
kubectl apply -f burstable.yaml
kubectl get pods
BURSTARBLE=$(kubectl get pods --no-headers -o custom-columns=":metadata.name" | grep qos-burstable)
# QoS 확인
kubectl get pod ${BURSTARBLE} -o jsonpath='{.status.qosClass}'
kubectl describe pod ${BURSTARBLE}
Burstable
Guaranteed 파드
# Request, Limit 존재. 값 동일
apiVersion: apps/v1
kind: Deployment
metadata:
name: qos-guaranteed
spec:
replicas: 1
selector:
matchLabels:
app: qos-guaranteed
template:
metadata:
labels:
app: qos-guaranteed
spec:
containers:
- name: nginx
image: nginx:alpine
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "100m"
touch guaranteed.yaml
vim guaranteed.yaml
# 배포
kubectl apply -f guaranteed.yaml
kubectl get pods
GUARANTEED=$(kubectl get pods --no-headers -o custom-columns=":metadata.name" | grep qos-guaranteed)
# QoS 확인
kubectl get pod ${GUARANTEED} -o jsonpath='{.status.qosClass}'
kubectl describe pod ${GUARANTEED}
Guaranteed
쿠버네티스 심화
1. RBAC
- Role Based Access Control
- 쿠버네티스 리소스에 대한 접근 제어
- 해당 과정을 인가(Authorization) 라고 지칭
- 각 리소스에 대한 CRUD 지정
Service Account
- 쿠버네티스 파드가 사용하는 역할
- Pod 배포 시 지정하지 않으면 default 사용
- Role, ClusterRole 과 함께 사용하여 권한을 부여 받음
- 네임스페이스에 종속
#
kubectl get serviceaccount
kubectl get sa
#
kubectl describe sa -n kube-system coredns
Role/ClusterRole
- Service Account 혹은 User 에 부여하기 위한 권한
- Role : 네임스페이스에 종속된 권한
- ClusterRole : 클러스터 전체 권한
# Role 조회
kubectl get role -A
kubectl describe role -n kube-system kube-proxy
# ClusterRole 조회
kubectl get clusterrole
kubectl describe clusterrole system:coredns
[실습] kubectl describe clusterrole system:coredns
- endpoints, namespaces, pods, services, endpointslices라는 resource에 대하여 list, watch 권한을 가지고 있다.
RoleBinding / ClusterRoleBinding
- 선언된 Role, ClusterRole 을 User, SA 등과 연결하는 리소스
- RoleBinding : Role 과 User, SA 간 연결
- ClusterRoleBinding : ClusterRole 과 User, SA 간 연결
# RoleBinding 조회
kubectl get rolebinding -A
kubectl describe rolebinding -n kube-system kube-proxy
# ClusterRoleBinding 조회
kubectl get clusterrolebinding
kubectl describe clusterrolebinding cluster-admin
쿠버네티스 플러그인 소개
- 쿠버네티스 활용은 모두 CLI 로 이루어지기 때문에, CLI 를 편리하게 사용하기 위한 많은 플러그인이 존재
- 실제 쿠버네티스 현업에서는 본인에게 맞는 도구를 설치하여 사용
- krew
- kubectl cli plug-in 설치 매니저
- krew 로 kube-ctx, kube-ns 설치 및 사용
- kube-ctx : 쿠버네티스 컨텍스트 사용
# 설치 kubectl krew install ctx # 컨텍스트 확인 kubectl ctx # 컨텍스트 사용 kubectl ctx <각자 자신의 컨텍스트 이름>
- kube-ns : 네임스페이스(단일 클러스터 내에서 가상 클러스터) 사용
# 설치 kubectl krew install ns # 네임스페이스 확인 kubectl ns # kube-system 네임스페이스 선택 사용 kubectl ns kube-system # default 네임스페이스 선택 사용 kubectl ns - 혹은 kubectl ns default
- get-all : kubectl get all 로도 안보이는 쿠버네티스의 모든 리소스 조회
# 설치 kubectl krew install get-all # 네임스페이스 확인 kubectl get-all -n kube-system
- neat : kubectl yaml 파일 형태로 리소스 출력
# 설치 kubectl krew install neat # 배포 k run nginx --image nginx # 파드 정보 확인 k get pods nginx -o yaml | k neat
'Docker & Kubernetes' 카테고리의 다른 글
도커 & 쿠버네티스 스터디 4주차 - Kubernetes Probe & GitOps 개요 (1) | 2025.05.18 |
---|---|
도커 & 쿠버네티스 스터디 3주차 - Kubernetes Availability & Network (0) | 2025.05.10 |
도커 & 쿠버네티스 스터디 1주차 : Docker 소개 & Docker 활용 (0) | 2025.04.19 |