[kubernetes] 쿠버네티스 실습 3 - 기본 사용법(2)

06 Dec 2023 - juno

#cloud  #kubernetes 


2023-12-06 클라우드 프로그래밍 14주차 강의


목차

  1. 데몬셋
  2. 크론잡
  3. 컨피그맵
  4. 시크릿
  5. 볼륨

1. 데몬셋

데몬셋(DemonSet)

데몬셋(실습)

데몬셋 yaml 파일 생성

vi daemonsets.yaml
    ✓ sudo su -> 루트의 home `~`(/root) 에서 작업해야한다.

데몬셋 yaml 파일 생성

apiVersion: apps/v1  # Kubernetes API 버전 지정
kind: DaemonSet       # 데몬셋 정의
metadata:  #
  name: prometheus-daemonset  # 데몬셋 이름 지정
spec:  # 데몬셋 스펙 정의
  selector:  # 파드 선택하는 방법 지정
    matchLabels:
      tier: monitoring   
      name: prometheus-exporter
  template:  # 파드 템플릿 정의 데몬셋이 생성하는 파드는 템플릿을 기반으로 생성
    metadata:  # 파드 메타데이터 정의
      labels:  # 파드 라벨 정의
        tier: monitoring
        name: prometheus-exporter
    spec:  # 파드 스펙 정의
      containers:  # 파드 포함 컨테이너 정의
      - name: prometheus  # 컨테이너 이름 지정
        image: prom/node-exporter  #  도커 이미지 지정
        ports:  # 컨테이너 포트 정의
        - containerPort: 80  #  컨테이너 사용 포트
    tier: monitoring   
    name: prometheus-exporter
    -> 이것들이 크게 의미있는것이 아니고 그냥 라벨링 해주고 이름 지어준 것 뿐이다.

데몬셋 생성 및 정보 확인

#데몬셋 생성
kubectl apply -f daemonsets.yaml
#데몬셋 상세 정보 확인
kubectl describe daemonset/prometheus-daemonset

데몬셋 상세 정보 확인(실행 화면)

image

상세정보 내용

  • Name: prometheus-daemonset: DaemonSet의 이름
  • Selector: name=prometheus-exporter,tier=monitoring: DaemonSet이 어떤 노드에 파드를 배포할지 선택하는 데 사용되는 레이블 셀렉터
  • Desired Number of Nodes Scheduled: 예상된 노드 수
  • Current Number of Nodes Scheduled: 현재 노드 수
  • Number of Nodes Scheduled with Up-to-date Pods: 최신 상태의 파드를 가진 노드 수
  • Number of Nodes Scheduled with Available Pods: 사용 가능한 파드를 가진 노드 수
  • Number of Nodes Misscheduled: 잘못 배치된 노드의 수
  • Pods Status: 파드의 상태(실행 중인 파드 수 / 대기 중인 파드 수 / 성공한 파드 수 / 실패한 파드 수)
  • Pod Template: 사용되는 파드 템플릿의 정보
  • Containers: 파드에 포함된 컨테이너의 정보
  • Events: DaemonSet과 관련된 이벤트 정보
    • Type: 이벤트의 유형 (Normal, Warning 등)
    • Reason: 이벤트의 발생 이유
    • Age: 이벤트가 발생한 시간 경과
    • From: 이벤트가 발생한 소스
    • Message: 이벤트에 대한 메시지

데몬셋 파드 리스트 확인 및 데몬셋 삭제

#데몬셋 확인
kubectl get daemonset
#파드 리스트 확인
kubectl get pods -o wide

데몬셋 파드 리스트 확인(실행 화면)

image

데몬셋 목록 조회 결과(각 열 의미)

  • NAME: DaemonSet의 이름
  • DESIRED: DaemonSet이 관리하는 파드의 원하는 수
  • CURRENT: 현재 DaemonSet이 관리하는 파드의 실제 수
  • READY: 현재 실행 중이고 모든 컨테이너가 정상적으로 시작된 파드 수
  • UP-TO-DATE: 최근에 업데이트된 컨트롤러 템플릿을 사용하여 생성된 파드의 수
  • AVAILABLE: 사용 가능한 파드 수
  • AGE: DaemonSet이 생성된 시간으로 표시된 시간 경과

