1. K8SM (Kubernetes Mesos)?
K8SM는 Apache Mesos에서 Google의 Kubernetes를 사용 할 수 있도록 개발 된 Mesos Framework 입니다.
초기 K8SM은 Mesosphere 팀에서 Kubernetes v0.14를 기준으로 개발 되었다가, Kubernetes v1.0 버전이 릴리즈 되면서, Kubernetes로 통합이 된 것으로 알고 있습니다.
K8SM을 구성하려면 Apache Mesos와 Google Kubernetes에 대한 이해가 있어야 합니다.
– Apache Mesos
https://www.yongbok.net/blog/apache-mesos-cluster-resource-management/
– Google Kubernetes
https://www.yongbok.net/blog/google-kubernetes-container-cluster-manager/
2. K8SM – Architecture
K8SM에 대해 제 나름 대로 그려 봤습니다.
(원본은 https://github.com/GoogleCloudPlatform/kubernetes/blob/master/contrib/mesos/docs/architecture.md 에서 확인 가능 합니다.)
원리는 아래와 같습니다.
1. 사용자가 Dockerfile 또는 YAML 파일을 작성하여 적절한 곳에 저장 및 업로드 합니다. 2. 사용자가 kubectl 명령어를 통해 Pods를 구성 하도록 요청 합니다. 3. API Server가 이 정보를 ETCD에 저장 합니다. 4. Scheduler가 ETCD에 저장 된 정보를 가지고, ZooKeeper에 Mesos Master의 리더를 물어 봅니다. 5. 리더 Mesos Master는 Mesos Slave 중 Workload가 낮은 서버를 선택 하여 작업을 지시 합니다. 6. Mesos Slave는 kubelet(executor)를 실행하여, 작업을 수행하고 proxy를 실행 합니다. 7. Mesos Slave가 Container 또는 Pods에 문제가 생겼을 때 Mesos Master로 보고 합니다. 8. API Server가 이를 감지하여, Controller Manager에 요청을 하여 문제를 해결 합니다.
Fig 1. The architecture diagram of Kubernetes Framework for Apache Mesos
3. K8SM – 구성
본 구성은 Ubuntu 14.04 LTS 64bit에서 테스트 되었으며, 위의 아키텍처와 같게 구성 될 것이고, Hostname과 IP 정보는 다음과 같습니다.
HostName IP etcd-0 172.17.1.1 etcd-1 172.17.1.2 etcd-2 172.17.1.3 mesos-master-0 172.17.1.4 mesos-master-1 172.17.1.5 mesos-master-2 172.17.1.6 mesos-master-3 172.17.1.7 kubernetes-mesos 172.17.1.8 kubernetes-minion-0 172.17.1.9 kubernetes-minion-1 172.17.1.10 kubernetes-minion-2 172.17.1.11 kubernetes-minion-3 172.17.1.12
만일, 물리 서버 1대 또는 개인 PC로 가상화를 통해 구성 할 생각이면, 아래 Docker를 활용 하는 방법도 있습니다.
https://github.com/ruo91/docker-kubernetes-mesos
4. K8SM – ETCD Cluster
ETCD를 빌드하기 위해서는 Go Language가 필요 합니다.
따라서, Go Language를 설치 후 ETCD를 빌드 합니다.
– Go Language 설치
root@ruo91:~# curl -o /opt/golang.sh -L "https://raw.githubusercontent.com/ruo91/golang-scripts/master/golang-auto.sh" root@ruo91:~# chmod a+x /opt/golang.sh root@ruo91:~# /opt/golang.sh root@ruo91:~# source /etc/profile
– ETCD 설치
최신 버전도 좋지만, release 버전을 통해 설치 하겠습니다.
root@ruo91:~# git clone https://github.com/coreos/etcd /opt/etcd-source \ root@ruo91:~# cd /opt/etcd-source root@ruo91:~# git checkout -b release-2.1 origin/release-2.1 root@ruo91:~# ./build && mv bin /opt/etcd root@ruo91:~# cd .. && rm -rf etcd-source root@ruo91:~# echo '# etcd' >> /etc/profile root@ruo91:~# echo 'export ETCD=/opt/etcd' >> /etc/profile root@ruo91:~# echo 'export PATH=$PATH:$ETCD' >> /etc/profile root@ruo91:~# echo '' >> /etc/profile root@ruo91:~# source /etc/profile
– ETCD Clustering
각각의 서버마다 실행 하시면 됩니다.
* etcd-0
root@ruo91:~# etcd \ --name "cluster-0" \ --data-dir "/tmp/etcd" \ --initial-cluster-state "new" \ --initial-cluster-token "etcd-cluster" \ --listen-peer-urls "http://0.0.0.0:2380" \ --listen-client-urls "http://0.0.0.0:4001" \ --advertise-client-urls "http://0.0.0.0:4001" \ --initial-advertise-peer-urls "http://172.17.1.1:2380" \ --initial-cluster "cluster-0=http://172.17.1.1:2380,cluster-1=http://172.17.1.2:2380,cluster-2=http://172.17.1.3:2380" \ > /tmp/etcd-cluster.log 2>&1 &
* etcd-1
root@ruo91:~# etcd \ --name "cluster-1" \ --data-dir "/tmp/etcd" \ --initial-cluster-state "new" \ --initial-cluster-token "etcd-cluster" \ --listen-peer-urls "http://0.0.0.0:2380" \ --listen-client-urls "http://0.0.0.0:4001" \ --advertise-client-urls "http://0.0.0.0:4001" \ --initial-advertise-peer-urls "http://172.17.1.2:2380" \ --initial-cluster "cluster-0=http://172.17.1.1:2380,cluster-1=http://172.17.1.2:2380,cluster-2=http://172.17.1.3:2380" \ > /tmp/etcd-cluster.log 2>&1 &
* etcd-2
root@ruo91:~# etcd \ --name "cluster-2" \ --data-dir "/tmp/etcd" \ --initial-cluster-state "new" \ --initial-cluster-token "etcd-cluster" \ --listen-peer-urls "http://0.0.0.0:2380" \ --listen-client-urls "http://0.0.0.0:4001" \ --advertise-client-urls "http://0.0.0.0:4001" \ --initial-advertise-peer-urls "http://172.17.1.3:2380" \ --initial-cluster "cluster-0=http://172.17.1.1:2380,cluster-1=http://172.17.1.2:2380,cluster-2=http://172.17.1.3:2380" \ > /tmp/etcd-cluster.log 2>&1 &
5. K8SM – Mesos Master
Mesos를 패키지로 설치 할 경우 ZooKeeper도 함께 설치 되므로, ZooKeeper 서버를 따로 구성 하지 않아도 됩니다.
만일, ZooKeeper 서버를 따로 구성 하려는 경우 본문의 ZooKeeper 관련 설정은 무시 하면 됩니다.
– Mesos 설치
root@ruo91:~# apt-get update && apt-get install -y add-apt-key root@ruo91:~# apt-key adv --keyserver keyserver.ubuntu.com --recv E56151BF root@ruo91:~# echo "deb http://repos.mesosphere.io/ubuntu trusty main" > /etc/apt/sources.list.d/mesosphere.list root@ruo91:~# apt-get update && apt-get install -y mesos
– ZooKeeper 설정
root@ruo91:~# echo '# ZooKeeper Quorum' >> /etc/zookeeper/conf/zoo.cfg root@ruo91:~# echo 'server.1=172.17.1.4:2888:3888' >> /etc/zookeeper/conf/zoo.cfg root@ruo91:~# echo 'server.2=172.17.1.5:2888:3888' >> /etc/zookeeper/conf/zoo.cfg root@ruo91:~# echo 'server.3=172.17.1.6:2888:3888' >> /etc/zookeeper/conf/zoo.cfg root@ruo91:~# echo 'server.4=172.17.1.7:2888:3888' >> /etc/zookeeper/conf/zoo.cfg
– ZooKeeper MyID 설정
* mesos-master-0
root@ruo91:~# echo '1' >> /etc/zookeeper/myid
* mesos-master-1
root@ruo91:~# echo '2' >> /etc/zookeeper/myid
* mesos-master-2
root@ruo91:~# echo '3' >> /etc/zookeeper/myid
* mesos-master-3
root@ruo91:~# echo '4' >> /etc/zookeeper/myid
– ZooKeeper 시작
각각의 서버마다 실행 하시면 됩니다.
root@ruo91:~# service zookeeper start
– Mesos Master 시작
각각의 서버마다 실행 하시면 됩니다.
실행 할때 주의 할 점이 있는데, mesos 0.2x 버전대에서 quorum 옵션 값이 2이 상이 되면 리더 Master 서버가 죽는 문제가 있습니다.
이 문제는 값을 1로 하면 해결이 되며, 해당 링크는 https://gist.github.com/jaytaylor/3fced64bcf1fecc61d18 에서 확인 하실 수 있습니다.
root@ruo91:~# mesos-master \ --quorum=1 \ --cluster=mesos-cluster \ --work_dir=/var/lib/mesos \ --zk=zk://172.17.1.4:2181,172.17.1.5:2181,172.17.1.6:2181,172.17.1.7:2181/mesos \ > /tmp/mesos-master.log 2>&1 &
6. K8SM – Minion & Mesos Slave
Minion에 Container가 실행 되므로, Docker가 설치 되어 있어야 합니다.
또한, Mesos Slave가 kubelet(executor), proxy를 실행 하기 위해서는 Kubernetes Server가 설치 되어 있어야 합니다.
– Docker 설치
root@ruo91:~# apt-get install -y docker.io
– Docker 설정 (AUFS 사용자만 설정 하시면 됩니다.)
Docker 데몬 옵션 설정 파일에 스토리지 드라이버를 OverlayFS로 변경 후 재시작 합니다.
OverlayFS로 설정하는 이유는 Docker 1.x 버전대 중에 AUFS를 기본으로 사용하는데, 이 AUFS가 리눅스 커널과 충돌이 잦습니다.
Container 실행 중에 HostOS가 멈춤 현상이 발생 할 수 있기 때문에,
Docker 공식 문서에서도 AUFS 대신에, Devicemapper, Btrfs, OverlayFS를 사용 하도록 권장 하고 있습니다.
(참고로, OverlayFS는 Linux Kernel 3.10+ 이상에서 사용 가능 합니다.)
root@ruo91:~# nano /etc/default/docker.io DOCKER_OPTIONS="-s overlay --dns-server 8.8.8.8 --dns-server 8.8.4.4 --dns-search google-public-dns-a.google.com"
기존의 Docker 이미지 저장소를 삭제하고 재시작 합니다.
root@ruo91:~# service docker.io stop root@ruo91:~# rm -rf /var/lib/docker root@ruo91:~# service docker.io start
– Mesos 설치
root@ruo91:~# apt-get update && apt-get install -y add-apt-key root@ruo91:~# apt-key adv --keyserver keyserver.ubuntu.com --recv E56151BF root@ruo91:~# echo "deb http://repos.mesosphere.io/ubuntu trusty main" > /etc/apt/sources.list.d/mesosphere.list root@ruo91:~# apt-get update && apt-get install -y mesos
– Mesos Slave 시작
각각의 서버마다 실행 하시면 됩니다.
root@ruo91:~# mesos-slave \ --master=zk://172.17.1.4:2181,172.17.1.5:2181,172.17.1.6:2181,172.17.1.7:2181/mesos \ > /tmp/mesos-slave.log 2>&1 &
– Kubernetes 빌드
kubernetes는 Docker를 활용하여 빌드가 됩니다. 따라서, Docker가 미리 설치 되어 있어야 합니다.
또한, 빌드시 주의 할 점이 있는데, KUBERNETES_CONTRIB 변수를 설정 하지 않으면, 빌드 완료시에 K8SM 관련 바이너리를 얻을 수 없습니다.
root@ruo91:~# git clone https://github.com/GoogleCloudPlatform/kubernetes /opt/k8s root@ruo91:~# cd k8s root@ruo91:~# export KUBERNETES_CONTRIB=mesos root@ruo91:~# make release
– Kubernetes Server 설정
빌드가 완료 되면 _output 디렉토리에 파일이 생성 됩니다.
여기서 필요한 파일은 server만 필요 하므로 client 파일은 SCP나 FTP로 파일을 따로 보관 바랍니다.
_output/release-tars/kubernetes-client-linux-amd64.tar.gz _output/release-tars/kubernetes-server-linux-amd64.tar.gz
root@ruo91:~# tar -C /opt -xzvf _output/release-tars/kubernetes-server-linux-amd64.tar.gz root@ruo91:~# echo '# Kubernetes Server' >> /etc/profile root@ruo91:~# echo 'export K8S_HOME=/opt/kubernetes' >> /etc/profile root@ruo91:~# echo 'export PATH=$PATH:$K8S_HOME/server/bin' >> /etc/profile root@ruo91:~# source /etc/profile
7. K8SM – Kubernetes Mesos Framework
K8SM도 기존 Kubernetes의 API Server, Scheduler, Controller Manager 서버를 km 바이너리로 실행 합니다.
따라서, 위 “K8SM – Minion & Mesos Slave”에서 언급한 “kubernetes-server-linux-amd64.tar.gz” 파일이 필요로 합니다.
(해당 server 파일을 /opt 디렉토리에 업로드 하였다는 가정하에 진행 하겠습니다.)
– Kubernetes Server 설정
root@ruo91:~# tar -C /opt -xzvf /opt/kubernetes-server-linux-amd64.tar.gz root@ruo91:~# echo '# Kubernetes Server' >> /etc/profile root@ruo91:~# echo 'export K8S_HOME=/opt/kubernetes' >> /etc/profile root@ruo91:~# echo 'export PATH=$PATH:$K8S_HOME/server/bin' >> /etc/profile root@ruo91:~# source /etc/profile
– Mesos Cloud 설정 파일 생성
Mesos의 Master에 대한 설정을 해줘야 합니다. ZooKeeper를 사용하여 Mesos Master의 리더를 선별을 하도록 사용중이면,
아래와 같이 ZooKeeper 서버를 추가 해주면 됩니다.
root@ruo91:~# cat > /opt/mesos-cloud.conf << EOF [mesos-cloud] mesos-master = zk://172.17.1.4:2181,172.17.1.5:2181,172.17.1.6:2181/mesos EOF
만일, Mesos Master를 단일로 운용 중이라면 아래와 같이 Mesos Master만 추가 해주면 됩니다.
root@ruo91:~# cat > /opt/mesos-cloud.conf << EOF [mesos-cloud] mesos-master = 172.17.1.4:5050 EOF
– K8SM 실행
K8SM의 실행 순서는 API Server -> Controller Manager -> Scheduler 로 합니다.
* API Server
root@ruo91:~# km apiserver \ --port=8080 \ --address=0.0.0.0 \ --cloud-provider=mesos \ --cloud-config=/opt/mesos-cloud.conf \ --service-cluster-ip-range=10.0.42.1/16 \ --etcd-servers=http://172.17.1.1:4001,http://172.17.1.2:4001,http://172.17.1.3:4001 \ --v=1 > /tmp/apiserver.log 2>&1 &
* Controller Manager
root@ruo91:~# km controller-manager \ --master=172.17.1.8:8080 \ --cloud-provider=mesos\ --cloud-config=/opt/mesos-cloud.conf \ --v=1 > /tmp/controller-manager.log 2>&1 &
* Scheduler
root@ruo91:~# km scheduler \ --address=0.0.0.0 \ --mesos-user=root \ --api-servers=172.17.1.8:8080 \ --etcd-servers=http://172.17.1.1:4001,http://172.17.1.2:4001,http://172.17.1.3:4001 \ --mesos-master=zk://172.17.1.4:2181,172.17.1.5:2181,172.17.1.6:2181,172.17.1.7:2181/mesos \ --v=2 > /tmp/scheduler.log 2>&1 &
8. K8SM – Web Server
K8SM은 Mesos와 Kubernetes 조합이므로 Mesos Master의 UI, Kubernetes의 API Server UI 두 개를 통해 웹으로 확인이 가능합니다.
이 부분을 특정 도메인을 통해 접속이 이뤄지도록 Nginx에 리버스 프록시 설정을 하겠습니다.
– Nginx 설치
root@ruo91:~# apt-get install -y nginx
– Nginx Reverse Proxy 설정
root@ruo91:~# nano /etc/nginx/conf.d/k8sm.conf
# Mesos master web ui server { listen 80; server_name mesos.yongbok.net; location / { proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://172.17.1.4:5050; client_max_body_size 10M; } } # Kubernetes apiserver web ui server { listen 80; server_name kubernetes.yongbok.net; location / { proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://172.17.1.8:8080; client_max_body_size 10M; } }
root@ruo91:~# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
root@ruo91:~# nginx -s reload
9. K8SM – Client & Test
Pods를 생성하기 위해서는 kubectl 바이너리가 필요합니다.
따라서, 위 “K8SM – Minion & Mesos Slave”에서 언급한 “kubernetes-client-linux-amd64.tar.gz” 파일이 필요로 합니다.
(해당 client 파일을 /opt 디렉토리에 업로드 하였다는 가정하에 진행 하겠습니다.)
– Kubernetes Client 설정
root@ruo91:~# tar -C /opt -xzvf /opt/kubernetes-client-linux-amd64.tar.gz root@ruo91:~# echo '# Kubernetes Client' >> /etc/profile root@ruo91:~# echo 'export K8S_HOME=/opt/kubernetes' >> /etc/profile root@ruo91:~# echo 'export PATH=$PATH:$K8S_HOME/client/bin' >> /etc/profile root@ruo91:~# source /etc/profile
Mesos Master에 K8SM이 정상적으로 등록이 되었는지 확인 해보겠습니다.
(-s 옵션은 API Server를 뜻하며, 실행시 k8sm-scheduler이 나오지 않는다면 구성에 문제가 있는 것입니다.)
root@ruo91:~# docker exec kubernetes-mesos kubectl get services
NAME LABELS SELECTOR IP(S) PORT(S) AGE k8sm-scheduler component=scheduler,provider=k8sm <none> 10.0.18.129 10251/TCP 33s kubernetes component=apiserver,provider=kubernetes <none> 10.0.0.1 443/TCP 1m
예제 Nginx YAML 파일을 통해 Pods를 구성 해봅니다.
root@ruo91:~# docker exec kubernetes-mesos kubectl create -f /opt/nginx.yaml -s 172.17.1.8:8080
pods/nginx
Pods를 확인 해봤을때, STATUS 부분에 Pending 상태로 되어있는 경우, Docker Images를 받아오는 중이라고 생각 하시면 됩니다.
또한, Running의 경우 Container가 실행 중이라는 뜻입니다.
root@ruo91:~# docker exec kubernetes-mesos kubectl get pods
NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 14s
Web Server 부분에서 설정한 도메인으로 접속 하면 웹에서 해당 UI를 확인 해볼 수 있습니다.
– Mesos Master WEB UI
– Mesos Master WEB UI – Framework
– Mesos Master WEB UI – Framework ID
– Kubernetes Web UI
– Kubernetes Web UI – Pods
Reference
– Google Kubernetes
https://github.com/googlecloudplatform/kubernetes
– Mesosphere Kubernetes Mesos
https://github.com/mesosphere/kubernetes-mesos
– ruo91/docker-kubernetes-mesos
https://github.com/ruo91/docker-kubernetes-mesos
– Yongbok Blog: Apache Mesos Cluster Resource Management
https://www.yongbok.net/blog/apache-mesos-cluster-resource-management/
– Yongbok Blog: Google Kubernetes- Container Cluster Manager
https://www.yongbok.net/blog/google-kubernetes-container-cluster-manager/
Thanks 🙂