728x90

deployment, replicaset, pod


디플로이먼트 생성

  • 디플로이먼트 생성
vagrant@kube-master1:~/test$ kubectl create deployment myapp --image=c1t1d0s7/myweb

 

 

  • 리소스 확인 (디플로이먼트, 리플리카셋, 파드)
vagrant@kube-master1:~/test$ kubectl get deployments,replicasets,pods
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myapp   1/1     1            1           18h

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/myapp-79877ddf67   1         1         1       18h

NAME                         READY   STATUS    RESTARTS   AGE
pod/myapp-79877ddf67-f9bp6   1/1     Running   1          18h

 

  • 리소스의 자세한 정보 확인
vagrant@kube-master1:~/test$ kubectl get deployments,replicasets,pods -o wide
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                      SELECTOR
deployment.apps/myapp   1/1     1            1           18h   go-myweb     ghcr.io/c1t1d0s7/go-myweb   app=myapp

NAME                               DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                      SELECTOR
replicaset.apps/myapp-79877ddf67   1         1         1       18h   go-myweb     ghcr.io/c1t1d0s7/go-myweb   app=myapp,pod-template-hash=79877ddf67

NAME                         READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
pod/myapp-79877ddf67-f9bp6   1/1     Running   1          18h   10.233.101.21   kube-node1   <none>           <none>

 

 

  • 내부에서 접속 확인
vagrant@kube-master1:~/test$ curl 10.233.101.21:8080
Hello World!
myapp-79877ddf67-f9bp6

 

  • 외부에서 접속 불가
vagrant@kube-master1:~/test$ curl 192.168.56.11
curl: (7) Failed to connect to 192.168.56.11 port 80: Connection refused

 

서비스 생성

 

  • 서비스 생성
vagrant@kube-master1:~/test$ kubectl expose deployment myapp --port=80 --target-port=8080 --name=myapp-svc --type=LoadBalancer

 

  • 생성된 서비스 확인
vagrant@kube-master1:~/test$ kubectl get all
NAME                         READY   STATUS    RESTARTS   AGE
pod/myapp-79877ddf67-f9bp6   1/1     Running   1          18h

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP      10.233.0.1      <none>        443/TCP        19h
service/myapp-svc    LoadBalancer   10.233.41.197   <pending>     80:30177/TCP   18h

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myapp   1/1     1            1           18h

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/myapp-79877ddf67   1         1         1       18h

 

  • 외부에서 접속 확인
vagrant@kube-master1:~/test$ curl 192.168.56.11:30177
Hello World!
myapp-79877ddf67-f9bp6

 

파드 스케일

  • 파드 스케일
vagrant@kube-master1:~/test$ kubectl scale deployment myapp --replicas=3
deployment.apps/myapp scaled

 

 

  • 파드 스케일 결과 확인
vagrant@kube-master1:~/test$ kubectl get all
NAME                         READY   STATUS    RESTARTS   AGE
pod/myapp-79877ddf67-f9bp6   1/1     Running   1          18h
pod/myapp-79877ddf67-j2h64   1/1     Running   0          7s
pod/myapp-79877ddf67-v4q8j   1/1     Running   0          7s

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP      10.233.0.1      <none>        443/TCP        19h
service/myapp-svc    LoadBalancer   10.233.41.197   <pending>     80:30177/TCP   18h

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myapp   3/3     3            3           18h

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/myapp-79877ddf67   3         3         3       18h

 

  • 파드가 삭제되어도 3개를 유지하기 위해서 바로 생성됨
vagrant@kube-master1:~/test$ kubectl delete pods myapp-79877ddf67-j2h64 &
[1] 23693
vagrant@kube-master1:~/test$ kubectl get all
NAME                         READY   STATUS        RESTARTS   AGE
pod/myapp-79877ddf67-5kxt4   1/1     Running       0          6s
pod/myapp-79877ddf67-gqj59   1/1     Running       0          32s
pod/myapp-79877ddf67-j2h64   0/1     Terminating   0          3m3s
pod/myapp-79877ddf67-v4q8j   1/1     Running       0          3m3s

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP      10.233.0.1      <none>        443/TCP        19h
service/myapp-svc    LoadBalancer   10.233.41.197   <pending>     80:30177/TCP   18h

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/myapp   3/3     3            3           18h

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/myapp-79877ddf67   3         3         3       18h

 

 

모든 리소스 삭제

  • 디플로이먼트, 서비스 삭제
vagrant@kube-master1:~/test$ kubectl delete deployments.apps myapp
deployment.apps "myapp" deleted

vagrant@kube-master1:~/test$ kubectl delete service myapp-svc
service "myapp-svc" deleted

vagrant@kube-master1:~/test$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.233.0.1   <none>        443/TCP   19h
728x90
728x90

네임스페이스


namespace: 네임스페이스

네임스페이스란

  • 오브젝트를 논리적으로 분리할 수 있는 논리적 파티션

 

네임스페이스

  • 기본 네임스페이스
항목 설명
default 기본 네임스페이스
kube-node-lease - 쿠버네티스 노드의 가용성을 체크하기 위한 네임스페이스
- 해당 네임스페이스에는 하트비트를 위한 리스 오브젝트가 있음
- 쿠버네티스 1.14 이상
kube-public - 모든 사용자(인증받지 않은 사용자 포함)가 읽기 권한으로 접근할 수 있음
- 관례적으로 만들어져 있찌만 아무 리소스도 없고, 꼭 사용해야하는 것은 아님
kube-system 쿠버네티스 클러스터의 핵심 리소스 배치

 

  • 추가 네임스페이스
