앞으로의 스터디 내용은 <Kubernetes in Action>을 기반으로 진행합니다.
자세한 내용은, 해당 책을 확인해주세요!
http://www.yes24.com/Product/Goods/89607047
1. 파드란
- 여러 개의 컨테이너가 함께 배치된 컨테이너 그룹이자 쿠버네티스의 기본 빌딩 블록
- 파드는 논리적인 호스트로, 동일한 파드 내 프로세스는 각각이 컨테이너 형태로 캡슐화되었다는 점을 제외하면
동일한 머신 위에서 동작하는 것과 같다 - 일반적으로 파드 하나 당 하나의 컨테이너만 포함한다
- 하나의 파드에 여러 컨테이너가 포함된다고 해도, 그 컨테이너들은 모두 하나의 워커 노드에서 실행된다
- 1개의 워커노드에 여러 개의 파드가 포함되고, 각 파드에는 1개 이상의 컨테이너가 포함된다
하나의 컨테이너에 여러 프로세스를 실행하지 않고 다중 컨테이너를 사용하는 이유
- 컨테이너는 단일 프로세스 실행 목적으로 설계 (프로세스 실행, 로그 관리, 자동 재시작 등)
- 단일 컨테이너, 단일 프로세스 = 다중 컨테이너의 활용 = 파드를 통한 관리의 필요성
- 파드를 통해 컨테이너를 모아서, 여러 연관 프로세스들을 함께 실행하고 (거의) 동일한 환경을 제공하기 위해 파드를 활용한다
가상머신은 멀티 프로세싱이 되는 운영체제이지만, 컨테이너는 싱글 프로세스라는 것이다.
로그, 권한 체크, 사이드카와 같은 여러 프로세스를 기존 컨테이너에서는 동일하게 구성하기 어려우므로,가상머신과 파드를 비교하는 것이 더 적합하다.
어플리케이션은, 기존 웹 서비스 외 여러가지 보조 프로세스가 존재하므로,
싱글 프로세스 외 기타 여러 컨테이너가 보조 역할을 하여 그룹을 만들어주기 위해 파드가 필요하다.
리눅스의 프로세스 네임스페이스를 통해 컨테이너에 여러 프로세스를 만들 수는 있지만, 바람직하지 않다.
컨테이너에서 소개되는 격리, 그 중에서 Proccess의 네임스페이스 분리에 대해서는 기존 리눅스에서 제공하는 chroot를 한번 만져보면 지금 내용이 더욱 잘 이해되지 않을까 싶다.
https://www.44bits.io/ko/post/change-root-directory-by-using-chroot
결론적으로, 파드는 하나의 목적을 위한 서비스를 묶는 것이 맞다.
파드에는 메인 프로세스 컨테이너 하나와 이를 보조하는 프로세스 컨테이너들로 구성하는 방식이다.
파드가 같은 컨테이너들은 동일한 리눅스 네임스페이스를 사용하여 <부분격리>된다
- 파드의 모든 컨테이너는 동일 네트워크 네임스페이스, 동일 UTS 네임스페이스, 동일 IPC 네임스페이스에서 실행되어, 호스트 이름과 네트워크 인터페이스를 공유한다. (PID 네임스페이스도 최신 버전에서 공유 가능)
- 네임스페이스 설명 : https://bluese05.tistory.com/12
- 단, <파일시스템>의 경우에는 완전히 컨테이너 간에 격리 상태를 이룬다.
- 컨테이너 간 파일 디렉터리를 공유하기 위해서는 <볼륨> 개념을 활용해야 한다. (추후 설명 예정)
파드 내 컨테이너들 간 동일한 IP와 포트 공유해서 발생하는 포트 충돌 문제
- 파드는 앞서 말했듯 컨테이너들끼리 동일한 네트워크 네임스페이스를 사용하게 하므로,
IP와 포트 공간도 공유한다는 것을 의미한다. - 따라서, 파드 안 컨테이너들은 포트 번호가 같지 않도록 해야 함에 유의하자.
- 파드 내 컨테이너는 모두 동일한 루프백 네트워크 인터페이스를 가져 로컬호스트를 통해 상호 통신이 가능하다
- 루프백 인터페이스(loopback interface)란 라우터나 스위치에 설정하는 가상의 인터페이스입니다. 루프백 인터페이스를 사용하는 이유는 여러가지가 있습니다. 예를 들어, 실제 네트워크에서는 각 라우터의 이더넷 인터페이스와 스위치를 연결한 후에 PC나 서버 등을 접속합니다.
출처: https://12bme.tistory.com/356 - loopback 이란 가상의 인터페이스를 만들어서 사용하는 것입니다.
인터페이스 예로는 LAN구간 , WAN구간 마다 다르겠지만 Serial와 Ethernet이 FastEthernet 등등 다양한 인터페이스가 존재합니다. 물리적인 인터페이스의 경우 Serial 일때 Clock rate , WAN 인캡슐레이션 등 부여를 해야하고 이는 즉 외부에 간섭을 받는다는 말이 됩니다. 하지만 loopback은 설정을 하지 않아도 되며, 라우터가 죽지 않는 이상 잘 돌아가게 됩니다. 다른 인터페이스는 죽으면 통신이 안되지만 loopback 은 그렇지 않기 때문에 비교적 안전한 인터페이스라고 말합니다.
https://min-310.tistory.com/169
- 루프백 인터페이스(loopback interface)란 라우터나 스위치에 설정하는 가상의 인터페이스입니다. 루프백 인터페이스를 사용하는 이유는 여러가지가 있습니다. 예를 들어, 실제 네트워크에서는 각 라우터의 이더넷 인터페이스와 스위치를 연결한 후에 PC나 서버 등을 접속합니다.
파드 간 플랫 네트워크
- 모든 파드는 하나의 플랫한 공유 네트워크 주소 공간에 상주한다
- 플랫 네트워크에서는 모든 장치와 워크 스테이션이 단일 스위치에 연결됩니다. 이는 모든 장치가 동일한 브로드 캐스트 네트워크의 일부이며 서로 통신 할 수 있음을 의미합니다.
https://seankim.life/2021/06/16/flat-network-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/
- 플랫 네트워크에서는 모든 장치와 워크 스테이션이 단일 스위치에 연결됩니다. 이는 모든 장치가 동일한 브로드 캐스트 네트워크의 일부이며 서로 통신 할 수 있음을 의미합니다.
- 모든 파드는 다른 파드의 IP 주소를 통해 접근하는 것이 가능하다.
각 파드는 라우팅 가능한 IP 주소를 얻고 다른 모든 파드는 해당 주소를 통해 파드를 본다 - 두 파드 간에 어떠한 NAT도 존재하지 않는다
어떤 워커노드에 속한 파드이든 상관없이 모든 파드는 상호 간 NAT 없는 플랫 네트워크 상의 통신이 가능하다는 의미이다.
- 네트워크 주소 변환(영어: network address translation, 줄여서 NAT)은 컴퓨터 네트워킹에서 쓰이는 용어로서, IP 패킷의 TCP/UDP 포트 숫자와 소스 및 목적지의 IP 주소 등을 재기록하면서 라우터를 통해 네트워크 트래픽을 주고 받는 기술을 말한다. https://ko.wikipedia.org/wiki/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC_%EC%A3%BC%EC%86%8C_%EB%B3%80%ED%99%98
- 두 파드가 서로 네트워크 패킷을 보내면 상대방 실제 IP주소를 패킷 안에 있는 출발지 IP 주소에서 찾을 수 있다
2. 파드의 컨테이너 구성
- 하나의 어플리케이션을 여러 파드로 구성하고,
각 파드에는 서로 밀접하게 관련 있는 프로세스 및 구성요소를 컨테이너로 나누어 하나의 파드를 구성한다 - 다계층 애플리케이션의 파드 분할 방법
- 프론트엔드 서버와 백엔드 (데이터베이스) 서버 컨테이너를 별개의 파드에 배치한다
파드를 분리하여 별개의 노드에 개별적으로 스케줄링해 인프라 활용도를 향상시킨다 - 컨테이너의 수평 확장 (스케일링 아웃) 관점에서도 프론트와 백 등을 여러 파드로 분할해야 한다.
파드는 스케일링의 기본 단위이다. 되도록 하나의 파드에 하나의 컨테이너를 두자. - 하나의 파드에 여러 컨테이너를 넣을 때에는 하나의 주 컨테이너를 다른 지원 컨테이너들이 보조하는 경우이다
파드에 여러 컨테이너를 넣을 경우에는,
1. 컨테이너를 함께 실행해야 하거나 (동일 호스트에서 실행할 필요성)
2. 컨테이너가 개별 구성 요소가 아니라, 여러 개가 모여 하나의 구성 요소를 나타내거나
3. 컨테이너가 함께 스케일링되어야 하는 경우이다
- 프론트엔드 서버와 백엔드 (데이터베이스) 서버 컨테이너를 별개의 파드에 배치한다
* 이번 챕터에서는 단일 컨테이너를 보유한 파드만을 기준으로 설명하며, 여러 컨테이너를 포함하는 파드의 경우 추후 설명한다.
3. 파드의 생성, 실행, 정지
(1) YAML 또는 JSON 디스크립터로 파드 생성
파드를 포함한 쿠버네티스 리소스를 JSON 혹은 YAML 파일 형태의 메니페스트에 정의해,
쿠버네티스 REST API 엔드포인트에 전송하여,
버전 관리 시스템에 넣어 다양한 속성 집합 설정이 가능하다.
쿠버네티스 리소스 유형 확인하기
쿠버네티스 리소스 유형
모든 리소스 유형, 속성을 알기 위해서는 API reference 문서를 참고해야 한다.
kubectl explain 활용하기
kubectl explain을 이용해 사용 가능한 API 오브젝트 필드 찾기
$ kubectl explain pods
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
$ kubectl explain pod.spec
KIND: Pod
VERSION: v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
PodSpec is a description of a pod.
FIELDS:
activeDeadlineSeconds <integer>
Optional duration in seconds the pod may be active on the node relative to
StartTime before the system will actively try to mark it failed and kill
associated containers. Value must be a positive integer.
affinity <Object>
If specified, the pod's scheduling constraints
automountServiceAccountToken <boolean>
AutomountServiceAccountToken indicates whether a service account token
should be automatically mounted.
containers <[]Object> -required-
List of containers belonging to the pod. Containers cannot currently be
added or removed. There must be at least one container in a Pod. Cannot be
updated.
dnsConfig <Object>
Specifies the DNS parameters of a pod. Parameters specified here will be
merged to the generated DNS configuration based on DNSPolicy.
dnsPolicy <string>
Set DNS policy for the pod. Defaults to "ClusterFirst". Valid values are
'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS
parameters given in DNSConfig will be merged with the policy selected with
DNSPolicy. To have DNS options set along with hostNetwork, you have to
specify DNS policy explicitly to 'ClusterFirstWithHostNet'.
enableServiceLinks <boolean>
EnableServiceLinks indicates whether information about services should be
injected into pod's environment variables, matching the syntax of Docker
links. Optional: Defaults to true.
ephemeralContainers <[]Object>
List of ephemeral containers run in this pod. Ephemeral containers may be
run in an existing pod to perform user-initiated actions such as debugging.
This list cannot be specified when creating a pod, and it cannot be
modified by updating the pod spec. In order to add an ephemeral container
to an existing pod, use the pod's ephemeralcontainers subresource. This
field is beta-level and available on clusters that haven't disabled the
EphemeralContainers feature gate.
hostAliases <[]Object>
HostAliases is an optional list of hosts and IPs that will be injected into
the pod's hosts file if specified. This is only valid for non-hostNetwork
pods.
hostIPC <boolean>
Use the host's ipc namespace. Optional: Default to false.
hostNetwork <boolean>
Host networking requested for this pod. Use the host's network namespace.
If this option is set, the ports that will be used must be specified.
Default to false.
hostPID <boolean>
Use the host's pid namespace. Optional: Default to false.
hostname <string>
Specifies the hostname of the Pod If not specified, the pod's hostname will
be set to a system-defined value.
imagePullSecrets <[]Object>
ImagePullSecrets is an optional list of references to secrets in the same
namespace to use for pulling any of the images used by this PodSpec. If
specified, these secrets will be passed to individual puller
implementations for them to use. For example, in the case of docker, only
DockerConfig type secrets are honored. More info:
https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
initContainers <[]Object>
List of initialization containers belonging to the pod. Init containers are
executed in order prior to containers being started. If any init container
fails, the pod is considered to have failed and is handled according to its
restartPolicy. The name for an init container or normal container must be
unique among all containers. Init containers may not have Lifecycle
actions, Readiness probes, Liveness probes, or Startup probes. The
resourceRequirements of an init container are taken into account during
scheduling by finding the highest request/limit for each resource type, and
then using the max of of that value or the sum of the normal containers.
Limits are applied to init containers in a similar fashion. Init containers
cannot currently be added or removed. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
nodeName <string>
NodeName is a request to schedule this pod onto a specific node. If it is
non-empty, the scheduler simply schedules this pod onto that node, assuming
that it fits resource requirements.
nodeSelector <map[string]string>
NodeSelector is a selector which must be true for the pod to fit on a node.
Selector which must match a node's labels for the pod to be scheduled on
that node. More info:
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
os <Object>
Specifies the OS of the containers in the pod. Some pod and container
fields are restricted if this is set.
If the OS field is set to linux, the following fields must be unset:
-securityContext.windowsOptions
If the OS field is set to windows, following fields must be unset: -
spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions -
spec.securityContext.seccompProfile - spec.securityContext.fsGroup -
spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls -
spec.shareProcessNamespace - spec.securityContext.runAsUser -
spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups -
spec.containers[*].securityContext.seLinuxOptions -
spec.containers[*].securityContext.seccompProfile -
spec.containers[*].securityContext.capabilities -
spec.containers[*].securityContext.readOnlyRootFilesystem -
spec.containers[*].securityContext.privileged -
spec.containers[*].securityContext.allowPrivilegeEscalation -
spec.containers[*].securityContext.procMount -
spec.containers[*].securityContext.runAsUser -
spec.containers[*].securityContext.runAsGroup This is an alpha field and
requires the IdentifyPodOS feature
overhead <map[string]string>
Overhead represents the resource overhead associated with running a pod for
a given RuntimeClass. This field will be autopopulated at admission time by
the RuntimeClass admission controller. If the RuntimeClass admission
controller is enabled, overhead must not be set in Pod create requests. The
RuntimeClass admission controller will reject Pod create requests which
have the overhead already set. If RuntimeClass is configured and selected
in the PodSpec, Overhead will be set to the value defined in the
corresponding RuntimeClass, otherwise it will remain unset and treated as
zero. More info:
https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md
This field is beta-level as of Kubernetes v1.18, and is only honored by
servers that enable the PodOverhead feature.
preemptionPolicy <string>
PreemptionPolicy is the Policy for preempting pods with lower priority. One
of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.
This field is beta-level, gated by the NonPreemptingPriority feature-gate.
priority <integer>
The priority value. Various system components use this field to find the
priority of the pod. When Priority Admission Controller is enabled, it
prevents users from setting this field. The admission controller populates
this field from PriorityClassName. The higher the value, the higher the
priority.
priorityClassName <string>
If specified, indicates the pod's priority. "system-node-critical" and
"system-cluster-critical" are two special keywords which indicate the
highest priorities with the former being the highest priority. Any other
name must be defined by creating a PriorityClass object with that name. If
not specified, the pod priority will be default or zero if there is no
default.
readinessGates <[]Object>
If specified, all readiness gates will be evaluated for pod readiness. A
pod is ready when all its containers are ready AND all conditions specified
in the readiness gates have status equal to "True" More info:
https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates
restartPolicy <string>
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
runtimeClassName <string>
RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group,
which should be used to run this pod. If no RuntimeClass resource matches
the named class, the pod will not be run. If unset or empty, the "legacy"
RuntimeClass will be used, which is an implicit class with an empty
definition that uses the default runtime handler. More info:
https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class This is a
beta feature as of Kubernetes v1.14.
schedulerName <string>
If specified, the pod will be dispatched by specified scheduler. If not
specified, the pod will be dispatched by default scheduler.
securityContext <Object>
SecurityContext holds pod-level security attributes and common container
settings. Optional: Defaults to empty. See type description for default
values of each field.
serviceAccount <string>
DeprecatedServiceAccount is a depreciated alias for ServiceAccountName.
Deprecated: Use serviceAccountName instead.
serviceAccountName <string>
ServiceAccountName is the name of the ServiceAccount to use to run this
pod. More info:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
setHostnameAsFQDN <boolean>
If true the pod's hostname will be configured as the pod's FQDN, rather
than the leaf name (the default). In Linux containers, this means setting
the FQDN in the hostname field of the kernel (the nodename field of struct
utsname). In Windows containers, this means setting the registry value of
hostname for the registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters to
FQDN. If a pod does not have FQDN, this has no effect. Default to false.
shareProcessNamespace <boolean>
Share a single process namespace between all of the containers in a pod.
When this is set containers will be able to view and signal processes from
other containers in the same pod, and the first process in each container
will not be assigned PID 1. HostPID and ShareProcessNamespace cannot both
be set. Optional: Default to false.
subdomain <string>
If specified, the fully qualified Pod hostname will be
"<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>". If not
specified, the pod will not have a domainname at all.
terminationGracePeriodSeconds <integer>
Optional duration in seconds the pod needs to terminate gracefully. May be
decreased in delete request. Value must be non-negative integer. The value
zero indicates stop immediately via the kill signal (no opportunity to shut
down). If this value is nil, the default grace period will be used instead.
The grace period is the duration in seconds after the processes running in
the pod are sent a termination signal and the time when the processes are
forcibly halted with a kill signal. Set this value longer than the expected
cleanup time for your process. Defaults to 30 seconds.
tolerations <[]Object>
If specified, the pod's tolerations.
topologySpreadConstraints <[]Object>
TopologySpreadConstraints describes how a group of pods ought to spread
across topology domains. Scheduler will schedule pods in a way which abides
by the constraints. All topologySpreadConstraints are ANDed.
volumes <[]Object>
List of volumes that can be mounted by containers belonging to the pod.
More info: https://kubernetes.io/docs/concepts/storage/volumes
2장 파드의 YAML 디스크립터 살펴보기
디스크립터 파일 확인하기
$ kubectl get po kubia -o yaml
apiVersion: v1 # 해당 디스크립터에서 사용한 쿠버네티스 API 버전
kind: Pod # 쿠버네티스 오브젝트 및 리소스 유형
metadata: # 파드 메타데이터 (이름, 레이블, 어노테이션)
creationTimestamp: "2022-02-06T04:12:30Z"
labels:
run: kubia
name: kubia
namespace: default
resourceVersion: "7887"
uid: 229271ca-7672-4dd5-bce8-1d89f309ac86
spec: # 파드 정의 및 내용 (컨테이너 목록, 볼륨 등)
containers:
- image: joon0615/kubia
imagePullPolicy: Always
name: kubia
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-sf8c7
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: minikube
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-sf8c7
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status: # 파드와 그 안의 컨테이너에 대한 상세 상태
conditions:
- lastProbeTime: null
lastTransitionTime: "2022-02-06T04:12:30Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2022-02-06T04:12:35Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2022-02-06T04:12:35Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2022-02-06T04:12:30Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: docker://aea5a91026a8c9f154fde88230d578e80cd6730c2e41a8e1c422df88273b03c5
image: joon0615/kubia:latest
imageID: docker-pullable://joon0615/kubia@sha256:fd06de01c736aba25effbe0c7024668a28a60a73344ab286853e2a813071353e
lastState: {}
name: kubia
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2022-02-06T04:12:34Z"
hostIP: 192.168.59.100
phase: Running
podIP: 172.17.0.3
podIPs:
- ip: 172.17.0.3
qosClass: BestEffort
startTime: "2022-02-06T04:12:30Z"
각 쿠버네티스 리소스가 보유한 3가지 주요 부분
- Metadata 메타데이터 = 파드에 대한 정보 : 이름, 네임스페이스, 레이블, 기타 정보
- Spec 스펙 = 파드 컨테이너, 볼륨, 기타 데이터 등 파드 자체에 대한 실제 명세
- Status 상태 = 파드 상태, 내부 IP 등 현재 실행 정보. (파드 신규 생성 시 작성 불필요)
# kubia-manual.yaml (source = https://github.com/luksa/kubernetes-in-action/blob/master/Chapter03/kubia-manual.yaml )
apiVersion: v1
kind: Pod
metadata:
name: kubia-manual
spec:
containers:
- image: luksa/kubia
name: kubia
ports:
- containerPort: 8080
protocol: TCP
- 포트를 명시적으로 정의한 이유
- 클러스터를 사용하는 모든 사람이 파드 노출 포트를 빠르게 확인 가능하도록
- 포트에 이름을 지정하여 편의성을 높이도록
- 굳이 정의하지 않더라도 컨테이너가 0.0.0.0 주소에 열어둔 포트의 접속을 허용할 시 접속 가능하다.
kubectl create 명령으로 파드 생성
$ kubectl create -f kubia-manual.yaml
pod "kubia-manual" created
실행 중인 파드의 정의 파일 확인하기 (YAML / JSON 요청)
만든 포맷과 다른 옵션으로 요청하면 전환하여 반환하도록 동작한다
$ kubectl get po kubia-manual -o yaml
$ kubectl get po kubia-manual -o json
(2) 애플리케이션 로그 보기
Node.js 애플리케이션을 통해 로그를 프로세스 표준 출력에 기록해보자.
도커와 같은 컨테이너 런타임이 이 표준 출력으로 기록도는 로그 스트림을 파일 형태로 전달하고,
컨테이너 런타임 명령어를 통해 사용자는 컨테이너 로그를 가져올 수 있다.
(ssh 접속 후 $docker logs <containerID>를 입력하면 가능하다고 한다)
kubectl로 파드 로그 보기
파드 로그, 컨테이너 로그를 kubectl을 활용하여 간단히 로컬 머신 상에서 확인해보자
$ kubectl logs kubia-manual
Kiada - Kubernetes in Action Demo Application
---------------------------------------------
Kiada 0.1 starting...
Local hostname is kubia-manual
Listening on port 8080
파드가 삭제되면 해당 로그도 함께 사라짐에 유의하자.
삭제 이후에도 로그를 확인하기 위해서는,
클러스터 전체의 중앙집중식 로깅 설정을 통해 모든 로그를 중앙 저장소에 저장하도록 해야 한다.
(3) 파드 동작 확인 요청
파드의 실제 동작 확인을 위해서는 서비스를 활용하거나, 포트 포워딩을 진행해야 한다.
서비스는 후술할 예정이니, 포트 포워딩에 대해 알아보자.
로컬 네트워크 포트를 파드 포트로 포트포워딩하기
포트 포워딩 구성은 $ kubectl port-forward 명령어를 통해 진행한다.
머신 로컬 포트 8888을 파드의 8080포트로 향하도록 포트포워딩해보자.
$ kubectl port-forward kubia-manual 8888:8080
Forwarding from 127.0.0.1:8888 -> 8080
Forwarding from [::1]:8888 -> 8080
이렇게 하나의 터미널에서 포트 포워딩을 실행 중이면,
다른 새로운 터미널 하나를 열어 아래의 명령어를 수행하여 로컬 머신 8888에 요청을 보내면,
앞서 실행 중인 포트 포워딩에 의해 파드의 포트로 이어준다.
$ curl localhost:8888
Kiada version 0.1. Request processed by "kubia-manual". Client IP: ::ffff:127.0.0.1
(4) 파드 중지와 제거
$ kubectl delete po podname
$ kubectl delete po podname_1 podname_2
- kubectl 명령어를 통해 파드를 삭제하도록 지시한다.
- 쿠버네티스가 파드를 삭제한 뒤 모든 컨테이너의 종료를 지시한다.
- 쿠버네티스는 SIGTREM 신호를 프로세스에 보내 지정 시간을 대기한다. (기본값=30초)
- 지정 시간 내 종료되지 않을 경우 SIGKILL 신호를 통해 강제로 종료한다.
레이블 셀렉터를 통한 파드 삭제
레이블에 대한 개념은 아래 쪽에 서술되어 있으니 확인토록 하자.
$ kubectl delete po -l creation_method=manual
네임스페이스와 소속 파드 한번에 제거하기
네임스페이스 개념은 아래쪽에 서술되어 있으니 확인토록 하자.
$ kubectl delete ns custom-namespace
네임스페이스는 유지하고 소속 파드 전체만 삭제하기
$ kubectl delete po --all
만약 파드를 레플리케이션 컨트롤러 등 자동 복구 기능을 활성화시켜 생성했다면, 이렇게 파드를 삭제해도 다시 새로운 파드가 생성되기 마련이다. 네임스페이스 내 전체 리소스를 삭제하려면 아래 명령어를 입력해야 한다.
$ kubectl delete all --all
4. 파드와 다른 리소스를 레이블로 조직화하기
레이블을 통한 파드 구성
마이크로서비스 아키텍처가 보편화되면서, 파드의 수도 매우 많이 늘어나기 때문에,
파드를 정리하는 메커니즘은 필수적이다.
파드를 작은 그룹들로 임의의 기준에 따라 나누어, 각 그룹을 한번에 작업하는 것이 좋다.
레이블을 활용해 파드와 더불어 다른 쿠버네티스 오브젝트까지 조직화한다.
레이블이란
- 파드와 다른 리소스를 조직화하는 기능
- 리소스에 첨부하는 키-값 쌍
- 레이블 셀렉터를 활용해 리소스 선택에 이용되는 기능
- 각 파드는 여러 개의 레이블을 가질 수 있다 (레이블 키는 고유해야 한다)
https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/labels/
활용예시
- app : 파드가 속한 애플리케이션, 구성요소 혹은 마이크로서비스가 무엇인지
(app=ui, app=as, app=pc, app=sc, app=os)
- rel : 실행 중인 애플리케이션의 상태
(rel=stable, rel=beta, rel=canary)
Canary Release, 카나리 릴리스란?
전체 사용자에게 배포하기 이전에 소수 사용자에게 테스트 용도로 확인하는 릴리스.
파드 생성 시 레이블 지정하기
# kubia-manual-with-lables.yaml
apiVersion: v1
kind: Pod
metadata:
name: kubia-manual-v2
labels:
creation_method: manual
env: prod
spec:
containers:
- image: luksa/kubia
name: kubia
ports:
- containerPort: 8080
protocol: TCP
https://github.com/luksa/kubernetes-in-action/blob/master/Chapter03/kubia-manual-with-labels.yaml
$ kubectl create -f kubia-manual-with-labels.yaml
pod/kubia-manual-v2 created
$ kubectl get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
kubia 1/1 Running 0 145m run=kubia
kubia-manual 1/1 Running 0 57m <none>
kubia-manual-v2 0/1 ContainerCreating 0 22s creation_method=manual,env=prod
$ kubectl get po -L creation_method,env
NAME READY STATUS RESTARTS AGE CREATION_METHOD ENV
kubia 1/1 Running 0 146m
kubia-manual 1/1 Running 0 59m
kubia-manual-v2 1/1 Running 0 2m16s manual prod
* get po 명령어는 레이블을 표시하지 않으므로 --show-lables 옵션을 추가해야 한다
* -L 스위치를 활용하면 지정한 해당 레이블을 열로 표시하여 정보를 확인할 수 있다
파드 레이블 수정하기
$ kubectl label po kubia-manual creation_method=manual
pod/kubia-manual labeled
기존 레이블을 변경하기 위해서는 --overwrite 옵션을 사용해야 한다
$ kubectl label po kubia-manual-v2 env=debug --overwrite
pod/kubia-manual-v2 labeled
$ kubectl get po -L creation_method,env
NAME READY STATUS RESTARTS AGE CREATION_METHOD ENV
kubia 1/1 Running 0 150m
kubia-manual 1/1 Running 0 63m manual
kubia-manual-v2 1/1 Running 0 6m16s manual debug
5. 특정 레이블을 가진 파드에서 작업 수행시키기
레이블 셀렉터를 이용한 파드 나열
- 레이블 셀렉터는 특정 레이블로 태그된 파드의 부분 집합을 선택해 작업을 수행한다
- 레이블 셀렉터는 다음 기준에 따라 리소스를 선택한다
- 특정 키를 포함할 경우 / 포함하지 않은 경우
- 특정 키 + 값을 가진 경우
- 특정 키를 가졌으나 해당 값을 가지지 않은 경우
6. 어노테이션
어노테이션은 레이블과 비슷한 키-값 쌍이지만, 식별 정보를 가지지 않는다.
어노테이션 셀렉터는 존재하지 않아 오브젝트 선택이 불가하기는 하지만, 레이블보다 많은 정보를 포함할 수 있다.
어노테이션은 추가 정보 제공 외에 스펙 명세를 넣어 자동으로 다른 프로세스가 읽게끔하기도 한다.
7. 네임스페이스
격리 기술을 제공하는 리눅스 네임스페이스와는 달리 쿠버네티스 내 오브젝트 그룹핑에 사용되는 개념이다.
네임스페이스는, 각 오브젝트를 겹치지 않는 그룹으로 분할할 때 사용된다.
모든 리소스를 단일 네임스페이스에 두는 대신 여러 네임스페이스로 분할할 수 있고,
분리된 네임스페이스는 같은 리소스 이름을 다른 네임스페이스에 걸쳐 여러번 사용할 수 있다.
네임스페이스는 권한 관리(접근 제어)를 위해서 하기도 하고, 격리를 위함이기도 하다.
'기술 공부 > 쿠버네티스' 카테고리의 다른 글
쿠버네티스 (5) | 서비스 (0) | 2022.02.16 |
---|---|
쿠버네티스 (4) | 레플리카셋, 데몬셋, 잡, 크론잡 (0) | 2022.02.10 |
쿠버네티스 (2) | 도커와 쿠버네티스 튜토리얼 (0) | 2022.02.06 |
쿠버네티스 (1-6) | 쿠버네티스의 기원과 개념 (0) | 2022.02.02 |
쿠버네티스 (1-5) | 쿠버네티스 소개 (0) | 2022.02.02 |