Kubernetes集羣部署關鍵知識總結

  Kubernetes集羣部署須要安裝的組件東西不少,過程複雜,對服務器環境要求很苛刻,最好是能連外網的環境下安裝,有些組件還須要連google服務器下載,這一點通常很難知足,所以最好是能提早下載好準備的就儘可能下載好。node

Kubernetes集羣部署要求

  • 服務器必須是Centos 7.2及以上
  • Kubernetes 採用1.12版本
  • Docker-ce v17.03.2
  • Etcd 3.2.9
  • Flanneld v0.7.0-amd64
  • TLS 認證通訊(全部組件,如etcd、kubernetes master 和node)
  • RBAC 受權
  • kubedns、dashboard、heapster等插件
  • harbor,使用nfs後端存儲

……nginx

部署方式

  • Minikube 快速搭建單節點Kubenetes集羣的工具,只能用做學習實踐。
  • kubeadm是Kubernetes官方提供的用於快速安裝Kubernetes集羣的工具
  • 使用Rancher部署K8S集羣,佈署在Docker環境中,方便快捷。
  • Ansible腳本安裝K8S集羣

  若是對Rancher吃不透的話仍是推薦使用Ansible腳本安裝K8S集羣,Ansible腳本將安裝的流程都封裝到了腳本里,只需更改安裝主機服務器地址和環境就能實現一鍵佈署。git

  推薦使用github上的 kubeasz ,能簡化不少流程。github

kubeasz致力於提供快速部署高可用k8s集羣的工具, 而且也努力成爲k8s實踐、使用的參考書;基於二進制方式部署和利用ansible-playbook實現自動化:即提供一鍵安裝腳本, 也能夠分步執行安裝各個組件, 同時講解每一步主要參數配置和注意事項。docker

集羣特性:TLS雙向認證、RBAC受權、多Master高可用、支持Network Policy、備份恢復apache

 佈署關鍵點

爲了初次安裝順利,關閉防火牆。json

確保各節點時區設置一致、時間同步。後端

沒法訪問公網狀況下,請下載離線docker鏡像完成集羣安裝。api

從國內下載docker官方倉庫鏡像很是緩慢,因此對於k8s集羣來講配置鏡像加速很是重要,配置 /etc/docker/daemon.json,若訪問不了外網就要配置局域網的鏡像倉庫地址。瀏覽器

docker要開啓docker遠程API 修改docker配置文件docker.service 在ExecStart這一行後面加上 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

docker 從 1.13 版本開始,將iptables 的filter 表的FORWARD 鏈的默認策略設置爲DROP,從而致使 ping 其它 Node 上的 Pod IP 失敗,所以必須在 filter 表的FORWARD 鏈增長一條默認容許規則 iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT

後續calico網絡、kube-proxy等將大量使用 iptables規則,要維護好服務器自己的iptables規則。

網絡組件

  Kubernetes中網絡是最複雜的,雖然從架構圖上看是很清楚的,但實際操做起來仍是處處報錯,涉及到防火牆,iptables規則,服務器間的網絡,網絡組件的配置、容器與容器間的訪問,容器與服務器的互相訪問等等。

  推薦flannel ,這裏參考其它博文着重介紹下:

  Flannel的功能是讓集羣中的不一樣節點主機建立的Docker容器都具備全集羣惟一的虛擬IP地址。
  Flannel實質上是一種「覆蓋網絡(overlay network)」,也就是將TCP數據包裝在另外一種網絡包裏面進行路由轉發和通訊,Flannel的設計目的就是爲集羣中的全部節點從新規劃IP地址的使用規則,從而使得不一樣節點上的容器可以得到「同屬一個內網」且」不重複的」IP地址,並讓屬於不一樣節點上的容器可以直接經過內網IP通訊。 

  默認的節點間數據通訊方式是UDP轉發,在Flannel的GitHub頁面有以下的一張原理圖:

 

 1. 數據從源容器中發出後,經由所在主機的docker0虛擬網卡轉發到flannel0虛擬網卡,這是個P2P的虛擬網卡,flanneld服務監聽在網卡的另一端。 Flannel也是經過修改Node的路由表實現這個效果的。

