天天看點

K8s叢集的部署

文章目錄

    • Kubernetes介紹
        • 背景介紹
        • 什麼是kubernetes
        • Kubernetes優勢
        • Kubernetes的核心概念
        • Kubernetes架構群組件
          • 架構
          • 元件
    • 實驗準備
    • 實驗步驟

官方文檔,參考: https://kubernetes.io/zh/docs/setup/independent/install-kubeadm/

swarm與Kubernetes 的對比參考: https://blog.csdn.net/meltsnow/article/details/95913308

Kubernetes介紹

背景介紹

雲計算飛速發展

  • IaaS
  • PaaS
  • SaaS

Docker技術突飛猛進

  • 一次建構,到處運作
  • 容器的快速輕量
  • 完整的生态環境

什麼是kubernetes

  • 首先,他是一個全新的基于容器技術的分布式架構領先方案。Kubernetes(k8s)是Google開源的容器叢集管理系統(谷歌内部:Borg)。在Docker技術的基礎上,為容器化的應用提供部署運作、資源排程、服務發現和動态伸縮等一系列完整功能,提高了大規模容器叢集管理的便捷性。
  • Kubernetes是一個完備的分布式系統支撐平台,具有完備的叢集管理能力,多擴多層次的安全防護和準入機制、多租戶應用支撐能力、透明的服務注冊和發現機制、內建智能負載均衡器、強大的故障發現和自我修複能力、服務滾動更新和線上擴容能力、可擴充的資源自動排程機制以及多粒度的資源配額管理能力。同時Kubernetes提供完善的管理工具,涵蓋了包括開發、部署測試、運維監控在内的各個環節。
  • Kubernetes中,Service是分布式叢集架構的核心,一個Service對象擁有如下關鍵特征:

    擁有一個唯一指定的名字

    擁有一個虛拟IP(Cluster IP、Service IP、或VIP)和端口号

    能夠體統某種遠端服務能力

    被映射到了提供這種服務能力的一組容器應用上

  • Service的服務程序目前都是基于Socket通信方式對外提供服務,比如Redis、Memcache、MySQL、Web Server,或者是實作了某個具體業務的一個特定的TCP Server程序,雖然一個Service通常由多個相關的服務程序來提供服務,每個服務程序都有一個獨立的Endpoint(IP+Port)通路點,但Kubernetes能夠讓我們通過服務連接配接到指定的Service上。有了Kubernetes内建的透明負載均衡和故障恢複機制,不管後端有多少服務程序,也不管某個服務程序是否會由于發生故障而重新部署到其他機器,都不會影響我們對服務的正常調用,更重要的是這個Service本身一旦建立就不會發生變化,意味着在Kubernetes叢集中,我們不用為了服務的IP位址的變化問題而頭疼了。
  • 容器提供了強大的隔離功能,所有有必要把為Service提供服務的這組程序放入容器中進行隔離。為此,Kubernetes設計了Pod對象,将每個服務程序包裝到相對應的Pod中,使其成為Pod中運作的一個容器。為了建立Service與Pod間的關聯管理,Kubernetes給每個Pod貼上一個标簽Label,比如運作MySQL的Pod貼上name=mysql标簽,給運作PHP的Pod貼上name=php标簽,然後給相應的Service定義标簽選擇器Label Selector,這樣就能巧妙的解決了Service于Pod的關聯問題。
  • 在叢集管理方面,Kubernetes将叢集中的機器劃分為一個Master節點和一群工作節點Node,其中,在Master節點運作着叢集管理相關的一組程序kube-apiserver、kube-controller-manager和kube-scheduler,這些程序實作了整個叢集的資源管理、Pod排程、彈性伸縮、安全控制、系統監控和糾錯等管理能力,并且都是全自動完成的。Node作為叢集中的工作節點,運作真正的應用程式,在Node上Kubernetes管理的最小運作單元是Pod。Node上運作着Kubernetes的kubelet、kube-proxy服務程序,這些服務程序負責Pod的建立、啟動、監控、重新開機、銷毀以及實作軟體模式的負載均衡器。
  • 在Kubernetes叢集中,它解決了傳統IT系統中服務擴容和更新的兩大難題。你隻需為需要擴容的Service關聯的Pod建立一個Replication Controller簡稱(RC),則該Service的擴容及後續的更新等問題将迎刃而解。在一個RC定義檔案中包括以下3個關鍵資訊。
  • 目标Pod的定義
  • 目标Pod需要運作的副本數量(Replicas)
  • 要監控的目标Pod标簽(Label)
  • 在建立好RC後,Kubernetes會通過RC中定義的的Label篩選出對應Pod執行個體并實時監控其狀态和數量,如果執行個體數量少于定義的副本數量,則會根據RC中定義的Pod模闆來建立一個新的Pod,然後将新Pod排程到合适的Node上啟動運作,知道Pod執行個體的數量達到預定目标,這個過程完全是自動化。

