在Docker容器技術(shù)火熱發(fā)展的今天,如何將分布在不同物理機上的Docker容器組織、管理、調(diào)度起來成為一個急需解決的問題,Kubernetes正是解決這個問題的最佳實踐。Kubernetes是一個開源的系統(tǒng),可以自動部署,擴展和管理運行在Docker容器中的應(yīng)用程序。Kubernetes可以根據(jù)應(yīng)用程序?qū)Y源的需求在集群中創(chuàng)建相應(yīng)的容器,在容器中啟動程序,同時借助于網(wǎng)絡(luò)插件在不同物理機的容器之間建立通信鏈接?;贙ubernetes,可以非常便利的將運行在容器中的大數(shù)據(jù)程序部署和管理起來。
簡介
Kubernetes原型是Google內(nèi)部的產(chǎn)品,具有15年產(chǎn)品負(fù)載管理的經(jīng)驗,目前是開源系統(tǒng)中Docker容器管理最成熟的產(chǎn)品,可以支持管理1000個節(jié)點,運行30000個Pods,在單個節(jié)點上,kubelet可支持100個Pods。Kubernetes按組管理容器,這樣可以按照邏輯單元組織應(yīng)用程序,使得應(yīng)用程序易于管理。同時支持水平擴展,可以增加和減少大數(shù)據(jù)計算節(jié)點的規(guī)模。Kubernetes本身不管理容器網(wǎng)絡(luò),容器網(wǎng)絡(luò)需要依賴于第三方網(wǎng)絡(luò)插件來建立,比如Flannel和Weave。
表1.Kubernetes相關(guān)的術(shù)語
Kubernetes架構(gòu)
Kubernetes本身也是一個分布式系統(tǒng),采用mast-slave模式運行在物理機上,Node節(jié)點上必須裝有Docker用于啟動容器。其架構(gòu)如圖1所示:
Master節(jié)點上主要運行Kubernetes API Server,Scheduler,Controller manager這幾個組件,負(fù)責(zé)接收Node節(jié)點的連接,從Node節(jié)點收集資源,調(diào)度Pod,通知Node創(chuàng)建Pod, 管理ReplicationController,提供REST接口等。 Node節(jié)點上主要運行kubelet和kube-proxy組件。kubelet負(fù)責(zé)管理容器,kube-proxy負(fù)責(zé)網(wǎng)絡(luò)代理和負(fù)載均衡。
圖1. Kubernetes 架構(gòu)
Weave(容器間網(wǎng)絡(luò)支持)
Weave在每個Docker物理機上都啟動了一個特殊的route容器,不同的宿主機上的route容器連接起來,route攔截所有普通容器的ip請求,通過UDP包發(fā)送到其它宿主機上的容器,這樣在不同物理機上的容器端就可以看到一個扁平的網(wǎng)絡(luò)。通過weave創(chuàng)建的overlay網(wǎng)絡(luò)同時支持tcp通信和udp通信。
圖2. Weave示意圖
1.安裝Weave
$ curl -L git.io/weave -o /usr/local/bin/weave $ chmod +x /usr/local/bin/weave $ weave setup
從Weave網(wǎng)站下載的Weave的binary是個腳本文件,執(zhí)行weave setup會下載weave使用的幾個Docker鏡像,weave也是以docker鏡像的形式發(fā)布產(chǎn)品包,沒有提供rpm安裝包:
docker.io/weaveworks/weave docker.io/weaveworks/weaveexec docker.io/weaveworks/plugin docker.io/weaveworks/weavedb
2.建立Weave overlayye
$ weave launch-proxy --rewrite-inspect --without-dns --no-detect-tls
$ weave launch-router
$ weave launch-router $(weave master host name)
此外,如果需要Docker 容器中的進程訪問其它物理機,需要將Docker host expose到weave網(wǎng)絡(luò)中($ weave expose)。 比如將HDFS這種基礎(chǔ)服務(wù)直接裝在物理機上,這樣在容器中啟動的大數(shù)據(jù)應(yīng)用就需要訪問物理機上的HDFS端口,如果不將物理機加入到weave網(wǎng)絡(luò)中,那么容器中將無法訪問物理機上的服務(wù)端口。該命令會輸出一個虛擬IP,作為物理機在overlay網(wǎng)絡(luò)中的IP地址。
3.驗證容器間的網(wǎng)絡(luò)
$ docker run -ti --rm -v /opt/netserver:/opt/netserver -v /usr/sbin/ifconfig:/usr/sbin/ifconfig rhel /bin/sh sh-4.2# ifconfig ethwe ethwe: flags=4163 mtu 1410 inet 10.32.0.2 netmask 255.240.0.0 broadcast 0.0.0.0 inet6 fe80::34ee:70ff:fe7d:e533 prefixlen 64 scopeid 0x20 ether 36:ee:70:7d:e5:33 txqueuelen 0 (Ethernet) RX packets 13 bytes 830 (830.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 620 (620.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 sh-4.2# /opt/netserver Starting netserver with host 'IN(6)ADDR_ANY' port '12865' and family AF_UNSPEC
$ docker run -ti --rm -v /opt/netperf:/opt/netperf -v /usr/sbin/ifconfig:/usr/sbin/ifconfig rhel /bin/sh sh-4.2# ifconfig ethwe ethwe: flags=4163 mtu 1410 inet 10.44.0.2 netmask 255.240.0.0 broadcast 0.0.0.0 inet6 fe80::b460:77ff:fe81:1f5d prefixlen 64 scopeid 0x20 ether b6:60:77:81:1f:5d txqueuelen 0 (Ethernet) RX packets 8 bytes 592 (592.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 7 bytes 550 (550.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
TCP_STREAM 類型測試:
sh-4.2# /opt/netperf -H 10.32.0.2 -l 10 -t TCP_STREAM MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.32.0.2 () port 0 AF_INET Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 10.32 90.63
UDP_STREAM類型測試:
sh-4.2# /opt/netperf -H 10.32.0.2 -l 10 -t UDP_STREAM MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.32.0.2 () port 0 AF_INET Socket Message Elapsed Messages Size Size Time Okay Errors Throughput bytes bytes secs # # 10^6bits/sec
212992 65507 10.00 509277 0 26688.73 212992 10.00 2475 129.70
經(jīng)筆者測試,目前只有Weave支持容器間UDP網(wǎng)絡(luò)通信,其它插件Flannel,OpenVSwitch以及Calico均不支持。
部署Kubernetes環(huán)境
本文以Linux RedHat操作系統(tǒng)為例,來說明如何安裝和部署Kubernetes集群。其中最關(guān)鍵的一點就是將Weave集成到kubelet中,這樣Kubernetes啟動容器的時候就會分配Weave網(wǎng)絡(luò)地址。要做到這一點,需要在kubelet配置文件中指定docker-endpoint 為Weave的socket /var/run/weave/weave.sock。
1.在所有節(jié)點上安裝Kubernetes和etcd:
$ yum install kubernetes etcd
2.確保所有節(jié)點上Docker service已經(jīng)啟動:
$ systemctl start docker
3.在Kubernetes master 節(jié)點上,更改下列配置文件:
a). /etc/etcd/etcd.conf:
ETCD_LISTEN_CLIENT_URLS='http://kube01:2379' ETCD_ADVERTISE_CLIENT_URLS='http://kube01:2379' b). /etc/kubernetes/config KUBE_ALLOW_PRIV='--allow-privileged=true' KUBE_MASTER='--master=http://kube01:8080' c). /etc/kubernetes/apiserver KUBE_API_ADDRESS='--insecure-bind-address=0.0.0.0' KUBE_ETCD_SERVERS='--etcd-servers=http://kube01:2379' KUBE_ADMISSION_CONTROL='--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota' d). /etc/kubernetes/kubelet: (這里將master也用作slave node) KUBELET_ADDRESS='--address=0.0.0.0' KUBELET_HOSTNAME='--hostname-override=kube01' KUBELET_API_SERVER='--api-servers=http://kube01:8080' KUBELET_ARGS='--docker-endpoint=unix:///var/run/weave/weave.sock'
4.啟動Kubernetes master:
# systemctl start etcd kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet
5.在kubernetes node節(jié)點,更改下列配置文件:
a). /etc/kubernetes/config KUBE_ALLOW_PRIV='--allow-privileged=true' KUBE_MASTER='--master=http://kube01:8080' b). /etc/kubernetes/kubelet KUBELET_ADDRESS='--address=0.0.0.0' KUBELET_HOSTNAME='--hostname-override=kube02' KUBELET_API_SERVER='--api-servers=http://kube01:8080' KUBELET_ARGS='--docker-endpoint=unix:///var/run/weave/weave.sock'
6.啟動Kubernetes node:
$ systemctl start kube-proxy kubelet
7.檢查Kubernetes 集群狀態(tài):
$ kubectl get nodes NAME LABELS STATUS AGE kube02 kubernetes.io/hostname=kube02 Ready 13m kube01 kubernetes.io/hostname=kube01 Ready 16m
8.啟動Kubernetes Dashboard模塊:
最開始Kubernetes的WEB模塊叫做kube-ui,是一個只讀的UI,目前發(fā)展到Kubernetes Dashboard,可以查看和修改,以及從WEB上提交YAML文件。Kubernetes Dashboard需要使用”kube-system”的namespace,如果沒有該namespace,那么需要先創(chuàng)建該namespace。
apiVersion: v1 kind: Namespace metadata: name: kube-system
然后創(chuàng)建Kubernetes Dashboard模塊:
$kubectl create -f https:///kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml deployment 'kubernetes-dashboard' created You have exposed your service on an external port on all nodes in your cluster. If you want to expose this service to the external internet, you may need to set up firewall rules for the service port(s) (tcp:32283) to serve traffic.
See http://releases./release-1.2/docs/user-guide/services-firewalls.md for more details. service 'kubernetes-dashboard' created
Kubernetes Dashboard 會啟動一個gcr.io/google_containers/kubernetes-dashboard-amd64:v1.1.0的Docker容器,該容器需要訪問Kubernetes master的8080端口,一般情況下,該容器會被調(diào)度到任意主機上啟動,所以需要把該yaml文件下載下來并手工指定apiserver-host配置。創(chuàng)建后訪問任意Node的32283端口即可訪問Kubernetes dashboard(如圖3所示)。
圖3. Kubernetes Dashboard.
至此,我們完成了Kubernetes集群的安裝部署,并且解決了Docker容器在不同物理機間的網(wǎng)絡(luò)支持問題,接下來將給大家介紹如何在當(dāng)前Kubernetes環(huán)境中部署IBM Spectrum Symphony集群。
部署集群
IBM Spectrum Symphony是一款大數(shù)據(jù)和高性能分析的產(chǎn)品。它一方面實現(xiàn)了對所有Hadoop接口的完全兼容,另一方面提供了自己的API,使得高性能分析應(yīng)用很容易在幾千臺機器上動態(tài)地運行。
1.首先編譯Symphony的docker鏡像(sym712):
$ docker build –t sym712 –f Dockerfile ./
Dockerfile內(nèi)容如下:
FROM rhel MAINTAINER Jin Ming Lv # Add user 'egoadmin' & install ssh-server and other basic tools RUN useradd -m egoadmin \ && echo 'egoadmin:egoadmin' | chpasswd \ && echo 'egoadmin ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers \ && echo -e '[base] \nname=CentOS-7 - Base - centos.com\nbaseurl=http://mirror./centos/7/os/\$basearch/\ngpgcheck=1\ngpgkey=http://mirror./centos/RPM-GPG-KEY-CentOS-7' > /etc/yum.repos.d/CentOS7-Base.repo \ && yum clean all \ && yum install -y openssh-server which net-tools sudo wget hostname tar openssh-clients gettext iputils \ && sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config \ && ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key \ && ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key \ && ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key \ && mkdir /var/run/sshd ADD platform_sym_adv_entitlement.dat /opt/platform_sym_adv_entitlement.dat # Download & Install Symphony package RUN wget --no-check-certificate -O /opt/symsetup_linux-x86_64.bin https://lweb.eng.platformlab.ibm.com/engr/pcc/release_eng/work/sym/sym_mainline/last/symsetup7.1.2.0_x86_64.bin \ && export CLUSTERADMIN=egoadmin \ && export CLUSTERNAME=symphony712 \ && export DERBY_DB_HOST=localhost \ && export BASEPORT=17869 \ && export SIMPLIFIEDWEM=Y \ && chmod +x /opt/* \ && /opt/symsetup_linux-x86_64.bin --quiet --force \ && rm -f /opt/*.bin USER egoadmin
2.啟動Symphony Master節(jié)點,用Replication Controller定義一個Symphony Master容器。用Replication Controller而不用Pod定義容器的好處在于Kubernetes會保證有一個Symphony master的容器存在,即便容器所在的物理機宕機。同時我們指定master容器需要使用的內(nèi)存和CPU大小。
kind: ReplicationController apiVersion: v1 metadata: name: sym-master spec: replicas: 1 selector: component: sym-master template: metadata: labels: component: sym-master spec: containers: - name: sym-master image: sym712 command: ['/bin/sh', '-c', 'source /opt/ibm/platform/profile.platform; egoconfig join `hostname` -f; egoconfig setentitlement /opt/platform_sym_adv_entitlement.dat; egosh ego start; sudo /usr/sbin/sshd -D'] resources: requests: cpu: 100m memory: 4096M limits: memory: 8192M
調(diào)用Kubernetes命令創(chuàng)建Symphony master容器。
$ kubectl create -f /tmp/sym_master.yaml replicationcontroller 'sym-master' created $ kubectl get rc NAME DESIRED CURRENT AGE sym-master 1 1 10s
查看master 容器已經(jīng)啟動。
$ kubectl get pod NAME READY STATUS RESTARTS AGE sym-master-04yws 1/1 Running 0 1m
3.container啟動之后,在master節(jié)點上我們需要獲得master節(jié)點的IP地址和hostname,用于在compute節(jié)點中指定此集群的master。
# kubectl get pods NAME READY STATUS RESTARTS AGE sym-master-rc-04yws 1/1 Running 0 1m # kubectl describe pod sym-master-04yws | grep IP IP: 10.32.0.1
Master節(jié)點的主機名為容器名稱sym-master-rc-04yws,IP地址為10.32.0.1。
4.啟動Symphony Compute節(jié)點,將master節(jié)點的IP地址和hostname配置在Compute節(jié)點的啟動命令中,在本例中,我們啟動2個compute節(jié)點連接到master容器中。
kind: ReplicationController apiVersion: v1 metadata: name: sym-compute spec: replicas: 2 selector: component: sym-compute template: metadata: labels: component: sym-compute spec: containers: - name: sym-compute image: sym712 command: ['/bin/sh', '-c', 'source /opt/ibm/platform/profile.platform; sudo chmod 777 /etc/hosts; echo '10.32.0.1 sym-master-rc-04yws' >> /etc/hosts; egoconfig join sym-master-rc-04yws -f; egosh ego start; sudo /usr/sbin/sshd -D'] resources: requests: memory: 2048M
調(diào)用Kubernetes命令創(chuàng)建Symphony compute節(jié)點。
$ kubectl create -f /tmp/sym_compute.yaml replicationcontroller 'sym- compute ' created
5.查看pod啟動狀態(tài):
$ kubectl get pods NAME READY STATUS RESTARTS AGE sym-compute-a6aff 1/1 Running 0 28s sym-compute- r5arf 1/1 Running 0 28s sym-master-04yws 1/1 Running 0 19m
6.登錄到任何一個container, 可以查看Symphony 集群的啟動狀態(tài):
$ docker exec -it 24b61a193f9c /bin/bash [egoadmin@sym-master-rc-9vicc platformsymphony]$ egosh resource list -l NAME status mem swp tmp ut it pg r1m r15s r15m ls sym-master-04yws ok 391M 670M 91G 25% 37 337.6 5.8 0.7 8.9 0 sym-compute-a6aff ok 391M 668M 91G 27% 47 418.2 6.3 0.0 8.9 0 sym-compute-r5arf ok 391M 668M 91G 27% 47 418.2 6.3 0.0 8.9 0
此時,Symphony集群的master和兩個compute nodes已經(jīng)正常啟動。
7.Kubernetes的replicationcontroller支持?jǐn)U減容,如果我們想將compute nodes擴展到10個,可以執(zhí)行以下命令。
$ kubectl scale --replicas=10 replicationcontrollers sym-compute replicationcontroller 'sym-compute' scaled
8.將Symphony master的WEB服務(wù)端口部署為Kubernetes的service,這樣可以在集群外部訪問到集群中Symphony master WEB GUI服務(wù)。
定義一個NodePort的Service,將sym-master的8443端口expose到集群外。
kind: Service apiVersion: v1 metadata: name: sym-webgui spec: ports: - port: 8443 targetPort: 8443 protocol: TCP name: https selector: component: sym-master type: NodePort
在Kubernetes中創(chuàng)建該Service:
$kubectl create -f sym-webgui-svc.yaml。 $ kubectl describe service sym-webgui Name: sym-webgui Namespace: default Labels: Selector: component=sym-master Type: NodePort Port: https 8443/TCP NodePort: https 31439/TCP Endpoints: 10.32.0.1:8443 Session Affinity: None No events.
Kubernetes會為該Service分配一個可用的端口31439,訪問Kubernetes集群中任意Node的31439端口可以訪問到Symphony master的8334端口。
比如在集群外部訪問https://docker_host1:31439/platform/login/login.html可以訪問到Symphony的GUI Portal。
結(jié)束語
隨著Docker容器技術(shù)和大數(shù)據(jù)技術(shù)的發(fā)展,兩者的結(jié)合變得非常重要,將大數(shù)據(jù)平臺運行在Docker容器中可以享受Docker帶來的隔離、發(fā)布等優(yōu)勢特性,使得大數(shù)據(jù)平臺的搭建變得非常簡單,同時又有很好的性能。本文以IBM Spectrum Symphony為例,來說明如何利用Kubernetes在集群中快速搭建和啟動一個大數(shù)據(jù)平臺。Kubernetes目前已經(jīng)發(fā)展的比較成熟,達到了商用的標(biāo)準(zhǔn),其中的Feature也是很多,本文沒有一一闡述,大家可以關(guān)注Kubernetes開源社區(qū)。
作者簡介:呂金明,2011加入IBM至今,一直從事分布式計算以及大數(shù)據(jù)相關(guān)的研發(fā)工作,以及大數(shù)據(jù)產(chǎn)品的集成,如Hadoop、Yarn、Spark,Docker等開源框架及技術(shù)。
|