클라우드/Docker & Kubernetes

k8s Core Concepts & setup

mini'scloud 2025. 8. 7. 16:25
  • k8s가 하는 것과 하지 않는 것을 구분하는 것은 중요함
  • k8s가 하는 것
    • pods 같은 객체를 생성하고 관리할 수 있음
    • pods를 모니터링하고 교체하고 scale등 ... 을 할 수 있음
    • k8s는 우리가 만들어 놓은 자원을 활용하고, 우리가 설정한 목표에 적용할거임
      • k8s가 자원을 생성하는 것은 아님 (우리가 설정해줘야함)
  • 우리가 설정해줘야하는 것 
    • 클러스터와 노드 인스턴스(worker + master nodes)를 만들어줘야함
    • 노드마다 API 서버를 세팅해야함 (kubelet, 또 다른 k8s services..)
    • cloud provider에서 Load balancer, file system 같은게 필요하다면 이것들도 설정을 해줘야함

Installation

  • master node가 있는 클러스터는 여러 시스템에 분산되어있음
    • master node에는 API 서버와 스케줄러 등..이 설치되야함
  • 또한 하나 이상의 worker node와 services(software)가 필요함
    • worker node에는 docker와 kubelete이 설치되어서 master node와 통신을 하게 만들어야함
  • kubectl (kube-control)
    • 클러스터에 명령을 내리는 도구임
    • 즉, 클러스터는 기술 인프라이고, kubectl은 인프라와 통신을 하기위한 도구임
    • kubectl을 master node와 API server와 혼동을 하면 안됨!!
    • kubectl은 명령만 내리고, master node가 명령을 수행하는거임

  • 로컬에서 클러스터 환경을 구축하기 위해 minikube를 활용할거임

먼저 kubectl을 설치 해볼거임

https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/#before-you-begin

 

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.33 client can communicate with v1.32, v1.33, and v1.34 control planes. Using the latest compatible version of kubectl helps avoid

kubernetes.io

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl.sha256"

 

아래는 checksum file이 잘되었는지 확인 하는 명령어

echo "$(cat kubectl.sha256)  kubectl" | shasum -a 256 --check

 

chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
sudo chown root: /usr/local/bin/kubectl

 터미널에서 어느 위치(디렉토리)에서든 실행할 수 있도록 설정하는 명령어임

 

kubectl version --client --output=yaml

확인 한번 해주고

 rm kubectl.sha256

정리해주면됨

 

 

minikube를 설치해볼거임

 

https://minikube.sigs.k8s.io/docs/start/?arch=%2Fmacos%2Farm64%2Fstable%2Fbinary+download

 

minikube start

minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes. All you need is Docker (or similarly compatible) container or a Virtual Machine environment, and Kubernetes is a single command away: minikube start What you’ll

minikube.sigs.k8s.io

curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-darwin-arm64
sudo install minikube-darwin-arm64 /usr/local/bin/minikube

 

minikube start

 

나는 Docker Desktop이 있기에, 드라이버를 virtual box 같은걸 지정안해줘도 docker위에 k8s가 올라가게 됨

만약 vritual machine을 사용하면 guest OS(우분투) 위에 minikube를 올려야하지만,

docker engine(경량화된 vm역할)을 통해 컨테이너에 바로 minikube를 올릴 수 있음

 

minikube status

 

minikube dashboard

대시보드에 드갈 수 있음


Understanding k8s Objects

 

Pod Objects

  • 보통 pod하나당 컨테이너 하나가 들어가지만, 로그 수집 컨테이너 같은걸 붙일때 다중 컨테이너를 사용하기도 함
  • volumes를 통해 pods들은 자원을 공유할 수 있음
  • 클러스터 내부 IP주소를 가짐
    • 즉, 한 Pod 내부에 있는 컨테이너들은 localhost (127.0.0.1) 주소를 통해 직접 통신할 수 있음
    • 같은 네트워크 네임스페이스를 공유하여, 서로 네트워크 인터페이스가 겹치기 때문임

Deployments Object

  • k8s는 deployment object라고 봐도 무방함
  • 사용자가 원하는걸 지정하면 그에 맞게 실행을 함
  • Deployment가 Pod의 직접 생성·제거, 유지관리, 자동 스케일링, 롤백까지 관리함
  • pod를 직접 생성하지는 않지만, 우리가 원하는걸 반영하고 관리해주는 역할임