항목 설명
ingress-nginx 쿠버네티스 인그레스 리소스를 위한 Nginx 인그레스 컨트롤러 배치
rook-ceph Rook Ceph 스토리지 관련 리소스 배치

 

네임스페이스 사용

  • 기본 네임스페이스 확인
vagrant@kube-master1:~$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   23h
ingress-nginx     Active   23h
kube-node-lease   Active   23h
kube-public       Active   23h
kube-system       Active   23h

 

  • 네임스페이스 생성
vagrant@kube-master1:~/test$ vi testnamespace.yml

 

 

  • yml 파일을 이용하여 네임스페이스 생성
vagrant@kube-master1:~/test$ kubectl create -f testnamespace.yml
namespace/test-ns created

 

  • 네임스페이스 목록 출력
  • 생성된 test-ns 네임스페이스 확인
vagrant@kube-master1:~/test$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   23h
ingress-nginx     Active   23h
kube-node-lease   Active   23h
kube-public       Active   23h
kube-system       Active   23h
test-ns           Active   34s

 

  • 파드는 같은 이름으로 중복 생성되지 않음
  • 현재 default 네임스페이스에서 testapp-pod가 실행되고 있음
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod.yml
Error from server (AlreadyExists): error when creating "testapp-pod.yml": pods "testapp-pod" already exists

 

  • test-ns 네임스페이스에 testapp-pod 파드 생성
  • 네임스페이스는 논리적으로 격리된 공간이므로 default 네임스페이스에 생성된 파드의 이름과 동일해도 파드가 생성됨 
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod.yml -n test-ns
pod/testapp-pod created

 

 

  • test-ns 네임스페이스에서 실행 중인 testapp-pod 파드 확인
vagrant@kube-master1:~/test$ kubectl get pods -n test-ns
NAME          READY   STATUS    RESTARTS   AGE
testapp-pod   1/1     Running   0          12s

vagrant@kube-master1:~/test$ kubectl get pods testapp-pod -n test-ns1 -o yaml | grep -i namespace
  namespace: test-ns1
  selfLink: /api/v1/namespaces/test-ns1/pods/testapp-pod
  
vagrant@kube-master1:~/test$ kubectl get pods testapp-pod-ns -n test-ns2 -o yaml |
 grep -i namespace
  namespace: test-ns2
  selfLink: /api/v1/namespaces/test-ns2/pods/testapp-pod-ns

 


 

실습


 

namespace 생성

  • yml 파일을 이용하여 myns1 네임스페이스 생성
vagrant@kube-master1:~/exam$ vi exam-ns.yml
apiVersion: v1
kind: Namespace
metadata:
  name: myns1
  
vagrant@kube-master1:~/exam$ kubectl create -f exam-ns.yml
namespace/myns1 created

 

  • 명령을 이용한 myns2 네임스페이스 생성
vagrant@kube-master1:~/exam$ kubectl create namespace myns2
namespace/myns2 created

 

  • 네임스페이스 생성 확인
vagrant@kube-master1:~/exam$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   24h
ingress-nginx     Active   24h
kube-node-lease   Active   24h
kube-public       Active   24h
kube-system       Active   24h
myns1             Active   11m
myns2             Active   6m33s

 

pod 생성

  • default namespace에 exam-pod 생성
vagrant@kube-master1:~/exam$ kubectl create -f exam-pod.yml

 

  • myns1 namespace에 exam-pod 생성
  • 조건: 명령어에 -n 옵션 부여
vagrant@kube-master1:~/exam$ kubectl create -f exam-pod.yml -n myns1
pod/exam-pod created

 

 

  • myns2 namespace에 exam-pod 생성
  • 조건: yml 파일을 이용하여 파드 생성
vagrant@kube-master1:~/exam$ vi exam-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: exam-pod
  namespace: myns2
spec:
  containers:
  - name: default
    image: c1t1d0s7/myweb
    ports:
    - containerPort: 8081
      protocol: TCP
      
vagrant@kube-master1:~/exam$ kubectl create -f exam-pod.yml
pod/exam-pod created

 

 

실행 중인 파드 정보 확인

  • 네임스페이스: default
vagrant@kube-master1:~/exam$ kubectl get pods -n default
NAME       READY   STATUS    RESTARTS   AGE
exam-pod   1/1     Running   0          9s

 

  • 네임스페이스: myns1
vagrant@kube-master1:~/exam$ kubectl get pods -n myns1
NAME       READY   STATUS    RESTARTS   AGE
exam-pod   1/1     Running   0          7m8s

 

  • 네임스페이스: myns2
vagrant@kube-master1:~/exam$ kubectl get pods -n myns2
NAME       READY   STATUS              RESTARTS   AGE
exam-pod   0/1     ContainerCreating   0          5s

 

리소스 삭제

  • myns2
  • 명령을 이용해 myns2 네임스페이스 삭제
  • & 옵션을 이용해 네임스페이스와 파드가 삭제되는 동안 다른 명령을 수행할 수 있도록 함
  • & 옵션을 사용하지 않으면 리소스가 삭제되는 동안 다른 작업 불가
vagrant@kube-master1:~/exam$ kubectl delete namespaces myns2 &
[1] 11067
vagrant@kube-master1:~/exam$ namespace "myns2" deleted

 

  • myns1
  • myns1 네임스페이스를 생성한 yml 파일을 이용하여 삭제
