참조 :

도커란 무엇인가? 포스팅에 이어 쿠버네티스에 정리하고자한다. 

 위키백과에서 쿠버네티스를 찾아보면 "쿠버네티스(Kubernetes, 쿠베르네테스, "K8s"[3])는 디플로이 자동화, 스케일링, 컨테이너화된 애플리케이션의 관리를 위한 오픈 소스 시스템으로서[4] 원래 구글에 의해 설계되었고 현재 리눅스 재단에 의해 관리되고 있다. 목적은 여러 클러스터의 호스트 간에 애플리케이션 컨테이너의 배치, 스케일링, 운영을 자동화하기 위한 플랫폼을 제공하기 위함이다.[3] 도커를 포함하여 일련의 컨테이너 도구들과 함께 동작한다.” 라고 나온다.

 처음 저 글을 봤을 땐 전혀 와 닿지 않지만, 쿠버네티스를 이용해 서비스를 짧은 기간인 3개월 정도 운영해본 후, 저 글을 다시 읽으니 저 3문장에 쿠버네티스를 아주 잘 설명 한 거같다. 요즘 오픈소스의 이름들을 보면 명칭에 아주 신경을 많이 쓴 것을 알 수 있는데, 쿠버네티스는 그리스어로 키잡이를 뜻한다고 한다. 




kubernetes는 플랫폼 이름이 길어서 줄여 k8s라고도 한다. 앞으로는 k8s라고 적겠다. ( 8은 kubernetes의 중간의 글자라고 생각하면 된다 )
 왼쪽 그림은 k8s의 마크다. k8s가 앞서 키잡이(배의 키를 조정하는 사람)를 뜻한다고 했는데, 옆에 도커마크랑 같이 봄 이해가 간다.

도커란 배들의 키잡이 역할을 해주는 플랫폼이구나 하고 넘어가면 된다.

그럼 k8s가 왜 필요한지 생각해보자 우리한테는 앞서 여러 application을 올릴 수 있는 컨테이너 플랫폼인 도커를 공부 하였다. 

도커만으로 충분하지 않을까? 
물론 경우에 따라선 도커만으로 충분하다. 앞으로는 관리자 역할에서 생각해보자.
하나의 노드에서 여러 컨테이너를 띄우다 보니 자원( disk, memory, cpu )이 부족하기 시작했다. 

관리자 : 서버를 하나 추가해서 컨테이너를 나눠서 노드에 담자


위 그림처럼 노드를 하나 늘려서 도커를 설치하였다. 하지만 관리하는 노드가 많아질수록 점점 복잡해진다.
또한 이러한 요구사항이 올 수도있다.

클라이언트 :  웹 서버를 배포할 건데 죽으면 안되니까 이중화로 구성해주고 로드밸런서를 둬서 트래픽을 분산시켜줘. !
관리자 :#@($

예가 이상할 수도 있지만, 간단하게 k8s의 필요성에 관해 설명하고자 했다. 
k8s은 위에서 필요한 기능들을 다 제공하고 있다. ! 

대충 이런 그림 !




그럼 좀 더 자세히 k8s의 아키텍처를 보자 
( 처음에 모르는 오픈소스를 볼 때, 이러한 그림부터 보면 좀 더 시간을 아낄 수 있다 )




일단 각각의 역할을 그림을 보면서 이해해보자. 
큰 그림으로 보면 kubectl을 통해 받은 명령어를 api server를 통해 kubelet으로 전달하면 Pod( container 묶음 )를 생성하며 서비스를 제공한다. 물론 메타데이터를 저장하는 etcd, 다양한 제어기능을 위한 controller-manager, 자원분배를 도와주는 scheduler, 네트워크 트래픽을 담당하는 kube-proxy도 있다. 

자세히 적으면 처음 k8s을 접하는 사용자의 이해에 어려움이 있을 수 있어, 여기서는 간략하게만 소개하고 나중에 좀 더 자세히 소개하도록 하겠다.

