쿠버네티스 전문가 양성과정 9주차 3일(2/15)

최수환·2023년 2월 15일
0

Kubernetes

목록 보기
39/75
post-thumbnail

Kubernetes

쿠버네티스 기본 명령어

1 . apply

git clone https://github.com/c1t1d0s7/goorm-8th-k8s
# 해당 사이트에서 실습자료 파일 다운로드 

/home/vagrant/goorm-8th-k8s/manifests/03_workload_pod/01_pod
# 해당 디렉터리로 가면 myapp-pod.yaml파일이 존재 

kubectl apply -f myapp-pod.yaml
# apply로 yaml파일 실행 

-> create와 apply가 같다고 생각하면 된다

2 . 정보 확인

kubectl get pods -o wide
# ip와 어떤 node에 배치됬는지를 확인할 수 있다.

kubectl get pod pod이름 -w 
# 해당 pod의 실시간 상태확인을 할 수 있다.	

kubectl get pods -o yaml
# 오브젝트의 정보/상태 yaml형식으로 상세 보기 

kubectl get pods -o json
# 오브젝트의 정보/상태 json형식으로 상세 보기 

kubectl describe pod myapp-pod or kubectl describe -f myapp-pod.yaml
# 해당 파드의 자세한 정보와 추가로 Events정보를 확인할 수 있다

📒 decribe 명령어의 events항목을 확인하게 되면 control-plane의 스케줄러에 의해 파드가 어떤 노드에 배치되었는지를 알 수 있다.

kubectl logs myapp-pod
# 해당 파드의 로그 확인 

3 . 포트 포워딩

kubectl port-forward myapp-pod 8080:8080
# 호스트 포트:컨테이너 포트

새 터미널 열고 curl localhost:8080
# 새 터미널에서 text 확인  

-> docker에서는 -p옵션으로 사용했다면 쿠버네티스에서는 port-forward로 따로 지정할 수 있다.

📗 쿠버네티스를 종료할때 VM을 일일이 종료시키는 것이 아니라 vagrant halt로 종료한다

📗 클러스터링된 시스템은 여러 시스템이 유기적으로 연결되어 있기때문에 스냅샷을 찍으면 시스템이 일관적으로 같은 시간대에 찍히는 것이 아니기 때문에 시스템간 차이가 발생한다. 따라서 스냅샷을 사용하면 에러가 발생하기때문에 사용하면 안된다.

📗 --help 적극 사용

label

레이블은 파드와 같은 오브젝트에 첨부된 키와 값의 쌍이다. 레이블은 오브젝트의 특성을 식별하는 데 사용 되어 사용자에게 중요하지만, 코어 시스템에 직접적인 의미는 없다. 레이블로 오브젝트의 하위 집합을 선택하고, 구성하는데 사용할 수 있다. 레이블은 오브젝트를 생성할 때에 붙이거나 생성 이후에 붙이거나 언제든지 수정이 가능하다. 오브젝트마다 키와 값으로 레이블을 정의할 수 있다. 오브젝트의 키는 고유한 값이어야 한다.

  • 오브젝트의 식별 정보를 저장한다

  • AWS의 tag와 같다고 생각하면 된다

  • 예를 들어 pod가 수만개가 된다면 이것을 이름만 가지고 이것의 특성이나, 기능을 일일이 기억할 수 없다.
    -> label을 사용하여 문서화 작업을 할 수 있다.
    = 검색하기 위한 식별 데이터 (목적 1)

  • 레이블을 이용하면 사용자가 느슨하게 결합한 방식으로 조직 구조와 시스템 오브젝트를 매핑할 수 있으며, 클라이언트에 매핑 정보를 저장할 필요가 없다.
    = 리소스간 연결하기 위해 사용 (목적 2)

  • 레이블 작성 예시

📗 레이블 참조

검색하기 위한 목적으로 label사용

git clone https://github.com/c1t1d0s7/goorm-8th-k8s
# 실습자료 파일 다운로드 

/home/vagrant/goorm-8th-k8s/manifests/03_workload_pod/02_label
# 해당 디렉터리에 접속 

kubectl create -f myapp-pod-label.yaml
# yaml파일 실행

kubectl get pods --show-labels
# 파드들의 레이블 보기 