실습을 해보자

  • 앱을 내 클러스터에서 실행을 해볼려고함

 

app.js

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send(`
    <h1>Hello from this NodeJS app!</h1>
    <p>Try sending a request to /error and see what happens</p>
  `);
});

app.get('/error', (req, res) => {
  process.exit(1);
});

app.listen(8080);
  • app.listen(8080): 이 앱을 포트 8080번에서 HTTP 요청을 받을 수 있도록 서버를 시작

 

 

Dockerfile

FROM node:14-alpine

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 8080

CMD [ "node", "app.js" ]
  • EXPOSE 8080: 컨테이너가 내부적으로 8080 포트를 사용한다는 것을 명시함
  • CMD: 컨테이너가 시작될 때 기본으로 실행할 명령어

 

package.json

{
  "name": "first-run",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Maximilian Schwarzmüller / Academind GmbH",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "body-parser": "^1.19.0"
  }
}
  •  Node.js 프로젝트에 필요한 패키지 정보가 들어있음

.dockerignore

node_modules
Dockerfile

 

이제 터미널에서 아래와 같이 실행을 해보자

docker build -t kub-first-app .
  • 이미지에 kub-first-app이라는 tag를 붙여서 실행할거임
  • 이제 kubectl을 이용해 이미지를 k8s로 보내는 과정을 해볼거임

 

먼저 dockerhub를 쓰지 않고 바로 보낼 경우 error가 발생함

kubectl create deployment first-app --image=kub-first-app
  • kubectl 명령어는 로컬 시스템에서 k8s 클러스터로 보낼때 항상 사용함 

kubectl get deployments 명령어를 통해 확인해보면

  • READY 부분에 0(current state)/1(target state)이 나오는데 1개중에 0개인 상태이므로 실패했다는 거임

kubectl get pods 명령어를 통해 확인해봐도 Err가 나온것을 확인할 수 있음

 

  • k8s는  pod를 생성할 때, 지정된 이미지를 클러스터(노드) 머신에서 받아와야 함
  • --image=kub-first-app라고 하면, k8s는 도커 허브같은 곳에서 kub-first-app이라는 이미지를 찾으려 시도함
  • 현재 이미지는 로컬 머신에만 있으면 ErrImagePull이 발생하게 된 것임
    • 즉, 쿠버네티스 클러스터/노드 내부의 로컬 도커 저장소에 동일한 이름의 이미지가 없으면,
    • 노드들은 기본적으로 외부(도커 허브 등)에서 이미지를 찾으려고 하기에 
    • Dockerhub에 이미지를 올리고 다운 받는 과정이 필요한거임
kubectl delete deployment first-app

다시 삭제하고 docker hub에 먼저 보내보자

 

docker-hub에서 Create Repository에서 kube-first-app을 등록해주면됨

docker tag kub-first-app <devminii/kube-first-app 자기 계정 이름 적어주면됨>
docker push devminii/kube-first-app

 

도커허브에 올리고 다시 아래 명령을 실행하면 이미지는 원격 이미지를 가리키게됨

kubectl create deployment first-app --image=devminii/kube-first-app

정상적인것을 확인할 수 있음

대시보드에서도 확인할 수 있음

 

 


Service Object

  • 포드와 그 안의 컨테이너에 도달할려면 Service가 필요함
  • Pods는 기본적으로 내부 IP를 가지고 있음

  • 내부 IP에는 외부에서 접근을 못하고, pod교체시 매번 내부 IP가 변경되는 문제가 있음
  • 즉, service는 pod를 함께 그룹화하고 변경되지 않는 공유 IP주소를 제공함

service에 대해 실습을 해보자

kubectl expose deployment first-app --type=LoadBalancer --port=8080
  • expose: Deployment와 연결된 Pod들을 Service(고정 IP)라는 네트워크 진입점으로 노출하는 명령어임
  • first-app이라는 이름의 Deployment를 tag함
  • 생성하는 서비스 타입을 LoadBalancer로 지정
    • 이 서비스에 대한 고유 주소를 생성함
    • 클라우드 환경에서는 외부에 IP를 할당하여, 외부에서 직접 접근할 수 있는 로드밸런서를 생성함
  • --port=8080: 서비스가 외부로 노출할 포트 번호가 8080