kubectl : kubectl은 간단하게 명령어를 보내는 역할만 한다. 
예) kubectl get pods  ( pod들을 확인하는 명령어  )
API server : 간단하게 명령어를 전달해주는 역할만 진행한다. 또한 etcd클러스터랑 통신한다. 이 정도만 알고 가자 !
( 기본적으로 REST방식으로 통신한다 ) 
etcd : kubernetes 클러스터 데이터(포드 수,상태,네임 스페이스 등), API 객체 및 서비스 검색 세부정보를 저장하는 데 사용되는 분산 키 값 저장소다. 
( 메타 데이터가 저장되는 역할을 한다 생각하면 된다 ) 
controller-manager :  컨트롤러 매니저는 복제, 서비스계정, 네임스페이스 등을 생성하고 이를 각 노드에 배포하며 관리하는 역할을 한다.
( 여기선 사용자가 다양한 설정을 정할 수 있는데 이러한 것을 제어하기 위해 도와주는 역할이라고 간단하게 넘어가자 ) 
scheduler : 스케줄러는 Pod,서비스 등 각 자원을 적절한 노드에 할당하는 역할을 한다.
kubelet :  노드는 기본적으로 정기적으로 새로운 pod 또는 수정된 pod의 사양으로 포드 및 컨테이너가 원하는 상태로 실행되고 있는지 확인한다.
kube-proxy :  노드로 들어오는 네트워크 트래픽을 적절한 컨테이너로 라우팅하고, 로드밸런싱 등 노드로 나가는 네트워크 트랙픽을 프록시하고 노드와 마스터간 통신을 관리한다.

이 포스팅은 k8s가 무엇인지 이해하는 것이 목적이기 때문에, 이해를 쉽게 하기 위해 어려운 내용은 다 제거했다. 좀 더 자세한 내용은 시간이 생긴다면, k8s 내부 컴포넌트들이 어떤 식으로 통신하는지 그림과 같이 정리할 생각이다.


 


'apps > docker' 카테고리의 다른 글

DevOps가 떠오른 이유  (0) 2018.11.25
도커란 무엇인가?  (0) 2018.08.04
flannel을 통한 pod간 통신  (2) 2018.07.03
도커에서 nodejs+mongodb 테스트  (0) 2018.07.01
kubernetes에서 gpu pod생성( nvidia-docker2 )  (2) 2018.05.30
docker에 대해 공부하면서 느낀 점을 공유하면 좋을 것 같아 포스팅합니다.


먼저 도커란 무엇인가 ? 
 공식 홈페이지에서 도커의 개요를 보면 도커란 "Docker는 컨테이너 이동을 주도하는 회사이며 하이브리드 클라우드의 모든 애플리케이션을 처리할 수 있는 유일한 컨테이너 플랫폼 제공 업체입니다“ 라고 쓰여있다. 

여기서 '컨테이너'란 말에 주목할 필요가 있다. 
컨테이너란 무엇일까? 
아래 그림을 보면 대충 감이 온다. 아래에 도커 이미지를 보면 귀여운 배 위에 컨테이너를 올린 모습을 볼 수 있다. 
대충 아! 컨테이너란 "다양한 OS에 여러 application이 올려져 있는 것"을 의미하는 거고 그런 컨테이너를 도커 위에 올리는구나 





그럼 이미 존재하는 Virtual Machines랑 뭐가 달라 ..? 
물론 다르다 위에 그림을 보면 각 컨테이너가 같은 Kernel을 공유하고 있는 모습을 볼 수 있다.


 위 그림을 보면 좀 더 명확하다. 
virtual machine의 경우 Hypervisor을 통해 가상화 기능을 제공한다. 각 독립 된 커널 공간을 가진 OS를 생성하는 식의 환경 구성을 해준다.
containers의 경우 커널 공간을 공유하며 같은 가상화 기능을 제공해준다.

* 같은 커 널공간을 공유하기 때문에 virtual machines보다 좀 더 가볍다. 


이런 구성도 가능하다.!! ( Virtual Machine에 OS를 설치 후 Docker를 설치 )
* 물론 이런 구성으로 실제 서비스를 제공하는 기업은 없을 거로 생각한다.  


