brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Jun 28. 2021

쿠버1탄-5. 쿠버네티스-Pod 알아보기

다음은 쿠버네티스 스터디 자료를 참고해  정리한 내용입니다.


어플리케이션 최소 실행 단위인 Pod를 알아보자.


<1> 아키텍처 - 컴포넌트

<2> Pod 소개

<3> 컨테이너 공유 확인하기

<4> myweb2-netshoot 컨테이너 내부 들어가서 확인

<5> myweb2-nginx 컨테이너 내부 들어가서 확인

<6> Pod 삭제

<7> 정리 

<8> 다음 과정 



<1>  아키텍처 - 컴포넌트

https://kubernetes.io/docs/concepts/overview/components/




1

쿠버네티스는 Control Plane(마스터)와 노드로 구성되어 있다.

마스터 = 컨트롤 플레인 = 제어하는 곳이다.

노드 = 워커 노드 = 일하는 곳이다. Pod와 컨테이너가 동작하는 곳이다.



2

Control Plane(마스터 노드)  ?

핵심 컴포넌트: 마스터는 고가용성을 위한 클러스터 마스터로 구축

apiserve *: 마스터로 전달되는 모든 요청을 받는 API 서버

etcd : 클러스터내 모든 메타 정보를 저장하는 서비스

kube-scheduler : 사용자의 요청에 따라 적절하게 컨테이너를 워커 노드에 배치하는 스케줄러

kube-controller-manager : 현재 상태와 바라는 상태를 지속적으로 확인하며 특정 이벤트에 따라 특정 동작을 수행하는 컨트롤러 -  https://kubernetes.io/docs/concepts/architecture/controller/

cloud-controller-manager : 클라우드 플랫폼(AWS, GCP, Azure 등)에 특화된 리소스를 제어하는
클라우드 컨트롤러 - https://kubernetes.io/docs/concepts/architecture/cloud-controller/



3

워커 노드 ?

kubelet : 마스터의 명령에 따라 컨테이너의 라이프 사이클을 관리하는 노드 관리자

kube-proxy : 컨테이너의 네트워킹을 책임지는 프록시, 네트워크 규칙을 유지 관리

Container Runtime : 실제 컨테이너를 실행하는 컨테이너 실행 환경, (Docker containerD CRI-O)

https://kubernetes.io/docs/concepts/architecture/nodes/



4

CNI?

Container Network Interface 는 k8s 네트워크 환경을 구성해준다

컨테이너 네트워크이다.

https://kubernetes.io/ko/docs/concepts/cluster-administration/networking/


네트워크 조건?

Pod-Pod 간에는 NAT없이 통신

노드의 에이전트(시스템 데몬과 Kubelete)은 모든 Pod와 통신

노드의 호스트 네트워크에 있는 Pod는 NAT없이 모든 노드에 있는 모든 Pod와 통신 가능

서비스 클러스터 IP대역은 각 노드의 Pod IP와 겹치지 않아야 한다.



5

DNS?

쿠버네티스 서비스를 위해 DNS레코드를 제공해 주며, Service Deiscovry 기능을 제공하는 CoreDNS가 있다.

쿠버네티스는 클러스터내에서 통신하기 위해 노드 위치와는 상관없이 어디서든 접근할 수 있는 서비스 끝점(Service Endpoint)이 필요합니다.

사용자(또는 Pod)는 서비스 끝점을 통해 다른 컨테이너(Pod)와 통신할 수 있습니다.

이를 위해 사용자는 서비스에 접근하기 위한 끝점의 접속 정보(예를 들면 IP)를 알아야 합니다.

이를 서비스 탐색(Service Discovery)이라 합니다.

쿠버네티스에서는 DNS 기반의 서비스 탐색을 지원하기에 사용자가 매번 새로운 서비스의 IP를 찾을 필요 없이 도메인 주소를 기반으로 서비스에 접근할 수 있습니다.

쿠버네티스에서는 서비스 탐색 기능을 Service 라는 리소스를 이용하여 제공합니다.경, (Docker containerD)

https://coredns.io/



6

쿠버네티스 리소스 ?

오브젝트라고 표현한다.

컨테이너 = 서비스가 올라가는 프로세스

Pod = 컨테이너가 운영되는 초소 실행단위

Replica Set = 컨터이너 집합을 관리하는 컨트롤러

Service Account = 사용자 계정

Node 



7

네임스페이스?

클러스터를 논리적으로 구분해주는것

예를 들어 Front 서비스를  별도의 네임스페이스를 만들어 해당 네임스페이스에서만 서비스한다.

 Kubectl 명령어로 실행할때도 기본으로  디폴트 네임스페이스에 질의하여 답한다.

네임스페이스를 변경하여 Pod를 조회한다.

네임서비스 리소스는 특정 네임 스페이스 안에만 존재한다.

Pod, Deployment, Service 는 네임스페이스 안에 포함 된다.

예)  프론트엔드 네임스페이스, 백엔드 네임스페이스, 모니터링 네임스페이스 




8

Node PersistentVolume , Storage Class는 네임서비스 밖에 클러스터 레벨에서 존재한다.


kubectl get namespace

kubectl get pods


// -n kube-system 네임스페이스에 존재하는 pod 확인

kubectl get pods  -n kube-system


// 모든 네임스페이스에 존재하는 Pod 확인

kubectl get pods  --all-namespaces





<2> Pod 소개


1

Pod안에는  1개 이상의 컨테이너가 구성되어 있다.

따라서, Pod가 지워지면 컨테이너도 지워진다.


Pod는 계란 판이고,  컨테이너는 계란이다.

계란 판위에 계란(컨테이너가 있는것이다.)

Pod는 IP를 가진다. 

컨테이너는 이 IP를 공유한다.

쿠버네티스 Pod는 node ip와는 다른 별도의 IP를 받는다.





2

ec2에 로그인

쿠버네티스 master API 서버 로그인 


도메인이 있는경우

ssh -i ~/.ssh/id_rsa ubuntu@api.k8s.serverchk.com


or

로컬 도메인으로 한 경우

ssh  키를 api 서버로 복사

scp -i ~/.ssh/id_rsa ~/.kube/config ubuntu@api.seo31.cndk.k8s:/tmp/


api 서버로 ssh로 접속

ssh -i ~/.ssh/id_rsa ubuntu@api.seo31.cndk.k8s



3

템플릿 만들기 ?


// 이미지로 myweb.yaml 파일 만들기~  

실제로 Pod를 생성하지 않고 파일만 만든다.   --dry-run=client -o yaml


kubectl run myweb --image nginx --dry-run=client -o yaml > myweb.yaml

cat myweb.yaml


[root@ip-172-20-41-255:~ (k8.serverchk.com:default)]# kubectl run myweb --image nginx --dry-run=client -o yaml


apiVersion: v1

kind: Pod

metadata:

  creationTimestamp: null

  labels:

    run: myweb

  name: myweb

spec:

  containers:

  - image: nginx

    name: myweb

    resources: {}

  dnsPolicy: ClusterFirst

  restartPolicy: Always

status: {}




4

다른 터미널에서 

ssh -i ~/.ssh/id_rsa ubuntu@api.k8s.serverchk.com

watch -d 'kubectl get pod' 



pod 삭제

kubectl delete pod --all



6

YAML 파일 생성 

YAML 파일에 컨테이너가 사용할 포트 TCP 80 설정

apply -f(file)  여러번 실행하더라도 항상 YAML 정의서에 선언된 내용과 동일한 결과 얻는다.


cat << EOF > myweb.yaml

apiVersion: v1

kind: Pod

metadata:

  name: myweb

spec:

  containers:

  - image: nginx:latest

    name: myweb-container

    ports:

    - containerPort: 80

      protocol: TCP

EOF




7

// Pod 배포

kubectl apply -f myweb.yaml && kubectl get pod -w

pod/myweb unchanged

NAME    READY   STATUS    RESTARTS   AGE

myweb   1/1     Running   0          56s


// myweb  현재 상태 1/1

// 요청사항 1



topasvga@cloudshell:~ (ap-seoul-1)$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
myweb   1/1     Running   0          33s




8

다시 실행해 보고 Pod 배포 갯수 확인?

멱등성을 가지므로 숫자는 동일하게 유지된다. 새로 생성 되지는 않는다!

 

kubectl apply -f myweb.yaml

pod/myweb unchanged




9

Pod  IP 정보를 확인

kubectl get pod -o wide



10

Pod 자세히 보기  describe

Pod 이름, Containe 이름 확인, Port 80 확인


kubectl describe pod myweb


// pull image ......  ngix 이미지를 가져옴



11

kubectl get pod -owide

NAME    READY   STATUS    RESTARTS   AGE     IP   NODE     NOMINATED NODE   READINESS GATES

myweb   1/1     Running   0          5m48s   100.98.158.130   ip-172-20-38-144.ap-northeast-1.compute.internal   <none>           <none>



13

Pod(Nginx) 확인

ping 100.98.158.130


14

 curl  100.98.158.129

<!DOCTYPE html>

<html>

<head>

<title>Welcome to nginx!</title>

<style>



15

# Pod 삭제

kubectl delete pod myweb

pod "myweb" deleted





<3>  컨테이너 공유 확인하기


Pod안에 2개의 컨테이너를 사용할수 있다.

Pod단위로 IP가 할당 되므로 컨터이너 2개는 같은 IP를 사용한다.


1

Pod 생성

myweb2 Pod에  2개 컨테이너 만들기

containers:

정보 확인하기

//  kubectl apply -f -      바로 실행하는 옵션이다.

//  containers:   복수이다.  1개 이상 들어간다는 뜻 ~


cat << EOF | kubectl apply -f -

apiVersion: v1

kind: Pod

metadata:

  name: myweb2

spec:

  containers:

  - name: myweb2-nginx

    image: nginx

    ports:

    - containerPort: 80

      protocol: TCP


  - name: myweb2-netshoot

    image: nicolaka/netshoot

    command: ["/bin/bash"]

    args: ["-c", "while true; do sleep 5; curl localhost; done"]

EOF


pod/myweb2 created


while true; do sleep 5; curl localhost; done  

// 5초마다 curl localhost  하는 명령어.



2

2개의 컨테이너가 만들어 진다~

  - name: myweb2-nginx

  - name: myweb2-netshoot


topasvga@cloudshell:~ (ap-seoul-1)$ kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
myweb2   2/2     Running   0          66s
topasvga@cloudshell:~ (ap-seoul-1)$



3

2/2 ?

Pod 내 모든 컨테이너 정상이여야지 Running 됨 

k get pod -owide



4

배포된 워커노드로 로그인

docker ps 로 확인 


docker ps --format "table {{.Image}}\t{{.Status}}\t{{.Names}}" | grep myweb2

컨테이너 2개가 보인다.


5

Pod 상세 정보 확인 ?

컨테이너 2개  보인다 

kubectl describe pod myweb2


  Normal  Scheduled  2m33s  default-scheduler  Successfully assigned default/myweb2 to ip-172-20-46-12.ap-northeast-1.compute.internal

  Normal  Pulling    2m32s  kubelet            Pulling image "nginx"

  Normal  Pulled     2m31s  kubelet            Successfully pulled image "nginx" in 1.394764066s

  Normal  Created    2m30s  kubelet            Created container myweb2-nginx

  Normal  Started    2m30s  kubelet            Started container myweb2-nginx

  Normal  Pulling    2m30s  kubelet            Pulling image "nicolaka/netshoot"

  Normal  Pulled     2m11s  kubelet            Successfully pulled image "nicolaka/netshoot" in 

  Normal  Created    2m10s  kubelet            Created container myweb2-netshoot

  Normal  Started    2m10s  kubelet            Started container myweb2-netshoot




<4>  myweb2-netshoot 컨테이너 내부 들어가서 확인


1

pod를 확인한다.

kubectl get pod -owide


2

pod내 컨테이너를  확인한다.

kubectl describe pod myweb2 


myweb2-nginx