데몬셋 삭제

#데몬셋 삭제 kubectl delete daemonset [데몬셋 이름]
kubectl delete daemonset prometheus-daemonset

✓ 만약 모든 파드를 삭제하고 싶을떄 pods 삭제 -all 하면 deployment로 생성할 때 “최소 몇개는 살려둬라” 했던 pod들이 살아있게 된다 따라서 deployment도 삭제 -all 해줘야 한다.


2. 크론잡

잡(job)

크론잡(실습)

크론잡 yaml 파일 생성

vi cronjob.yaml

크론잡 yaml 파일 내용

apiVersion: batch/v1
kind: CronJob   # CronJob 정의
metadata:
  name: hello  # CronJob의 이름 지정
spec:
  schedule: "*/1 * * * *"  # CronJob 실행 일정 지정
  jobTemplate:  # Job 템플릿 정의
    spec:
      template:
        spec:
          containers:
          - name: hello  # 컨테이너 이름 지정
            image: busybox  # 도커 이미지 지정
            imagePullPolicy: IfNotPresent  # 이미지 풀 정책 설정(이미지가 없을 때만 풀도록 설정)
            command:  # 컨테이너에서 실행할 명령어 정의
            - /bin/sh  # 셸 실행
            - -c  # 명령어 실행시 사용할 인자
            - date; echo Hello from the Kubernetes cluster  # date 명령어와 메시지 출력 명령어
          restartPolicy: OnFailure  # Job이 실패할 때만 다시 시작되도록 재시작 정책 설정
      schedule: "*/1 * * * *" -> "*/1"은 시간(분)

image

크론잡 생성 및 목록 확인

#크론잡 생성
kubectl create -f cronjob.yaml
#크론잡 목록 확인
kubectl get cronjob hello
#크론잡 목록 상세정보 확인
kubectl get cronjob -w

크론잡 목록 확인(실행 화면)

image

크론잡 목록 상세 정보 확인(실행 화면)

image

    kubectl get pods -o wide 를 사용해서 확인해보면 completed된 파드들을 확인할 수 있다. 1분에 한개씩 생성되어서 특정행위를 하고 내려가는 것이다.

CronJob 리소스에 대한 정보(각 열 의미)

  • NAME: CronJob의 이름
  • SCHEDULE: Cron 표현식에 따라 작업이 예약된 시간
    • */1 * * * *“로 설정 매 분마다 실행 예약
  • SUSPEND: 현재 CronJob이 일시 중지되었는지 여부
  • ACTIVE: 현재 실행 중인 작업의 수
  • LAST SCHEDULE: 가장 최근에 작업이 예약된 시간
  • AGE: CronJob이 생성된 이후의 경과 시간

파드 변화 확인 및 크론잡 삭제

#파드 변화 확인
kubectl get pod -w
#크론잡 삭제
kubectl delete cronjob hello

파드 변화 확인(실행 화면)

image

크론잡 삭제(실행 확인)

image

✓ 데몬셋과 크론잡은 활용할일이 많지 않음, 어떤 식으로 동작하고 용도가 무엇인지 정도 알기


CoreDNS

    내부적으로 어떻게 도는지는 알 수 없음
    쿠버네티스가 가지고 있는 도메인에 대해서 IP를 반환해준다.

DNS

CoreDNS(실습)

CoreDNS 구성 및 서비스 확인

#CoreDNS 구성 확인
#두 개의 파드로 구성
kubectl  get po -n kube-system -l k8s-app=kube-dns
#두 개의 파드에 대한 서비스 확인
#kube-dns는 TCP, UDP 모두 53 포트 사용
kubectl get svc -n kube-system -l k8s-app=kube-dns

