포스트

(멋쟁이사자처럼_백엔드스쿨플러스) Day12 kubernetes

kubernetes

kubernetes의 기본개념

  • kubernates는 컨테이너화된 애플리케이션을 자동으로 배포, 스케일링 및 관리하는 오픈소스 플랫폼이다.
  • kubernetes는 컨테이너 오케스트레이션 툴로, 컨테이너화된 애플리케이션을 배포, 확장, 관리하는 작업을 자동화한다.

kubernetes의 기본용어

클러스터

  • 클러스터는 여러개의 서버를 하나의 그룹으로 묶어서 관리하는 것을 의미한다.
  • kubernetes 클러스터는 마스터노드와 워커노드로 구성된다. Image

마스터노드

  • 마스터노드는 클러스터를 관리하는 노드로, 클러스터의 상태를 관리하고 클러스터의 작업을 스케줄링한다.
  • 마스터노드는 API 서버, 스케줄러, 컨트롤러 매니저, etcd로 구성된다.
    • API 서버: 클러스터의 상태를 관리하고 클러스터의 작업을 스케줄링한다.
    • 스케줄러: 새로운 파드를 어떤 노드에 배치할지 결정한다.
    • 컨트롤러 매니저: 클러스터의 상태를 관리하고 클러스터의 작업을 스케줄링한다.
    • etcd: 클러스터의 상태를 저장하는 데이터베이스이다.

워커노드

  • 워커노드는 실제로 컨테이너가 실행되는 노드로, 마스터노드의 명령을 받아 컨테이너를 실행한다.
  • 워커노드는 kubelet, kube-proxy, 컨테이너 런타임으로 구성된다.
    • kubelet: 마스터노드의 명령을 받아 컨테이너를 실행한다.
    • kube-proxy: 네트워크 규칙과 포워딩을 관리한다.
    • 컨테이너 런타임: 컨테이너를 실행하는 소프트웨어이다.

파드

  • 파드는 쿠버네티스의 가장 작은 배포 단위로, 하나 이상의 컨테이너로 구성된다.
  • 파드는 동일한 네트워크 네임스페이스, IP 주소, 포트 공간, IPC 네임스페이스, 호스트 이름을 공유한다.

서비스

  • 서비스는 파드의 집합에 대한 네트워크 엔드포인트를 제공하는 리소스이다.
  • 서비스는 파드의 레이블 셀렉터를 사용하여 파드를 선택하고, 클러스터 내부 또는 외부로 노출할 수 있다.

kubernetes 클러스터 생성

클러스터 생성과정

1) kubeadm init (마스터 노드)

  • kubeadm이 먼저 사전 검사를 실행 (포트, 메모리, CPU 등)
  • API 서버용 인증서 생성
  • kubelet-config 파일 생성
  • API 서버, 컨트롤러 매니저, 스케줄러를 static pod manifest로 생성
  • etcd 데이터베이스 초기화

2) 컨트롤 플레인 구성요소 시작

  • API 서버가 가장 먼저 시작
  • 그 다음 컨트롤러 매니저
  • 마지막으로 스케줄러가 시작
  • 이 시점에서 기본적인 컨트롤 플레인이 동작 시작

3) 워커 노드 연결 (kubeadm join)

  • 워커 노드에서 마스터가 생성한 조인 토큰을 사용해 kubeadm join 실행
  • 워커 노드가 API 서버에 자신을 등록
  • kubelet이 시작되고 API 서버와 통신 시작

클러스터 생성하기

1) nslookup vpc1-k8s.sik2.site 로 확인

  • nslookup은 도메인 이름에 대한 IP 주소를 조회하는 명령어이다.
  • vpc1-k8s.sik2.site 도메인 이름에 대한 IP 주소가 있어야 api 서버에 접속할 수 있다.

    Image