vagrant@kube-master1:~/exam$ kubectl delete -f exam-ns.yml
namespace "myns1" deleted

 

  • default
  • exam-pod.yml 파일에서 namespace: myns2 부분을 지우고 저장
vagrant@kube-master1:~/exam$ vi exam-pod.yml

vagrant@kube-master1:~/exam$ kubectl get pods
No resources found in default namespace.
728x90
728x90

label


 

label: 레이블

label이란

  • 레이블은 쿠버네티스 클러스터의 모든 오브젝트(파드 포함)에 키/값 쌍으로 리소스를 식별하고 속성을 지정하는 데 사용
  • 오브젝트 갯수가 많아진다면 오브젝트를 식별하는 데 매우 어려울 수 있으며, 오브젝트의 적절한 레이블을 부여하여 성격을 정의하고 검색을 용이하게 할 수 있음
  • 레이블은 사용자에게는 중요하지만, 쿠버네티스 클러스터에 직접적인 의미는 없음

 

label이 포함한 yml 파일로 파드 생성

  • testapp-pod-lable1.yml 파일 생성
vagrant@kube-master1:~/test$ vi testapp-pod-label.yml

apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod-label1
  labels:
    env: dev
    tier: frontend
spec:
  containers:
  - name: testapp
    image: c1t1d0s7/myweb
    ports:
    - containerPort: 8080
      protocol: TCP

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod-label.yml
pod/testapp-pod-label1 created

 

  • 실행 중인 파드 확인
vagrant@kube-master1:~/test$ kubectl get pods
NAME                 READY   STATUS              RESTARTS   AGE
testapp-pod          1/1     Running             0          51m
testapp-pod-label1   0/1     ContainerCreating   0          7s

 

  • 레이블 확인
  • LABELS 값 확인
vagrant@kube-master1:~/test$ kubectl get pods --show-labels
NAME                 READY   STATUS    RESTARTS   AGE    LABELS
testapp-pod          1/1     Running   0          53m    <none>
testapp-pod-label1   1/1     Running   0          2m8s   env=dev,tier=frontend

vagrant@kube-master1:~/test$ kubectl get pods --show-labels -l env=dev
NAME                 READY   STATUS    RESTARTS   AGE     LABELS
testapp-pod-label1   1/1     Running   0          3m48s   env=dev,tier=frontend

 

  • 기존 파드에 label 생성
  • name=label 추가
vagrant@kube-master1:~/test$ kubectl label pods testapp-pod-label1 name=label
pod/testapp-pod-label1 labeled

vagrant@kube-master1:~/test$ kubectl get pods --show-labels
NAME                 READY   STATUS    RESTARTS   AGE   LABELS
testapp-pod          1/1     Running   0          65m   <none>
testapp-pod-label1   1/1     Running   0          14m   env=dev,name=label,tier=frontend

 

  • 기존 파드의 label 수정
  • env=dev 값을 env=ops 값으로 수정
vagrant@kube-master1:~/test$ kubectl label pods testapp-pod-label1 env=ops --overwrite
pod/testapp-pod-label1 labeled

vagrant@kube-master1:~/test$ kubectl get pods --show-labels
NAME                 READY   STATUS    RESTARTS   AGE   LABELS
testapp-pod          1/1     Running   0          63m   <none>
testapp-pod-label1   1/1     Running   0          12m   env=ops,name=label,tier=frontend

 


annotation


 

annotation: 어노테이션

어노테이션이란

  • 주석
  • 오브젝트에 비-식별 메타데이터를 지정하여 추가적인 정보를 제공하기 위해 사용
  • 레이블은 레이블 셀렉터를 이용하여 식별 및 검색을 할 수 있지만, 어노테이션은 셀렉터를 가지고 있지 않음
  • 어노테이션 사용 예: 선언적 구성 정보, 타임 스탬프, 릴리즈 ID, 로킹, 모니터링, 디버깅 정보, 책임자, 관리자 정보 등

 

어노테이션을 포함한 yml 파일로 파드 생성

  • testapp-pod-anno.yml 파일 생성
 vagrant@kube-master1:~/test$ vi testapp-pod-anno.yml
 
 apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod-anno
  annotations:
    test: abcde

spec:
  containers:
  - name: testapp
    image: c1t1d0s7/myweb
    ports:
    - containerPort: 8080
      protocol: TCP

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod-anno.yml
pod/testapp-pod-anno created

 

  • 실행 중인 파드 확인
vagrant@kube-master1:~/test$ kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
testapp-pod          1/1     Running   0          160m
testapp-pod-anno     1/1     Running   0          14s
testapp-pod-label1   1/1     Running   0          109m
testapp-pod-label2   1/1     Running   0          16m

 

  • 어노테이션 값 확인
vagrant@kube-master1:~/test$ kubectl get pods testapp-pod-anno -o yaml | grep -i -A 3 'annotation'
  annotations:
    file: testapp-pod-anno.yml
    subtitle: annotation
  creationTimestamp: "2022-06-22T03:14:44Z"
  managedFields:
  - apiVersion: v1
--
        f:annotations:
          .: {}
          f:file: {}
          f:subtitle: {}

 

  • testapp-pod-anno 파드의 자세한 정보 확인
vagrant@kube-master1:~/test$ kubectl describe pods testapp-pod-anno
~
Annotations:  test: abcde
~

 

  • 실행 중인 파드의 어노테이션 수정
vagrant@kube-master1:~/test$ kubectl annotate pods testapp-pod test="defgh"
pod/testapp-pod annotated

 

  • 변경된 어노테이션 확인
