[CKA] Pod 생성 하기
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(엠버셔더) | 안에 있는 데이터를 밖으로 전달하기 위한 컨테이너 |