2. 源主機的flanneld服務將本來的數據內容UDP封裝後根據本身的路由表投遞給目的節點的flanneld服務,數據到達之後被解包,而後直接進入目的節點的flannel0虛擬網卡,而後被轉發到目的主機的docker0虛擬網卡,最後就像本機容器通訊同樣由docker0路由到達目標容器。 

3. 使每一個結點上的容器分配的地址不衝突。Flannel經過Etcd分配了每一個節點可用的IP地址段後,再修改Docker的啓動參數。「--bip=X.X.X.X/X」這個參數,它限制了所在節點容器得到的IP範圍。


flannel 使用 vxlan 技術爲各節點建立一個能夠互通的 Pod 網絡,使用的端口爲 UDP 8472,須要開放該端口。

 

kube-apiserver的高可用

  keepalived+haproxy配置多個後端真實kube-apiserver的endpoints,並啓用存活監測後端kube-apiserver,保證kube-apiserver的高可用。

dashboard

  dashboard 1.7 之後默認開啓了自帶的登錄驗證機制,1.7 開始,dashboard 只容許經過 https 訪問,若是使用 kube proxy 則必須監聽 localhost 或 127.0.0.1,對於 NodePort 沒有這個限制,可是僅建議在開發環境中使用。

  對於不知足這些條件的登陸訪問,在登陸成功後瀏覽器不跳轉,始終停在登陸界面。

參考: https://github.com/kubernetes/dashboard/wiki/Accessing-Dashboard---1.7.X-and-abovehttps://github.com/kubernetes/dashboard/issues/2540

  1. kubernetes-dashboard 服務暴露了 NodePort,可使用 https://NodeIP:NodePort 地址訪問 dashboard;
  2. 經過 kube-apiserver 訪問 dashboard;
  3. 經過 kubectl proxy 訪問 dashboard:

 Ingress 

Ingress其實就是從kuberenets集羣外部訪問集羣的一個入口,將外部的請求轉發到集羣內不一樣的Service 上,其實就至關於nginx、apache 等負載均衡代理服務器,再加上一個規則定義,路由信息的刷新須要靠Ingress controller來提供。

Ingress controller能夠理解爲一個監聽器,經過不斷地與kube-apiserver打交道,實時的感知後端service、pod 等的變化,當獲得這些變化信息後,Ingress controller再結合Ingress的配置,更新反向代理負載均衡器,達到服務發現的做用。其實這點和服務發現工具consulconsul-template很是相似。

未配置ingress:
集羣外部 -> NodePort -> K8S Service
配置了ingress:
集羣外部 -> Ingress -> K8S Service
注意:ingress 自己也須要部署Ingress controller時暴露NodePort讓外部訪問;若是你集羣支持,能夠方便地使用LoadBalancer地址暴露ingress服務。

  Traefik 提供了一個簡單好用 Ingress controller,是一款開源的反向代理與負載均衡工具。它最大的優勢是可以與常見的微服務系統直接整合,能夠實現自動化動態配置。

 

若是採用Rancher部署會有從k8s.gcr.io拉取鏡像失敗問題

新版本的Kubernetes在安裝部署中,須要從k8s.grc.io倉庫中拉取所需鏡像文件,但因爲國內網絡防火牆問題致使沒法正常拉取。

解決方案
docker.io倉庫對google的容器作了鏡像,能夠經過下列命令下拉取相關鏡像:
docker pull mirrorgooglecontainers/kube-apiserver:v1.12.0
docker pull mirrorgooglecontainers/kube-controller-manager:v1.12.0
docker pull mirrorgooglecontainers/kube-scheduler:v1.12.0
docker pull mirrorgooglecontainers/kube-proxy:v1.12.0
docker pull mirrorgooglecontainers/pause:3.1
docker pull mirrorgooglecontainers/etcd:3.2.24
docker pull coredns/coredns:1.2.2