CoreDNS 구성 확인(실행 화면)

image

두 개의 파드에 대한 서비스 확인(실행 화면)

image

CoreDNS의 내용을 담고 있는 Corefile 정보 확인

#Corefile 정보 확인
kubectl describe cm -n kube-system coredns

Corefile 정보 확인(실행 화면)

사진

Corefile의 출력 내용

  • errors: 에러 발생시 stdout에 내용 기록
  • health: CoreDNS 상태 확인 부분
  • ready: DNS 서비스 준비가 되었다면 200 OK 반환
  • kubenetes: CoreDNS가 쿠버네티스의 서비스 및 파드의 IP를 기반으로 DNS 질의에 응답
  • prometheus: 지정된 포트(9153)로 프로메테우스의 메트릭 정보 확인
    • 프로메테우스(Prometheus)는 오픈 소스 시스템 모니터링 및 경고 도구
    • 시스템 상태를 모니터링하는 데 사용
    • 메트릭(Metrics)은 시스템의 동작을 측정하고 표현하는 수치 값

CoreDNS가 어떻게 사용되는지 확인

#파드 하나 생성후 /erc/resolv.conf 파일 내용 확인
#파드 생성시 kubelet은 /erc/resolv.conf 파일에 CoreDNS를 가리키는 IP 주소를 네임서버로 등록
#resolv.conf 파일에 등록된 네임서버를 이용해 도메인을 IP로 변경 가능
kubectl run -it --rm --image=busybox --restart=Never busybox -- cat /etc/resolv.conf

파드 하나 생성후 /erc/resolv.conf 파일 내용 확인(실행 화면)

사진

resolv.conf에 등록된 결과(의미)

  • nameserver: CoreDNS의 IP 주소
  • search: DNS에 질의하는 부분으로 도메인 주소 표시
  • ndots: 도메인에 포함될 .(점)의 최소 개수(예, www.a.com에서 “.”의 개수)

3. 컨피그맵

컨피그맵(ConfigMap)

컨피그맵 생성 명령어

옵션 의미

컨피그맵(실습)

리터럴 값(–from-literal) 사용 방법

컨피그맵 JAVA_HOME 환경 변수 정의

kubectl create configmap my-config --from-literal=JAVA_HOME=/usr/java

컨피그맵 JAVA_HOME 환경 변수 정의(실행 화면)

사진넣기

컨피크맵 삭제

kubectl delete configmap my-config

컨피그맵 변수 추가 정의

kubectl create configmap my-config --from-literal=JAVA_HOME=/usr/java --from-literal=URL=http://localhost:8000

컨피그맵 변수 추가 정의(실행 화면)

사진추가

컨피그맵 활용

vi configmap-test.yaml
apiVersion: apps/v1
kind: Deployment    #유형 = 디플로이먼트
metadata:
  name: java-app    # java-app이라는애들을 관리하겠다.
spec:
  replicas: 1
  selector:
    matchLabels:
      app: java-app
  template:
    metadata:
      labels:
        app: java-app
    spec:
      containers:
      - name: java-container
        image: openjdk:11
        command: ["sh", "-c", "while true; do sleep 3600; done"]
        env:
        - name: JAVA_HOME
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: JAVA_HOME # JAVA_HOME=/usr/java, 위에서 컨피그맵에 정의한 이것을 사용하겠다.
        - name: URL
          valueFrom:
            configMapKeyRef:
              name: my-config 
              key: URL  # URL=http://localhost:8000, 위에서 컨피그맵에 정의한 이것을 사용하겠다.
    command: ["sh", "-c", "while true; do sleep 3600; done"] 
    -> 이 옵션으로 java11이 3600초(1분) 동안 돌게끔 한다?
    
    name: my-config
    key: URL
    -> my-config에서 설정한 URL을 사용하겠다.
kubectl apply -f configmap-test.yaml
kubectl get pods
kubectl exec -it [Pod 이름] -- /bin/bash
echo $JAVA_HOME