kubectl get services

상태를 확인할 수 있음

외부 IP는 아직 확인할 수 없음

 

minikube service first-app

이 URL을 통해 외부에 접근하면 됨

 

 

  • /error 주소를 주게되면 k8s는 스스로 재시작을 할려고 할것임
  • kubectl get pods를 통해 확인이 가능함
kubectl scale deployment/first-app --replicas=3
  • first-app이라는 이름의 Deployment의 Replica 수를 3개로 조정 (명령어로 scale을 관리할 수 있음, 자동은 아님)

 

  • error가 발생해도 다른 pod에 의해 계속 실행되고, error가 발생한 pod는 자동으로 재시작되면서 복구됨
kubectl scale deployment/first-app --replicas=1
  • 이렇게하면 다시 replica가 1로 돌아가서 pod가 하나만 남는것을 확인할 수 있음

코드를 변경하고 원할 경우에 대해 실습을 해보자

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send(`
    <h1>Hello from this NodeJS app!</h1>
    <p>Try sending a request to /error and see what happens</p>
    <p>Try Try Try Try</p>
  `);
});

app.get('/error', (req, res) => {
  process.exit(1);
});

app.listen(8080);
  • 코드를 잠시 고치고 해보자
  • 코드를 바꾸고 나서 이미지는 다시 빌드해줘야함
docker build -t devminii/kube-first-app .

 

  • 업데이트된 이미지를 반영하여 새로운 배포로 업데이트할려함
  • 먼저 배포가 존재하는지 확인함
kubectl get deployments

 

 

다시 docker hub에 올리고 이미지를 변경할거임

docker push devminii/kube-first-app
kubectl set image deployment/first-app kube-first-app=devminii/kube-first-app
  •  fisrt-app이라는 Deployment 내의 kube-first-app 컨테이너의 이미지를 
  • devminii/kube-first-app으로 update하라는 뜻
  • 이렇게 하면 반영이 안되게 나옴
  • 그래서 아래와 같이 할거임
docker build -t devminii/kube-first-app:2 .
  • ‘devminii/kube-first-app:2’ 버전 도커 이미지를 새로 만들어서 저장함
docker push devminii/kube-first-app:2
kubectl set image deployment/first-app kube-first-app=devminii/kube-first-app:2
  • k8s가 2가 붙은 이미지를 이전에 사용된거와 다른 태그로 인식하고
  • 다시 다운받아 이를 기반으로 컨테이너를 다시 시작하도록함
kubectl rollout status deployment/first-app
  • rollout된 것을 확인하는 명령어

 

 

 

Rollbacks & History

  • first-app:3로 실제 존재하지 않는 이미지를 실행시켜볼거임
kubectl set image deployment/first-app kube-first-app=devminii/kube-first-app:3

 

  • roll out 진행상황을 아래 명령어를 통해 검사해볼거임
kubectl rollout status deployment/first-app

  • 방금 3을 배포했는데 업데이트가 아직되지 않았으며, 이전 pod가 끝나기를 기다리고있는 상태임
    • 왜냐하면 3은 없는 이미지이기에 기존에있는 pod가 종료할 필요가 없기 때문인거임
  • 즉, 업데이트를 롤백해야함

kubectl rollout undo deployment/first-app

 

  • 더 오래전으로 돌아가고 싶으면 history를 봐야함
kubectl rollout history deployment/first-app --revision=1
  • revision=1, 2, 3...원하는 번호를 선택해서 정해주면됨

  • 처음에 했던걸로 돌아가볼려고 함
kubectl rollout undo deployment/first-app --to-revision=1

이렇게 하면 처음에 했던게 나오게 됨

 

 

'클라우드 > Docker & Kubernetes' 카테고리의 다른 글

Virtualization  (0) 2025.08.19
k8s-Deployment (AWS EKS)  (0) 2025.08.11
Managing Data & Volumes with k8s  (0) 2025.08.08
k8s core concepts & setup (2)  (0) 2025.08.07
Kubernetes Concepts  (0) 2025.08.06