版本信息須要根據實際狀況進行相應的修改。經過docker tag命令來修改鏡像的標籤:
docker tag docker.io/mirrorgooglecontainers/kube-proxy:v1.12.0 k8s.gcr.io/kube-proxy:v1.12.0
docker tag docker.io/mirrorgooglecontainers/kube-scheduler:v1.12.0 k8s.gcr.io/kube-scheduler:v1.12.0
docker tag docker.io/mirrorgooglecontainers/kube-apiserver:v1.12.0 k8s.gcr.io/kube-apiserver:v1.12.0
docker tag docker.io/mirrorgooglecontainers/kube-controller-manager:v1.12.0 k8s.gcr.io/kube-controller-manager:v1.12.0
docker tag docker.io/mirrorgooglecontainers/etcd:3.2.24 k8s.gcr.io/etcd:3.2.24
docker tag docker.io/mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1
docker tag docker.io/coredns/coredns:1.2.2 k8s.gcr.io/coredns:1.2.2
使用docker rmi刪除不用的鏡像

dashboard沒法顯示監控圖

dashboard 和heapster influxdb都部署完成後 dashboard依舊沒法顯示監控圖 經過排查 heapster log有超時錯誤

$ kubectl logs -f pods/heapster-2882613285-58d9r -n kube-system

E0630 17:23:47.339987 1 reflector.go:203] k8s.io/heapster/metrics/sources/kubelet/kubelet.go:342: Failed to list *api.Node: Get http://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: i/o timeout E0630 17:23:47.340274 1 reflector.go:203] k8s.io/heapster/metrics/heapster.go:319: Failed to list *api.Pod: Get http://kubernetes.default/api/v1/pods?resourceVersion=0: dial tcp: i/o timeout E0630 17:23:47.340498 1 reflector.go:203] k8s.io/heapster/metrics/processors/namespace_based_enricher.go:84: Failed to list *api.Namespace: Get http://kubernetes.default/api/v1/namespaces?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.254.0.2:53: dial udp 10.254.0.2:53: i/o timeout E0630 17:23:47.340563 1 reflector.go:203] k8s.io/heapster/metrics/heapster.go:327: Failed to list *api.Node: Get http://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.254.0.2:53: dial udp 10.254.0.2:53: i/o timeout E0630 17:23:47.340623 1 reflector.go:203] k8s.io/heapster/metrics/processors/node_autoscaling_enricher.go💯 Failed to list *api.Node: Get http://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.254.0.2:53: dial udp 10.254.0.2:53: i/o timeout E0630 17:23:55.014414 1 influxdb.go:150] Failed to create infuxdb: failed to ping InfluxDB server at "monitoring-influxdb:8086" - Get http://monitoring-influxdb:8086/ping: dial tcp: lookup monitoring-influxdb on 10.254.0.2:53: read udp 172.30.45.4:48955->10.254.0.2:53: i/o timeout`
我是docker的systemd Unit文件忘記添加

ExecStart=/root/local/bin/dockerd --log-level=error $DOCKER_NETWORK_OPTIONS
後邊的$DOCKER_NETWORK_OPTIONS,致使docker0的網段跟flannel.1不一致。

kube-proxy報錯kube-proxy[2241]: E0502 15:55:13.889842 2241 conntrack.go:42] conntrack returned error: error looking for path of conntrack: exec: 「conntrack」: executable file not found in $PATH

致使現象:kubedns啓動成功,運行正常,可是service 之間沒法解析,kubernetes中的DNS解析異常

解決方法:CentOS中安裝conntrack-tools包後重啓kubernetes 集羣便可。

Unable to access kubernetes services: no route to host

致使現象: 在POD 內訪問集羣的某個服務的時候出現no route to host

$ curl my-nginx.nx.svc.cluster.local
curl: (7) Failed connect to my-nginx.nx.svc.cluster.local:80; No route to host
解決方法:清除全部的防火牆規則,而後重啓docker 服務

$ iptables --flush && iptables -tnat --flush
$ systemctl restart docker

使用NodePort 類型的服務,只能在POD 所在節點進行訪問

致使現象: 使用NodePort 類型的服務,只能在POD 所在節點進行訪問,其餘節點經過NodePort 不能正常訪問

解決方法: kube-proxy 默認使用的是proxy_model就是iptables,正常狀況下是全部節點均可以經過NodePort 進行訪問的,我這裏將阿里雲的安全組限制所有去掉便可,而後根據須要進行添加安全限制。

相關文章
相關標籤/搜索