일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 자바스크립트
- 위코드
- Python
- fastapi
- stash
- Docker
- 명령어
- docstring
- Dockerfile
- onicecandidate
- 리눅스
- 표준출력
- minikube
- 기초
- revert
- 쿠버네티스
- 도커
- kurento
- 6.6.0
- corsmiddleware
- 파이썬
- RTCP
- underscore
- 독스트링
- 7.0.0
- 미니큐브
- Docker Compose
- JavaScript
- 표준에러
- kubernetes
- Today
- Total
Devlog
kubernetes 입문하기 본문
쿠버네티스(Kubernetes)는 도커와 같은 컨테이너 서비스를 편하게 관리하도록 도와주는 일종의 도구이다. 쿠버네티스가 도커 전체를 대체하는 것은 아니지만 컨테이너를 생성, 삭제, 모니터링하는 일련의 과정들을 자동으로 수행해 관리해 주는 매우 유용한 도구이다. 어떻게 사용하는 것인지 알아보도록 하자.
세팅하기
https://minikube.sigs.k8s.io/docs/start/
minikube start
minikube is local Kubernetes
minikube.sigs.k8s.io
이번 학습에서는 쿠버네티스가 아닌 미니큐브를 사용해 볼 것이다. 미니큐브는 쿠버네티스를 쉽게 배우고 개발할 수 있도록 만들어진 로컬 쿠버네티스라고 한다. 링크로 이동하면 설치를 하기위한 명령어 가이드가 있다. 필자는 Macbook M1을 사용하고 있기에 아래와 같이 선택해 주고, homebrew 설치 방식을 택해서 설치해 주었다.
다음으로 kubectl 도구를 설치해 줄 것이다. kubectl 커맨드 라인 인터페이스 중 하나로 쿠버네티스의 클러스터를 관리, 제어하는 데 사용된다. kubectl의 설치는 아래 링크의 가이드를 따라주면 된다.
https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/
Install and Set Up kubectl on macOS
Before you begin You must use a kubectl version that is within one minor version difference of your cluster. For example, a v1.26 client can communicate with v1.25, v1.26, and v1.27 control planes. Using the latest compatible version of kubectl helps avoid
kubernetes.io
이동하면 각 운영체제로 나누어 별도의 링크를 타고 들어가면 설치 명령어를 순서대로 아주 친절하게 설명해 주니 따라 하도록 하자.
정상적으로 설치되었다면 다음의 명령어들을 실행시켜 보도록 하자. 참고로 필자는 minikube 클러스터를 생성할 가상환경으로 도커를 사용하였다. 도커 이외에도 선택지들은 있으니 본인의 입맛에 맞추어 사용하면 된다.
# kubectl 설치 확인
> kubectl version --client
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"darwin/arm64"}
Kustomize Version: v4.5.7
# minikube 시작하기
❯ minikube start --driver=docker
😄 Darwin 13.2.1 (arm64) 의 minikube v1.29.0
✨ 기존 프로필에 기반하여 docker 드라이버를 사용하는 중
👍 minikube 클러스터의 minikube 컨트롤 플레인 노드를 시작하는 중
🚜 베이스 이미지를 다운받는 중 ...
🔄 Restarting existing docker container for "minikube" ...
🐳 쿠버네티스 v1.26.1 을 Docker 20.10.23 런타임으로 설치하는 중
🔗 Configuring bridge CNI (Container Networking Interface) ...
🔎 Kubernetes 구성 요소를 확인...
▪ Using image docker.io/kubernetesui/metrics-scraper:v1.0.8
▪ Using image docker.io/kubernetesui/dashboard:v2.7.0
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
💡 Some dashboard features require the metrics-server addon. To enable all features please run:
minikube addons enable metrics-server
🌟 애드온 활성화 : storage-provisioner, default-storageclass, dashboard
🏄 끝났습니다! kubectl이 "minikube" 클러스터와 "default" 네임스페이스를 기본적으로 사용하도록 구성되었습니다.
# minikube 상태 확인
❯ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
Pod 객체
Pod 객체는 쿠버네티스에서 가장 작은 배포단위이다. Pod는 하나 또는 그 이상의 컨테이너를 포함할 수 있고, 같은 Pod내의 컨테이너는 동일한 호스트에서 실행되게 된다. 그리고 다음과 같은 특징들을 같는다.
- Pod 내의 컨테이너는 같은 호스트에서 실행되므로, 같은 Pod 내의 컨테이너 간에는 로컬 네트워크를 통해 통신할 수 있다.
- Pod는 IP 주소와 포트를 가지며, 다른 Pod나 서비스(Service)와 통신할 수 있다.
- Pod 내의 컨테이너는 공유된 스토리지 볼륨(Volume)을 사용할 수 있다.
Pod는 일반적으로 직접 생성하고 사용되지 않는다. 상위 수준의 객체에 의해 생성, 관리된다. 상위 수준의 객체는 Pod를 추상화하고, 여러 개의 Pod를 관리하기 위한 많은 기능들을 가지고 있다.
Deployment 객체
Deployment 객체는 리소스 객체 중 하나로, 파드(Pod)를 관리하고 배포하는 데 사용된다. 다음과 같은 특징을 가지고 있다.
- 지정된 수의 파드를 유지하도록 보장합니다.
- 새로운 버전의 애플리케이션을 배포할 때, 롤아웃(rolling update) 전략을 사용하여 서비스 중단 없이 업데이트를 수행할 수 있습니다.
- 이전 버전으로 롤백(rollback)할 수 있습니다.
- 스케일링(scale)을 통해 파드의 개수를 동적으로 조정할 수 있습니다.
객체 생성하기
명령적 접근방식으로 Deployment 객체를 생성해 보자. 생성하는 명령문은 다음과 같다.
kubectl create deployment {객체 이름} --image={이미지 이름}
여기서 객체 이름은 Deployment 객체의 이름을 말하고, 이미지 이름은 컨테이너를 생성하기 위한 이미지의 이름을 말한다.
여기서 주의할 점이 있다. 우리는 현재 도커 컨테이너의 가상환경 안에 쿠버네티스 클러스터를 생성하였다. 그렇기에 명령어에 들어갈 이미지는 클러스터 내에 존재하거나 도커 허브와 같이 클라우드에 올라가 있는 이미지의 이름이 되어야 한다. 자신의 로컬 환경에만 존재하는 이미지의 이름을 이용해 생성하면 객체 생성에 성공했다는 결과가 반환되지만 실제로는 이미지를 가져오지 못했다는 오류와 함께 제대로 실행되지 않으니 꼭 확인하도록 하자.
Service 객체
Service 객체는 로드 밸런싱, 서비스 디스커버리 및 네트워크 관리를 위한 추상화된 리소스 객체이다. 한 개 이상의 Pod 집합에 대해 엔드포인트를 정의하고, 클라이언트가 Pod 집합과 상호작용할 수 있도록 도와준다. 그리고 다음과 같은 특징들을 갖는다.
- Service는 클러스터 내의 다른 리소스와 연결된 IP 주소와 포트를 가진다. 클라이언트는 Service의 IP 주소와 포트를 사용하여 Pod에 접근할 수 있다.
- Service는 하나 이상의 Pod를 선택하는 셀렉터(selector)를 가지며, 해당 셀렉터와 일치하는 Pod 집합을 대상으로 한다.
- Service는 로드 밸런싱을 통해 요청을 여러 Pod로 분산시킬 수 있다.
- Service는 DNS 이름을 사용하여 클라이언트가 Pod 집합에 연결할 수 있도록 지원한다.
객체 생성하기
명령적 접근방식으로 Service 객체를 생성해 보자. 생성하는 명령문은 다음과 같다.
kubectl expose depolyment {객체 이름} --type={유형 이름} --port={포트 번호}
명령어들에 대해 알아보면 객체 이름은 이전 과정에서 생성해 주었던 Deployment 객체의 이름이다. 유형은 다양한 선택지가 존재하는 데 몇 가지에 대해 알아보면 다음과 같다.
- ClusterIP: ClusterIP는 클러스터 내부에서만 사용할 수 있는 가상 IP 주소를 제공한다. 이 유형의 Service를 사용하면 클러스터 내부에서만 서비스에 액세스 할 수 있다. 이 유형의 Service는 보통 같은 네임스페이스에 있는 Pod들과 통신할 때 사용된다.
- NodePort: NodePort는 클러스터 외부에서 액세스할 수 있는 고정된 포트를 제공한다. 이 유형의 Service를 사용하면 클러스터 외부에서 Pod에 직접 액세스할 수 있다. 이를 위해 쿠버네티스 클러스터의 모든 노드에 해당 포트로 액세스할 수 있는 엔드포인트가 생성된다.
- LoadBalancer: LoadBalancer는 클라우드 제공업체가 제공하는 로드 밸런서와 같은 로드 밸런서를 자동으로 생성한다. 이 유형의 Service는 클러스터 외부에서도 서비스를 사용할 수 있도록 제공하며, 외부 IP 주소를 가지며 로드 밸런싱 기능을 제공한다.
- ExternalName: ExternalName은 클러스터 외부에 있는 서비스를 사용할 때 사용된다. 이 유형의 Service는 DNS 질의에 대해 외부 서비스의 DNS 이름을 반환한다. 이를 통해 클러스터 내부의 애플리케이션은 클러스터 외부의 서비스를 참조할 수 있다.
여기서 NodePort를 사용하여 외부에 포트를 공개시키면 바로 접근이 가능할 것 같지만 그렇지 않다. 왜냐하면 우리가 만든 클러스터는 도커 컨테이너 내부에 존재하는 가상 머신이기 때문이다. 그렇기에 외부에서 접근이 가능하게 하려면 별도의 특수한 명령어가 필요하다.
minikube service {서비스 객체 이름}
위 명령어를 입력하면 이전에 Service 객체를 생성할 때 지정해 준 포트로 접근할 수 있는 URL을 제공한다. 하지만 이 기능은 minikube에서 제공하는 특수한 명령어이므로 유의하도록 하자.
스케일링 설정하기
클라이언트의 유입이 많을 수 있다고 생각되면 Pod에서 생성해야 할 컨테이너의 수를 늘려주어야 한다. 이를 설정하는 방법은 다음과 같다.
kubectl scale deployment/{객체 이름} --replicas={컨테이너 수}
위와 같이 특정 Deployment 객체에 의해 관리되는 Pod가 관리할 컨테이너의 숫자를 입력해 주면 쿠버네티스가 자동으로 컨테이너의 숫자를 늘려준다.
배포 중인 애플리케이션 업데이트 하기
우리가 현재 배포 중인 애플리케이션에 변경 사항이 발생했다면, 이를 어떻게 반영할 수 있을까? 명령어는 다음과 같다.
kubectl set image deployment/{객체명} {기존 이미지명}={새로운 이미지명}
명령어에서 업데이트할 Deployment 객체의 이름을 입력한 뒤 해당 객체에 존재하는 이미지 중 업데이트할 기존의 이미지와 대체할 이미지의 이름을 적어준다.
여기서 주의할 점. 업데이트될 새로운 이미지의 이름이 기존 이미지의 이름과 완전히 같다면 이미지가 이미 클러스터에 존재하기에 새로운 이미지를 받아와 적용하지 않고, 기존 이미지가 그대로 사용될 수 있다. 이 때는 새로운 이미지의 이름에 버전을 구분하는 태그를 달아주면 이를 해결할 수 있으니 참고하자.
롤백하기
이번에는 배포 중인 애플리케이션이 문제가 발생했을 때 이를 이전 버전으로 롤백하는 방법에 대해 알아보자. 문제가 생기는 상황은 다양할 수 있는데, 예를 들면 이전과정에서와 같이 배포 중인 애플리케이션을 업데이트하기 위해 새로운 이미지를 씌울려는데 이름을 잘못 지정해 주었다고 하자. 그러면 해당 이미지를 가져오지 못해 오류가 발생할 것이다. 그리고 쿠버네티스 특성상 새로운 이미지의 컨테이너가 띄워지지 않으면 기존의 컨테이너를 삭제하지 않는다. 이러지도 저러지도 못하는 상황이 된 것이다.
여기서 해결할 수 있는 명령어는 다음과 같다.
kubectl rollout undo deployment/{객체명}
문제가 발생한 객체의 이름을 입력하여 위 명령어를 입력해 주면 문제가 발생한 이전 버전으로 돌아가게 된다.
그런데 꼭 문제가 발생하지 않았더라도 어떤 목적에 따라 더 이전의 버전으로 롤백하고 싶을 수 있다. 이때는 기록을 확인한 뒤 해당 버전으로 롤백이 가능하다. 먼저 기록을 확인하는 명령어는 다음과 같다.
# 전체 리비젼 목록 확인
kubectl rollout history deployment/{객체명}
# 특정 리비젼에 대한 상세확인
kubectl rollout history deployment/{객체명} --revision={리비젼 번호}
# 특정 리비젼으로 이동
kubectl rollout history deployment/{객체명} --to-revision={리비젼 번호}
위와 같은 명령어로 기록을 확인하고 롤백이 가능하다.
구성파일을 통해 객체 생성하기
이제까지 쿠버네티스의 기본적인 객체인 Deployment, Service 객체의 생성에 관해 알아보았다. 그런데 꼭 이렇게 명령어를 하나하나 입력해 가며 관리해야 할까? 그렇지 않다! 일련의 수행 과정을 담는 구성파일을 작성하여 쿠버네티스가 알아서 하도록 할 수 있다. 마치 도커 컴포즈와 같은 것이다. 복잡한 도커 명령어를 입력하는 대신 컴포즈 파일을 작성하여 도커에 명령을 내리듯이 쿠버네티스 또한 가능하다.
그러면 바로 구성 파일을 보면서 각각이 의미하는 바에 대해 알아보자.
# kube_config.yaml
apiVersion: v1 # 원래는 core/v1 하지만 core는 생략가능
kind: Service # Service 객체 생성
metadata:
name: backend # 객체명
spec:
selector:
app: first-app # 외부 공개할 Pod 객체 선택
port:
- protocol: 'TCP' # 프로토콜 설정
port: 80 # 서비스를 통해 외부에 공개될 포트
target: 8000 # 서비스가 연결할 Pod 객체의 포트
type: NodePort # 서비스 유형 선택
---
apiVersion: apps/v1 # 쿠버네티스 API 버전 지정
kind: Deployment # Deployment 객체 생성
metadata:
name: app-deployment # 객체명
spec:
replicas: 1 # 복제할 Pod 객체의 수
selectors:
matchLabels:
app: first-app # 해당 객체가 관리할 Pod를 식별
template:
metadata:
labels:
app: first-app # 생성할 Pod 객체명
spec:
container:
- name: first-node # 컨테이너 명
image: hub/kube-first-app # 컨테이너가 사용할 이미지
imagePullPolicy: Always # 항상 최신 이미지를 불러오도록 설정
livenessProbe: # 서버 상태를 체크할 활성프로브 설정
httpGet:
path: / # 서버에 요청할 엔드포인트
port: 8000 # 서버의 포트
periodSeconds: 10 # 요청 주기
initialDelaySeconds: 5 # 최초 서버 가동 시 요청을 보낼 시간
쿠버네티스 API 버전에 따라 사용가능한 구성항목들이 존재하니 아래 링크를 참고하도록 하자.
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#-strong-api-overview-strong-
이렇게 구성파일을 작성하였다면, 하나의 명령어를 통해 모든 명령을 간단히 내릴 수 있다. 명령어는 다음과 같다.
kubectl apply -f=kube_config.yaml
-f 옵션 뒤에는 구성파일의 이름을 주면 된다.
'데브옵스' 카테고리의 다른 글
Docker-Compose 사용하기 (0) | 2023.01.13 |
---|---|
컨테이너 내부 서버가 통신 하는 방법 (1) | 2023.01.09 |
도커 볼륨으로 데이터 관리하기 (0) | 2023.01.08 |
Dockerfile 만들기 (0) | 2023.01.08 |