2) aws 클러스터 생성

  1. on master
    • kubeadm init 을 통해 포트 및 메모리, CPU 등 사전 검사를 실행한다.
      1
      
      kubeadm init --control-plane-endpoint "vpc1-k8s.sik2.site:6443" --upload-certs --pod-network-cidr=10.10.0.0/16 -v=5
      
    • kubeadm init 명령어를 통해 클러스터를 생성한다.
    • –control-plane-endpoint: API 서버의 엔드포인트를 지정한다.
    • –upload-certs: 인증서를 업로드한다.
    • –pod-network-cidr: 파드 네트워크 CIDR을 지정한다.
    • -v=5: 로그 레벨을 지정한다.

      Image

  2. on worker
    • 마스터노드에서 생성된 kubeadm join 명령어를 통해 워커 노드를 마스터 노드에 연결한다.
      1
      
      kubeadm join vpc1-k8s.sik2.site:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
      
      • kubeadm join 명령어를 통해 워커 노드를 마스터 노드에 연결한다.
      • –token: 토큰을 지정한다.
      • –discovery-token-ca-cert-hash: 인증서 해시를 지정한다. Image

3) 칼리코 설정

  • 칼리코는 쿠버네티스 클러스터의 네트워크 정책을 관리하는 오픈소스 솔루션이다.
  • 칼리코를 설치하면 클러스터 내의 모든 파드가 서로 통신할 수 있다.

    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
    29
    30
    31
    32
    
      kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml
        
      mkdir /kube
      cd /kube
        
      cat <<EOF | tee /kube/calico-resources.yaml
      # This section includes base Calico installation configuration.
      # For more information, see: https://projectcalico.docs.tigera.io/master/reference/installation/api#operator.tigera.io/v1.Installation
      apiVersion: operator.tigera.io/v1
      kind: Installation
      metadata:
        name: default
      spec:
        calicoNetwork:
          bgp: Disabled
          ipPools:
          - cidr: 10.10.0.0/16
            encapsulation: VXLAN
        
      ---
        
      # This section configures the Calico API server.
      # For more information, see: https://projectcalico.docs.tigera.io/master/reference/installation/api#operator.tigera.io/v1.APIServer
      apiVersion: operator.tigera.io/v1
      kind: APIServer
      metadata:
        name: default
      spec: {}
      EOF
        
      kubectl create -f calico-resources.yaml
      systemctl restart containerd
    
  • kubectl get nodes로 결과를 확인 할 수 있다.

    Image

    kubectl 설치

    • kubectl은 쿠버네티스 클러스터와 통신하기 위한 명령줄 도구이다.
      1
      2
      3
      
      mkdir -p $HOME/.kube
      cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      chown $(id -u):$(id -g) $HOME/.kube/config
      

    kubectl 명령어 자동완성기능 활성화

    1
    2
    3
    4
    5
    6
    
    yum install bash-completion -y
    source /usr/share/bash-completion/bash_completion
    kubectl completion bash | tee /etc/bash_completion.d/kubectl > /dev/null
    echo 'alias k=kubectl' >>~/.bashrc
    echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
    source /usr/share/bash-completion/bash_completion
    

4) 클러스터 구성 취소 방법

  • 클러스터를 삭제하는 방법은 다음 명령어를 순서되로 입력하면된다.

    1
    2
    3
    4
    5
    6
    
    kubeadm reset
    y 입력
    rm -rf $HOME/.kube
    rm -rf /etc/cni/net.d
    systemctl restart kubelet
    systemctl restart containerd
    

Pod 만들기 및 삭제

  • nginx 이미지run을 마스터 노드에서 실행하면 마스터노드는 워커노드에 pod를 생성한다.
  • service를 생성하지 않는다면 외부접근 불가능하다.
  • 마스터노드에서는 pod에 대해 조회를 할 수 있다.

    1
    2
    
    kubectl run webserver --image=nginx:latest
    kubectl get pods -o wide
    

    Image

  • pod 삭제하기
    1
    
    kubectl delete pod webserver
    

DataBase Pod 만들기

  • mysql 이미지를 사용하여 pod를 생성한다.
  • 데이터베이스는 한곳에 저장 해야한다.
  • 스크립트 파일 yaml에서 pod를 생성할 워커노드를 지정할 수 있다. Image

  • 폴더 생성하기 및 yaml 파일 생성

    1
    2
    3
    
    mkdir -p /kube/mysql-1
    cd /kube/mysql-1
    vi mysql-1.yaml
    
  • 리소스 정의 파일
  • ----는 여러개의 리소스를 한번에 생성할 때 사용한다.
  • 여기서는 리소스 구성, 서비스, 시크릿을 한번에 생성한다.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