-> label이 키=벨류 쌍으로 존재하는 것을 확인

kubectl get pods -l env=dev
# env키값이 dev라는 벨류값을 가진 pod만 검색

kubectl get pods -l env=dev,tier=frontend
# env가 dev를, tier가 frontend라는 벨류값을 가진 pod만 검색

kubectl get pods -l env=dev,tier!=backend
# env가 dev를, tier가 backend가 아닌 벨류값을 가진 pod만 검색

kubectl get pods -l env 
# env라는 키값을 가진 pod만 검색

kubectl get pods -l '!env'
# env라는 키값을 가지고 있지 않는 pod만 검색
# 반드시 탈출문자를 사용 

kubectl get pods -A --show-labels
# 쿠버네티스의 모든 컨테이너의 레이블보기 

kubectl get pods -A --show-labels -l tier=control-plane
# 쿠버네티스의 모든 컨테이너의 레이블중 tier가 control-plane 벨류값을 가진 pod만 검색

📗 연산자 또는 IN, NOT IN , EXISTS를 이용해 label을 검색해서 원하는 리소스를 찾을수 있다.

Annotation

쿠버네티스 어노테이션을 사용하여 임의의 비-식별 메타데이터를 오브젝트에 첨부할 수 있다. 도구 및 라이브러리와 같은 클라이언트는 이 메타데이터를 검색할 수 있다

-> 레이블과 마찬가지로 키-벨류 쌍으로 이루어짐

  • 어노테이션은 레이블과 다르게 식별하기 위한 정보가 아닌 해당 리소스의 정보를 저장하기 위해 사용하는 것이다. 주석과 비슷하다고 생각하면 된다.

📗 어노테이션 참조

어노테이션 사용

/home/vagrant/goorm-8th-k8s/manifests/03_workload_pod/03_annotation
# 위의 실습과 마찬가지로 실습자료 파일 다운로드후 해당 디렉터리 이동

kubectl create -f myapp-pod-annotation.yaml
# yaml파일 실행

kubectl get pod myapp-pod-annotation -o yaml
# 해당 리소스의 어노테이션 정보 보기 

kubectl describe pod myapp-pod-annotation
# 해당 리소스의 어노테이션 정보 보기 

-> 레이블처럼 kubectl get pods --show-annotations로 검색하지 못한다
= 식별하기 위한 정보가 아니기때문이다

kubectl annotate pod myapp-pod-annotation message=hello
# 어노테이션 추가
# 만일 추가하고자 하는 정보가 이미 있어서 추가가 안된다면 overwrite옵션을 사용 

네임스페이스

  • 쿠버네티스에서, 네임스페이스는 단일 클러스터 내에서의 리소스 그룹 격리 메커니즘을 제공한다. 즉, 분리하기 위함이다.
  • 쉽게말해 기능에 따라 그룹으로 묶어서 분리시킨 느낌이다
  • 네임스페이스 내에서 리소스의 이름은 유일해야한다. 네임스페이스간 이름은 유일할 필요없다.

📗 네임스페이스 참조

네임스페이스 사용

kubectl get namespaces


-> 기본적으로 여러 네임스페이스중 우리가 찾는 pod는 default에서 찾게 된다

kubectl get pods

-> 따라서 이 명령으로 입력하면 기본적으로 default네임스페이스에서 찾는다. default네임스페이스에 포함된 파드가 출력된다.

kubectl get pods -n kube-system

-> 만약 default네임스페이스가 아닌 kube-system이라는 네임스페이스에서 파드를 찾고싶다면 -n옵션을 이용해 네임스페이스를 지정한 후 파드를 찾으면 된다.

kubectl get pods -A


-> 어떤 파드가 어떤 네임스페이스를 사용하는지 알 수 있다.
-> 따라서 자동완성 기능도 default 네임스페이스에서 찾아서 완성시키기 때문에, 만약 찾고자 하는 파드가 다른 네임스페이스에 포함된다면, -n으로 해당 네임스페이스를 먼저 지정한 후 tab을 누르면 원하는 검색을 자동완성 할 수 있다.

kubectl create -f myapp-pod.yaml -n kube-public
# 파드를 생성할 때 네임스페이스를 지정해서 생성