vagrant@kube-master1:~/test$ kubectl get pods testapp-pod -o yaml | less

728x90
728x90

파드


파드 개념

파드란

  • 쿠버네티스의 기본 구성 요소
  • 쿠버네티스의 객체 모델 중에서 생성 및 배포가 가능한 가장 작은 단위
  • 쿠버네티스 클러스터 내에서 애플리케이션을 배포하며 동작하는 프로세스
  • 파드는 컨테이너이며, 한 개 이상의 컨테이너들로 구성됨

 

파드 리소스의 주요 필드

항목 설명
.spec.containers 컨테이너 정의
.spec.containers.image 컨테이너에 사용할 이미지
.spec.containers.name 컨테이너 이름
.spec.containers.ports 노출할 포트 정의
.spec.containers.ports.containerPort 노출할 컨테이너 포트번호
.spec.containers.ports.protocol 노출할 컨테이너 포트의 프로토콜(default: TCP)

 


 

기본 템플릿 사용


yml 파일을 이용한 파드 생성

하나의 컨테이너를 생성하는 템플릿 구성

  • testapp-pod.yml 파일 생성
  • apiVersion: API 버전
  • kind: 생성할 오브젝트 종류
  • metadata.name: 파드 오브젝트의 이름
  • spec.containers.name: 컨테이너 이름
  • spec.containers.image: 컨테이너에 사용할 이미지
  • spec.containers.ports.containerPort, protocol: 노출할 컨테이너 포트, 프로토콜
vagrant@kube-master1:~/test$ vi testapp-pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: testapp-pod
spec:
  containers:
  - name: testapp
    image: c1t1d0s7/myweb
    ports:
    - containerPort: 8080
      protocol: TCP

 

  • 파드 생성
vagrant@kube-master1:~/test$ kubectl create -f testapp-pod.yml
pod/testapp-pod created

 

  • 실행 중인 파드 정의 확인
  • kubectl get pods 파드명 -o yaml
  • kubectl get pods 파드명 -o json
vagrant@kube-master1:~/test$ kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
testapp-pod   1/1     Running   0          45s

vagrant@kube-master1:~/test$ kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE    IP             NODE         NOMINATED NODE   READINESS GATES
testapp-pod   1/1     Running   0          3m9s   10.233.101.7   kube-node1   <none>           <none>

vagrant@kube-master1:~/test$ curl 10.233.101.7:8080
Message: Hello World!
Hostname: testapp-pod
Platform: linux
Uptime: 2134
IP: 10.233.101.7
DNS: 169.254.25.10

 

  • 파드의 자세한 정보 확인
vagrant@kube-master1:~/test$ kubectl describe pods testapp-pod | less

 

  • 파드 로그 확인
vagrant@kube-master1:~/test$ kubectl logs testapp-pod

Tue Jun 21 2022 02:39:58 GMT+0000 (Coordinated Universal Time)
...Start My Node.js Application...
Tue Jun 21 2022 02:43:17 GMT+0000 (Coordinated Universal Time)
Received Request From ::ffff:10.233.89.0

 

728x90
728x90

Docker Compose 설치


전제 조건

  • Docker Compose에는 Docker Engine 필요
  • Docker Compose 플러그인에는 Docker CLI 필요

 


 

Docker Engine, Docker CLI 설치

리포지토리를 사용하여 설치

  • 리포지토리 설정
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

 

 

  • docker engine, containerd, docker-compose 설치
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

 

  • 도커 시작
sudo systemctl start docker

 


 

Compose CLI 플러그인 수동 설치

  • 명령어를 바로 실행할 수 있도록 /usr/local/bin 디렉토리에 docker-compose 설치
curl -SL https://github.com/docker/compose/releases/download/v2.6.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

 

  • docker-compose 설치 확인
ls -l /usr/local/bin/docker-compose
-rw-r--r--. 1 root root 25968640 Jun 20 22:54 /usr/local/bin/docker-compose

 

 

 

  • /usr/local/bin/docker-compose 디렉토리 권한 변경
  • chmod a+x: 모든 사용자 계정에 대해 실행 권한 추가
chmod a+x /usr/local/bin/docker-compose
ls -l /usr/local/bin/docker-compose
-rwxr-xr-x. 1 root root 25968640 Jun 20 22:54 /usr/local/bin/docker-compose

 

  • docker-compose 명령 실행 확인
docker-compose --help
728x90
728x90
앞에서 kubespray를 이용하여 쿠버네티스 설치를 해보았으므로
이번에는 마스터 노드의 스냅샷을 1로 복원하고 kubeadm을 이용해 쿠버네티스 설치 진행

 

모든 VM에 docker-ce 설치


리포지토리를 이용한 설치

도커 리포지토리 설정

  • HTTPS를 통해 리포지토리를 사용할 수 있도록 패키지 인덱스 업데이트 및 apt 패키지 설치
vagrant@kube-master1:~$ sudo apt-get update
vagrant@kube-master1:~$ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release

 

 

  • Docker 공식 GPG 키 추가
vagrant@kube-master1:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

 

  • 리포지토리 설정
vagrant@kube-master1:~$ echo \
>   "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
>   $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

 

도커 엔진 설치

  • apt 패키지 업데이트 및 Docker Engine, containerd 설치
vagrant@kube-master1:~$ sudo apt-get update
vagrant@kube-master1:~$ sudo apt-get install docker-ce docker-ce-cli containerd.io

 


 

모든 VM에 kubeadm, kubelet, kubectl 설치


 

kubeadm 설치

