Kubernetes集群部署關鍵知識總結


  Kubernetes集群部署需要安裝的組件東西很多,過程復雜,對服務器環境要求很苛刻,最好是能連外網的環境下安裝,有些組件還需要連google服務器下載,這一點一般很難滿足,因此最好是能提前下載好准備的就盡量下載好。

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后端存儲

……

部署方式

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

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

  推薦使用github上的 kubeasz ,能簡化很多流程。

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

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

 布署關鍵點

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

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

無法訪問公網情況下,請下載離線docker鏡像完成集群安裝。

從國內下載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 進行訪問的,我這里將阿里雲的安全組限制全部去掉即可,然后根據需要進行添加安全限制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM