새소식

Kubernetes

[Cloud Compute] Kubernetes 구축하기 - 3. 어플리케이션 배포하기

  • -

지난 글에서 구축까지 진행해보았다.

이제는 어떻게 어플리케이션을 배포하고 통신을 할 수 있는지 알아보자.

 

0. 시작하기에 앞서 명령어 알아보기

지금까지는 그냥 따라왔다면 이제는 명령어에 대해 조금 더 알아봐야한다.

 

구축하는 과정에서 사용한 kubeadm 은 클러스터를 관리하는 명령어다.

이제는 kubectl 이라는 리소스를 관리하는 명령어를 사용할 것이다.

 

1. 리소스 관리

생성명령어 : create, apply

변경명령어 : apply

교체명령어 : replace

삭제명령어 : delete

확인명령어 : describe

kubectl {command}

 

위의 형태로 관리하게 될 것이다.

이 외에도 많은 명령어들이 있으니 --help 플래그로 찾아보고 사용하면 된다.

 

2. 리소스 확인

리소스의 타입은 많지만 주로 사용하고 있는 타입은 다음과 같다. (타입 : ...typeCommand)

 

  1. Node : node, nodes
  2. Pod : pod
  3. Deployment : deployments, deployment, deploy
  4. StatefulSet : statefulsets, statefulset, sts
  5. Service : services, service, svc
  6. Endpoint : endpoints, ep
  7. Ingress : ingress, ing
  8. PersistentVolume : persistentVolume, pv
  9. PersistentVolumeClaim : persistentVolumeClaim, pvc

뭐...이것저것 많지만 지금은 저렇게 타입의 종류가 있다고만 생각하고 넘어가자.

 

3. 명령어와 리소스타입의 조합

kubectl {command} {type} {resourceName}

 

위와 같은 구조로 모든 리소스를 관리할 수 있다.

 

 

1. 노드 상태 확인하기

먼저 노드들의 상태를 보고 어떤 정보를 얻어올 수 있는지 확인해보자.

간단하게 노드 상태를 확인하는 명령어는 지난 글 마지막에 사용해보았다.

그 외에 보다 자세하게 정보를 얻을 수 있는 방법이 있다.

바로 kubectl describe 라는 명령어다.

 

kubectl describe nodes

 

kubernetes에 배포된 자원에 대해 상세정보를 확인할 수 있는 명령어다.

지금같이 리소스 타입만 명시하면 해당 리소스 타입에 존재하는 리소스들의 정보를 나열하게 된다.

실행결과는 길어서 사진보다는 텍스트로 적어보았다.

더보기
ubuntu@ip-172-31-33-228:~$ kubectl describe node
Name:               ip-172-31-33-228
Roles:              control-plane
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=ip-172-31-33-228
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/control-plane=
                    node.kubernetes.io/exclude-from-external-load-balancers=
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Sun, 19 Feb 2023 08:49:41 +0000
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
                    node-role.kubernetes.io/master:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  ip-172-31-33-228
  AcquireTime:     <unset>
  RenewTime:       Sun, 26 Feb 2023 06:31:11 +0000
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Sun, 19 Feb 2023 09:13:09 +0000   Sun, 19 Feb 2023 09:13:09 +0000   CiliumIsUp                   Cilium is running on this node
  MemoryPressure       False   Sun, 26 Feb 2023 06:27:40 +0000   Sun, 19 Feb 2023 08:49:40 +0000   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Sun, 26 Feb 2023 06:27:40 +0000   Sun, 19 Feb 2023 08:49:40 +0000   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Sun, 26 Feb 2023 06:27:40 +0000   Sun, 19 Feb 2023 08:49:40 +0000   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Sun, 26 Feb 2023 06:27:40 +0000   Sun, 19 Feb 2023 09:13:05 +0000   KubeletReady                 kubelet is posting ready status. AppArmor enabled
Addresses:
  InternalIP:  172.31.33.228
  Hostname:    ip-172-31-33-228
Capacity:
  cpu:                2
  ephemeral-storage:  16069568Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1992300Ki
  pods:               110
Allocatable:
  cpu:                2
  ephemeral-storage:  14809713845
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1889900Ki
  pods:               110
System Info:
  Machine ID:                 ec2da57dce2b8c91dcc9a7bf094726bc
  System UUID:                ec2da57d-ce2b-8c91-dcc9-a7bf094726bc
  Boot ID:                    a06b43db-2ae3-4553-a9a4-ba22e719c816
  Kernel Version:             5.4.0-1094-aws
  OS Image:                   Ubuntu 18.04.6 LTS
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.6.18
  Kubelet Version:            v1.24.1
  Kube-Proxy Version:         v1.24.1
PodCIDR:                      192.168.0.0/24
PodCIDRs:                     192.168.0.0/24
Non-terminated Pods:          (9 in total)
  Namespace                   Name                                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                        ------------  ----------  ---------------  -------------  ---
  kube-system                 cilium-cwq9w                                100m (5%)     0 (0%)      100Mi (5%)       0 (0%)         6d21h
  kube-system                 cilium-operator-74c4bc768c-4d9k6            0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d21h
  kube-system                 coredns-6d4b75cb6d-jhjhj                    100m (5%)     0 (0%)      70Mi (3%)        170Mi (9%)     6d21h
  kube-system                 coredns-6d4b75cb6d-km7b5                    100m (5%)     0 (0%)      70Mi (3%)        170Mi (9%)     6d21h
  kube-system                 etcd-ip-172-31-33-228                       100m (5%)     0 (0%)      100Mi (5%)       0 (0%)         6d21h
  kube-system                 kube-apiserver-ip-172-31-33-228             250m (12%)    0 (0%)      0 (0%)           0 (0%)         6d21h
  kube-system                 kube-controller-manager-ip-172-31-33-228    200m (10%)    0 (0%)      0 (0%)           0 (0%)         6d21h
  kube-system                 kube-proxy-s4hnb                            0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d21h
  kube-system                 kube-scheduler-ip-172-31-33-228             100m (5%)     0 (0%)      0 (0%)           0 (0%)         6d21h
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                950m (47%)   0 (0%)
  memory             340Mi (18%)  340Mi (18%)
  ephemeral-storage  0 (0%)       0 (0%)
  hugepages-1Gi      0 (0%)       0 (0%)
  hugepages-2Mi      0 (0%)       0 (0%)
Events:              <none>



Name:               ip-172-31-39-2
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=ip-172-31-39-2
                    kubernetes.io/os=linux
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Sun, 19 Feb 2023 09:24:38 +0000
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  ip-172-31-39-2
  AcquireTime:     <unset>
  RenewTime:       Sun, 26 Feb 2023 06:31:11 +0000
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Sun, 19 Feb 2023 09:25:06 +0000   Sun, 19 Feb 2023 09:25:06 +0000   CiliumIsUp                   Cilium is running on this node
  MemoryPressure       False   Sun, 26 Feb 2023 06:30:19 +0000   Sun, 19 Feb 2023 09:24:38 +0000   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Sun, 26 Feb 2023 06:30:19 +0000   Sun, 19 Feb 2023 09:24:38 +0000   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Sun, 26 Feb 2023 06:30:19 +0000   Sun, 19 Feb 2023 09:24:38 +0000   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Sun, 26 Feb 2023 06:30:19 +0000   Sun, 19 Feb 2023 09:25:09 +0000   KubeletReady                 kubelet is posting ready status. AppArmor enabled
Addresses:
  InternalIP:  172.31.39.2
  Hostname:    ip-172-31-39-2
Capacity:
  cpu:                2
  ephemeral-storage:  16069568Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1992300Ki
  pods:               110
Allocatable:
  cpu:                2
  ephemeral-storage:  14809713845
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             1889900Ki
  pods:               110
System Info:
  Machine ID:                 ec2c85595275e76883ee72f9c77b92a4
  System UUID:                ec2c8559-5275-e768-83ee-72f9c77b92a4
  Boot ID:                    f40c1872-b6a2-42f4-932b-a094211b8365
  Kernel Version:             5.4.0-1094-aws
  OS Image:                   Ubuntu 18.04.6 LTS
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.6.18
  Kubelet Version:            v1.24.1
  Kube-Proxy Version:         v1.24.1