apiVersion: apps/v1                   #api 버전
kind: Deployment              #리소스 종류(파드, 서비스, 레플리카셋, 디플로이먼트 등) 
metadata:         
  name: mysql-1-deployment  #리소스 이름
spec:                       #리소스의 구성 요소
  selector:                 #파드 선택자      
    matchLabels:            #선택자 레이블        
      app: mysql-1          #선택자 레이블 값          
  template:                 #파드 템플릿      
    metadata:               #파드 메타데이터
      labels:
        app: mysql-1        #파드 레이블
    spec:                   #파드 스펙
      nodeSelector:         #선택 노드
        kubernetes.io/hostname: ec2-2 
      containers:
      - image: mysql        #컨테이너 이미지
        name: mysql-1       #컨테이너 이름 
        ports:
        - containerPort: 3306 #컨테이너 포트
          name: mysql-1       #컨테이너 포트 이름
        volumeMounts:
        - name: vol
          mountPath: /etc/mysql/conf.d
          subPath: etc/mysql/conf.d
        - name: vol
          mountPath: /var/lib/mysql
          subPath: var/lib/mysql
        env:
        - name: TZ
          value: "Asia/Seoul"
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-1-secret
              key: password
      volumes:
      - name: vol
        hostPath:
          path: /data/ec2-2/mysql-1
          type: DirectoryOrCreate

---

apiVersion: v1
kind: Service
metadata:
  name: mysql-1-service
spec:
  ports:
  - port: 3306
  selector:
    app: mysql-1

---

apiVersion: v1
kind: Secret
metadata:
  name: mysql-1-secret
data:
  password: MTIzNA==
  • mysql-1.yaml 적용하기
    1
    
    kubectl apply -f mysql-1.yaml
    
  • 접속확인 (tab으로 자동완성)
    1
    2
    
    kubectl exec -it mysql-1-deployment-7b8d7b8b8b-7b8d7b8b8b -- /bin/bash
    > mysql -uroot -p
    

    Image

Deployment, ReplicaSet, Pod

  • Deployment와 replicaSet은 파드를 관리하는 리소스이다.
  • 항상 정해진 pod를 관리 할 수 있다.

Deployment

  • Deployment는 레플리카셋을 관리하며, 애플리케이션의 선언적 업데이트를 제공하는 상위 수준의 리소스이다.
  • Deplyment 정보는 etcd에 저장되어 관리되고, Controller Manager는 API 서버를 통해 조회하고 ReplicaSet을 생성 및 관리한다.
  • 주요기능
    • 롤링 업데이트: 무중단 업데이트 지원
    • 롤백: 이전 버전으로 쉽게 되돌리기 가능
    • 배포 이력: 이전 배포 상태 기록 유지
    • 스케일링: 애플리케이션 규모 조정
    • 일시 중지와 재개: 업데이트 일시 중지 및 재개 가능
  • 디플로이먼트의 구성 예시

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example-deployment
    spec:
      replicas: 3
      strategy:
        type: RollingUpdate        # 업데이트 전략
        rollingUpdate:
          maxSurge: 1             # 최대 초과 허용 파드 수
          maxUnavailable: 1       # 최대 불가용 허용 파드 수
      selector:
        matchLabels:
          app: example
      template:
        metadata:
          labels:
            app: example
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
    

ReplicaSet

  • ReplicaSet은 지정된 수의 파드 복제본이 항상 실행되도록 보장하는 리소스이다.
  • ReplicaSet은 파드의 수를 지정하고, 파드의 상태를 모니터링하여 파드가 삭제되면 새로운 파드를 생성한다.
  • 주요기능
    • 지정된 수의 파드가 항상 실행되도록 유지
    • 파드 장애 발생 시 자동으로 새로운 파드 생성
    • 노드 장애 시 다른 노드에 파드를 재생성
    • 수평적 확장/축소 지원
  • 레플리카셋의 구성 요소

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    apiVersion: apps/v1
    kind: ReplicaSet
    metadata:
      name: example-replicaset
    spec:
      replicas: 3                    # 원하는 파드 복제본 수
      selector:                      # 관리할 파드를 선택하는 라벨 셀렉터
        matchLabels:
          app: example
      template:                      # 파드 템플릿
        metadata:
          labels:
            app: example
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
    