Kubernetes優勢

  • 容器編排
  • 輕量級
  • 開源
  • 彈性伸縮
  • 負載均衡

Kubernetes的核心概念

1.Master

k8s叢集的管理節點,負責管理叢集,提供叢集的資源資料通路入口。擁有Etcd存儲服務(可選),運作Api Server程序,Controller Manager服務程序及Scheduler服務程序,關聯工作節點Node。Kubernetes API server提供HTTP Rest接口的關鍵服務程序,是Kubernetes裡所有資源的增、删、改、查等操作的唯一入口。也是叢集控制的入口程序;Kubernetes Controller Manager是Kubernetes所有資源對象的自動化控制中心;Kubernetes Schedule是負責資源排程(Pod排程)的程序

2.Node

Node是Kubernetes叢集架構中運作Pod的服務節點(亦叫agent或minion)。Node是Kubernetes叢集操作的單元,用來承載被配置設定Pod的運作,是Pod運作的主控端。關聯Master管理節點,擁有名稱和IP、系統資源資訊。運作docker eninge服務,守護程序kubelet及負載均衡器kube-proxy.

每個Node節點都運作着以下一組關鍵程序
kubelet:負責對Pod對于的容器的建立、啟停等任務
kube-proxy:實作Kubernetes Service的通信與負載均衡機制的重要元件
Docker Engine(Docker):Docker引擎,負責本機容器的建立和管理工作
           

Node節點可以在運作期間動态增加到Kubernetes叢集中,預設情況下,kubelet會向master注冊自己,這也是Kubernetes推薦的Node管理方式,kubelet程序會定時向Master彙報自身情報,如作業系統、Docker版本、CPU和記憶體,以及有哪些Pod在運作等等,這樣Master可以獲知每個Node節點的資源使用情況,并實作高效均衡的資源排程政策。

3.Pod

運作于Node節點上,若幹相關容器的組合。Pod内包含的容器運作在同一主控端上,使用相同的網絡命名空間、IP位址和端口,能夠通過localhost進行通。Pod是Kurbernetes進行建立、排程和管理的最小機關,它提供了比容器更高層次的抽象,使得部署和管理更加靈活。一個Pod可以包含一個容器或者多個相關容器。

Pod其實有兩種類型:普通Pod和靜态Pod,後者比較特殊,它并不存在Kubernetes的etcd存儲中,而是存放在某個具體的Node上的一個具體檔案中,并且隻在此Node上啟動。普通Pod一旦被建立,就會被放入etcd存儲中,随後會被Kubernetes Master排程到某個具體的Node上進行綁定,随後該Pod被對應的Node上的kubelet程序執行個體化成一組相關的Docker容器并啟動起來,在預設情況下,當Pod裡的某個容器停止時,Kubernetes會自動檢測到這個問起并且重新開機這個Pod(重新開機Pod裡的所有容器),如果Pod所在的Node當機,則會将這個Node上的所有Pod重新排程到其他節點上。

4.Replication Controller

Replication Controller用來管理Pod的副本,保證叢集中存在指定數量的Pod副本。叢集中副本的數量大于指定數量,則會停止指定數量之外的多餘容器數量,反之,則會啟動少于指定數量個數的容器,保證數量不變。Replication Controller是實作彈性伸縮、動态擴容和滾動更新的核心。

5.Service

Service定義了Pod的邏輯集合和通路該集合的政策,是真實服務的抽象。Service提供了一個統一的服務通路入口以及服務代理和發現機制,關聯多個相同Label的Pod,使用者不需要了解背景Pod是如何運作。