어떻게 이런 게 가능할까 ? 
namespaces 와 cgroup에 대해서 알아야 한다. 

namespace 
먼저 리눅스 커널의 주요 이름 공간에 대해서 알아보자.
이름공간
기능
Mount namespace
파일 시스템 분리
UTS namespace
호스트 네임 분리
IPC namespace
프로세스간 통신 분리
User namespace
유저(UID/GID) 분리
PID namespace
프로세스 테이블 분리
Network namespace
네트워크 설정 분리
이름 공간은 모두 리눅스 상에서 동작하는 프로세스에 할당하는 자원을 분리하는 기능을 한다.

cgroups (Control Groups)
cgroups(Control Groups)는 자원(resources)에 대한 제어를 가능하게 해주는 리눅스 커널의 기능입니다.
cgroups는 다음 자원을 제어할 수 있다.
* 메모리, CPU, I/O, 네트워크, device노드

사실 이러한 기술이 처음 나온 건 아니다. LXC 등 유사한 기술이 많았으나 도커가 히트친 이유는 사용자 편의성 ( 이미지 repository 등 )에 있다고 생각한다

그럼 마지막으로 도커 이미지에 대해 알아보자.

도커 이미지
도커 이미지는 특정 프로세스를 실행하기 위한 환경이다. 
이 이미지는 필자가 가진 이미지들이다. 
Default registry ( hub.docker.com )에 등록된 centos:7같은 이미지를 가져올 수도 있고, 개인적으로 172.30.1.19:5000같은 registry을 등록해서 이미지를 주고 받을 수도 있다.
또한 nodejs-mongodb-test처럼 자신이 만든 서비스( api서버로 데이터를 받아 mongodb에 저장하는 간단한 서비스)를 이미지로써 제공할 수도 있다. 
yjhui-MacBook-Pro:elk yjh$ docker images
REPOSITORY                TAG                     IMAGE ID            CREATED             SIZE
nodejs-mongodb-test       yang                    ffe8520fe8cd        4 weeks ago         664MB
172.30.1.19:5000/centos   7                       e934aafc2206        3 months ago        199MB
centos                    7                       e934aafc2206        3 months ago        199M
mongo                     latest                  9a63ed32fc2b        5 weeks ago         378MB

도커를 사용하며 가장 편리한 점은 서비스를 만들어 상용 서버에 배포를 하려고 하면 환경이 달라 예상치 못한 일들이 발생해서 반나절을 보낸 경우가 많았다....
도커를 사용한다면 이런 불필요한 삽질을 줄일 수 있을 거로 생각한다. 
이미지를 구워서 실행하면 배포 완료..?  또한 서비스가 죽어도 다시 살리는 기능도 제공한다. 

물론 실제 서비스에서 도커를 통해 서비스를 안정적으로 제공하기 위해서는 도커에 대해 좀 더 공부가 필요하다.
앞으로의 포스팅은 도커의 다양한 기능에 대해 공부해 포스팅할 예정이다. 



'apps > docker' 카테고리의 다른 글

DevOps가 떠오른 이유  (0) 2018.11.25
쿠버네티스란 무엇인가?  (0) 2018.08.18
flannel을 통한 pod간 통신  (2) 2018.07.03
도커에서 nodejs+mongodb 테스트  (0) 2018.07.01
kubernetes에서 gpu pod생성( nvidia-docker2 )  (2) 2018.05.30
간단한 내용이지만 이 간단한 정보를 확인하는데 불필요한 삽질을 하였기에 도움이 될까 포스팅합니다.

서로 다른 노드에 있는 pod간 통신을 완성하기 위해서는 관련 기능을 제공하는 network plugin이 필요하다.
필자의 경우는 flannel plugin을 설치했다.

구글링하다 좋은 케이스를 찾았기에 공유

* 만약 잘못된 정보가 있으면 지적해주세요




그림을 보면 노드1에서 노드2로 다른 ip끼리 패킷을 보낼 때, 보내는 컨테이너의 출발지와 목적지를 가지고 있는 모습을 확인 할 수 있다.
그리고 flannel에서 패킷을 주고받는 node의 출발지와 목적지 정보를 UDP로 캡슐화해서 보내는 역할을 수행한다. 
이런 식으로 flannel plugin을 설치하여 컨테이너 간 통신을 할 수 있다.

테스트한 yaml파일은 아래와 같다.
$ cat cent.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: test
  labels:
    app: test
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
      - image: centos:7.2.1511
        name: test
        command: ["/bin/bash","-c","while true; do sleep 1000; done"]
        imagePullPolicy: IfNotPresent



$ cat mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
  labels:
    name: mysql-pod
    context: docker-k8s-lab
spec:
  containers:
    -
      name: mysql
      image: mysql:5.7
      env:
        -
          name: "MYSQL_USER"
          value: "mysql"
        -
          name: "MYSQL_PASSWORD"
          value: "mysql"
        -
          name: "MYSQL_DATABASE"
          value: "sample"
        -
          name: "MYSQL_ROOT_PASSWORD"
          value: "supersecret"
      ports:
        -
          containerPort: 3306

yaml을 통해 centos, mysql을 실행하여 centos pod에서 mysql에 접속되는 지 테스트

pods 확인
$ kubectl get pods
mysql-pod                       1/1       Running   0          6m
test-6b5c774944-fqcdl           1/1       Running   0          17m


mysql을 설치해준다.
$ yum install mysql 

master서버에서 mysql pod의 ip주소 체크
$  kubectl describe pod test-6b5c774944-fqcdl
Name:               mysql-pod
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               jf-api/192.168.0.89
Start Time:         Tue, 03 Jul 2018 17:32:13 +0900
Labels:             context=docker-k8s-lab
                    name=mysql-pod
Annotations:        kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"context":"docker-k8s-lab","name":"mysql-pod"},"name":"mysql-pod","namespace":"d...
Status:             Running
IP:                 10.244.1.53
Containers:
  mysql:
    Container ID:   docker://ee63968f90c86a3062627a68c3830d425b1b385ebc61cc1c960e824411799f7e
    Image:          mysql:5.7
    Image ID:       docker-pullable://mysql@sha256:f030e84582d939d313fe2ef469b5c65ffd0f7dff3b4b98e6ec9ae2dccd83dcdf
    Port:           3306/TCP
    State:          Running
      Started:      Tue, 03 Jul 2018 17:32:16 +0900
    Ready:          True
    Restart Count:  0
    Environment:
      MYSQL_USER:           mysql
      MYSQL_PASSWORD:       mysql
      MYSQL_DATABASE:       sample
      MYSQL_ROOT_PASSWORD:  supersecret
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-dn4mq (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-dn4mq:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-dn4mq
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason                 Age   From               Message
  ----    ------                 ----  ----               -------
  Normal  Scheduled              9m    default-scheduler  Successfully assigned mysql-pod to jf-api
  Normal  SuccessfulMountVolume  9m    kubelet, jf-api    MountVolume.SetUp succeeded for volume "default-token-dn4mq"
  Normal  Pulled                 9m    kubelet, jf-api    Container image "mysql:5.7" already present on machine
  Normal  Created                9m    kubelet, jf-api    Created container
  Normal  Started                9m    kubelet, jf-api    Started container


centos접속 후 mysql 접속확인
$ kubectl exec -it test-6b5c774944-fqcdl /bin/sh

sh-4.2# mysql -h10.244.1.22 -umysql -pmysql -Dsample
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [sample]

이와 같이 pod간 커뮤니케이션을 flannel을 통해 할 수 있다는 것을 확인했다.!




 



'apps > docker' 카테고리의 다른 글

쿠버네티스란 무엇인가?  (0) 2018.08.18
도커란 무엇인가?  (0) 2018.08.04
도커에서 nodejs+mongodb 테스트  (0) 2018.07.01
kubernetes에서 gpu pod생성( nvidia-docker2 )  (2) 2018.05.30
centos7에서 nvidia driver설치하기  (0) 2018.05.28

+ Recent posts