kubeadm: 클러스터를 부트스트랩하는 명령

kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트

kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티

  • 구글 클라우드의 공개 사이닝 키 다운로드
vagrant@kube-master1:~$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

 

  • 쿠버네티스 apt 리포지토리 추가
vagrant@kube-master1:~$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

 

  • apt 패키지 업데이트 및 kubelet, kubeadm, kubectl 설치
vagrant@kube-master1:~$ sudo apt-get update
vagrant@kube-master1:~$ sudo apt-get install -y kubelet=1.19.11-00 kubeadm=1.19.11-00 kubectl=1.19.11-00
vagrant@kube-master1:~$ sudo apt-mark hold kubelet kubeadm kubectl

 


 

Control-Plane 초기화


 

kubeadm으로 클러스터 생성

  • control-plane 초기화
vagrant@kube-master1:~$ sudo kubeadm init --control-plane-endpoint 192.168.56.11 --pod-network-cidr 10.233.0.0/16 --apiserver-advertise-address 192.168.56.11

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join 192.168.56.11:6443 --token e1s1aa.vnseumbldt9vq4uu \
    --discovery-token-ca-cert-hash sha256:28b7199719f1409880704e77657ec30a527562501ec03870d7738c0aff5188cc \
    --control-plane

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.56.11:6443 --token e1s1aa.vnseumbldt9vq4uu \
    --discovery-token-ca-cert-hash sha256:28b7199719f1409880704e77657ec30a527562501ec03870d7738c0aff5188cc

 

  • worker 노드 추가를 위해 명령어 복사
# 실행 결과 마지막 부분
kubeadm join 192.168.56.11:6443 --token e1s1aa.vnseumbldt9vq4uu \
    --discovery-token-ca-cert-hash sha256:28b7199719f1409880704e77657ec30a527562501ec03870d7738c0aff5188cc

 

 

  • 루트 사용자가 아닌 일반 사용자 계정으로 실행
vagrant@kube-master1:~$ mkdir -p $HOME/.kube
vagrant@kube-master1:~$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
vagrant@kube-master1:~$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

vagrant@kube-master1:~$ kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

 

  • 노드 상태 확인
vagrant@kube-master1:~$ kubectl get nodes
NAME           STATUS   ROLES    AGE   VERSION
kube-master1   Ready    master   12m   v1.19.11

 

 


 

worker 노드 추가


 

각각의 노드에 접속하여 노드를 클러스터에 추가

  • 위에서 복사해 놓은 kubeadm join 명령으로 추가
# kube-node1

vagrant@kube-master1:~$ ssh kube-node1
vagrant@kube-node1:~$ sudo kubeadm join 192.168.56.11:6443 --token e1s1aa.vnseumbldt9vq4uu \
>     --discovery-token-ca-cert-hash sha256:28b7199719f1409880704e77657ec30a527562501ec03870d7738c0aff5188cc

# kube-node2
vagrant@kube-master1:~$ ssh kube-node2
vagrant@kube-node2:~$ sudo kubeadm join 192.168.56.11:6443 --token e1s1aa.vnseumbldt9vq4uu \
>     --discovery-token-ca-cert-hash sha256:28b7199719f1409880704e77657ec30a527562501ec03870d7738c0aff5188cc

# kube-node3
vagrant@kube-master1:~$ ssh kube-node3
vagrant@kube-node3:~$ sudo kubeadm join 192.168.56.11:6443 --token e1s1aa.vnseumbldt9vq4uu \
>     --discovery-token-ca-cert-hash sha256:28b7199719f1409880704e77657ec30a527562501ec03870d7738c0aff5188cc

 

  • 노드 상태 확인
vagrant@kube-master1:~$ kubectl get nodes
NAME           STATUS     ROLES    AGE   VERSION
kube-master1   Ready      master   17m   v1.19.11
kube-node1     Ready      <none>   62s   v1.19.11
kube-node2     Ready      <none>   36s   v1.19.11
kube-node3     NotReady   <none>   12s   v1.19.11
728x90
728x90

암호 없이 ssh 로그인 설정


ssh 키 생성 및 복사

  • ssh 키 생성
vagrant@kube-master1:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:csgTKKowCqnYLPCzPPlZKMumIoe5RgJBXEMKep2uO9k vagrant@kube-master1
The key's randomart image is:
+---[RSA 2048]----+
|+.o+             |
|+....o           |
|.oo + .          |
|.+ o . o         |
|O   . = S        |
|X* . . +         |
|OoB+. .          |
|==B*Eo           |
|*=*+o            |
+----[SHA256]-----+

 

  • 각 노드들에 ssh 키 복사
vagrant@kube-master1:~$ ssh-copy-id vagrant@localhost
vagrant@kube-master1:~$ ssh-copy-id vagrant@kube-node1
vagrant@kube-master1:~$ ssh-copy-id vagrant@kube-node2
vagrant@kube-master1:~$ ssh-copy-id vagrant@kube-node3

 

  • 암호 없이 ssh 로그인 확인
vagrant@kube-master1:~$ ssh kube-node1
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-187-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Jun 20 05:43:35 UTC 2022

  System load:  0.0               Processes:             99
  Usage of /:   3.4% of 38.71GB   Users logged in:       0
  Memory usage: 4%                IP address for enp0s3: 10.0.2.15
  Swap usage:   0%                IP address for enp0s8: 192.168.56.21


0 updates can be applied immediately.

New release '20.04.4 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

 

==> 모든 노드에서 스냅샷 생성: 1

 


 