kubectl -n kube-public get pods
# default에 생성되지 않고 지정한 네임스페이스에 파드 생성되는 것을 확인

kubectl -n kube-public get pod myapp-pod -o yaml
# 정보를 확인해보면 namespace가 지정되어있는것을 확인

kubectl delete -f myapp-pod.yaml -n kube-public
# 삭제할때도 네임스페이스를 지정하고 삭제해야한다

-> 네임스페이스 지정을 안하면 default에서 찾아서 삭제하는데 default에는 존재하지않아 삭제되지 않는다
-> 일반적으로 네임스페이스는 yaml파일에 지정해서 사용하지 않고 -n옵션을 사용해서 유동적으로 바꿔가며 지정한다

kubectl config set-context --current --namespace=변경 네임스페이스
# default네임스페이스 변경
kubectl config view --minify | grep namespace
# 변경된 네임스페이스 확인 

ex . 네임스페이스 생성 및 생성한 네임스페이스에 파드 생성

apiVersion: v1
kind: Namespace
metadata:
  name: development
 	
---
# 네임스페이스 생성

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: development
spec:
  containers:
  - name: myapp
    image: nginx 
    ports:
    - containerPort: 80     

-> 처음부터 존재하는 네임스페이스가 아닌 새로운 네임스페이스에 파드를 생성하려면 네임스페이스가 존재하지 해야 한다.
-> 따라서 yaml파일에 두가지 리소스를 작성해 하나는 네임스페이스 생성 , 하나는 생성된 네임스페이스에 파드를 생성한다

📌 정리하자면 기존의 존재하는 네임스페이스를 이용하여 -n으로 해당 네임스페이스 넣거나 yaml파일에 해당 네임스페이스를 작성해서 파드를 생성하면 그 네임스페이스에 파드가 생성된다.
그러나 기존의 네임스페이스가 아닌 사용자가 정의한 네임스페이스는 미리 만들어놓지 않고 yaml파일에 정의한 네임스페이스를 작성하거나
-n으로 해당 네임스페이스를 사용하면 오류가 발생한다. 따라서 사용자가 정의한 네임스페이스를 사용하고 싶다면 yaml파일 등으로 미리 만들어놓고 사용한다

파드 생명 주기

  • 파드는 파드의 수명 중 한 번만 스케줄된다. 파드가 노드에 스케줄(할당)되면, 파드는 중지되거나 종료될 때까지 해당 노드에서 실행된다
  • 파드가 생성되고, 고유 ID(UID)가 할당되고, 종료(재시작 정책에 따라) 또는 삭제될 때까지 남아있는 노드에 스케줄된다
  • 만약 노드가 종료되면, 해당 노드에 스케줄된 파드는 타임아웃 기간 후에 삭제되도록 스케줄된다.
  • UID로 정의된 특정 파드는 다른 노드로 절대 "다시 스케줄"되지 않는다
  • 쉽게말해, 어떤 파드가 스케줄러에 의해 node2에 배치되면 생을 마감할때까지 무조건 node2에서만 존재한다는 것이다.

파드의 단계

파드의 phase는 파드가 라이프사이클 중 어느 단계에 해당하는지 표현하는 간단한 고수준의 요약이다

컨테이너의 상태

파드가 가지고 있는 하나 이상의 컨테이너는 각각의 상태가 있다.

📗 생명 주기 참조

컨테이너 재시작 정책

  • 파드의 spec 에는 restartPolicy 필드가 있다. 사용 가능한 값은 Always, OnFailure 그리고 Never이다. 기본값은 Always이다.

  • restartPolicy 는 파드의 모든 컨테이너에 적용된다. restartPolicy 는 동일한 노드에서 kubelet에 의한 컨테이너 재시작만을 의미한다. 파드의 컨테이너가 종료된 후, kubelet은 5분으로 제한되는 지수 백오프 지연(10초, 20초, 40초, …)으로 컨테이너를 재시작한다. 컨테이너가 10분 동안 아무런 문제없이 실행되면, kubelet은 해당 컨테이너의 재시작 백오프 타이머를 재설정한다

컨테이너 프로브(Probe)

프로브는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)이다. 진단을 수행하기 위해서, kubelet은 컨테이너 안에서 코드를 실행하거나, 또는 네트워크 요청을 전송한다