세 리소스의 관계

  1. 계층 구조
    • Deployment → ReplicaSet → Pod
    • 각 상위 리소스는 하위 리소스의 라이프사이클을 관리

Image

  1. 일반적인 사용 패턴
    • 직접 Pod 생성 < ReplicaSet 사용 < Deployment 사용
    • 대부분의 경우 Deployment를 통해 관리
  2. 업데이트 프로세스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    Deployment 업데이트
          ↓
    새로운 ReplicaSet 생성
          ↓
    새로운 Pod 생성
          ↓
    이전 Pod 제거
          ↓
    이전 ReplicaSet 보존 (롤백 가능)
    

서비스명으로 포워딩 할수있게 하는 준비작업

1) nginx 는 마스터 노드에 설치

  • 마스터노드에 설치 함으로써 외부에서 접근 할때 마스터노드를 통해 워커노드로 접근 할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    
    # 환경 변수 설정
    mkdir -p /data/ec2-1/nginx-proxy-manager-1/data/nginx/custom
    echo "resolver 127.0.0.1  valid=10s;" > /data/ec2-1/nginx-proxy-manager-1/data/nginx/custom/server_proxy.conf
    echo "resolver 127.0.0.1  valid=10s;" > /data/ec2-1/nginx-proxy-manager-1/data/nginx/custom/server_stream.conf
    mkdir -p /kube/nginx-proxy-manager-1
    cd /kube/nginx-proxy-manager-1
    vi nginx-proxy-manager-1.yaml
    

2) nginx-proxy-manager-1.yaml 적용

  • 마스터노드에 설치하는 nginx 설정 파일을 작성한다.

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-proxy-manager-1-deployment
    spec:
      selector:
        matchLabels:
          app: nginx-proxy-manager-1
      template:
        metadata:
          labels:
            app: nginx-proxy-manager-1
        spec:
          nodeSelector: # 추가됨
            kubernetes.io/hostname: ec2-1 # 추가됨
          tolerations:
          - key: node-role.kubernetes.io/control-plane
            operator: Exists
            effect: NoSchedule
          containers:
          - image: jc21/nginx-proxy-manager:latest
            name: nginx-proxy-manager-1
            ports:
            - containerPort: 3306 #3306으로 요청이 들어오면
              hostPort: 3306 #워커노드의 3306으로 포워딩
            - containerPort: 443
              hostPort: 443
            - containerPort: 80
              hostPort: 80
            - containerPort: 81
              hostPort: 81
            env:
            - name: TZ
              value: "Asia/Seoul"
            volumeMounts:
            - name: vol
              mountPath: /data
              subPath: data
            - name: vol
              mountPath: /etc/letsencrypt
              subPath: etc/letsencrypt
          - image: "janeczku/go-dnsmasq:release-1.0.7"
            name: dnsmasq
            args:
              - --listen
              - "127.0.0.1:53"
              - --default-resolver
              - --append-search-domains
              - --hostsfile=/etc/hosts
              - --verbose
          volumes:
          - name: vol
            hostPath:
              path: /data/ec2-1/nginx-proxy-manager-1
              type: DirectoryOrCreate
    
  • yaml 파일 적용
    1
    
    kubectl apply -f nginx-proxy-manager-1.yaml
    
  • yaml 파일 삭제
    1
    
    kubectl delete -f nginx-proxy-manager-1.yaml
    

3) worker 노드에 nginx(웹어플리케이션) 설치

  • 워커노드에 설치할 application 설정 파일을 작성한다.
    1
    2
    3
    
    mkdir -p /kube/nginx-test-1
    cd /kube/nginx-test-1
    vi nginx-test-1.yaml
    

    4) Service 접속 과정

  • 외부 요청 → nginx-proxy-manager → Pod의 애플리케이션(예: Node.js, Python 등)

    Image

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.