外部系統通路Service的問題

首先需要弄明白Kubernetes的三種IP這個問題

Node IP:Node節點的IP位址

Pod IP: Pod的IP位址

Cluster IP:Service的IP位址

首先,Node IP是Kubernetes叢集中節點的實體網卡IP位址,所有屬于這個網絡的伺服器之間都能通過這個網絡直接通信。這也表明Kubernetes叢集之外的節點通路Kubernetes叢集之内的某個節點或者TCP/IP服務的時候,必須通過Node IP進行通信

其次,Pod IP是每個Pod的IP位址,他是Docker Engine根據docker0網橋的IP位址段進行配置設定的,通常是一個虛拟的二層網絡。

最後Cluster IP是一個虛拟的IP,但更像是一個僞造的IP網絡,原因有以下幾點:

Cluster IP僅僅作用于Kubernetes Service這個對象,并由Kubernetes管理和配置設定P位址
Cluster IP無法被ping,他沒有一個“實體網絡對象”來響應
Cluster IP隻能結合Service Port組成一個具體的通信端口,單獨的Cluster IP不具備通信的基礎,并且他們屬于Kubernetes叢集這樣一個封閉的空間。
           

Kubernetes叢集之内,Node IP網、Pod IP網于Cluster IP網之間的通信,采用的是Kubernetes自己設計的一種程式設計方式的特殊路由規則。

6.Label

Kubernetes中的任意API對象都是通過Label進行辨別,Label的實質是一系列的Key/Value鍵值對,其中key于value由使用者自己指定。Label可以附加在各種資源對象上,如Node、Pod、Service、RC等,一個資源對象可以定義任意數量的Label,同一個Label也可以被添加到任意數量的資源對象上去。Label是Replication Controller和Service運作的基礎,二者通過Label來進行關聯Node上運作的Pod。

我們可以通過給指定的資源對象捆綁一個或者多個不同的Label來實作多元度的資源分組管理功能,以便于靈活、友善的進行資源配置設定、排程、配置等管理工作。

一些常用的Label如下:

版本标簽:"release":"stable","release":"canary"......
環境标簽:"environment":"dev","environment":"qa","environment":"production"
架構标簽:"tier":"frontend","tier":"backend","tier":"middleware"
分區标簽:"partition":"customerA","partition":"customerB"
品質管控标簽:"track":"daily","track":"weekly"
           

Label相當于我們熟悉的标簽,給某個資源對象定義一個Label就相當于給它大了一個标簽,随後可以通過Label Selector(标簽選擇器)查詢和篩選擁有某些Label的資源對象,Kubernetes通過這種方式實作了類似SQL的簡單又通用的對象查詢機制。

Label Selector在Kubernetes中重要使用場景如下:

kube-Controller程序通過資源對象RC上定義Label Selector來篩選要監控的Pod副本的數量,進而實作副本數量始終符合預期設定的全自動控制流程
kube-proxy程序通過Service的Label Selector來選擇對應的Pod,自動建立起每個Service到對應Pod的請求轉發路由表,進而實作Service的智能負載均衡
通過對某些Node定義特定的Label,并且在Pod定義檔案中使用Nodeselector這種标簽排程政策,kube-scheduler程序可以實作Pod”定向排程“的特性
           

Kubernetes架構群組件