image

파일/디렉터리(–from-file) 사용 방법

Hello, World! 내용 html 파일 생성

echo Hello, World! >> configmap_test.html

html 파일 이용하여 컨피그맵 생성

kubectl create configmap configmap-file --from-file configmap_test.html

html 파일 이용하여 컨피그맵 생성(실행 화면)

사진넣기

컨피그맵 내용 확인

kubectl describe configmap configmap-file

컨피그맵 내용 확인(실행 화면)

사진넣기

컨피그맵 파일 활용

vi configmap-file-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        volumeMounts:
        - name: configmap-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: configmap-volume
        configMap:
          name: configmap-file  # 이 파일안에있는 
          items:
          - key: configmap_test.html  # 이 html을 
            path: index.html          # 이 index.html로 만들어라

적용

kubectl apply -f configmap-file-test.yaml
kubectl get pods -o wide

image

curl 10.244.2.67

image

    congifmap-file안에 적은 configmap_test.html이 index에 적용된 것을 확인 할 수 있다.

4. 시크릿

시크릿

시크릿(실습)

✓ 컨피그맵과 사용법은 거의 동일하다.

시크릿 생성

kubectl create secret generic dbuser --from-literal=username=testuser --from-literal=apssword=1234

시크릿 생성(실행 화면)

사진넣기

시크릿 활용

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: mycontainer
        image: myimage
        env:
        - name: USERNAME
          valueFrom:
            secretKeyRef:
              name: dbuser
              key: username
        - name: PASSWORD
          valueFrom:
            secretKeyRef:
              name: dbuser
              key: password

시크릿 삭제

kubectl delete secret dbuser

5. 볼륨

    - 가장 많이 활용되는 부분

    - 이미지파일을 보통 내부(pod,container) 볼륨에 넣지 않음
    ↳ 왜냐면 생성된 모든 파드들이 동기화되어야하기때문에 하나라도 동기화 되지 않는 오류가 발생하면 그냥 오류가 나버리는 것이기 때문

볼륨

image

볼륨 분류

image

볼륨 유형

image

emptyDir(실습) 임시 볼륨 마운트 후 데이터 읽고 쓰기

emptydir yaml 파일 생성 및 실행

#emptydir yaml 파일 생성
nano emptydir.yaml
#emptydir yaml 파일 실행
kubectl apply -f emptydir.yaml

emptydir yaml 파일 내용

apiVersion: v1
kind: Pod
metadata:
  name: emptydata   # Pod의 이름을 'emptydata'로 지정
spec:
  containers:
  - name: nginx
    image: nginx   # Nginx 이미지를 사용하는 컨테이너를 정의
    volumeMounts:
    - name: shared-storage
      mountPath: /data/shared   # 'shared-storage' 볼륨을 '/data/shared' 경로에 마운트
  volumes:
  - name : shared-storage
    emptyDir: {}   # 'shared-storage' 볼륨을 EmptyDir 타입으로 정의

emptydata 파드에 접속 및 디렉토리 이동

#emptydata 파드에 접속
kubectl exec -it emptydata -- /bin/bash
#/data/shared 디렉토리로 이동
cd /data/shared

emptydata 파드에 접속 및 디렉토리 이동(실행 화면)

사진넣기

text 파일 생성 및 확인

#text 파일 생성
echo "hello" > test.txt
#생성 파일 확인
ls –al
#파일 내용 확인
date,cat test.txt

text 파일 생성 및 확인(실행 화면)

사진넣기

hostPath(실습) 로컬 볼륨 마운트 후 데이터 생성

hostpath yaml 파일 생성

vi hostpath.yaml

hostpath yaml 파일 내용

apiVersion: v1
kind: Pod
metadata:
  name: hostpath   # Pod의 이름을 'hostpath'로 지정
