오브젝트
를 어떻게.yaml
형식으로 정의하여리소스
로 만들 것인가
$ kubectl api-resources
: 어떤 오브젝트의
$ kubectl api-versions
: 어떤 버전을 사용할 것인가
🌟 Spec & State
spec
(명세) : 오브젝트를 생성할 때 리소스에 원하는 특징(의도한 상태)에 대한 설명을 제공해서 설정status
(상태) : 쿠버네티스 시스템과 컴포넌트에 의해 제공되고 업데이트된 오브젝트의 현재 상태🎈 쿠버네티스 API 그룹 : 쿠버네티스의 컴포넌트들은 api 서버와 항상 http 기반의 api로 통신
기능 변경
이 있을 수 있음downtime
발생할 수도 있음(특정 기능을 사용하기 위해서 컨테이너 재시작)🎈 개발 순서
Alpha ➜ Beta ➜ Stable
v1alpha1 ➜ v1alpha2 ➜ v1alpha3 ➜ v1beta1 ➜ v2beta2 ➜ v1
(웬만해서 alpha는 없음)
현재 지원되는 api 버전
$ kubectl api-versions
패치 버전은 상관 없으나 마이너버전 업그레이드에 따라 지원하는 api 달라질 수 있음
ex. auto-scaling의 경우
v1, v2beta1, v2beta2 존재 (3가지 형태의 오브젝트)
대부분 .yaml
파일로 kubectl에 제공
kubectl은 API 요청이 이루어질 때, JSON 형식으로 정보 변환
쿠버네티스의 모든 yaml 은 딕셔너리
로 시작
➜ 리스트가 아니기 때문에 순서는 상관 x
🌟 모든 리소스에 항상 선언하는 필드
apiVersion
: 오브젝트에 따라 지원하는 api 버전 다름 (오브젝트 종류에 영향 받음)kind
: 오브젝트의 종류metadata
: 오브젝트의 메타데이터 지정spec
🌟 : 오브젝트의 의도한 상태를 선언🎈 $ 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 파일에서 대소문자 구별)
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 명령
으로만 처리명령형 오브젝트
구성yaml
)을 순서대로 하나씩 실행선언형 오브젝트
구성pod == 컨테이너의 모음
하나의 파드에 컨테이너 하나 이상 포함 가능
쿠버네티스는 컨테이너 직접 컨트롤 x ➜ 최소 단위 : pod
파드 생성 : $ 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
: 상세한 정보 출력
-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 : 발생한 내용
🎈 Pod가 제대로 작동을 안할 때
파드
가 작동 안 함 ➜ event log
확인어플리케이션
이 작동 안 함 ➜ 어플리케이션 로그
확인어플리케이션 로그 확인
$ kubectl logs myweb
어플리케이션 로그를 볼 수 있는 것은 파드밖에 없기 때문에 서브커맨드로 따로 pods를 붙이지 않음
$ kubectl delete pods myweb
💡 pod는 종료되지 않는 app을 실행하는 것이 Default (따로 -d 옵션 붙일 필요 x)
➜ app이 종료 되면 로그 발생하고 app 다시 실행
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
밀접한 관계
)💡 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를 별도의 로그 서버로 전송하는 서버
하나의 파드에 network / volume 부여 받음
🌟 pod 내에서는 모든 컨테이너가 같은 네트워크
공유
➜ 파드에는 하나의 ip
만 부여 됨
실행되지 않는 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"
이름
: NS 안
에서만 유일
➜ 네임스페이스가 다르면 같은 이름 존재 가능
UID
: cluster 전체
에서 유일
kubectl 명령의 서브 커맨드
- create
- get
- describe
- logs
- delete
- replace
- patch
- apply
- diff
🎈 핵심 기능 : 리소스 분리
분리 기준
보통 서비스 분리에 가장 많이 사용
DNS 이름이 분리
되는 용도권한
을 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
🎈 특성
key-value
형태중복
설정 가능특성 구분
시 사용🎈 레이블 기능
🎈 레이블 확인
파드에 붙어있는 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
$ kubectl get nodes --show-labels
kubernetes.io/
와k8s.io/
접두사 : 쿠버네티스의 핵심 컴포넌트로 예약 되어있음
➜ AWS, GCP, Azure 사용 시 필요한 레이블
🎈 기능
검색
: 여러 개의 pods를 구분 리소스 간 연결
: 여러 타입의 오브젝트 간 관계 설정-l
옵션
$ kubectl get pods -l APP=apache
$ kubectl get pods -l ENV=staging
=
== ==
: label이 일치하는!=
: label이 일치하지 않는$ kubectl get pods -l APP=apache
==
$ kubectl get pods -l APP==apache
ENV가 staging이 아닌 pod 정보 확인
kubectl get pods -l 'ENV!=staging'
➜ 검색에 많이 사용하지는 x
in
notin
exists
: 키만 매칭doesnotexists
: 키 제외 매칭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'
! 는 이스케이프 문자이므로 반드시 ' ' 와 함께 사용
💡 어노테이션에 기록할 수 있는 정보 예제 ( 정리 필요 :) )
주석의 의미와는 약간 다름
레이블과 비슷하지만 비-식별 메타데이터
➜ 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 하면 됨
➕ 쿠버네티스가 익숙해진 후 읽으면 좋은 도서
쿠버네티스 패턴
쿠버네티스 모범 사례