쿠버네티스 설치


 

python3, python3-pip, git 설치

vagrant@kube-master1:~$ sudo apt update
vagrant@kube-master1:~$ sudo apt install -y python3 python3-pip git

 

kubespray 배포

  • kubespray git repository 클론
vagrant@kube-master1:~$ git clone --single-branch --branch v2.14.2 https://github.com/kubernetes-sigs/kubespray.git
vagrant@kube-master1:~$ ls
kubespray

 

  • requirements.txt 파일에서 의존성 확인 및 설치
vagrant@kube-master1:~$ cd kubespray/
vagrant@kube-master1:~/kubespray$ sudo pip3 install -r requirements.txt

 

 

인벤토리 구성

  • 인벤토리 준비
vagrant@kube-master1:~/kubespray$ cp -rfp inventory/sample inventory/mycluster

 

  • 인벤토리 수정
vagrant@kube-master1:~/kubespray$ vi inventory/mycluster/inventory.ini

# :% d 명령 실행으로 파일 내용 모두 지우기

 

  • 수정 내용
[all]  
kube-master1	ansible_host=192.168.56.11 ip=192.168.56.11 ansible_connection=local
kube-node1      ansible_host=192.168.56.21 ip=192.168.56.21
kube-node2      ansible_host=192.168.56.22 ip=192.168.56.22
kube-node3      ansible_host=192.168.56.23 ip=192.168.56.23

[all:vars]  
ansible_python_interpreter=/usr/bin/python3

[kube-master]  
kube-master1 

[etcd]  
kube-master1  

[kube-node]  
kube-node1  
kube-node2  
kube-node3  

[calico-rr]  

[k8s-cluster:children]  
kube-master  
kube-node  
calico-rr

 

  • 파라미터 확인 및 변경 (false -> true 변경)
vagrant@kube-master1:~/kubespray$ vi inventory/mycluster/group_vars/k8s-cluster/addons.yml

metrics_server_enabled: true
ingress_nginx_enabled: true

 

앤서블 실행

 

  • 앤서블 통신 확인
  • 각 호스트 별로 앤서블 통신이 가능한지 확인하고 success가 뜨면 쿠버네티스 설치 준비 완료
vagrant@kube-master1:~/kubespray$ ansible all -i inventory/mycluster/inventory.ini -m ping

 

  • 플레이북 실행
  • 앤서블을 통한 쿠버네티스 설치 시작 (약 20분 소요)
ansible-playbook -i inventory/mycluster/inventory.ini cluster.yml --become

 

  • 설치 완료

 

 

  • 자격 증명 가져오기
vagrant@kube-master1:~/kubespray$ mkdir ~/.kube
vagrant@kube-master1:~/kubespray$ sudo cp ~root/.kube/config ~/.kube
vagrant@kube-master1:~/kubespray$ sudo chown vagrant:vagrant -R ~/.kube

 

kubectl 실행

  • kubectl 명령 자동 완성
vagrant@kube-master1:~/kubespray$ kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl
vagrant@kube-master1:~/kubespray$ exec bash

 

  • Kubernetes 클러스터 확인
vagrant@kube-master1:~$ kubectl get nodes
NAME           STATUS   ROLES    AGE   VERSION
kube-master1   Ready    master   27m   v1.18.10
kube-node1     Ready    <none>   26m   v1.18.10
kube-node2     Ready    <none>   26m   v1.18.10
kube-node3     Ready    <none>   27m   v1.18.10

vagrant@kube-master1:~$ kubectl cluster-info
Kubernetes master is running at https://192.168.56.11:6443

 

==> 모든 노드에서 스냅샷 생성: kubespray 

728x90
728x90

마이크로서비스 및 DevOps


모놀로식 아키텍처

특징

  • 단일 프로세스에서 실행되거나 몇몇 시스템에서 몇 개의 프로세스로 실행되는 거대한 모놀리식 애플리케이션

 

장점

  • 간단한 개발
  • 간편한 배포
  • 단순한 확장성

 

단점

  • 코드 품질이 낮아짐
  • 애플리케이션의 시작이 오래 걸림
  • 애플리케이션의 확장이 어려움
  • 컴포넌트별 개발의 어려움
  • 다양한 기술 적용의 어려움

 


 

마이크로서비스 아키텍처

특징

  • 모놀로식 아키텍처의 크기가 커짐에 따라 발생하는 문제점을 극복하기 위해 마이크로서비스라는 기능적으로 세분화되고 독립적으로 작동하는 방식 사용

 

장점

  • 크고 복잡한 애플리케이션을 지속적으로 배포할 수 있음
  • 향상된 유지 보수성 각 서비스는 작기 때문에 이해하고 변경하기 쉬움
  • 테스트 용이성 각 서비스는 독립적으로 테스트 가능
  • 배포 효율성 각 서비스는 독립적으로 배포 가능
  • 독립적으로 개발 테스트 배포 및 확장
  • 개발에 생산성이 높고 배포 속도가 높음
  • 다양한 기술 적용 가능

 

단점

  • 분산 시스템 설계에 따른 복잡성
  • 서비스 간 통신 매커니즘을 따로 구현
  • 서비스 간 상호 작용 테스트
  • 배포 및 관리 운영상의 복잡성
  • 증가된 리소스 소비

 


 

DevOps

작동 방식

  • DevOps 모델에서는 개발팀과 운영팀의 서로 단절되었던 역할들이 서로 조율하고 협업하여 더욱 안정적이고 뛰어난 제품을 생산할 수 있도록 지원

 