架構
K8s叢集的部署
元件
  • Kubernetes Master控制元件,排程管理整個系統(叢集),包含如下元件:

    1.Kubernetes API Server

    作為Kubernetes系統的入口,其封裝了核心對象的增删改查操作,以RESTful API接口方式提供給外部客戶和内部元件調用。維護的REST對象持久化到Etcd中存儲。

    2.Kubernetes Scheduler

    為建立立的Pod進行節點(node)選擇(即配置設定機器),負責叢集的資源排程。元件抽離,可以友善替換成其他排程器。

    3.Kubernetes Controller

    負責執行各種控制器,目前已經提供了很多控制器來保證Kubernetes的正常運作。

  • Replication Controller

    管理維護Replication Controller,關聯Replication Controller和Pod,保證Replication Controller定義的副本數量與實際運作Pod數量一緻。

  • Node Controller

    管理維護Node,定期檢查Node的健康狀态,辨別出(失效|未失效)的Node節點。

  • Namespace Controller

    管理維護Namespace,定期清理無效的Namespace,包括Namesapce下的API對象,比如Pod、Service等。

  • Service Controller

    管理維護Service,提供負載以及服務代理。

  • EndPoints Controller

    管理維護Endpoints,關聯Service和Pod,建立Endpoints為Service的後端,當Pod發生變化時,實時更新Endpoints。

  • Service Account Controller

    管理維護Service Account,為每個Namespace建立預設的Service Account,同時為Service Account建立Service Account Secret。

  • Persistent Volume Controller

    管理維護Persistent Volume和Persistent Volume Claim,為新的Persistent Volume Claim配置設定Persistent Volume進行綁定,為釋放的Persistent Volume執行清理回收。

  • Daemon Set Controller

    管理維護Daemon Set,負責建立Daemon Pod,保證指定的Node上正常的運作Daemon Pod。

  • Deployment Controller

    管理維護Deployment,關聯Deployment和Replication Controller,保證運作指定數量的Pod。當Deployment更新時,控制實作Replication Controller和 Pod的更新。

  • Job Controller

    管理維護Job,為Jod建立一次性任務Pod,保證完成Job指定完成的任務數目

  • Pod Autoscaler Controller

    實作Pod的自動伸縮,定時擷取監控資料,進行政策比對,當滿足條件時執行Pod的伸縮動作。

  1. Kubernetes Node運作節點,運作管理業務容器,包含如下元件:
  • Kubelet

    負責管控容器,Kubelet會從Kubernetes API Server接收Pod的建立請求,啟動和停止容器,監控容器運作狀态并彙報給Kubernetes API Server。

  • Kubernetes Proxy

    負責為Pod建立代理服務,Kubernetes Proxy會從Kubernetes API Server擷取所有的Service資訊,并根據Service的資訊建立代理服務,實作Service到Pod的請求路由和轉發,進而實作Kubernetes層級的虛拟轉發網絡。

  • Docker

    Node上需要運作容器服務。

實驗準備

主機名(IP) 服務
server1(172.25.11.1) master
server2(172.25.11.2) node1
server3(172.25.11.3) node2
  • 一個或者多個相容 deb 或者 rpm 軟體包的作業系統,比如 Ubuntu 或者 CentOS
  • 每台機器 2 GB 以上的記憶體,記憶體不足時應用會受限制
  • 主節點上 2 CPU 以上
  • 叢集裡所有的機器有完全的網絡連接配接,公有網絡或者私有網絡都可以

實驗步驟

  • 首先在每個節點清理之前做過的swarm的實驗。(如果沒有則這一步跳過)
server2~4:
[[email protected] ~]# docker swarm leave
[[email protected] ~]# docker network prune 
[[email protected] ~]# docker volume prune 
[[email protected] ~]# docker ps -a 

server1:
[[email protected] wordpress]# docker node ls
[[email protected] wordpress]# docker node rm server2
[[email protected] wordpress]# docker node rm server3
[[email protected] wordpress]# docker node rm server4
[[email protected] wordpress]# docker node ls
[[email protected] wordpress]# docker swarm leave -f
[[email protected] wordpress]# docker network prune
[[email protected] ~]# docker volume prune 
           
  • 在3個節點上,關閉系統的交換分區。
swapoff -a  
vim /etc/fstab      #注釋swap的定義
#/dev/mapper/rhel-swap   swap                    swap    defaults        0 0    
           
  • 在3個節點上安裝以下軟體:

    其中:kubeadm: 用來初始化叢集的指令。 kubelet: 在叢集中的每個節點上用來啟動 pod 和 container 等。 kubectl: 用來與叢集通信的指令行工具。

yum install -y cri-tools-1.13.0-0.x86_64.rpm   kubectl-1.15.0-0.x86_64.rpm  kubelet-1.15.0-0.x86_64.rpm  kubernetes-cni-0.7.5-0.x86_64.rpm kubeadm-1.15.0-0.x86_64.rpm
           
K8s叢集的部署
  • 在3個節點上導入鏡像:
