ETC

[CKA] Pod 생성 하기

코린이s 2023. 8. 11. 20:16
728x90

kubectl 기본 사용방법을 배워 보도록 하자!

우선 kubectl 은 control plane 에게 원하는것을 요청할때 사용하는 도구이다.

약어를 입력하여 호출할수 있는데 아래와 같이 지원하는 약어를 확인 할 수 있으며 예를 들어 pods 라고 적어야하나 po 만 적어도 동작한다는 의미이다.

root@master:~# kubectl api-resources
pods   po       v1   true         Pod
..

run 은 파드를 생성하는 명령어로 nginx 파드를 생성해보자

root@master:~# kubectl run webserver --image=nginx:1.14 --port 80
pod/webserver created

파드가 생성중이며 기다리면서 상세적으로 어떤 동작을 하고 있는지 확인하기 위해

root@master:~# kubectl get pod
NAME        READY   STATUS              RESTARTS   AGE
webserver   0/1     ContainerCreating   0          11s

아래와 같이 describe 를 사용하여 파드 이벤트 정보를 보면 현재는 시작 되었다고 나온다.

root@master:~# kubectl describe pod webserver
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  40s   default-scheduler  Successfully assigned default/webserver to node01.corin.com
  Normal  Pulling    39s   kubelet            Pulling image "nginx:1.14"
  Normal  Pulled     30s   kubelet            Successfully pulled image "nginx:1.14" in 9.275423353s (9.275471856s including waiting)
  Normal  Created    29s   kubelet            Created container webserver
  Normal  Started    29s   kubelet            Started container webserver

다시 확인해보면 정상적으로 Running 상태로 파드 정보가 나온다.

root@master:~# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
webserver   1/1     Running   0          58s

파드 정보를 더욱 확장해서 보려면 -o wide 를 추가로 입력하면 된다.

root@master:~# kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP          NODE               NOMINATED NODE   READINESS GATES
webserver   1/1     Running   0          69s   10.47.0.1   node01.corin.com   <none>           <none>

해당 파드의 IP 로 curl 명령어를 이용하여 호출해보면 정상적으로 nginx 기본 화면이 나온다.

root@master:~# curl 10.47.0.1
...
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documen
..

만약 브라우저 같이 화면을 보고 싶다면 아래와 같이 elinks 를 설치하고 호출해보면

root@master:~# apt-get update
root@master:~# apt-get install elinks
root@master:~# elinks 10.47.0.1

아래와 같이 화면이 이쁘게 출력 된다. 만약 나가고 싶다면 ESC > File > EXIT 커서 이동 및 엔터 하면 나가진다.

run 의 경우 파드 하나 실행 했다면 파드 여러개를 실행하기 위해 create deployment를 써보자!

예제로 httpd 이미지를 가지고 3개의 파드를 띄워보자! 

root@master:~# kubectl create deployment httpd --image=httpd:latest --replicas=3
deployment.apps/httpd created

파드 정보를 보면 3개의 httpd 의 파드가 생성 되었다.

root@master:~# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
httpd-69545969bd-47lt2   0/1     ContainerCreating   0          10s
httpd-69545969bd-6d67v   0/1     ContainerCreating   0          10s
httpd-69545969bd-pjbt5   0/1     ContainerCreating   0          10s

상세 정보를 아래와 같이 확인하면 scale up 3개가 된것을 볼 수 있으며

root@master:~#kubectl describe deployment httpd
..
Events:
  Type     Reason                 Age   From                   Message
  ----     ------                 ----  ----                   -------
  Warning  ReplicaSetCreateError  57s   deployment-controller  Failed to create new replica set "httpd-69545969bd": Unauthorized
  Normal   ScalingReplicaSet      57s   deployment-controller  Scaled up replica set httpd-69545969bd to 3

다시 확인해보면 정상적으로 Running 상태임을 알 수 있다.