장점

  • 출시 시간 단축
  • 시장과 경쟁 지형에 따른 유연한 대응
  • 시스템 안정성 및 신뢰성 유지
  • 평균 복구 시간 개선

 


 

쿠버네티스란


쿠버네티스

  • 여러 컨테이너 오케이스트레이션 도구 중 현재 가장 주목받고 있는 도구
  • 구글에 의해 개발된 컨테이너 오케스트레이션 도구
  • 기본적으로 도커 플랫폼 사용

 

도커

  • 도커 엔진이 설치된 단일 시스템에서 다수의 컨테이너를 구동하는 방식으로 쉽게 구성 가능
  • 단일 시스템만으로는 확보할 수 있는 자원이 한정되어 있어, 구동 가능한 서비스의 한계가 있음
  • 도커 엔진이 구동되고 있는 시스템에 장애가 발생할 경우, 해당 시스템의 컨테이너를 사용하는 모든 서비스가 중지될 수 있는 가능성이 있음

 

오케이스트레이션

  • 다수의 시스템과 애플리케이션을 쉽게 설정하고 유지 관리할 수 있는 방식 의미
  • 도커 자체적으로 '도커 스웜'을 통해서 오케스트레이션을 지원하고 있음
  • 도커 스웜은 도커와 유사한 동작 방식으로 쉬운 사용법을 제공하고 있으나 기능이 비교적 단순하고 세세한 조정이 어려운 단점이 있음

 

쿠버네티스 아키텍처

  • 쿠버네티스 클러스터는 여러 시스템의 연결로 구성
  • 마스터와 노드 구성 요소로 분류할 수 있음
  • 필요에 따라 추가 요소(애드온)가 있을 수 있음
  • 쿠버네티스 클러스터 구성 요소

[출처]&nbsp;https://kubernetes.io/ko/docs/concepts/overview/components/

 


 

쿠버네티스 구성 요소

 


 

마스터 노드

  • 쿠버네티스 클러스터를 구성하기 위한 핵심 요소들의 모음
  • 클러스터를 조정하기 위한 컨트롤 플레인을 제공함
  • 노드에 작업을 분재하는 스케쥴링 등 클러스터에서 전반적인 결정을 수행하고 대응이 필요한 클러스터 이벤트를 감지하고 이에 대응하는 역할 수행
  • 마스터의 기능: API 서버, etcd, 스케줄러, 쿠버네티스 컨트롤러 관리자, 클라우드 컨트롤러 관리자

 

kubectl

  • 쿠버네티스 클러스터에 명령을 내리는 역할
  • 바로 실행되는 바이너리 형태로 배포됨
  • 주로 API 서버와 통신함

 

API 서버

  • 쿠버네티스 클러스터의 중심 역할을 하는 통로
  • 주로 etcd와 통신
  • API는 서로 다르게 구성되어 있는 기능들이 데이터를 주고 받기 위한 방식으로 인터페이스를 뜻함
  • 쿠버네티스의 구성 요소들은 마스터의 API 서버와 메세지를 주고 받게 되고 API 서버가 허브 역할을 수행하여 모든 요청을 수신하며 명령을 전달하는 역할 수행

 

etcd

  • etc 디렉토리 + distributed(퍼뜨렸다) 합성어
  • 쿠버네티스 클러스터의 모든 정보 데이터를 저장하는 저장소
  • 데이터 저장 시 'key-value' 형태로 데이터를 저장함
  • 데이터 백업에 대하여 반드시 고려할 필요가 있음

 

scheduler

  • 클러스터 내에서 생성되는 파드를 감지하고 실행할 노드를 선택하는 역할을 수행하는 구성 요소
  • 리소스 상태, 하드웨어/소프트웨어/정책 상의 제약, 어피니티 등 다양한 기존에 따라 배치 결정

 

쿠버네티스 컨트롤러 매니저

  • API 서버를 통해 클러스터의 상태를 감시하고, 필요한 상태를 유지하는 기능을 수행하는 구성 요소
  • 컨트롤러 종류
종류 설명
노드 컨트롤러 노드를 관리하며 노드가 다운되었을 때 알림 및 대응
레플리케이션 컨트롤러 복제 컨트롤러를 사용하는 모든 오브젝트를 관리하며 알맞은 수의 파드를 유지하는 기능
엔드포인트 컨트롤러 서비스와 파드 연결
서비스 어카운트 및 토큰 컨트롤러 쿠버네티스의 네임스페이스, 계정, 토큰 담당

 

클라우드 컨트롤러 관리자

  • AWS, GCP 등 각 클라우드 서비스와 클라우드에서 동작하는 쿠버네티스 구성 요소가 상호 작용할 수 있도록 해주는 기능
  • 쿠버네티스 1.6에서 도입된 알파 기능
  • 클라우드 환경에서 쿠버네티스 컨트롤러가 하는 역할 수행

 


 

워커 노드

  • 쿠버네티스의 컨테이너가 동작하는 런타임 환경을 제공하며, 동작 중인 파드를 유지하는 기능 담당
  • 노드의 역할: 큐블릿, 프록시, 컨테이너 런타임

 

kubelet

  • 쿠버네티스 클러스터의 각 노드에서 실행되는 에이전트로 마스터로부터 제공받는 파드의 구성 정보, 즉 노드가 수행하여야 할 작업을 전달받아서 컨테이너가 확실하게 동작하도록 보장하는 역할 수행

 