PodCIDR:                      192.168.1.0/24
PodCIDRs:                     192.168.1.0/24
Non-terminated Pods:          (2 in total)
  Namespace                   Name                CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                ------------  ----------  ---------------  -------------  ---
  kube-system                 cilium-wtwc4        100m (5%)     0 (0%)      100Mi (5%)       0 (0%)         6d21h
  kube-system                 kube-proxy-r7v4s    0 (0%)        0 (0%)      0 (0%)           0 (0%)         6d21h
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                100m (5%)   0 (0%)
  memory             100Mi (5%)  0 (0%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
Events:              <none>

 

클러스터를 구축하는데 사용된 노드 2개에 대한 상세정보가 모두 나와서 굉장히 길어졌다.

위 결과창에서 가장 눈여겨봐야 하는 부분은 크게 2가지로 Conditions Allocated resources 이다.

Conditions 는 해당 노드가 어플리케이션이 배포될 수 있는지 상태를 알려주는 부분이다.

공식문서에 따라 다음과 같으니 참고하자

 

노드 컨디션 설명
Ready 노드가 상태 양호하며 파드를 수용할 준비가 되어 있는 경우 True, 노드의 상태가 불량하여 파드를 수용하지 못할 경우 False, 그리고 노드 컨트롤러가 마지막 node-monitor-grace-period (기본값 40 기간 동안 노드로부터 응답을 받지 못한 경우) Unknown
DiskPressure 디스크 사이즈 상에 압박이 있는 경우, 즉 디스크 용량이 넉넉치 않은 경우 True, 반대의 경우 False
MemoryPressure 노드 메모리 상에 압박이 있는 경우, 즉 노드 메모리가 넉넉치 않은 경우 True, 반대의 경우 False
PIDPressure 프로세스 상에 압박이 있는 경우, 즉 노드 상에 많은 프로세스들이 존재하는 경우 True, 반대의 경우 False
NetworkUnavailable 노드에 대해 네트워크가 올바르게 구성되지 않은 경우 True, 반대의 경우 False

 

Allocated resources 는 어플리케이션 실행에 필요한 하드웨어 자원의 사용량으로 얼마나 남았는지 계산을 해야 앞으로 배포하려는 어플리케이션의 필요 하드웨어 자원을 맞출 수 있다.

잔여 리소스보다 어플리케이션의 리소스가 커도 배포 시행은 가능하다.

단지, Pending상태로 배포가능한 노드를 찾는데 멈춰서 정상적으로 배포되지 못할 뿐이다.

 

잔여 하드웨어 리소스를 잘 계산해서 어플리케이션의 필요 하드웨어 리소스를 정하는 것이 중요하다

 

 

물론 처음에는 얼마나 차지하는지 알 수 없을 수 있으니, 배포해보고 필요리소스를 맞춰보면 된다.

필요리소스를 지정하는 것은 뒤에서 알아보자.

 

 

 

2. 네임스페이스

kubernetes에는 namespace라는 개념이 있다.

리소스 그룹을 격리하여 사용할 수 있는데 쉽게 말해 아파트 단지에 여러개의 아파트가 존재하는 것이다.

1동의 101호와 2동의 101호가 다르듯 같은 클러스터 내에서 공간을 분리시키는 것이다.

초기화된 상태에서 namespace 목록을 살펴보자. 

 

kubectl get namespaces

 

default, kube-system, kube-public, kube-node-lease 4개가 보였다. 

 

각각의 namespace에 속한 pod를 보려면 다음 명령어를 실행해보자. {namespace} 를 원하는 namespace의 이름으로 바꿔서 실행해보면 된다.

kubectl get pod -n {namespace}

 

 

네트워크 플러그인인 cilium과 내부 dns를 위한 coredns, 각종 설정들이 저장되는 etcd 등 다양한 pod들이 보인다.

이렇듯 namespace별로 리소스배포가 가능하다.

 

특정 namespace에 있는 리소스를 관리하려고 한다면 아래와 같은 명령어구조를 갖게 된다.

kubectl {command} {type} {resourceName} -n {namespace}

 

 

3. 간단하게 어플리케이션 배포해보기

일단 클러스터가 막 초기화된 상태이기 때문에 잔여리소스도 넘쳐나니 배포에는 아무 문제가 없다.

공식문서에 예제로도 나오는 busybox를 배포하며 그 과정을 살펴보자.

 

busybox.yaml 이라는 이름으로 파일을 만들어보았다.

apiVersion: apps/v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    command: ['sh', '-c', 'sleep 3600']

 

배포하기 위한 yaml에 대한 설명은 더 잘되어있는 블로그들이 많다.

여기서는 실전적인 내용이니 간단하게만 언급하고 넘어가려고 한다.

 

metadata.name=busybox 로  Pod의 이름을 "busybox"라고 지어줬다.

containers로 여러개의 컨테이너가 들어갈 수 있지만 단일 컨테이너만 들어가있다.

spec.containers[0].name=busybox 로 0번째 컨테이너의 이름을 "busybox"로 지어줬다.

spec.containers[0].image=busybox 로 busybox의 최신버전 image를 사용하는 것을 명시했다.

spec.containers[0].command=[~~~] 로 컨테이너가 최초에 실행되며 실행할 명령어를 지정했다. 

해당 command가 없이는 busybox 컨테이너가 바로 종료되기 때문에 sleep 3600으로 살아있도록 한것이다.

 

이제 설정을 했으니 아래 명령어로 배포해보자.

kubectl create -f busybox.yaml

 

create 커맨드로 리소스를 생성할 것을 지정했다.

-f 플래그를 이용해서 파일을 이용해 리소스를 생성할 것을 명시했으며 파일명은 busybox.yaml 이다.

 

실행하였다면 다음 명령어로 확인해보자

kubectl get pod

 

위에 namespace에서 했던 명령어와는 다르게 -n 플래그가 없는데 없을 때는 기본 namespace=default 로 실행하게 된다.

 

Test라는 디렉토리를 생성해서 그 안에서 실행된 결과

 

성공적으로 배포가 되었다!

이제 저 busybox라는 이름의 Pod는 command에서 지정한 3600초 동안 sleep상태로 유지되며 시간이 되면 종료되며 에러를 뱉게 될것이다.

 

기본적으로 Pod는 내부의 모든 컨테이너가 실행중일 때 Running 상태로 존재한다.

그런데 sleep 3600 이 시간되어 종료되면 컨테이너가 종료되기 때문에 에러가 발생하는 것이다.

 

4. Master노드에 배포가능하게 만들기

기본적으로 Master노드는 배포가 안되게 막혀있다.

무엇이 막고 있는지 살펴보기 위해 다음 명령어를 실행해보자.

 

kubectl describe nodes

 

전체 Node를 확인하는 명령어라 길게 나오긴 하는데 kubectl get nodes 로 node를 확인한 후,

kubectl describe node {nodeName} 으로 단일 node에 대해서 확인하는게 깔끔하다.

 

일단 나온 정보중에 이런 부분이 있다.

Taints:             node-role.kubernetes.io/master:NoSchedule
                    node-role.kubernetes.io/control-plane:NoSchedule

Taints 라는 속성은 Node에만 적용되는 속성으로  파드를 노드에서 멀어지게 하거나 실행되지 않도록 사용된다.

이런 제한을 통과하기 위해 tolerations 라는 Pod용 속성 또한 존재한다.

 

우리는 제한적인 클러스터 규모를 사용했기 때문에 Master노드 또한 Pod가 배포될 수 있도록 Taints를 제거할 것이다.

 

kubectl taint nodes {nodeName} node-role.kubernetes.io/control-plane:NoSchedule-
kubectl taint nodes {nodeName} node-role.kubernetes.io/master:NoSchedule-

 

 

Taints 항목이 <none>으로 변한 것을 확인할 수 있다.

이제 Master노드 또한 Pod가 배포될 수 있는 상태가 되었다.

 

 

다음은 간단하게 html과 nginx로 서버를 만들어보고 외부통신을 받아보는 것을 진행해보자.

 

이전글

 

[Cloud Compute] Kubernetes 구축하기 - 2. 클러스터 구축

처음 쿠버네티스를 도입하며 가장 애먹었던 부분이 이 구축파트다. 분명히 이전에 했을 때는 잘됐는데 초기화하고 다시 해보니 안되는 경우도 많았다. 특히나 네트워크 플러그인....하... 수없이

bateaux.tistory.com

 

다음글

 

[Cloud Compute] Kubernetes 구축하기 - 4. nginx 서버 배포하기

지난 글에서 간단하게 어플리케이션을 배포하는 과정을 진행해보았다. 이번에는 nginx와 html을 배포해서 간단한 웹서버를 구축해보려고 한다. 어떻게 보면 지난글보다 이번글이 더 중요할 수 있

bateaux.tistory.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.