[[email protected] images]# ls
coredns.tar  kube-apiserver.tar           kube-proxy.tar      pause.tar
etcd.tar     kube-controller-manager.tar  kube-scheduler.tar

[[email protected] images]# for i in *.tar;do docker load -i $i;done
[[email protected] images]# docker images
[[email protected] images]# scp * server2:
[[email protected] images]# scp * server3:
           
K8s叢集的部署
  • 由于可能會出現iptables 被繞過導緻網絡請求被錯誤的路由,需要給所有節點進行相應配置,并且所有節點開啟服務,設定服務開機自啟動。
[[email protected] images]# vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[[email protected] images]# sysctl --system
[[email protected] sysctl.d]# scp k8s.conf server2:/etc/sysctl.d/   
[[email protected] sysctl.d]# scp k8s.conf server3:/etc/sysctl.d/
[[email protected] images]# sysctl --system
[[email protected] images]# sysctl --system

[[email protected] sysctl.d]# systemctl enable kubelet
[[email protected] sysctl.d]# systemctl start kubelet
           
  • server1(master節點初始化),選擇一個 Pod 網絡插件,并檢查是否在 kubeadm 初始化過程中需要傳入什麼參數。設定 --Pod-network-cidr 來指定網絡驅動的 CIDR。
[[email protected] sysctl.d]# kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=172.25.11.1
           
K8s叢集的部署
  • server2和server3,利用server1master節點的初始化資訊,加入叢集。
[[email protected] ~]# kubeadm join 172.25.11.1:6443 --token gx0ip7.jcgusexw76bxt4g0 \
>     --discovery-token-ca-cert-hash sha256:4848f2cdd60ac44a95537ee637e786f2669725f198a3816218b36d0922d53282

[[email protected] ~]# kubeadm join 172.25.11.1:6443 --token gx0ip7.jcgusexw76bxt4g0 \
>     --discovery-token-ca-cert-hash sha256:4848f2cdd60ac44a95537ee637e786f2669725f198a3816218b36d0922d53282
           
  • 在所有節點安裝:

    [[email protected] sysctl.d]# yum install yum-utils device-mapper-persistent-data lvm2

  • 在server1(master節點)建立普通使用者管理叢集,如果需要讓普通使用者可以運作 kubectl,運作如下指令,這也是 kubeadm init 輸出的一部分:
server1:建立普通使用者 授權。
[[email protected] sysctl.d]# useradd kubeadm
[[email protected] sysctl.d]# vim /etc/sudoers
kubeadm ALL=(ALL)       NOPASSWD:ALL

[[email protected] ~]# su - kubeadm 
[[email protected] ~]$  mkdir -p $HOME/.kube
[[email protected] ~]$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[[email protected] ~]$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
[[email protected] ~]$ kubectl  get nodes
           
K8s叢集的部署
  • 此時所有節點的狀态為not ready。
[[email protected] ~]$ kubectl  get nodes
           
K8s叢集的部署
  • 配置server1的kubectl指令的補齊功能。
lftp 172.25.11.250:/pub/k8s> mget flannel.tar kube-flannel.yml 
[[email protected] ~]# cp kube-flannel.yml /home/kubeadm/
[[email protected] ~]# su - kubeadm 
[[email protected] ~]$ echo "source <(kubectl completion bash)" >>.bashrc 
           
K8s叢集的部署
K8s叢集的部署
  • 給所有節點安裝pod網絡:
[[email protected] ~]# docker load -i flannel.tar     #在3個節點都要導入鏡像
[[email protected] ~]# scp flannel.tar server2:   
[[email protected] ~]# scp flannel.tar server3:
[[email protected] ~]# docker load -i flannel.tar
[[email protected] ~]# docker load -i flannel.tar
           
  • 下載下傳并應用.yml檔案,再次檢視,發現所有節點的狀态已經變為ready。
[[email protected] ~]$ kubectl apply -f kube-flannel.yml
[[email protected] ~]$ kubectl get nodes
[[email protected] ~]$ kubectl get pods --all-namespaces
[[email protected] ~]$ systemctl status kubelet.service
           
K8s叢集的部署
K8s叢集的部署
K8s叢集的部署
  • 至此,k8s叢集部署完成。
k8s

繼續閱讀