myweb2-netshoot



3

nginx 컨테이너 웹 접속 로그 출력  

kubectl logs -f myweb2 -c myweb2-nginx


// pod내  myweb2-nginx 컨테이너의 로그를 보는것이다.

// 반드시 컨테이너 이름을 적어야 한다. -c myweb2-nginx




4

myweb2-netshoot 컨테이너 내부로 들어가 확인


-c 옵션으로  어떤 컨테이너에 대해 명령어를 수행할지 명시한다.

kubectl exec -it myweb2 -c myweb2-netshoot -- zsh


5

웹 접속 확인?

curl -s localhost |grep nginx


 myweb2  #  curl -s localhost |grep nginx

<title>Welcome to nginx!</title>

<h1>Welcome to nginx!</h1>

<p>If you see this page, the nginx web server is successfully installed and

<a href="http://nginx.org/">nginx.org</a>.<br/>

<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>



4

호스트 이름 확인 ?

cat /etc/hosts


myweb2 #  cat /etc/hosts

# Kubernetes-managed hosts file.

127.0.0.1       localhost

::1     localhost ip6-localhost ip6-loopback

fe00::0 ip6-localnet

fe00::0 ip6-mcastprefix

fe00::1 ip6-allnodes

fe00::2 ip6-allrouters

100.98.158.185  myweb2



5

IP  확인 ?

ip a

ip route show


100.98.158.185  로 IP 확인함.



6

라우팅 확인 ?

ip route show


 myweb2 #  ip route show

default via 169.254.1.1 dev eth0

169.254.1.1 dev eth0 scope link



7

TCP Listen  확인  ?    TCP 80 Listen 

ss -tln



8

컨테이너에서 나가기

exit





<5> myweb2-nginx 컨테이너 내부 들어가서 확인


clear


1

kubectl exec -it myweb2 -c myweb2-nginx -- /bin/bash


2

업데이트와 IP 확인가능한 툴 설치

apt update

apt install -y procps net-tools


3

웹 접속 확인

curl -s localhost |grep nginx


4

호스트 이름 확인

cat /etc/hosts


root@myweb2:/# cat /etc/hosts

# Kubernetes-managed hosts file.

127.0.0.1       localhost

::1     localhost ip6-localhost ip6-loopback

fe00::0 ip6-localnet

fe00::0 ip6-mcastprefix

fe00::1 ip6-allnodes

fe00::2 ip6-allrouters

100.98.158.185  myweb2


5

ip 확인?


ifconfig

root@myweb2:/# ifconfig

// IP가 같다.


nginx와 netshoot  ip 가 같다.

같은 Pod 라서 IP 가 같은 것이다.



6

기존 온프라미스는 IP단위로 관리했었다.

Pod안의 컨테이너는 IP가 같다.


root@myweb2:/# exit


7

Pod 생성과정?

1) kubectl  로  Pod 생성 요청하면

2) API  서버가 받아 etcd 에 요청 정보와 상태 정보를 저장한다.

3) 컨트롤러 매니저가   API 서버를 모니터링 한다. 

4) 컨트롤러 매니저는 생성 요청이 왔는지 확인. 

5) 스케쥴러가 Pod 할당 모니터링

6) 스케쥴러가 노드 1에 할당 요청

7) kubelet 이  API 서버에 미배포 Pod 확인

8) C Rruntime에 Pod 생성요청

9) C Runtime 이 Pod (컨테이너)생성한다.

10) node는 Etcd에  노드1에 pod가 정상 동작중이라고 알려준다.





<6> Pod 삭제


kubectl delete pod myweb2




<7> 정리 


어플리케이션 최소 실행 단위는 Pod

Pod안에는 1개 이상의 컨테이너가 구성되어 있다.

따라서, Pod가 지워지면 안에 있는 모든 컨테이너도 지워진다.

Pod는 IP를 가진다. 컨테이너들은  이 IP를 공유한다.

모두 API서버를 거쳐서 통신 한다 !!!





<8> 다음 과정 


https://brunch.co.kr/@topasvga/1670


감사합니다.


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari