이제 직접 쿠버네티스 API를 통해 컨테이너를 생성 및 관리 해보자
쿠버네티스는 object를 통해 클러스터를 구성 및 관리한다.
kubectl은 쿠버네티스의 CLI(커맨드라인 인터페이스)이다.
쿠버네티스 시스템에서 kubectl 명령을 입력하는 것을 통해 오브젝트와 컨트롤러의 생성 및 변경을 요청할 수 있다.
쿠버네티스의 오브젝트는 쿠버네티스 시스템의 가장 기본적인 구성단위이다.
오브젝트를 생성하면 쿠버네티스 시스템은 오브젝트의 동작을 보장하기 위해 작동한다. 최종적으로 오브젝트가 클러스터의 상태를 관리하는 역할을 한다.
거의 모든 쿠버네티스 오브젝트는 2가지의 공통된 상태를 갖는다.
만약 모종의 이유로 Status가 Spec과 달라진다면 Master Node가 Status를 Spec과 일치시키기 위한 작동을 한다.
kubectl api-resources
쿠버네티스 시스템이 사용하는 모든 object의 정보를 출력하는 명령어이다.
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Job
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
leases coordination.k8s.io/v1 true Lease
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1beta1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment
NAME
: object의 이름을 뜻한다. kubectl 명령어를 통해 특정 object를 명시할 때 NAME
의 이름을 지정하면 된다. SHORTNAMES
가 있는 경우 약어로도 지정이 가능하다.APIVERSION
: 말그대로 API 버전을 나타낸다. 오브젝트를 쉽게 생성하기 위해 yaml 파일에 오브젝트 명세를 기술하는 방식을 이용하는데, 이 때 올바른 API 버전을 입력해야 시스템이 명세를 이해하고 오브젝트를 생성할 수 있다.NAMEDSPACE
: 네임스페이스 안에 집어넣을 수 있는지 여부이다. 네임스페이스는 하나의 클러스터를 다수의 팀, 사용자가 사용할 때 서로의 리소스를 격리하는 역할을 한다.KIND
: yaml 파일에 오브젝트 명세를 기술할 때 이것이 어떤 object인지 알려주기 위해 KIND
값을 지정해야한다.kubectl create -f awesome_filename.yaml
쿠버네티스 오브젝트를 쉽게 관리하기 위해 yaml 파일을 이용한다.
복잡한 명령어를 입력할 필요 없이 yaml 파일에 오브젝트의 정보를 명세하는 것을 통해 오브젝트를 생성할 수 있다.
오브젝트 종류에 따라 yaml 파일에 필요한 정보, 작성하는 방법이 조금씩 다르지만, 우선 기본적인 구조는 아래와 같다.
apiVersion: <연결할 API의 버전>
kind: <리소스의 유형(Pod, Namespace)>
metadata: <리소스의 기본 정보 필드(name, label, namespace)
- name: <object의 이름>
namespace: <(옵션)네임스페이스 이름>
spec: <배포되는 리소스의 원하는 상태 정의 (아래는 Pod 예시)>
- containers:
- name: nginx
image: nginx:1.15.11
ports:
- containerPort: 80
쿠버네티스 컨트롤러는 클러스터의 상태를 모니터링하여, 필요한 경우(spec과 status가 다른 경우) 오브젝트 및 다른 컨트롤러의 생성 및 변경을 요청한다.
컨트롤러 역시 오브젝트의 한 종류이다.
앞서 설명했듯이 컨트롤러는 object의 status를 모니터링하고 있다가, 상태가 변동되어 spec과 달라질 경우, 다시 같아지는 방향으로 동작한다.
컨트롤러는 어떤 object 또는 controller를 관리하는 지에 따라 다양한 종류가 있다.
컨트롤러에 정의된 pod 수에 따라, 만약 가용 가능한 pod가 정의된 수보다 적다면 이를 자동으로 생성하는 역할을 한다.
컨트롤러가 배포한 pod가 있는 node와의 통신이 끊겼을 때, 동일한 pod를 다른 node의 생성할 수도 있다.
리소스 부하를 모니터링하여, 만약 pod에 걸리는 부하가 늘어날 경우 pod를 자동으로 생성한다.
반대로 부하가 줄어들 경우 생성한 pod를 다시 줄이는 역할도 할 수 있다.
부하가 어느 정도일 때 pod를 생성할지, 최소/최대 몇 개의 pod를 운용할 지는 사용자가 정의한 값에 따른다.
pod 내부 컨테이너에 설치된 어플리케이션을 업데이트 및 롤백하는 기능흘 제공한다.
Job이란 한 번만 실행되고 종료되는(삭제되는) 일회성 어플리케이션을 말한다.
사용빈도가 낮아 그때그때 생성하여 쓰는 것이 효율적인 어플리케이션에 주로 사용한다.
컨트롤러를 통해 일회성 pod를 생성하여 작업하고, 작업 완료 후 컨테이너는 삭제한다.
생성된 pod는 그대로 남아있기 때문에 작업 결과 로그 등을 확인 가능하다.
k8s을 통해 배포할 수 있는 가장 작은 컴퓨팅 단위이다.
pod는 하나 이상의 컨테이너 그룹으로 구성되며, 하나의 컨테이너 그룹은 하나 이상의 컨테이너와 각 컨테이너가 공유하는 네트워크, Namespace, Volume 등으로 구성된다.
하나의 클러스터에서 리소스를 그룹화하여 서로 격리하기 위한 오브젝트이다.
클러스터 하나 또는 파드 하나의 환경을 분리하여 여러 사용자가 이용해야 하는 경우 사용한다.
가상화를 통해 하나의 큰 물리적 자원을 논리적으로 쪼개어 여러 클라이언트가 사용하는 것과 유사한 개념이다.
하나의 노드에는 기본적으로 default namespace가 존재하여 별도로 네임스페이스를 지정하지 않는 서비스, pod는 모두 여기에 저장된다.
ReplicaSet는 컨트롤러의 한 종류로, Pod의 개수를 유지하는 역할을 한다. (AutoHealing)
ReplicaSet 생성시 spec에 replicas
값을 지정하여 지정한 개수의 pod 숫자를 유지하도록 정의할 수 있다.
생성할 pod의 명세를 template
로 함께 정의해주어야 한다.
Pod를 생성하기 위한 명세를 말한다.
Pod를 생성하기 위한 yaml 파일의 문법과 유사하게 작성하면 된다.
Pod를 자동으로 생성하는 컨트롤러(ReplicaSet, Deployment 등)의 yaml 파일에 포함되어야 한다.
Deployment는 ReplicaSet을 관리하기 위한 컨트롤러이다.
ReplicaSet이 관리하는 Pod의 버전 업데이트와 Rollback 기능을 제공한다.
버전 업데이트 및 롤백을 위해서는 기존 Pod를 삭제하고, 새로 운영할 Pod를 생성하는 재배포 과정을 거쳐야 한다.
재배포 방식에는 크게 Recreate, Rolling Update 두 가지가 있다.
Pod가 삭제된 시간부터, 새로운 Pod가 생성되어 작동하기까지 일시적으로 서비스를 이용할 수 없는 시간(Downtime)이 발생한다는 단점이 있다.
운영 중인 pod의 수가 일정하게 유지되기 때문에 Downtime이 존재하지 않는다.
그러나 일시적으로 총 pod의 수가 1개 더 많아야하기 때문에 그만큼의 리소스가 있어야 한다.
보통 한번에 여러개의 pod가 동시에 업데이트를 진행하기 때문에 그만큼의 리소스를 확보하기 어렵다는 단점이 있다.
Pod를 네트워크에 노출시켜 외부 또는 내부의 사용자가 접근할 수 있도록 하기 위해 사용하는 object
일반적으로 각 pod는 서로 다른 ip를 보유하고 있기 때문에 이를 통한 접근이 가능하다.
그러나 만약 pod가 장애, 버전 업데이트 등으로 인해 교체되면 원래 ip로는 더이상 접근이 불가능하게 된다.
또한 ip로 직접 접근하는 방식은 로드 밸런싱을 위해서도 적합하지 않다.
사용자는 service object를 통해 항상 일정한 방식으로 pod에 접근할 수 있게 된다.
Service는 selector와 label 명세를 바탕으로 연결할 Pod를 찾는다.
selector와 label은 key-value 형태로 이루어져있다. (동일한 key, 동일한 value를 바탕으로 찾음)
Service의 spec에 정의되는 속성으로, 어떤 이름의 어플리케이션을 찾을지 지정한다.
Pod의 metadata에 정의되는 속성으로, Service의 selector와 동일한 키-값을 가져야 한다.
클라이언트가 public ip와 포트번호를 통해 Service를 접근했을 때, Service가 포트번호를 통해 어떤 pod에 접근해야하는지 알아낼 수 있다.
이를 포트 포워딩이라한다.
Service의 spec에 정의되는 속성으로 port
와 targetPort
를 지정할 수 있다.
port
: 사용자 요청의 포트 번호targetPort
: 요청을 전달할 대상의 포트 번호Service와 pod를 연결하기 위해서는 selector-label, port fowarding이 모두 일치해야 한다.
서비스에 접근할 수 있는 방식에 따라 다양한 Service 유형이 존재한다.
Sevice를 생성할 때 자동으로 부여되는 서비스의 pivate IP(클러스터 IP)를 통해 서비스에 접근하는 방식이다.
모든 노드(Worker node)에 각각 port를 할당하여 접근하는 방식이다.
기본적으로 30000 ~ 32767 사이의 포트가 부여되며 사용자가 지정할 수 있다.
각 node의 public IP와 할당된 port를 바탕으로 외부 사용자가 노드 및 pod에 접근하는 것이 가능하다.
AWS 환경에서 외부 네트워크를 통해 접근하고 싶은 경우 보안 규칙으로 이 포트번호 범위를 지정하면 접근이 가능하다.
ClusterIP의 상위 개념으로, clusterIP가 기본적으로 할당되기 때문에 이를 이용한 접근도 가능하다.
NodePort 유형에서 사용자가 Nodeport에 접근하기 위해서는 Node의 Public IP 및 포트번호를 알아야 했다. 그러나 이렇게 직접 접근이 가능한 정보를 외부에 공개하는 것은 보안적인 측면에서 그다지 바람직한 방법은 아니다.
Load Balancer 유형에서는 각 Node와 연결된 로드 밸런서를 만들어 로드 밸런서의 Public IP를 통해 사용자가 service 및 pod에 접근할 수 있도록 하는 방식이다.
NodePort와 ClusterIP의 모든 기능을 포함한다.
단 Load Balancer의 기능을 온전히 사용하기 위해서는 추가적인 플러그인을 설치하거나, 로드 밸런서 환경을 지원해주는 클라우드 기반 k8s 환경을 이용해야 한다. (load balancer의 public IP 할당을 위해)
Volume은 각 Pod 또는 Pod에 속한 컨테이너들이 서로 공유하여 사용할 수 있는 데이터 저장소이다.
Volume의 대부분은 object가 아니기 때문에 별도의 yaml 파일로 관리되지 않는다.
대신 pod를 관리하는 yaml 파일에서 별도로 명세할 수 있다.
Pod가 생성될 때 pod안에 함께 생성되는 volume으로, 말 그대로 비어있는 디렉토리이다.
Pod가 삭제될 때도 함께 삭제가 되는 일종의 임시 Volume으로, 이러한 특성으로 인해 pod에 종속된 volume이라고 한다.
Node 안에 생성되는 Volume으로 Pod에 종속되지 않은 Volume이다.
그러나 Node 안에서만 공유가 이루어지기 때문에, 재배포된 Pod가 다른 Node에 위치할 경우 volume을 사용할 수 없다는 문제점이 있다. -> 자동화 관리에 부적합
영구적인 Volume이란 의미이며, object로써 관리가 가능하다. (yaml 파일)
별도의 클라우드 저장소 서비스나 직접 구축되어있는 스토리지를 클러스터와 연결하여 사용하는 개념이다.
때문에 스토리지 종류, 클라우드 공급자에 따라 스토리지에 대한 세부 정보를 반드시 명세해야 한다.
PV에 하는 요청이라는 뜻으로, PV를 각 Pod에 직접 연결하지 않고, PVC라는 중간다리를 통해 처리함으로써 pod와 스토리지를 분리하는 역할을 한다.
이를 통해 Pod의 생성/삭제가 스토리지에 영향을 주지않고, 각 pod에 맞는 다양한 환경의 스토리지를 구성할 수 있다는 장점이 있다.
구조를 간략하게 나타내면 위와 같다.
PV-PVC 방법은 사용자가 스토리지의 자원을 가져와 PV를 선언하고, PVC가 직접 어떤 PV와 연결하는지 선언해야한다. (정적 프로비저닝)
StorageClass는 동적 프로비저닝을 통해 PVC에서 원하는 스토리지의 크기, 접근 모드를 지정해주기만 하면 알아서 스토리지에서 자원을 할당해주는 방식이다.
AWS EKS, Azuer AKS와 같은 클라우드 기반의 쿠버네티스를 사용할 때 이러한 방식을 이용할 수 있다.