프로브 종류

컨테이너에 대해 어떤 상태를 확인할 것인지 정한다


-> 특별한 사유가 없다면 liveness,readness,startup은 항상 설정해야한다. 그래야 컨테이너에 올라온 어플리케이션이 실제로 돌아가는지 알 수 있다.
-> 쿠버네티스에서는 probe를 사용하지 않으면 어플리케이션이 실제로 돌아가는지 안돌아가지는 알 수 없기때문이다.

체크 매커니즘

정한 상태를 확인할 방법을 선택한다.

프로브 결과

프로브 사용 예시

1 . livenessProbe 예시

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod-liveness
spec:
  containers:
  - name: myapp
    image: ghcr.io/c1t1d0s7/go-myweb:alpine
    ports:
    - containerPort: 8080
      protocol: TCP
    livenessProbe: # 프로브 종류
      httpGet: # 체크 매커니즘
        path: /health
        port: 8080

-> 해당 yaml파일을 실행하고 아래의 코드를 실행한다

kubectl describe pod myapp-pod-liveness


-> 위 사진처럼 해당 정보를 볼 수 있는데

period : 확인할 주기
timeout : 확인하고 응답이 오는 시간
failure : 연속으로 실채한 횟수
-> 즉, 3*(10+1)초 후에는 failure이기 때문에 재시작을 한다.

2 . startupProbe 예시

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod-startup
spec:
  containers:
  - name: myapp
    image: ghcr.io/c1t1d0s7/go-myweb:alpine
    ports:
    - containerPort: 8080
      protocol: TCP
    startupProbe:
      httpGet:
        path: /health
        port: 8080
    livenessProbe:
      httpGet:
        path: /health
        port: 8080


-> livenessProbe와 마찬가지로 연속 3번실패한다면 재시작 정책으로 restart한다
-> 만일 livenessProbe만 있는 상태에서 단순히 어플리케이션이 늦게 시작되는 것이지 장애가 있는 것이 아닌데도 livenessProbe가 실패3번이 되어 재시작을 해버린다. 그렇게 해당 어플리케이션은 무한히 재시작될것이다. 이것을 방지하기 위해 startupProbe을 이용해 어플리케이션이 실행될때까지 다른 probe는 비활성화 한다.

최종 실습

apiVersion: v1
kind: Namespace
metadata: 
  name: develop

--- # develop 네임스페이스 생성

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: develop # 이전에 생성한 네임스페이스 지정 
  labels: # 키:벨류 레이블 추가 
    app.kubernetes.io/name: mysql
    app.kubernetes.io/version: "5.7" # 문자열 주의
    app.kubernetes.io/component: database
  annotations: # 어노테이션 추가
    make: choisuhwan
spec: 
  containers:
  - name: mysdb
    image: mysql:5.7
    ports:
    - containerPort: 3306 # mysql기본 port
      protocol: TCP 
    env: # mysql의 환경변수 작성
    - name: MYSQL_ROOT_PASSWORD 
      value: password
    startupProbe: # startupprobe작성
      exec: # exec방식
        command: # shell 형태로 명령어 작성
        - mysqladmin 
        - ping 
      periodSeconds: 30 
      failureThreshold: 5
      # 주기와 연속실패횟수 설정
    livenessProbe: 
      exec: 
        command: ['mysqladmin','ping'] # exec형태로 명령어 작성 
      periodSeconds: 10
      failureThreshold: 3

-> 처음에 환경변수를 작성안하고 파드를 만들었더니 에러가 발생했다. 이때 kubectl logs myapp으로 log를 확인해보니 환경변수를 추가하라는 문구가 나타났다.
-> 환경변수와 probe작성 시 아래에 어떤 항목이 들어가고 어떤 자료형이 들어가는지 헷갈렸지만 explain을 참조하니 해결되었다.

kubectl port-forward myapp 3306:3306
# 3306으로 포트포워딩

새로운 창열고 sudo apt install mysql-client
# mysql 클라이언트 패키지 설치

mysql -h 127.0.0.1 -u root -p 로 접속 
# 새로운창에서 mysql접속 
profile
성실하게 열심히!

0개의 댓글