0517_Kubernetes_Objects, Pods, Label, Annotation

HYOJU DO·2022년 5월 17일
0

Kubernetes

목록 보기
4/13
post-thumbnail

쿠버네티스 오브젝트


오브젝트 를 어떻게 .yaml 형식으로 정의하여 리소스 로 만들 것인가

$ kubectl api-resources : 어떤 오브젝트의
$ kubectl api-versions : 어떤 버전을 사용할 것인가

🌟 Spec & State

  • spec (명세) : 오브젝트를 생성할 때 리소스에 원하는 특징(의도한 상태)에 대한 설명을 제공해서 설정
    사용자가 지정
  • status (상태) : 쿠버네티스 시스템과 컴포넌트에 의해 제공되고 업데이트된 오브젝트의 현재 상태
    k8s가 지정

오브젝트의 버전

🎈 쿠버네티스 API 그룹 : 쿠버네티스의 컴포넌트들은 api 서버와 항상 http 기반의 api로 통신

  • Core Group
    ➜ 그룹 지정 X
  • 보통은 API 그룹/버전 형태로 표시

🎈 APIVERSION

  • Stable
    - vX
    - v1, v2
  • Beta
    - v1betaX, v2betaX
    - 충분히 검증 ➜ 오류 x
    - 버전이 올라가게 되면 기능 변경이 있을 수 있음
    - downtime 발생할 수도 있음(특정 기능을 사용하기 위해서 컨테이너 재시작)
    - Mission Critical ➜ 24/7 시스템에서는 지양
  • Alpha
    - v1alphaX, v2alphaX
    - 기본적으로 비활성화
    - 개발중인 API ➜ 언제든지 기능 변경 가능, 오류 존재할 수 있음
    - k8s 자체 개발할 것 아니면 쓸 일 x

🎈 개발 순서
Alpha ➜ Beta ➜ Stable
v1alpha1 ➜ v1alpha2 ➜ v1alpha3 ➜ v1beta1 ➜ v2beta2 ➜ v1
(웬만해서 alpha는 없음)

현재 지원되는 api 버전

$ kubectl api-versions

패치 버전은 상관 없으나 마이너버전 업그레이드에 따라 지원하는 api 달라질 수 있음
ex. auto-scaling의 경우
v1, v2beta1, v2beta2 존재 (3가지 형태의 오브젝트)

  • 안정적 실행 ➜ v1
  • 더 많은 최신 기능 실행 -> v2beta2


오브젝트 정의

대부분 .yaml 파일로 kubectl에 제공
kubectl은 API 요청이 이루어질 때, JSON 형식으로 정보 변환

쿠버네티스의 모든 yaml 은 딕셔너리 로 시작
➜ 리스트가 아니기 때문에 순서는 상관 x
🌟 모든 리소스에 항상 선언하는 필드

  • apiVersion : 오브젝트에 따라 지원하는 api 버전 다름 (오브젝트 종류에 영향 받음)
  • kind : 오브젝트의 종류
  • metadata : 오브젝트의 메타데이터 지정
    ➕ 메타 데이터 : 데이터를 설명하기 위한 데이터
    일반적으로 리소스 이름, 네임스페이스, 레이블(label), 주석(annotation) 을 붙임
  • spec 🌟 : 오브젝트의 의도한 상태를 선언
    ➜ 기본적으로 kind에 따라 스펙의 내용이 달라짐
    ➜ 없는 경우도 드물지만 존재

🎈 $ kubectl api-resources

서버에서 지원되는 API 리소스 확인

NAME                            SHORTNAMES    APIVERSION            NAMESPACED        KIND
------------------------------------------------------------------------------------------------------
bindings                                         v1                    true         Binding
componentstatuses                 cs             v1                    false        ComponentStatus
configmaps                        cm             v1                    true         ConfigMap
...

NAME != KIND
(yaml 파일에서 대소문자 구별)

  • name ➜ 소문자로 시작 / 복수형
  • kind ➜ 대문자로 시작 / 단수형

yaml 파일 예시

apiVersion: apps/v1
kind: Deployment ✔️
metadata:
  name: nginx-deployment ✔️
spec:
...

오브젝트 정보 확인 : $ kubectl get

$ kubectl get [오브젝트 종류]

오브젝트 종류 : nodes, services, pods, ...
short name 으로도 지정 가능 (no, svc, po ..) ➜ yaml 파일에서는 불가


🌟 리소스 정의 출력 : $ kubectl explain

$ kubectl explain [리소스].[추가 검색 단어]. ...

계층적으로 내려가며 검색 가능

➕ 사용 예시

