Cluster 생성하기 (kubeadm 이용)

|

Create your Kubenetes Cluster

Kubenetes에서 클러스터(Cluster)를 생성하는 방법입니다. 보다 자세한 내용은 여기를 참고하세요.

저는 편의상 AWS에 인스턴스를 3개 만들어서 테스트해보았습니다. 각각의 인스턴스 이름을 master, node1, node2라고 정의했습니다.


각 인스턴스에 Docker 및 Kubenetes 설치

각 인스턴스에 Docker와 Kubenetes를 설치합니다. 설치 방법은 여기를 참고하시면 됩니다.


Master 설정

master 노드에서 다음 명령어를 입력합니다.

sudo kubeadm init

설치는 몇 분간 걸리기 때문에 기다려줍니다.

$ sudo kubeadm init

[init] Using Kubernetes version: v1.9.3
[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks.
        [WARNING FileExisting-crictl]: crictl not found in system path
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [ip-172-31-1-36 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 172.31.1.36]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "scheduler.conf"
[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
[init] This might take a minute or longer if the control plane images have to be pulled.
[apiclient] All control plane components are healthy after 90.001359 seconds
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[markmaster] Will mark node ip-172-31-1-36 as master by adding a label and a taint
[markmaster] Master ip-172-31-1-36 tainted and labelled with key/value: node-role.kubernetes.io/master=""
[bootstraptoken] Using token: f4938e.4b23af938d801cf6
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: kube-dns
[addons] Applied essential addon: kube-proxy

Your Kubernetes master 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 machines by running the following on each node
as root:

  kubeadm join --token f4938e.4b23af938d801cf6 172.31.1.36:6443 --discovery-token-ca-cert-hash sha256:aecc8acc0450992c780cb4b809e50b5583e37d7403480a43d0e2c3b67037c25f

ubuntu@ip-172-31-1-36:~$

위와 같은 메시지가 나오면 설치가 완료된 것입니다. 마지막 부분에 있는

kubeadm join --token f4938e.4b23af938d801cf6 172.31.1.36:6443 --discovery-token-ca-cert-hash sha256:aecc8acc0450992c780cb4b809e50b5583e37d7403480a43d0e2c3b67037c25f

부분을 메모해둡니다.


kubectl 권한 활성화

다음 명령어를 실행해서 kubectl 명령어의 권한을 활성화해줍니다.

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


Pod Network Add-On 설치

본격적인 통신을 하기 위해서는 Pod Network Add-On을 설치해야 합니다. Kube-DNS를 비록하여 각종 어플리케이션을 배포(Deploy)하기 전에 네트워크 설정부터 해야 합니다. 네트워크 설정이 되기 전까지는 각 어플들은 실행되지 않을 것입니다.

Network Add-On은 다음과 같은 종류들이 있으며, 각 클러스터마다 하나의 Network Add-On만 설치 가능합니다.

  • Calico
  • Canal
  • Flannel
  • Kube-router
  • Romana
  • Weave Net

예를 들어 Weave Net은 다음 스크립트를 이용해서 설치할 수 있습니다.

export kubever=$(kubectl version | base64 | tr -d '\n')
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$kubever"

Pod Network가 설치되고 나면 kube-dns Pod가 Running 상태로 바뀌게 됩니다. kubectl get pods --all-namespaces 명령어를 이용해서 확인할 수 있습니다.

$ kubectl get pods --all-namespaces

NAMESPACE     NAME                                     READY     STATUS    RESTARTS   AGE
kube-system   etcd-ip-172-31-1-36                      1/1       Running   0          18m
kube-system   kube-apiserver-ip-172-31-1-36            1/1       Running   0          18m
kube-system   kube-controller-manager-ip-172-31-1-36   1/1       Running   0          19m
kube-system   kube-dns-6f4fd4bdf-z9mvq                 3/3       Running   0          19m
kube-system   kube-proxy-8rqmn                         1/1       Running   0          16m
kube-system   kube-proxy-bhjmm                         1/1       Running   0          19m
kube-system   kube-proxy-fqppb                         1/1       Running   0          17m
kube-system   kube-scheduler-ip-172-31-1-36            1/1       Running   0          19m
kube-system   weave-net-2tgkz                          2/2       Running   0          3m
kube-system   weave-net-jw88d                          2/2       Running   0          3m
kube-system   weave-net-wlxvd                          2/2       Running   0          3m


노드 연결

node1node2에서 위에서 메모해둔 kubeadm join 스크립트를 실행합니다.

$ sudo kubeadm join --token f4938e.4b23af938d801cf6 172.31.1.36:6443 --discovery-token-ca-cert-hash sha256:aecc8acc0450992c780cb4b809e50b5583e37d7403480a43d0e2c3b67037c25f

[preflight] Running pre-flight checks.
        [WARNING FileExisting-crictl]: crictl not found in system path
[discovery] Trying to connect to API Server "172.31.1.36:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://172.31.1.36:6443"
[discovery] Requesting info from "https://172.31.1.36:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "172.31.1.36:6443"
[discovery] Successfully established connection with API Server "172.31.1.36:6443"

This node has joined the cluster:
* Certificate signing request was sent to master and a response
  was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.


연결된 Node 확인

이제 master 노드가 생성되었고, node1node2가 연결(Join)되었습니다. master 노드에서 다음 명령어를 이용해서 노드 리스트를 조회할 수 있습니다.

$ kubectl get nodes

NAME               STATUS    ROLES     AGE       VERSION
ip-172-31-1-36     Ready     master    21m       v1.9.3
ip-172-31-15-223   Ready     <none>    18m       v1.9.3
ip-172-31-2-21     Ready     <none>    18m       v1.9.3


종료하기

지금까지 kubeadm을 이용해서 작업한 내용을 종료시키기 위해서는 각 노드들을 먼저 정리를 해야 합니다. 다음 명령어를 이용해서 각 노드들의 데이터를 지울 수 있습니다.

kubectl drain <node name> --delete-local-data --force --ignore-daemonsets

kubectl delete node <node name>

노드가 제거 완료되면 kubeadm reset 명령어를 이용해서 모든 상태를 원래대로 돌립니다.

kubeadm reset

Kubernetes 설치 방법

|

Install Kubernetes on Ubuntu

Ubuntu 16.04 LTS 기준으로 Kubernetes를 설치하는 방법입니다. 자세한 내용은 여기를 참고하세요.


Docker 설치

Kubernetes를 사용하기 위해서는 먼저 Docker가 설치되어 있어야 합니다. Docker 최신 버전 설치 방법은 여기에 설명되어 있지만, 안타깝게도 Kubernetes는 Docker 최신 버전을 지원하지 않을 가능성이 높습니다. 따라서 다음 명령어를 이용해서 Kubernetes가 지원하는 버전의 Docker를 설치해야 합니다.

sudo apt-get update
sudo apt-get install -y docker.io

또는 Docker CE 17.03 버전을 설치합니다.

sudo apt-get update
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
sudo add-apt-repository \
   "deb https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable"
sudo apt-get update && apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 17.03 | head -1 | awk '{print $3}')

sudo apt-get update && apt-get install -y apt-transport-https


Kubernetes Key 설치

먼저 다음 명령어를 통해 Kubernetes 설치를 위한 Key를 다운로드 합니다.

sudo su

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add


apt-get 용 Repository 추가

그 다음 /etc/apt/sources.list.d/kubernetes.list 파일을 만듭니다.

cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF

또는 nano 명령어를 이용해서 생성할 수도 있습니다.

sudo nano /etc/apt/sources.list.d/kubernetes.list

그리고 위 파일안에

deb http://apt.kubernetes.io/ kubernetes-xenial main

을 추가합니다.


Kubernetes 설치

apt-get update

apt-get install -y kubelet kubeadm kubectl kubernetes-cni

Microservice Architecture, Doocker, Kubernetes

|

Microservice Architecture

조대협님의 Youtube 강좌를 보면서 나름대로 요약한 글입니다. 또한 SlideShare는 여기를 참고하면 됩니다.

모노리틱 아키텍처(Monolithic Architecture)

모노리틱 아키텍처(Monolithic Architecture)는 예전부터 사용되어져오던 아키텍처이며, 다음 이미지와 같이 하나의 통서버에서 모든 것들을 처리하는 시스템 구조입니다.

Image

하나의 서버에 모든 비즈니스 로직이 포함되며, 하나의 중앙 집중형 데이터베이스에 모든 데이터가 저장됩니다. 다양한 기술들을 혼용해서 사용하기 어렵기 때문에 단일화된 기술을 주로 사용합니다.

장점으로는

  • 단일화된 기술 사용
  • 관리가 수월함

이 있으며, 단점으로는

  • 여러 기술 혼용이 어렵기 때문에 부위별 적절한 기술 사용이 어려움
  • 배포 및 재기동 시간이 오래 걸림
  • 향후 수정이 용이하지 않음

가 있습니다.


마이크로서비스 아키텍처(Microservice Architecture)

마이크로서비스 아키텍처(Microservice Architecture)는 시스템을 여러 개의 독립된 서비스로 분할하고 조합하여 시스템을 구성하는 방법입니다. 과거 SOA(Service Oriented Architecture)의 경량화된 버전이라고 볼 수 있습니다.

여러 개의 서비스들로 이루어져 있으며, 각각은 RESTful API 등을 이용해서 통신을 합니다. 서비스별로 다른 기술 스택을 사용할 수 있기 때문에 적재적소에 알맞은 기술을 선택할 수 있는 장점이 있습니다.

장점으로는

  • 필요한 서비스에 적절한 기술을 적용 가능 (ex. 복잡한 데이터는 RDBMS를 사용하고, 양이 많은 고속 데이터는 NoSQL을 사용한다던지, 빠른 개발로 스크립트 언어를 사용하고 튼튼한 시스템 개발로는 Java를 사용하는 등)

이 있으며, 단점으로는

  • 여러 기술을 동시에 다뤄야 하기 때문에 운영의 부담이 커질 수 있음
  • 따라서 개발자가 떠나면 유지 보수가 어려움

과 같은 단점이 있습니다.

Image


마이크로 서비스 아키텍처 구성

마이크로 서비스 아키텍처 구조는 보통 다음 그림과 같습니다.

Image


API 게이트웨이

API 게이트웨이는 클라이언트와 API 서버 앞에서 일종의 프록시 역할을 담당하며 다음과 같은 역할을 합니다.

  • API 인증/인가
  • Logging
  • Routing
  • 메시지 변환
  • 메시지 프로토콜 변환

API 게이트웨이는 SOA ESB(Enterprise Service BUS)의 단순화 버전이라고 볼 수 있으며 필수적인 요소는 아닙니다. 잘 사용하면 좋은 컴포넌트가 될 수 있지만, 잘 못 쓰면 서비스를 망칠 수도 있기 때문에 도입은 신중하게 할 필요가 있습니다.


API 게이트웨이를 이용한 설계 패턴

API 게이트웨이를 이용한 설계 패턴들은 다음과 같습니다.

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image


Docker

Docker의 기본 설명은 생략을 하도록 하겠습니다. Docker를 사용하다보면 컨테이너들을 어떤 물리 서버에 배포할 것인지가 이슈가 됩니다. 또한 컨테이너 관리나(Container Management), 로드 밸런싱(Load Balancing), 헬스 체크(Health Check), Rolling Upgrade 등의 이슈도 같이 발생합니다.

그래서 Docker Swarm, Apache Mesos, Kubernetes 등의 솔루션이 있습니다.

이 중에서 Kubernetes는 다음과 같습니다.


Kubernetes

구글은 과거부터 컨테이너 서비스를 운영해왔습니다. VM보다 컨테이너를 더 오래 사용했으며, 현재 20억개 이상의 컨테이너를 운영하고 있습니다.

Kubernetes는 구글의 오랜 컨테이너 서비스 운영 경험의 산물이라고 볼 수 있습니다. Public, Private 인프라에서 모두 사용가능한 오픈 소스입니다.


Pods

Pod는 Kubernetes의 최소 논리 단위이며 하나의 어플을 표현하는 최소 단위이기도 합니다. 하나의 Pod에는 복수 개의 컨테이너가 포함될 수 있으며, 주로 Tightly Coupled 되는 컨테이너들을 하나의 Pod에 묶어서 사용합니다. 예를 들면 Nginx와 Tomcat를 묶는다던지 Tomcat과 Memcached를 묶을 수 있습니다.

Pod에 있는 컨테이너들은 물리적으로 같은 서버에 생성이 되며, 같은 Pod에 있는 컨테이너들끼리는 Disk Volume을 공유할 수 있습니다.

Image


Replication Controllers

Replication Controller는 Pod들을 생성하고 관리하는 역할을 합니다. Pod 생성은 미리 정의된 Template로부터 생성되며 Pod의 가동상태를 체크하고, 죽으면 다시 기동시키는 역할, Auto Scaling 등의 작업을 합니다.

Image


Services

서비스는 Pod 들의 집합(ex. 웹서버 서비스, 백엔드 서비스, 캐쉬 서비스)이며 IP Address가 지정(Expose)되고, Pod간 로드 밸런싱 제공합니다.

Image

SSL(Secure Sockets Layer)

|

SSL

SSL(Secure Sockets Layer)는 데이터를 암호화하거나 통신 상대를 인증함으로써 데이터를 보호하는 프로토콜입니다. 보통 HTTP 통신을 할 때, ‘https://’로 시작하는 URL들이 대표적인 예시이며 HTTPS(HTTP over SSL)는 HTTP를 SSL로 암호화한 프로토콜입니다.


대표적인 SSL 서버 프로그램

SSL 서비스를 제공하는 대표적인 서버 프로그램으로는 오픈 소스인 ‘OpenSSL’이나 Windows에 내장되어 있는 ‘IIS’가 있습니다. OpenSL은 주로 Apache 웹 서버와 연계해서 사용합니다.


SSL로 방지할 수 있는 위험

SSL은 데이터 보호를 위해 다음과 같은 기능들을 제공합니다.

  • 암호화
  • 메시지 다이제스트(Message Digest)
  • 디지털 증명서

암호화는 전송하는 데이터를 암호화해서 중간에 누군가가 패킷을 가로채더라도 그 안의 내용을 해석하지 못하도록 하는 기능입니다.

메시지 다이제스트는 메시지(데이터)의 해시값(다이제스트 값)을 계산하여 데이터와 함께 전송하는 방법입니다. 중간에 누군가가 패킷을 변조하더라도 다이제스트 값을 확인하면 데이터의 변조 사실을 확인할 수 있습니다. 데이터의 무결성을 보장해주는 방법입니다.

디지털 증명서는 서버가 신뢰할 수 있는 서버인지 증명하는 파일입니다. 중간에 누군가가 접속 경로를 바꾸어 가짜 서버에 접속했을 때 확인할 수 있도록 하는 기능입니다.


SSL 서버

SSL은 디지털 증명서를 이용해서 해당 서버가 신뢰할 수 있는 서버인지 아닌지 확인합니다. 즉, SSL 서버에는 디지털 증명서를 설치해야하는 작업이 필요합니다.

증명서를 설치하는 절차는 다음과 같습니다.

  1. 서버 관리자는 비밀키와 공개키를 생성한 후 공개키를 CSR(Certificate Signing Request)이라는 증명서 서명 요청 형태로, 제 3의 기관인 CA(Certification authority)에 제출합니다. 공개키는 제출하고, 비밀키는 별도로 보관합니다.

  2. CA에서는 여신 판단을 한 다음 CSR에 ‘신뢰할 수 있습니다’라는 디지털 서명을 합니다. 그 이후 ‘디지털 증명서’를 서버 관리자에게 발행합니다.

  3. 서버 관리자는 디지털 증명서를 서버에 설치합니다.


SSL 암호화의 흐름

서버에 디지털 증명서를 설치하고 나면, 이제 SSL 서버로 동작을 할 수 있습니다.

  1. 서버는 클라이언트가 접속하면, 클라이언트에게 공개키와 디지털 증명서를 전송합니다.

  2. 클라이언트는 디지털 증명서내의 디지털 서명을 보고 증명서의 유효성을 체크합니다. 유효한 증명서임이 확인되면 공통키의 파라메터를 서버에서 보내온 공개키로 암호화한다음 서버에 전송합니다..

  3. 서버는 클라이언트로부터 받은 데이터를 비밀키를 이용해 복호화한다음 공통키의 파라메터를 확인합니다. 여기까지의 작업을 ‘SSL 핸드쉐이크(SSL Handshake)’라고 합니다.

  4. 클라이언트와 서버는 공통키의 파라메터로부터 공통키를 만들고 그 이후부터는 공통키를 이용해서 암호화 통신을 수행합니다.

ssh Config 사용법

|

ssh config

ssh 접속을 하기 위해서는 보통 ssh [사용자ID]@[Target IPAddress]와 같이 사용하거나 그 외 포트, 키(Key) 등을 옵션으로 해서 같이 사용해야 하는 경우가 많아서 번거롭습니다.

ex) 
ssh snowdeer@10.13.152.45

ssh snowdeer@10.13.152.45 -i ~/.ssh/snowdeer_aws.pem

이럴 때 ‘ssh config’를 사용하면 보다 간편하게 ssh를 사용할 수 있습니다.


~/.ssh/config 설정 파일

‘ssh config’ 파일의 위치는 ~/.ssh/config 입니다. 폴더나 파일이 존재하지 않는다면 직접 만들면 됩니다. 해당 파일을 생성하고 권한은 다음과 같이 부여합니다.

chmod 440 ~/.ssh/config

그리고 config 파일 내용은 다음과 같이 작성합니다.

Host master
    HostName 10.13.152.45
    User ubuntu
    IdentityFile ~/.ssh/snowdeer-aws-seoul.pem

Host node1
    HostName 10.13.152.113
    User ubuntu
    IdentityFile ~/.ssh/snowdeer-aws-seoul.pem

Host node2
    HostName 10.13.11.53
    User ubuntu
    IdentityFile ~/.ssh/snowdeer-aws-seoul.pem


config 파일 사용법

사용법은 단순합니다. 단순히 ssh <host name>으로 명령을 내리면 됩니다.

ex) ssh node1