프록시

  • 클러스터의 각 노드에서 실행되는 네트워크 프록시로 '서비스'를 구현하기 위한 기능 담당
  • 클러스터 내부 간 통신이나, 클러스터 외부에서 내부로 전달되는 통신 등 호스트 레벨의 네트워크 규칙을 구성하고 외부 연결을 파드에 포워딩하며 서비스의 추상화 제공

 

컨테이너 런타임

  • 각 노드에서 실제 컨테이너의 동작을 책임지는 구성 요소
  • 파드 안에서 다양한 종류의 컨테이너가 문제 없이 작동하게 만드는 표준 인터페이스
  • 구성 요소: docker, containerd, CRI-O, rktlet, Kubernetes CRI

 

파드

  • 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해서 모인 단위
  • 파드는 언제라도 죽을 수 있는 존재임

 

네트워크 플러그인

  • 쿠버네티스 클러스터의 통신을 위해서 네트워크 플러그인을 선택하고 구성해야 함
  • 네트워크 플러그인은 일반적으로 CNI로 구성함
  • CNI: 컨테이너 네트워크 인터페이스로 컨테이너의 네트워크 안정성과 확장성을 보장하기 위해 개발됨
  • CNI 종류: 캘리코, 플래널, 실리움, 큐브 라우터, 로마나, 위브넷 등

 

CoreDNS

  • 빠르고 유연한 DNS 서버
  • 쿠버네티스 클러스터에서 도메인 이름을 이용하여 통신하는 데 사용
  • 도메인 네임을 편리하게 관리해주는 CoreDNS를 일반적으로 사용함

 


 

쿠버네티스 추가 요소

항목 설명
클러스터 DNS 쿠버네티스 클러스터 내의 여러 오브젝트(파드, 컨테이너, 서비스 등)에 대하여 주소 기반으로 오브젝트를 접근할 수 있는 DNS 서비스 제공
대시보드 쿠버네티스 클러스터 구성 및 모니터링을 위한 웹 기반 인터페이스 제공
컨테이너 리소스 모니터링 컨테이너 리소스 사용량의 시계열 매트릭스 기록
클러스터 로깅 컨테이너 로그를 중앙 로그 저장소에 저장하고 관리

 

쿠버네티스 API

  • API 버전 규칙
쿠버네티스의 모든 구성 요소는 API 오브젝트로 취급되며, API 서버를 통해 API로 메세지를 주고 받음
쿠버네티스는 리소스를 쉽게 표현하기 위해, 'api/v1' 또는 '/apis/extensions/v1beta1'과 같이 각각 다른 API를 호출하여 사용할 수 있음
같은 종류의 리소스라고 하더라도 서로 다른 API 버전이 존재할 수 있으며, API 버전이 다르다는 것은 안정성이나 기술 지원의 수준이 다르다는 것을 의미함
  • API 버전 종류: 알파 버전 API, 베타 버전 API, 안전화 버전 API

 

메니페스트

  • 쿠버네티스는 클러스터의 상태를 나타내기 위해 오브젝트 객체를 정의하여 사용함
  • 오브젝트를 생성할 때는 오브젝트의 기본 정보, 오브젝트의 상세 스펙을 정확하게 제시해야 함
  • YAML, JSON 문법으로 정의할 수 있음
  • 오브젝트 정의 시 필수 요구 필드 값
필드 값 설명
apiVersion 오브젝트를 생성하기 위한 API 버전 지정
kind 오브젝트의 종류 명시
metadata name, label, namespace 등 기본적인 정보 기술
spec 오브젝트의 세부 상태 정의

 

오브젝트 관리

  • 명령형 명령어: kubectl 명령 실행 시 오브젝트 생성에 필요한 정보 인수 또는 옵션을 사용하여 전달하는 방식
  • 명령형 오브젝트 구성: 오브젝트에 대한 세부 사항을 YAML/JSON 포맷으로 작성하고, kubectl 명령은 작성된 파일을 참고하여 실행하는 방식
  • 선언형 오브젝트 구성: 특정 디렉토리에 오브젝트 파일을 배치하는 방식, kubectl 명령은 특정 디렉토리에 배치된 오브젝트 파일을 참고하여 오브젝트 관리

 


 

쿠버네티스 클러스터 구성 도구

kubespray

  • 상용 서비스에 적합한 보안성과 고가용성이 있는 쿠버네티스 클러스터를 배포하는 오픈 소스 프로젝트
  • 서버 환경 설정 자동화 도구인 앤서블 기반으로 개발됨
  • 온프레미스 환경에서 상용 서비스의 쿠버네티스 클러스터를 구성할 때 유용함
  • 추가 구성 요소를 클러스터에 실행하는 역할 (ingress-nginx 컨트롤러, 헬름, 볼륨 플러그인, cert-manager 등)
  • kubespray에서 제공하는 고가용성 구조는 kubeadm과 다름 ==> 로그밸런서를 사용하지 않고 노드 각각의 nginx가 리버스 프록시로 실행됨
  • nginx-proxy가 전체 마스터 노드를 바라봄

 

[출처] https://www.bookstack.cn/read/kubespray/ha-mode.md

 

kubeadm

  • 쿠버네티스에서 공식 제공하는 클러스터 생성/관리 도구
  • 여러 대의 서버를 쿠버네티스 클러스터로 쉽게 구성할 수 있음
  • 고가용성을 제공하는 클러스터도 구성할 수 있음 ==> 워커 노드들이 마스터 노드에 접근할 때 로드밸런서를 거쳐 접근함

 

[출처]&nbsp;https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/ha-topology/

728x90

+ Recent posts