$ kubectl explain pods.metadata   # 리소스 별로 거의 동일
$ kubectl explain pods.spec       # 리소스마다 다름 -> 🌟 required 항목 확인!!
$ kubectl explain pods.spec.containers --recursive
$ kubectl explain pods.spec.containers.images

--recursive : 적용 가능한 것들에 대해 계층적 으로 이름만 보여 줌
ansible docs와 비슷한 기능
해당 리소스를 어떻게 정의하는지에 대해 출력
홈페이지에 올라와있지 않은 내용 (오로지 이 명령어에만 존재)

➕ FIELD : yaml 파일에서 지정해야하는 부분
➕ status : read-only
➜ 프로그램에서 가지고 오는 것 (우리가 정의 불가능


오브젝트 관리

  • 명령형 커맨드 : 모든 구성 요소를 kubectl 명령 으로만 처리
    - kubectl create
    - kubecrtl run
    - kubectl expose
  • 명령형 오브젝트 구성
    : 여러 개의 오브젝트 파일( yaml )을 순서대로 하나씩 실행
    - kubectl create -f a.yaml ➜ -f : 파일 지정
    - kubectl apply -f a.yaml
    - kubectl replace -f a.yaml
  • 선언형 오브젝트 구성
    : yaml 파일 모음을 한 번에 실행
    - kubectl create -f resources/ ➜ 디렉토리 지정 (파일 여러 개 지정)
    - kubectl replace -f resources/


Workload : Pods


pod == 컨테이너의 모음
하나의 파드에 컨테이너 하나 이상 포함 가능

쿠버네티스는 컨테이너 직접 컨트롤 x ➜ 최소 단위 : pod

  • 우리는 무조건 pod만 늘릴 수 있음
  • pod를 늘려서 컨테이너를 늘리는 것이지 컨테이너만 늘릴 수 x
  • 파드 단위로 각 호스트에 배치 (여러 개의 컨테이너를 하나의 호스트에 한 번에 배치 할 수 있음)

파드 생성 및 관리 : 명령형 커맨드

파드 생성 : $ kubectl run

$ kubectl run myweb --image httpd

--image : 도커 허브의 이미지 가져 옴

파드 목록 확인

$ kubectl get pods

특정 파드 확인

$ kubectl get pods [파드이름]

관련 정보 확인

파드 상세정보 확인

$ kubectl get pods -o

NAME : 파드 이름
READY : 준비 된 컨테이너의 갯수 / 총 컨테이너의 갯수 (1/1 : 컨테이너 하나 중 하나 준비)
STATUS : 실행 상태
RESTARTS : 재시작 횟수
AGE : 시작한 후 경과 된 시간

-o : docker inspect의 format 부분과 동일한 정보
-o wide : 상세한 정보 출력

  • IP : 해당되는 pod의 IP
  • NODE : pod가 어떤 노드에 연결되어있는가

-o yaml , -o json : raw 데이터 yaml, json 형태로 보여줌 (etcd에 저장되어있는 정보)

상세 정보 깔끔하게 보기 : $ kubectl describe

$ kubectl describe pods myweb

kubectl get pods -o wide 내용 가공해서 보여줌

🌟 Events 🌟

kubectl describe 에서만 확인 가능
➜ 🌟 이벤트 로그 : 쿠버네티스에서 이 리소스를 만들기 위한 오브젝트 자체의 로그 ( !=애플리케이션 로그 )
➜ myweb 이라는 pod의 life cycle 에 대한 정보
시간순 으로 기술 (가장 옛날 ➜ 최근) ✔️ 순서 중요
From 누구에 의해서 / Reason 어떤 이유로 발생했는가 / Message : 발생한 내용


Log 확인

🎈 Pod가 제대로 작동을 안할 때

  • 파드 가 작동 안 함 ➜ event log 확인
  • 컨테이너 내의 어플리케이션이 작동 안 함 ➜ 어플리케이션 로그 확인

어플리케이션 로그 확인

$ kubectl logs myweb

어플리케이션 로그를 볼 수 있는 것은 파드밖에 없기 때문에 서브커맨드로 따로 pods를 붙이지 않음


Pod 삭제

$ kubectl delete pods myweb

💡 pod는 종료되지 않는 app을 실행하는 것이 Default (따로 -d 옵션 붙일 필요 x)

➜ app이 종료 되면 로그 발생하고 app 다시 실행



파드 생성 및 관리 : YAML 파일로 파드 정의

yaml 파일 예시

apiVersion: v1
kind: Pod 
metadata:
  name: myweb
spec:
  containers:
    - name: myweb
      image: httpd
      ports:
        - containerPort: 80
          protocol: TCP

🌟 해당 yaml 파일에 정의한대로 pod 오브젝트 생성

$ kubectl create -f myweb.yaml

myweb.yaml

apiVersion: v1  
kind: Pod       # kubectl api-resources
metadata:
  name: myweb
spec:
  containers:    # 리스트 형태
  - name: myweb
    image: httpd

🎈 명령형

생성 된 pod 확인

$ kubectl get pods

yaml 형태로 pod 정보 확인

$ kubectl get pods -o yaml

특정 pod (my web) 정보 확인

$ kubectl describe pods myweb

myweb pod 로그 확인

$ kubectl logs myweb

🎈 선언형

해당 yaml 파일에 정의 된 오브젝트의 정보 확인

$ kubectl get -f myweb.yaml

해당 yaml 파일에 정의 된 오브젝트의 상세 정보 확인

$ kubectl describe -f myweb.yaml

해당 yaml 파일에 정의 된 오브젝트 삭제

$ kubectl delete -f myweb.yaml

💡 명령형과 선언형 섞어써도 상관 x



파드 디자인

  • 단일 컨테이너 실행 파드 : 일반적인 형태
  • 멀티 컨테이너 실행 파드 : 여러 개의 컨테이너를 실행하는 파드 (상대적으로 밀접한 관계)
    ➜ 메인 app 존재 + 메인 app 기능을 확장하기 위한 컨테이너(sidecar container) 배치
    ➜ 항상 main app과 함께 움직여야 의미를 가지는 app이 밀접한 관계에 있는 app

💡 Composite Container 패턴
composite container == multi container
옆에 붙어있으면 기본적으로 sidecar
기능적으로 3가지로 분류

  • sidecar : 단순 기능 분리 및 확장
  • ambassador : 일반적으로 proxy 형태
    ex. 웹 앱이 사용하는 DB가 여러 개 있는 데 이와 연결되기 위해 LB 역할의 proxy 배치
    ( 내부에서 외부로 가지고 들어오는 것 조정 )
  • adapter : log 등의 출력 표준화
    ( 외부에서 내부로 들어와서 가져가는 것 조정 )

🎈 Anti-Pattern Example

절대로 오른쪽 구조로 구성하면 안 됨

컨테이너 사용 이유 : 기능 분리
wp와 mysql은 밀접한 관계 X
➜ 별도의 파드로 떨어뜨려놔야 함

하나의 파드에는 반드시 하나의 main app 존재
컨테이너를 여러 개 배치하는 주된 용도는 main app를 도와줄 수 있는 app 만 배치
ex1. git이나 s3에서 web 컨텐츠를 가지고 와서 main web 어플(apache)에 제공하는 app (보조적인 기능만 수행)
ex2. web 서버의 log를 별도의 로그 서버로 전송하는 서버



Pod 특징


하나의 파드에 network / volume 부여 받음
🌟 pod 내에서는 모든 컨테이너가 같은 네트워크 공유
➜ 파드에는 하나의 ip 만 부여 됨


Pods의 네트워크 공유

실행되지 않는 web.yaml

apiVersion: v1  
kind: Pod       # kubectl api-resources
metadata:
  name: myweb
spec:
  containers:    # 리스트 형태
  - name: myweb1
    image: httpd
  - name: myweb2
    image: httpd

Pod 내에서는 네트워크를 공유
➜ 웹 서버 2개가 포트를 공유 하게 되면 하나의 웹 app 컨테이너는 running이 안 됨
리스트는 순서가 있으므로 먼저 생성 된 myweb1 컨테이너가 먼저 실행되고, 두 번째 실행되는 컨테이너는 오류 발생

특정 컨테이너 로그 확인

$ kubectl logs myweb -c myweb2

-c : 컨테이너 지정 옵션

포트 포워딩

$ kubectl explain pods.spec

쿠버네티스에서는 포트포워딩이 가능하지만
디버깅이나 테스트용으로 사용하는 것이지 외부로 노출하려고 쓰는 것 x
✔️ 서비스를 노출시키는 것이 유일하게 외부로 노출시키는 방법

$ kubectl port-forward pods/myweb 8080:80

포트 포워딩을 하면 포그라운드 상태로 동작

다른 터미널

웹 서버 생성 확인

$ curl 192.168.100.110:80 📌 정확하게 확인하기

web.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb
spec:
  containers:
    - name: myweb
      image: httpd
      ports:        # 단순 정보
	    - containerPort: 80
	      protocol: "TCP"

오브젝트 이름 & UID

이름 : NS 안에서만 유일
➜ 네임스페이스가 다르면 같은 이름 존재 가능
UID : cluster 전체에서 유일


kubectl 명령의 서브 커맨드

  • create
  • get
  • describe
  • logs
  • delete
  • replace
  • patch
  • apply
  • diff



Namespace(NS)


🎈 핵심 기능 : 리소스 분리

분리 기준

  • 서비스 별
  • 사용자 별
  • 환경 별 (개발, 스테이징, 프로덕션)

보통 서비스 분리에 가장 많이 사용

  • 서비스 : DNS 이름이 분리 되는 용도
  • RBAC(역할 기반 엑세스 제어) : 권한을 NS에 설정 가능
    ex. 어떤 NS는 읽기만, 어떤 NS는 읽고 쓰기 등

종류

  • kube-sysetm : 쿠버네티스의 핵심 컴포넌트 존재
  • kube-public : 모든 사용자가 읽기 권한
  • kube-node-lease : 노드의 HeartBeat 체크를 위한 lease 리소스 존재
  • default : 기본 작업 공간

우리는 super user ➜ 어느 파일이든 읽고 쓰기 가능 ( config 파일로 인증을 받았기 때문)

🎈 NameSpace 확인

NS 확인

$ kubectl get namespaces (ns)

파드들의 NS 확인

$ kubectl get pods --all-namespaces

🎈 오브젝트의 NameSpace 확인

default NS에 있는 파드 확인
➜ 아무 것도 지정하지 않고 pod 생성 시 default NS 에 포함

$ kubectl get pods -n default

kube-system NS에 있는 파드 확인

$ kubectl get pods -n kube-system

kube-node-leases NS에 있는 lease 확인

$ kube get leases -n kube-node-leases

leases : 노드의 목록과 동일 (kubectl get nodes 실행 시 출력되는 목록)
➜ HB (HeartBeat : 핫빗) 역할 : 노드가 살아있는지 죽어있는지 체크

🎈 NameSpace 생성 및 삭제

developments NS 생성

$ kubectl create namespace developments

NS 확인

$ kubectl get ns

developments NS 삭제
✔️ NS 안에 리소스가 없어야함

$ kubectl delete ns developments

🎈 NameSpace 지정하여 파드 생성 & 삭제

NS 리소스의 상세 정보 출력

$ kubectl explain namespace

➕ FIELDS : Finalizers ➜ 해당 리소스를 삭제할 때 어떻게 할 것인가

ns-dev.yaml
아주 드물게 spec이 없는 경우

apiVersion: v1
kind: Namespace
metadata:
  name: dev

해당 yaml 파일로 NS 생성 & 생성 확인

$ kubectl create -f ns-dev.yaml
$ kubectl get ns

♢ 명령형

dev NS에 웹 파드 생성

$ kubectl run myweb --image httpd -n dev

-n : 옵션 붙여서 NS 지정 가능 (안하면 default에 배치)

kubectl run myweb --image httpd 로 생성된 파드와 위의 파드는 다른 존재
(다른 NS에 존재하는 이름만 같은 파드)

dev NS에 있는 myweb 파드 삭제

$ kubectl delete pods myweb -n dev

NS 설정하여 파드 정확히 지정한 후 삭제


♢ 선언형

myweb-dev.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb
  namespace: dev
spec:
  containers:
    - name: myweb
      image: httpd
      ports:
        - containerPort: 80
          protocol: TCP

해당 yaml 파일로 파드 생성

$ kubectl create -f myweb-dev.yaml

해당 yaml 파일이 선언한 파드 삭제

$ kubectl delete -f myweb-dev.yaml

💡 NS가 달라도 Pod끼리 통신 가능 ➜ 우리가 확인할 때 나눠지는 것 뿐

💡 NAMESPACED of $ kubectl api-resources

  • NS 사용 : true
  • NS 사용 x : false

➕ NS 활용 구조

  • 일반적 : 클러스터 1 - NS 多
  • 완전 분리 : 클러스터 多 - NS x



Label & Label Selector


Label

권장 레이블

🎈 특성

  • key-value 형태
  • 태그와 비슷한 기능
  • 리소스에 중복 설정 가능
  • 오브젝트 특성 구분 시 사용
  • json, yaml 등으로 표현 가능
  • metadata에 labels라는 키를 사용
    ➜ 똑같은 키-벨류를 가지는 label 여러 오브젝트에 부여 가능

🎈 레이블 기능

  • 🌟 검색
  • 리소스 간의 연결 (Controller와 연관)

🎈 레이블 확인

파드에 붙어있는 label 간단히 확인

$ kubectl get pods --show-labels

yaml 형식으로 label 확인

$ kubectl get pods X -o yaml

label 상세 정보 확인

$ kubectl describe pods X

🎈 레이블 관리

기존 리소스에 레이블 부여

kubectl label pods myweb APP=apache
kubectl label pods myweb ENV=developments

확인

kubectl get pods --show-labels

기존 레이블 덮어쓰기 (✔️ --overwrite 옵션 필수)

kubectl label pods myweb ENV=staging --overwrite

레이블 삭제 (label 키 값 -)

kubectl label pods myweb ENV-

🎈 yaml 파일에 label 정의

myweb.yaml

apiVersion: v1  
kind: Pod       # kubectl api-resources
metadata:
  name: myweb-label
  labels:
    APP: apache
    ENV: development
spec:
  containers:    # 리스트 형태
  - name: myweb1
    image: httpd
    ports:
      - containerPorts: 80
        protocol: TCP

파드 생성

$ kubectl create -f myweb.yaml

파드의 label 확인

$ kubectl get pods --show-labels

Label의 구문과 캐릭터 셋

$ kubectl get nodes --show-labels

kubernetes.io/ 와 k8s.io/ 접두사 : 쿠버네티스의 핵심 컴포넌트로 예약 되어있음
➜ AWS, GCP, Azure 사용 시 필요한 레이블


LabelSelector

🎈 기능

  • 검색 : 여러 개의 pods를 구분
  • 리소스 간 연결 : 여러 타입의 오브젝트 간 관계 설정

Label 검색

-l 옵션

$ kubectl get pods -l APP=apache
$ kubectl get pods -l ENV=staging

일치성 (equality base)

  • = == == : label이 일치하는
  • != : label이 일치하지 않는
$ kubectl get pods -l APP=apache
==
$ kubectl get pods -l APP==apache

ENV가 staging이 아닌 pod 정보 확인

kubectl get pods -l 'ENV!=staging'

집합성 (set base)

➜ 검색에 많이 사용하지는 x

  • in
  • notin
  • exists : 키만 매칭
    kubectl get pods -l 'ENV'
  • doesnotexists : 키 제외 매칭
    kubectl get pods -l '!ENV'

ENV에 staging 이라는 것이 있으면

$ kubectl get pods -l 'ENV in (staging)'
$ kubectl get pods -l 'ENV in (staging)' # value 2개 가능
$ kubectl get pods -l 'APP notin (apache)'

키만 매칭 (exists)

$ kubectl get pods -l 'ENV'

키 제외 매칭 (doesnotexists)

$ kubectl get pods -l '!ENV'

! 는 이스케이프 문자이므로 반드시 ' ' 와 함께 사용


Annotations


💡 어노테이션에 기록할 수 있는 정보 예제 ( 정리 필요 :) )

주석의 의미와는 약간 다름
레이블과 비슷하지만 비-식별 메타데이터
➜ Selector X
단순히 정보만 저장 (꼭 필요하진 x)

클라이언트는 이 메타데이터 검색 가능
✔️ 클라이언트란? == 다른 어플리케이션
클라이언트는 어노테이션 메타 데이터를 가지고 갈 수 있음
ex. 개발자가 어떠한 작업을 하기 위해
어노케이션을 부여하면 어플리케이션이 다르게 동작하는 것 볼 수 있음

🎈 anonotation 확인

$ kubectl get pods myweb -o yaml | more

annotation을 부여하지 않았는데 생성되어있음
➜ calico 어플리케이션이 네트워크를 관리하기 위한 용도로 붙여놓은 것

🎈 annotation 설정

♢ 명령형 커맨드
pod에 annotation 생성

$ kubectl annotate pods myweb created-by=Do

확인

$ kubectl get pods myweb -o yaml | head

변경 ( --overwrite 옵션 필요)

$ kubectl annotate pods myweb created-by=Kim --overwrite

삭제

$ kubectl annotate pods myweb created-by-

♢ 선언형 YAML

myweb.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myweb-label-anno
  labels:
    APP: apache
    ENV: staging
  annotations:
    Created-by: Ken
spec:
  containers:
    - name: myweb
      image: httpd
      ports:
        - containerPort: 80
          protocol: TCP

➕ pods 말고 다른 리소스들에도 적용 가능




알면 좋을 추가사항

💡 ohmyzshell plugins에 kubectl 추가해서 사용

💡리소스 만들고 항상 지우기 ➜ 이름이나 네트워크 충돌할 가능성 존재
어짜피 yaml 파일에서 다시 create 하면 됨

➕ 쿠버네티스가 익숙해진 후 읽으면 좋은 도서
쿠버네티스 패턴
쿠버네티스 모범 사례



profile
Be on CLOUD nine! ☁️ ( 수정 예정 == 📌)

0개의 댓글