root@master:~# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
httpd-69545969bd-47lt2   1/1     Running   0          58s
httpd-69545969bd-6d67v   1/1     Running   0          58s
httpd-69545969bd-pjbt5   1/1     Running   0          58s

실행중인 파드의 정보를 yaml 형태로 보려면 아래와 같이 -o yaml 을 붙여주면 되며

root@master:~# kubectl get pod webserver -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2023-08-11T10:35:22Z"
  labels:
    run: webserver
  name: webserver
  namespace: default
  resourceVersion: "3641"
  uid: a499e291-9966-4f0a-a99b-da881613aa88
spec:
  containers:
  - image: nginx:1.14
    imagePullPolicy: IfN
    ..
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2023-08-11T10:35:22Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2023-08-1

json 형태로도 확인 가능하다.

root@master:~# kubectl get pod webserver -o json
{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "creationTimestamp": "2023-08-11T10:35:22Z",
        "labels": {
            "run": "webserver"
        },
        "name": "webserver",
        ..

이제 해당 파드안에 접속하여 index.html 파일을 수정해보자!

아래와 같이 exec 를 입력하며 /bin/bash로 들어간다는 의미로 수정후에 파드에서 나가서 curl 를 호출하면 정상적으로 변경한 내용이 출력된다.

root@master:~# kubectl exec -it webserver -- /bin/bash
root@webserver:/# cd /usr/share/nginx/html/
root@webserver:/#
root@webserver:/usr/share/nginx/html# echo "CORIN HELLO" > index.html
root@webserver:/usr/share/nginx/html# cat index.html
CORIN HELLO
root@webserver:/usr/share/nginx/html# exit
exit
root@master:~# curl 10.47.0.1
CORIN HELLO

logs 를 이용하면 로그 확인이 가능하다.

root@master:~# kubectl logs webserver
10.32.0.1 - - [11/Aug/2023:10:37:17 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.32.0.1 - - [11/Aug/2023:10:39:12 +0000] "GET / HTTP/1.1" 200 612 "-" "ELinks/0.12pre6 (textmode; Linux 4.15.0-142-generic x86_64; 80x23-2)" "-"
10.32.0.1 - - [11/Aug/2023:10:48:21 +0000] "GET / HTTP/1.1" 200 12 "-" "curl/7.47.0" "-"

만약 로컬 (Master 노드) IP:PORT 호출했을시 파드IP:PORT로 호출하고 싶다면 포트 포워드 기능을 사용해보자!

8080포트 호출시 80으로 보낸다는 의미이며

root@master:~# kubectl port-forward webserver 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080

새창을 다시 켜서 Master 노드에서 8080포트로 호출시 정상적으로 파드와 통신된다.

root@master:~# curl localhost:8080
CORIN HELLO

생성한 deployment를 확인시에는 아래 명령어를 이용하며

root@master:~# kubectl get deployments.apps
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
httpd   3/3     3            3           9m15s

우리는 실행중인 파드의 spec.replicas를 edit 를 이용해 2로 수정한다. edit는 동작중인 api resources 수정시 사용한다.

root@master:~# kubectl edit deployments.apps
spec:
  progressDeadlineSeconds: 600
  replicas: 2
:wq!
deployment.apps/httpd edited

정상적으로 변경 되었다는 로그가 나오며 실제 확인시 2개로 변경 되었다.

root@master:~# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
httpd-69545969bd-47lt2   1/1     Running   0          10s
httpd-69545969bd-6d67v   1/1     Running   0          10s

이제 원하는 이미지의 파드 생성을 명령어가 아닌 yaml 파일을 이용하여 해보자!

아래와 같이 yaml 파일을 생성할 수 있으며

root@master:~# kubectl run webserver --image=nginx:1.14 --port 80 --dry-run -o yaml > nginx.yaml

확인해보면 아래와 같이 만들어져있다.

root@master:~# vi nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: nginx:1.14
    name: webserver
    ports:
    - containerPort: 80
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

여기서 필요없는 부분을 삭제하고 저장한뒤

root@master:~# vi nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: nginx:1.14
    name: webserver
    ports:
    - containerPort: 80
:wq!

기존에 떠있던 모든 파드, deployment를 삭제하고

root@master:~# kubectl delete pod webserver
pod "webserver" deleted
root@master:~# kubectl delete deployments.apps httpd
deployment.apps "httpd" deleted

yaml 파일로 파드를 실행시키기 위해서 아래와 같이 -f 를 이용하며

파드 조회시 정상적으로 하나 떠있는것을 볼 수 있다.

root@master:~# kubectl create -f nginx.yaml
pod/webserver created
root@master:~# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
webserver   1/1     Running   0          10s

여기서 생각해볼 수 있다. yaml 파일 하나로 여러 컨테이너를 띄울수 있을까? 정답은 Yes 이다.

그 구조를 multi-container 라고 하며 아래와 같이 spec.containers 부분에 여러 컨테이너 정의가 가능하며 yaml 파일을 수정해보자!

# pods.yaml

apiVersion: v1
kind: Pod
metadata:
  name: multipod
spec:
  containers:
  - name: my-nginx
    image: nginx
    ports:
    - containerPort: 80
  - name: my-centos
    image: centos
    command:
    - sleep
    - "10000"

이제 해당 yaml 파일 기반으로 컨테이너를 생성해보자!

[node1 ~]$ kubectl create -f pods.yaml 
pod/multipod created

Creating 되면서 Ready 부분을 보면 파드 하나에 2개의 컨테이너가 정상적으로 기동 되었다는것을 볼 수 있다.

[node1 ~]$ kubectl get pods
NAME       READY   STATUS              RESTARTS   AGE
multipod   0/2     ContainerCreating   0          13s
[node1 ~]$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
multipod   2/2     Running   0          19s

파드가 같기에 IP를 하나 쓰는것이며 그렇게 되면 각 컨테이너를 어떻게 선택해서 들어갈까?

아래와 같이 -c 옵션으로 컨테이너명을 입력하면 된다!

index.html 을 수정하며

[node1 ~]$ kubectl exec multipod -c my-nginx -it -- /bin/bash
root@multipod:/# echo "CORIN" > /usr/share/nginx/html/index.html 
root@multipod:/# cat /usr/share/nginx/html/index.html
CORIN
root@multipod:/# exit

nginx 호출(80 port)해보면 정상적으로 변경된것을 볼 수 있다.

[node1 ~]$ kubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
multipod   2/2     Running   0          13m   10.5.1.2   node2   <none>           <none>
[node1 ~]$ curl 10.5.1.2
CORIN

이번에는 다른 컨테이너인 my-centos 에 접속한다.

[node1 ~]$ kubectl exec multipod -c my-centos -it -- /bin/bash
[root@multipod /]#

내부 host 정보를 보면 본인 파드 명으로 host 가 잡혀 있으며 파드명으로 curl 호출하면 같은 IP의 80포트로 호출하게 되니 다른 컨테이너 nginx를 호출한것이 되어 index.html 파일 내용이 출력 되게 된다.

[root@multipod /]# 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
10.5.1.2        multipod
[root@multipod /]# curl multipod
CORIN

이렇게 multi-container 를 사용하게 되면 파드안에 여러 컨테이너를 포함할 수 있다.

끝!

# 참고사항

멀티 컨테이너 Pod 실행 패턴

종류 내용
Sidecar 하나의 컨테이너로는 움직일 수 없고 다른 컨테이너가 있어야 동작할 수 있는 형태 
Adapter 외부 요청을 내부로 전달하기 위한 컨테이너(=어뎁터 역할)가 반드시 필요할때
Ambassador(엠버셔더) 안에 있는 데이터를 밖으로 전달하기 위한 컨테이너

 

728x90