以前在《Kubernetes初體驗》中咱們使用Minikube快速體驗了一把Kubernetes,而後在《Kubernetes架構及資源關係簡單總結》一文中咱們又簡單介紹了Kubernetes的框架以及Kubernetes中的一些關鍵術語和概念,或者稱之爲資源、對象。本文主要講Kubernetes的一種原始部署方式。Kubernetes從開發至今,其部署方式已經變得愈來愈簡單。常見的有三種:html
kube-up.sh
就能夠部署一個Kubernetes集羣。可參見官方文檔《Manually Deploying Kubernetes on Ubuntu Nodes》。PS:目前,該文檔部署Kubernetes 1.5.3版本會有些問題,可關注#39224。其實,除了上面三種方式外,有些Linux發行版已經提供了Kubernetes的安裝包,好比在CentOS 7上面,直接執行yum install -y etcd kubernetes
便可安裝Kubernetes,而後作些配置就能夠完成部署了。我相信對於Google這種追求自動化、智能化的公司,他們會讓Kubernetes部署方式還會更加簡化。但這些都不是本文的重點,本文要講述的是如何像堆積木同樣一個模塊一個模塊的部署Kubernetes。爲何要這樣作?node
爲了更好的理解學習Kubernetes。前面咱們已經簡單介紹過Kubernetes的架構,知道它實際上是由幾大模塊組成,各個模塊間合做構成一個集羣。如今簡單化的部署方式屏蔽了不少細節,使得咱們對於各個模塊的感知少了不少。並且很容器以爲Kubernetes的內部部署細節很是的麻煩或者複雜,但其實並不是如此,其實Kubernetes集羣就是由爲數很少的幾個二進制文件組成,部署一個基本的集羣也非難事。由於是使用Go開發的,這些二進制文件也沒有任何依賴,從別的地方拷貝過來就可以使用。本文就介紹如何從這些二進制文件搭建一個Kubernetes集羣, 以加深對Kubernetes的理解。並且,其餘部署方式其實也只是對這種方式的一種封裝。linux
如今Systemd逐漸替代了Upstart,有的部署方式也只支持Systemd的Linux發行版,若是是Upstart,還得作適配。至於什麼是Systemd和Upstart,不是本文要討論的,後續會總結髮出來。這裏我使用的Linux發行版是Ubuntu 16.04。固然Ubuntu 15.04+的都使用的是Systemd,應該都是適用的,其餘使用Systemd的系統應該也是適用的,但可能須要作些小的改動。另外,前文介紹了Kubernetes集羣分爲Master和Node,因此咱們部署也同樣,分爲Master的部署和Node的部署。git
個人環境是用Virtualbox虛擬了兩臺Ubuntu 16.04,虛擬機和主機的通訊方式是NAT和host-only方式。NAT用於訪問外網,host-only用於兩臺虛擬機之間訪問,IP分別爲192.168.56.101和192.168.56.102.其中101這臺機器機器既是Master,又是Node;102是Node。本文只裝了101,後面再測試網絡等須要多臺的時候再安裝102.由於Kubernetes裏面Node是主動向Master註冊的(經過Node上面的kubelet),因此要擴展Node的話也很是容易。github
咱們都須要哪些二進制文件呢?回想一下《Kubernetes架構及資源關係簡單總結》中,Kubernetes集羣內主要包含這些模塊:Master中:APIServer、scheduler、controller manager、etcd;Node中:kubelet、kube-proxy、runtime(這裏指Docker)。docker
上面每一個模塊都由一個二進制文件實現,因此咱們須要上面每一個模塊對應的那個二進制文件。獲取方式有不少。最直觀的方式就是去github上面下載release的包,裏面有二進制文件。但那個包有1GB+大小,特別對於中國用戶就呵呵了,固然還有許多其餘獲取的方式。shell
注意:源代碼目錄裏面也有不少名字和二進制名字相同的文件,但那些不是二進制文件,而是一些去掉後綴的shell腳步,都只有KB級別的大小,而真正的二進制文件都是MB級別的,注意別搞錯了。ubuntu
推薦使用下面的命令下載kubernetes-server-linux-amd64.tar.gz
包:api
curl -L https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/kubernetes-server-linux-amd64.tar.gz -o kubernetes-server-linux-amd64.tar.gz
這個包解壓後的kubernetes/server/bin
目錄下就有咱們須要的二進制文件(只使用了其中6個):安全
Bash
ubuntu➜ bin ll total 1.3G -rwxr-x--- 1 root root 145M Dec 14 09:06 hyperkube -rwxr-x--- 1 root root 118M Dec 14 09:06 kube-apiserver -rw-r----- 1 root root 33 Dec 14 09:06 kube-apiserver.docker_tag -rw-r----- 1 root root 119M Dec 14 09:06 kube-apiserver.tar -rwxr-x--- 1 root root 97M Dec 14 09:06 kube-controller-manager -rw-r----- 1 root root 33 Dec 14 09:06 kube-controller-manager.docker_tag -rw-r----- 1 root root 98M Dec 14 09:06 kube-controller-manager.tar -rwxr-x--- 1 root root 6.6M Dec 14 09:06 kube-discovery -rwxr-x--- 1 root root 44M Dec 14 09:05 kube-dns -rwxr-x--- 1 root root 44M Dec 14 09:05 kube-proxy -rw-r----- 1 root root 33 Dec 14 09:06 kube-proxy.docker_tag -rw-r----- 1 root root 174M Dec 14 09:06 kube-proxy.tar -rwxr-x--- 1 root root 51M Dec 14 09:06 kube-scheduler -rw-r----- 1 root root 33 Dec 14 09:06 kube-scheduler.docker_tag -rw-r----- 1 root root 52M Dec 14 09:06 kube-scheduler.tar -rwxr-x--- 1 root root 91M Dec 14 09:06 kubeadm -rwxr-x--- 1 root root 49M Dec 14 09:06 kubectl -rwxr-x--- 1 root root 46M Dec 14 09:06 kubefed -rwxr-x--- 1 root root 103M Dec 14 09:06 kubelet
我將這些二進制文件都放到了/opt/bin
目錄下,而且將該目錄加到了PATH中。你也能夠直接將這些文件放到系統的PATH路徑中,好比/usr/bin
。
OK,有了這些二進制文件,咱們就能夠開始部署了。
前文介紹過,Master上面主要四個模塊:APIServer、scheduler、controller manager、etcd,咱們一一來部署。
我建議直接使用apt install etcd
命令去安裝,這樣同時也會安裝etcdctl。安裝完後etcd的數據默認存儲在/var/lib/etcd/default
目錄,默認配置文件爲/etc/default/etcd
,可經過/lib/systemd/system/etcd.service
文件進行修改。
Kubernets新版本(我記得好像是1.6開始吧,記不清了)已經不支持etcd 2.x版本了,可是在Ubuntu 16.04上面經過apt install
裝的是2.2版本,這樣會致使api-server沒法和etcd通信,而致使一些問題,因此建議從github下載最新etcd 3.x(https://github.com/coreos/etcd/releases),而後手動安裝。建立/lib/systemd/system/etcd.service
文件:
[Unit] Description=Etcd Server Documentation=https://github.com/coreos/etcd After=network.target [Service] User=root Type=simple EnvironmentFile=-/etc/default/etcd ExecStart=/opt/k8s/v1_6_9/etcd-v3.2.7-linux-amd64/etcd # 改成你本身路徑 Restart=on-failure RestartSec=10s LimitNOFILE=40000 [Install] WantedBy=multi-user.target
安裝好之後,執行如下命令:
Bash
# 從新加載systemd配置管理,切記增長`*.service`後必定要先執行該命令,不然啓動服務時會報錯 systemctl daemon-reload systemctl enable etcd.service # 將etcd加到開機啓動列表中 systemctl start etcd.service # 啓動etcd
安裝好之後,etcd默認監聽http://127.0.0.1:2379
地址供客戶端鏈接。咱們可使用etcdctl
來檢查etcd是否正確啓動:
Bash
ubuntu➜ bin etcdctl cluster-health member ce2a822cea30bfca is healthy: got healthy result from http://localhost:2379 cluster is healthy
能夠看到運行正常。固然,部署多臺的話,由於全部Node都須要訪問etcd,因此etcd必需要監聽在其餘Node能夠訪問的IP上面才能夠,在/etc/default/etcd
中增長如下兩行:
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"
重啓etcd便可使etcd在全部IP上起監聽。
APIServer對應的二進制文件是kube-apiserver
,咱們先來設置systemd服務文件/lib/systemd/system/kube-apiserver.service
:
[Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes After=etcd.service Wants=etcd.service [Service] EnvironmentFile=/etc/kubernetes/apiserver ExecStart=/opt/bin/kube-apiserver $KUBE_API_ARGS Restart=on-failure Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target
重點項簡單說明:
After
。EnvironmentFile
是該服務的配置文件。ExecStart
說明如何啓動該服務。咱們看到kube-apiserver
的啓動參數爲$KUBE_API_ARGS
,咱們在配置文件/etc/kubernetes/apiserver
中定義這個環境變量:
KUBE_API_ARGS="--etcd_servers=http://127.0.0.1:2379 --insecure-bind-address=0.0.0.0 --insecure-port=8080 --service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535 --admission_control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ResourceQuota --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
選項說明:
--etcd_servers
:就是etcd的地址。--insecure-bind-address
:apiserver綁定主機的非安全IP地址,設置0.0.0.0
表示綁定全部IP地址。--insecure-port
:apiserver綁定主機的非安全端口,默認爲8080。--service-cluster-ip-range
:Kubernetes集羣中Service的虛擬IP地址段範圍,以CIDR格式表示,該IP範圍不能與物理機真實IP段有重合。-service-node-port-range
:Kubernetes集羣中Service可映射的物理機端口範圍,默認爲30000~32767.--admission_control
: Kubernetes集羣的准入控制設置,各控制模塊以插件形式依次生效。--logtostderr
:設置爲false表示將日誌寫入文件,不寫入stderr。--log-dir
: 日誌目錄。--v
:日誌級別。OK,APIServer的部署配置完成了,其實主要分兩部分:
後面其餘模塊的配置與之大同小異。
controller manager對應的二進制文件是kube-controller-manager
,且該服務依賴於kube-apiserver。
依舊先配置systemd的服務文件/lib/systemd/system/kube-controller-manager.service
:
[Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes After=kube-apiserver.service Requires=kube-apiserver.service [Service] EnvironmentFile=/etc/kubernetes/controller-manager ExecStart=/opt/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
在/etc/kubernetes/controller-manager
中設置$KUBE_CONTROLLER_MANAGER_ARGS
:
KUBE_CONTROLLER_MANAGER_ARGS="--master=http://192.168.56.101:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
--master
指的是APIServer的地址。
scheduler對應的二進制文件是kube-scheduler
,scheduler依賴於APIServer。
配置systemd服務文件/lib/systemd/system/kube-scheduler.service
:
[Unit] Description=Kubernetes Scheduler Manager Documentation=https://github.com/kubernetes After=kube-apiserver.service Requires=kube-apiserver.service [Service] EnvironmentFile=/etc/kubernetes/scheduler ExecStart=/opt/bin/kube-scheduler $KUBE_SCHEDULER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
在配置文件/etc/kubernetes/scheduler
中設置$KUBE_SCHEDULER_ARGS
:
KUBE_SCHEDULER_ARGS="--master=http://192.168.56.101:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
至此,Master上面的四個模塊都部署完了,咱們按照順序啓動他們,並將其加入到開機自啓動選項中:
# 從新加載systemd配置管理,切記增長`*.service`後必定要先執行該命令,不然啓動服務時會報錯 systemctl daemon-reload # enable表示該服務開機自啓,start表示啓動該服務 systemctl enable kube-apiserver.service systemctl start kube-apiserver.service systemctl enable kube-controller-manager.service systemctl start kube-controller-manager.service systemctl enable kube-scheduler.service systemctl start kube-scheduler.service
而後咱們分別運行systemctl status <service_name>
來驗證服務的狀態,「running」表示啓動成功。若是未成,也可看到錯誤日誌。
Node上面運行三個模塊:kubelet、kube-proxy、runtime。其中runtime目前指的是docker或者rkt,這裏咱們使用docker,docker的安裝這裏就不贅述了,最好安裝最新版本的docker。
kubelet對應的二進制文件是kubelet
,且其依賴Docker服務。
配置systemd服務文件/lib/systemd/system/kubelet.service
:
[Unit] Description=Kubernetes Kubelet Server Documentation=https://github.com/kubernetes After=docker.service Requires=docker.service [Service] WorkingDirectory=/var/lib/kubelet EnvironmentFile=/etc/kubernetes/kubelet ExecStart=/opt/bin/kubelet $KUBELET_ARGS Restart=on-failure [Install] WantedBy=multi-user.target
在配置文件/etc/kubernetes/kubelet
中設置參數$KUBELET_ARGS
KUBELET_ARGS="--api-servers=http://192.168.56.101:8080 --hostname-override=192.168.56.101 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
其中--hostname-override
設置本Node的名稱。
kube-proxy對應的二進制文件爲kube-proxy
,且該服務依賴於network
服務。
配置systemd服務文件/lib/systemd/system/kube-proxy.service
:
[Unit] Description=Kubernetes Kube-Proxt Server Documentation=https://github.com/kubernetes After=network.target Requires=network.target [Service] EnvironmentFile=/etc/kubernetes/proxy ExecStart=/opt/bin/kube-proxy $KUBE_PROXY_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
在配置文件/etc/kubernetes/proxy
中設置參數$KUBE_PROXY_ARGS
KUBE_PROXY_ARGS="--master=http://192.168.56.101:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
而後咱們依次啓動Node上的服務(Docker安裝好之後默認開機自啓且已經啓動,這裏再也不啓動):
systemctl daemon-reload systemctl enable kubelet.service systemctl start kubelet.service systemctl enable kube-proxy.service systemctl start kube-proxy.service
待服務都成功啓動後,kubelet會主動向Master註冊本身所在的Node。若是全部服務都啓動成功,咱們就能夠看到可用的Node了:
ubuntu➜ system kubectl get node NAME STATUS AGE 192.168.56.101 Ready 1h
再在另一臺Node上面也部署一下,就能夠看到兩個節點了。
至此,本文就介紹完了。不過要應用到生產環境中,咱們還有一些安全項和網絡項須要配置,後面再介紹。