쿠버네티스

[클라우드] 3.Kuberdnetes Pod 배포하기

트리스탄1234 2022. 8. 28. 09:25
728x90
반응형

Kubernetes에서 배포 가능한 객체(Obejct )는 여러가지가 있지만 그중 최소 단위는 Pod 입니다. 이 Pod는 개별적인 IP를 가지고 Pod내부에는 그림과 같이 한개의 컨테이너나 여러개의 컨네티어와 볼륨 등으로 구성할 수 있습니다. 권고 사항은 한개의 Pod에 한개의 컨테이너를 구성하는게 권고 사항입니다. 그 이유는 MSA(Micro Service Architecture)로써 Pod에 여러개의 컨테이너가 존재를 하면 모니터링을 통한 프로세스 단위의 로그 수집이나 모니터링 장애 처리등이 어렵게 되어서 입니다.

Pod내의 컨테이너들은 모두 같은 IP를 보유하고 있습니다. Pod들은 Kubernetes 클러스터내에서 상황에 따라 Scale in/out이 가능하고, 장애 발생시 신규 Pod를 자동으로 생성이 되어서, IP변경이 자주 일어 납니다. 이런 경우 Pod의 IP로는 외부에 노출하여 서비스를 제공을 한다면, 자주 바뀌는 IP로 인하여 서비스에 문제가 발생할수 있습니다. 그래서 Pod앞단에 Service객체를 생성하고 모든 서비스 요청을 서비스 객체를 통해 Pod에 전달 되는 구조로 구성을 하는것이 좋습니다.

그럼 이제 YAML 파일을 통해 Pod를 배포해 보겠 습니다. 우선 Test 디렉토리 밑에 Pod 디렉토리를 만들어서 그 디렉토리 안에서 Pod.yaml 파일을 만들어 오래와 같은 내용을 입력 후 저장 합니다.

root@master-VirtualBox:~/test# mkdir Pod
root@master-VirtualBox:~/test#cd Pod
root@master-VirtualBox:~/test#vi Pod.yaml
apiVersion: v1
kind: Pod ==> 배포되는 객체 정의
metadata:
labels:
run: my-nginx
name: my-nginx
namespace: default
spec:
containers:
- image: nginx:1.14.1
imagePullPolicy: Always
name: my-nginx
ports:
- containerPort: 80
protocol: TCP

그럼 이제 생성된 Pod.yaml 파일을 이용해서 Node에 배포를 하고 그 정보를 조회해 봅시다

root@master-VirtualBox:~/test/Pod# kubectl apply -f Pod.yaml ==> Pod 객체 배포
pod/my-nginx created
root@master-VirtualBox:~/test/Pod# kubectl get pod ==> 배포된 Pod 정보 조회
NAME READY STATUS RESTARTS AGE
my-nginx 0/1 ContainerCreating 0 10s
root@master-VirtualBox:~/test/Pod#
root@master-VirtualBox:~/test/Pod#
root@master-VirtualBox:~/test/Pod# kubectl get pod -o wide ==> Pod의 세부 정보 확인
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx 1/1 Running 0 21s 172.16.168.198 worknode1-virtualbox <none> <none>
root@master-VirtualBox:~/test/Pod#
root@master-VirtualBox:~/test/Pod#
root@master-VirtualBox:~/test/Pod# kubectl describe pod my-nginx ==> 세부 정보 확인
Name: my-nginx
Namespace: default
Priority: 0
Node: worknode1-virtualbox/192.168.1.5
Start Time: Mon, 01 Aug 2022 10:27:18 +0900
Labels: run=my-nginx
Annotations: cni.projectcalico.org/podIP: 172.16.168.198/32
cni.projectcalico.org/podIPs: 172.16.168.198/32
Status: Running
IP: 172.16.168.198
IPs:
IP: 172.16.168.198
Containers:
my-nginx:
Container ID: containerd://7226da65d1387a927040dcdc899d7e269771536d420f423944ca195f42b9f17e
Image: nginx:1.14.1
Image ID: docker.io/library/nginx@sha256:32fdf92b4e986e109e4db0865758020cb0c3b70d6ba80d02fe87bad5cc3dc228
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 01 Aug 2022 10:27:33 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-dgp5c (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-dgp5c:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 63s default-scheduler Successfully assigned default/my-nginx to worknode1-virtualbox
Normal Pulling 63s kubelet Pulling image "nginx:1.14.1"
Normal Pulled 48s kubelet Successfully pulled image "nginx:1.14.1" in 14.381250558s
Normal Created 48s kubelet Created container my-nginx
Normal Started 48s kubelet Started container my-nginx
root@master-VirtualBox:~/test/Pod#

이제 Pod를 배포를 했는데요. 그럼 이 Pod의 상태에 대해서 알아 봅시다 Pod는 아래그림과 같이 5개의 상태가 있습니다.

  • Pending : Pod안에서 컨테이너가 시작되지전의 상태
  • Running: Pod에서 컨테이너가 실행중인 상태
  • Succeeded: Pod안의 모든 컨테이너가 정상 종료된 상태
  • Failed: Pod안에 하나 이상의 컨테이너가 비정상 종료 된 상태
  • Unknown: Pod의 상태를 알수 없는 경우

그럼 조금전에 생성한 Pod의 상태를 살펴 봅시다. 상태가 Running상태로 컨테이너가 정상적으로 실행이 되고 있는 상태 입니다.

root@master-VirtualBox:~/test/Pod# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx 1/1 Running 0 12m

그럼 이제 이런 배포 과정이 어떻게 진행이 되는지 그림을 통해 알아 봅시다. kubectl 명령어로 컨테이너를 실행을 시키면 그 절차는 아래 그림과 같은 과정을 거치게 됩니다.

그림출처: 쿠버네티스 인 액션

위의 그림에서 docker의 이미지가 어떻게 생성이 되는지를 보여주고 있습니다. 로컬 저장소에 실행 하려는 이미지가 있으면 다운로드 과정이 생략이 되는데요. yaml파일의 설정값 하나를 살펴 보겠 습니다.

apiVersion: v1
kind: Pod
metadata:
labels:
run: my-nginx
name: my-nginx
namespace: default
spec:
containers:
- image: nginx:1.14.1
imagePullPolicy: Always
name: my-nginx
ports:
- containerPort: 80
protocol: TCP

위의 파라메터 중 빨간색 imagePullPolicy 파라메터를 사용해서 image를 다운할건지 생략 할것인지를 설정을 할수 있습니다. 설정 가능한 값과 동작방식은 아래와 같습니다.

  • Always : 배포시마다 레지스트리에서 이미지를 다운로드 실행
  • Never : 배포시 레지스트리에서 이미지를 다운로드 받지 않고 Node에 존재하는 이미지를 사용합니다. 만약 Node에 Image가 존재하지 않는다면 에러가 발생합니다.
  • IfNotPresent : Default설정값으로 배포하려는 Images가 Node에 존재할 경우 이미지 다운로드를 skip합니다.

Kubernetes의 Cluster에서 API 서버로의 접근 및 인증과 권한을 위해서 2가지 계쩡을 사용을 합니다.

  • User account: kubectl 명령어를 통해 API 서버로의 접근시 사용자의 권한과 인증을 위해 사용하는 계정
  • Service account: 클러스터내의 컨테이너안의 프로세스에서 API 서버로의 접근시 사용하는 계정

이런 계정은 yaml 파일에서 정의가 되고 별도로 언급을 하지 않으면 default값을 사용하게 됩니다.

그럼 yaml파일과 kubectl명령을 통해 서비스 계정의 정보를 조회를 해보겠습니다.

apiVersion: v1
kind: Pod
metadata:
...
spec:
containers:
- image: nginx
...
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default ==> 컨테이너에서 사용하는 계정 설정
serviceAccountName: default
root@master-VirtualBox:~/test/Pod# kubectl get service ==> setvice 계정의 정보 조회
serviceaccounts services

 

728x90
반응형