spec:
  containers:
  - name: nginx
    image: nginx   # Nginx 이미지를 사용하는 컨테이너를 정의
    volumeMounts:
    - name: localpath
      mountPath: /data/shared   # 'localpath' 볼륨을 '/data/shared' 경로에 마운트
  volumes:
  - name: localpath
    hostPath:
      path: /tmp   # 호스트 경로를 '/tmp'로 설정
      type: Directory   # 호스트 경로의 타입을 디렉토리로 지정
    - master의 /data/shared를 worker노드의 /tmp와 연결
    - 어떤 worker노드가 될지는 알수 없음 wide를 통해 확인가능

hostpath yaml 파일 실행 및 hostpath 파드 접속

#hostpath yaml 파일 실행
kubectl apply -f hostpath.yaml
#hostpath 파드 접속
kubectl exec -it hostpath -- /bin/bash
#/data/shared 디렉토리 이동
cd /data/shared

hostpath yaml 파일 실행(실행 화면)

사진넣기

hostpath 파드 접속 및 디렉토리 이동(실행 화면)

사진넣기

text 파일 생성 및 생성 파일 확인

#text 파일 생성
echo "hello" > test.txt
#생성 파일 확인
ls –al

text 파일 생성 및 생성 파일 확인(실행 화면)

사진넣기

외부볼륨

NFS (Network File System)**

CephFS

GlusterFS

AWS EBS (Elastic Block Store):

각각의 볼륨 타입은 특정 사용 사례와 요구 사항에 따라 선택되어야 함. 예를 들어, AWS EBS는 AWS 환경에서 운영되는 서비스에 적합하고, CephFS나 GlusterFS는 고가용성과 확장성이 중요한 경우에 사용됨. NFS는 설정이 간단하고 범용적이지만, 고성능을 요구하는 애플리케이션에는 적합하지 않을 수 있음.

NFS (Network File System) 실습

NFS 서버 설치(marst)

#NFS 서버 패키지 설치
sudo apt-get update
sudo apt-get install nfs-kernel-server
#NFS 서버 재시작
sudo systemctl restart nfs-kernel-server

NFS 유틸리티 설치(worker0, worker1)

sudo apt-get updat
sudo apt-get install --reinstall nfs-common

공유 디렉토리 생성

sudo mkdir -p /nfs_share
#디렉토리 권한 설정
sudo chown nobody:nogroup /nfs_share
sudo chmod 777 /nfs_share

사진넣기

NFS 공유설정

sudo vi /etc/exports
# /etc/exports 공유 설정
/nfs_share 192.168.47.0/24(rw,sync,no_root_squash,no_subtree_check)

사진추가하기

변경사항 적용

sudo systemctl restart nfs-kernel-server

공유폴더 확인

showmount -e 192.168.47.128

실습사진넣기

워크노드에서 마운트 테스트

#에러 로그 미출력시 성공
sudo mount -t nfs 192.168.47.128:/nfs_share /mnt
#마운트 해제
sudo umount /mnt

실습사진넣기

PersistentVolume 설정

cd ~
sudo vi nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.47.128
    path: "/nfs_share"

적용

kubectl apply -f nfs-pv.yaml

PersistentVolumeClaim(PVC) 설정

sudo nano nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

적용

kubectl apply -f nfs-pvc.yaml

실습사진추가

PVC 마운트 pod 생성

vi nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
  - name: nfs-container
    image: nginx
    volumeMounts:
    - name: nfs-storage
      mountPath: "/usr/share/nginx/html"
  volumes:
  - name: nfs-storage
    persistentVolumeClaim:
      claimName: nfs-pvc
#파드생성
kubectl apply -f nfs-pod.yaml
#공유폴더에 파일 생성
echo hello nginx >> /nfs_share/index.html
#파드(컨테이너) 내부 접근
kubectl exec -it nfs-pod -- /bin/bash 
#root@nfs-pod:/ 컨테이너
cd /usr/share/nginx/html/
cat index.html

사진넣기



reference

교수님 강의 및 블로그, hull.kr