如何在CentOS上建立Kubernetes集羣

歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~html

本文由編程男孩 發表於雲+社區專欄node

介紹linux

Kubernetes(常簡稱爲K8s)是用於自動部署、擴展和管理容器化(containerized)應用程序的開源系統。Google設計並捐贈給Linux基金會來使用的。它旨在提供「跨主機集羣的自動部署、擴展以及運行應用程序容器的平臺」。它支持一系列容器工具, 包括Docker等。nginx

Kubeadm是 Kubernetes 官方推出的部署工具 ,例如API服務器,Controller Manager和Kube DNS,該工具實做相似Docker swarm 同樣的部署方式,透過初始化Master 節點來提供給Node快速加入。可是,它的缺點也很明顯,它不會建立用戶或處理操做系統級依賴關係及其配置的安裝。對於這些步驟,可使用AnsibleSaltStack等配置管理工具。使用這些工具能夠更輕鬆地更改其餘集羣或從新建立現有集羣。git

在本教程中,您將使用Ansible和Kubeadm從頭開始設置Kubernetes集羣,而後給它部署一個容器化的Nginx程序。github

目標

您的羣集將包含如下物理資源:docker

  • 一個主節點

主節點(Kubernetes中的節點指的是服務器)負責管理集羣的狀態。咱們將用它運行Etcd,該服務器目的是將工做負載調度到工做節點的組件之間存儲集羣數據。shell

  • 兩個工做節點

工做節點是運行工做負載(即容器化應用程序和服務)的服務器。一旦工做節點分配了工做負載,工做節點將繼續運行您的工做負載,即便計劃在調度完成後中止工做也是如此。經過添加工做節點能夠增長羣集的容量。數據庫

完成本教程後,您將擁有一個能夠運行容器化應用程序的集羣,前提是集羣中的服務器具備足夠的CPU和RAM資源供應用程序使用。幾乎任何傳統的Unix應用程序(包括Web應用程序,數據庫,守護程序和命令行工具)均可以進行容器化,並在集羣上運行。羣集自己將在每一個節點上消耗大約300-500MB的內存和10%的CPU。編程

設置羣集後,您將部署Web服務器Nginx以確保它正確運行。

準備

  • 本地Linux / macOS /BSD計算機上的SSH密鑰對。若是您以前沒有使用過SSH密鑰,同時使用的是騰訊雲的服務器的話,請參考建立 SSH 密鑰文檔。若是您使用的不是騰訊雲的服務器,請自行搜索,本文暫不涉及。本教程的本地計算機是Linux操做系統,請勿使用Windows進行試驗。
  • 運行CentOS 7的三臺服務器,內存至少爲1GB。沒有服務器的同窗能夠在這裏購買,不過我我的更推薦您使用免費的騰訊雲開發者實驗室進行試驗,學會安裝後在購買服務器。您應該可以以SSH密鑰對的root用戶身份SSH到每一個服務器。請務必將您的公鑰添加到主節點上的centos用戶賬戶。若是您須要有關向特定用戶賬戶添加SSH密鑰的指導,請參閱密鑰綁定/解綁服務器文檔。
  • Ansible須要安裝在您的本地計算機上。有關安裝說明,請按照Ansible官方安裝文檔
  • 瞭解如何從Docker鏡像啓動容器。若是須要複習,請參閱如何安裝使用Docker的「第5步 - 運行Docker容器」 。

第1步 - 設置工做區目錄和Ansible配置

在本節中,您將在本地計算機上建立一個用做工做區的目錄。您還將在本地配置Ansible,以便它能夠與遠程服務器上的命令進行通訊。爲此,您將建立一個hosts文件包,其包含例如服務器的IP地址和每一個服務器所屬的組等信息。

在三臺服務器中,一臺服務器將做爲主服務器master_ip。另外兩臺服務器則是是工做節點,並擁有IPworker_1_ipworker_2_ip

在本地計算機的主目錄中建立一個名爲~/kube-cluster/hosts的目錄並進入其中:

mkdir ~/kube-cluster
cd ~/kube-cluster

該目錄將是本教程的工做區,包含全部Ansible設置。它也將是您運行全部本地命令的目錄。

使用vi命令建立一個名爲~/kube-cluster/hosts的文件或用您最喜歡的文本編輯器:

vi ~/kube-cluster/hosts

i將如下文本插入到文件中,該文件將指定有關羣集邏輯結構的信息:

[masters]
master ansible_host=master_ip ansible_user=root

[workers]
worker1 ansible_host=worker_1_ip ansible_user=root
worker2 ansible_host=worker_2_ip ansible_user=root

完成後,按,ESC而後輸入:wq將更改寫入文件並退出。

您可能還記得在Ansible中用於指定服務器信息的庫存文件,例如IP地址,遠程用戶和服務器分組,以做爲執行命令的單個單元進行目標。~/kube-cluster/hosts將是您的庫存文件,而且您已向其添加了兩個Ansible組(主服務器工做服務器),用於指定集羣的邏輯結構。

服務器組中,有一個名爲「master」的服務器,其中列出了主節點的IP(master_ip),並指定Ansible應以根用戶身份運行遠程命令。

一樣,在workers組中,有兩個工做服務器(worker_1_ipworker_2_ip),它們也須要指定ansible_user爲root用戶。

在設置服務器清單以後,讓咱們繼續安裝操做系統級依賴關係並建立配置設置。

第2步 - 安裝Kubernetes的依賴項

在本節中,您將使用CentOS的yum軟件包管理器安裝Kubernetes所需的軟件包。這些包是:

  • Docker - 容器運行時。這是運行容器的組件。Kubernetes正在積極開發對rkt等其餘運行容器服務的支持。
  • kubeadm - CLI工具,以標準方式安裝和配置羣集的各個組件。
  • kubelet - 在全部節點上運行並處理節點級操做的系統服務/程序。
  • kubectl- 經過其API服務器向集羣發出命令的CLI工具。

建立工做空間中指定的文件vi ~/kube-cluster/kube-dependencies.yml

vi ~/kube-cluster/kube-dependencies.yml

將下面的內容插到文件內:

- hosts: all
  become: yes
  tasks:
   - name: install Docker
     yum:
       name: docker
       state: present
       update_cache: true

   - name: start Docker
     service:
       name: docker
       state: started

   - name: disable SELinux
     command: setenforce 0

   - name: disable SELinux on reboot
     selinux:
       state: disabled

   - name: ensure net.bridge.bridge-nf-call-ip6tables is set to 1
     sysctl:
      name: net.bridge.bridge-nf-call-ip6tables
      value: 1
      state: present

   - name: ensure net.bridge.bridge-nf-call-iptables is set to 1
     sysctl:
      name: net.bridge.bridge-nf-call-iptables
      value: 1
      state: present

   - name: add Kubernetes' YUM repository
     yum_repository:
      name: Kubernetes
      description: Kubernetes YUM repository
      baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
      gpgkey: https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
      gpgcheck: yes

   - name: install kubelet
     yum:
        name: kubelet
        state: present
        update_cache: true

   - name: install kubeadm
     yum:
        name: kubeadm
        state: present

   - name: start kubelet
     service:
       name: kubelet
       enabled: yes
       state: started

- hosts: master
  become: yes
  tasks:
   - name: install kubectl
     yum:
        name: kubectl
        state: present

文件中的的第一部份內容以下:

  • 容器運行時,安裝Docker。
  • 啓動Docker服務。
  • 請禁用SELinux,由於Kubernetes還沒有徹底支持它。
  • 設置網絡所需的一些與netfilter相關的sysctl值。這將容許Kubernetes設置iptables規則,以便在節點上接收橋接的IPv4和IPv6網絡流量。
  • 將Kubernetes YUM存儲庫添加到遠程服務器的存儲庫列表中。
  • 安裝kubeletkubeadm

第二部分意思是在主節點上設置一下kubectl的任務。

完成後保存並關閉文件。

接下來,執行playbook

ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

完成後,您將看到相似於如下內容的輸出:

PLAY [all] ****

TASK [Gathering Facts] ****
ok: [worker1]
ok: [worker2]
ok: [master]

TASK [install Docker] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [disable SELinux] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [disable SELinux on reboot] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [ensure net.bridge.bridge-nf-call-ip6tables is set to 1] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [ensure net.bridge.bridge-nf-call-iptables is set to 1] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [start Docker] ****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [add Kubernetes' YUM repository] *****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [install kubelet] *****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [install kubeadm] *****
changed: [master]
changed: [worker1]
changed: [worker2]

TASK [start kubelet] ****
changed: [master]
changed: [worker1]
changed: [worker2]

PLAY [master] *****

TASK [Gathering Facts] *****
ok: [master]

TASK [install kubectl] ******
ok: [master]

PLAY RECAP ****
master                     : ok=9    changed=5    unreachable=0    failed=0   
worker1                    : ok=7    changed=5    unreachable=0    failed=0  
worker2                    : ok=7    changed=5    unreachable=0    failed=0

執行後,Docker,kubeadmkubelet將安裝在全部遠程服務。kubectl不是必需組件,僅用於執行集羣命令。可是咱們建議您仍是安裝它,由於您將僅從主節點運行kubectl命令。

如今安裝了全部系統依賴項。讓咱們設置主節點並初始化集羣。

第3步 - 設置主節點

在本節中,您將設置主節點。然而在建立配置以前,咱們須要熟悉幾個概念,如PodsPod 網絡插件

Kubernetes的基本調度單元稱爲「pods」。它能夠把更高級別的抽象內容增長到容器化組件。一個pod通常包含一個或多個容器,這樣能夠保證它們一直位於主機上,而且能夠共享資源。Kubernetes中的每一個pod都被分配一個惟一的(在集羣內的)IP地址這樣就能夠容許應用程序使用端口,而不會有衝突的風險。Pod能夠定義一個卷,例如本地磁盤目錄或網絡磁盤,並將其暴露在pod中的一個容器之中。pod能夠經過Kubernetes API手動管理,也能夠委託給控制器來管理。

每一個pod都有本身的IP地址,一個節點上的pod應該可以使用pod的IP訪問另外一個節點上的pod。單個節點上的容器能夠經過本地接口輕鬆進行通訊。然而,pod之間的通訊更復雜,而且須要單獨的網絡組件,該組件能夠透明地將流量從一個節點上的pod傳送到另外一個節點上的pod。此功能由pod網絡插件提供。對於這個羣集,建議您將使用Flannel選項

在本地計算機上建立一個命名爲master.yml的Ansible playbook :

vi ~/kube-cluster/master.yml

將如下內容添加到文件中以初始化集羣並安裝Flannel:

- hosts: master
  become: yes
  tasks:
    - name: initialize the cluster
      shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
      args:
        chdir: $HOME
        creates: cluster_initialized.txt

    - name: create .kube directory
      become: yes
      become_user: centos
      file:
        path: $HOME/.kube
        state: directory
        mode: 0755

    - name: copy admin.conf to user's kube config
      copy:
        src: /etc/kubernetes/admin.conf
        dest: /home/centos/.kube/config
        remote_src: yes
        owner: centos

    - name: install Pod network
      become: yes
      become_user: centos
      shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml >> pod_network_setup.txt
      args:
        chdir: $HOME
        creates: pod_network_setup.txt

這是上面內容的詳解:

  • 第一個任務經過運行kubeadm init初始化集羣。傳遞--pod-network-cidr=10.244.0.0/16參數指定將從中分配pod IP的私有子網。Flannel默認使用上述子網,咱們告訴kubeadm使用相同的子網。
  • 第二個任務建立一個.kube目錄在/home/centos。此目錄將保存配置信息,例如鏈接到羣集所需的管理密鑰文件以及羣集的API地址。
  • 第三個任務將/etc/kubernetes/admin.conf生成的文件複製kubeadm initcentos用戶的主目錄。這將容許您用kubectl訪問新建立的羣集。
  • 最後一個任務運行kubectl apply安裝Flannelkubectl apply -f descriptor.[yml|json]是告訴kubectl建立descriptor.[yml|json]文件中描述的對象的語法。kube-flannel.yml文件包含Flannel在羣集中設置所需的對象的說明。

完成後保存並關閉文件。執行配置:

ansible-playbook -i hosts ~/kube-cluster/master.yml

完成後,您將看到相似於如下內容的輸出:

PLAY [master] ****

TASK [Gathering Facts] ****
ok: [master]

TASK [initialize the cluster] ****
changed: [master]

TASK [create .kube directory] ****
changed: [master]

TASK [copy admin.conf to user's kube config] *****
changed: [master]

TASK [install Pod network] *****
changed: [master]

PLAY RECAP ****
master                     : ok=5    changed=4    unreachable=0    failed=0

要檢查主節點的狀態,請使用如下命令經過SSH鏈接到該節點:

ssh centos@master_ip

進入主節點後,執行:

kubectl get nodes

您如今將看到如下輸出:

NAME      STATUS    ROLES     AGE       VERSION
master    Ready     master    1d        v1.10.1

輸出代表master節點已完成全部初始化任務,而且處於Ready能夠開始接受工做節點並執行發送到API服務器的任務的狀態。您如今能夠從本地計算機添加工做程序。

第4步 - 設置工做節點

將工做程序添加到集羣涉及在每一個集羣上執行單個命令。此命令包括必要的羣集信息,例如主服務器API服務器的IP地址和端口以及安全令牌。只有傳入安全令牌的節點才能加入羣集。

f反回您的工做區並建立一個名爲workers.yml的配置:

vi ~/kube-cluster/workers.yml

將如下文本添加到文件中:

- hosts: master
  become: yes
  gather_facts: false
  tasks:
    - name: get join command
      shell: kubeadm token create --print-join-command
      register: join_command_raw

    - name: set join command
      set_fact:
        join_command: "{{ join_command_raw.stdout_lines[0] }}"


- hosts: workers
  become: yes
  tasks:
    - name: join cluster
      shell: "{{ hostvars['master'].join_command }} >> node_joined.txt"
      args:
        chdir: $HOME
        creates: node_joined.txt

如下是配置的做用:

  • 第一個配置獲取join命令,以便在worker節點上運行。該命令將採用如下格式:kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>一旦它得到具備的令牌哈希值的命令,該任務就將其設置爲可用,以便下一個配置可以訪問該信息。
  • 第二個配置有一個任務,它在全部工做節點上運行join命令。完成此任務後,兩個工做節點將成爲羣集的一部分。

完成後保存並關閉文件。執行配置:

ansible-playbook -i hosts ~/kube-cluster/workers.yml

完成後,您將看到相似於如下內容的輸出:

PLAY [master] ****

TASK [get join command] ****
changed: [master]

TASK [set join command] *****
ok: [master]

PLAY [workers] *****

TASK [Gathering Facts] *****
ok: [worker1]
ok: [worker2]

TASK [join cluster] *****
changed: [worker1]
changed: [worker2]

PLAY RECAP *****
master                     : ok=2    changed=1    unreachable=0    failed=0   
worker1                    : ok=2    changed=1    unreachable=0    failed=0  
worker2                    : ok=2    changed=1    unreachable=0    failed=0

經過添加工做節點,您的羣集如今已徹底設置並正常運行,工做節點能夠隨時運行工做負載。讓咱們驗證羣集是否按預期工做。

第5步 - 驗證羣集

集羣有時可能在安裝過程當中失敗,由於節點已關閉或主服務器與工做服務器之間的網絡鏈接沒法正常工做。讓咱們驗證集羣並確保節點正常運行。

您須要從主節點檢查羣集的當前狀態,以確保節點已準備就緒。若是從主節點斷開鏈接,則可使用如下命令經過SSH將其從新鏈接到主節點:

ssh centos@master_ip

而後執行如下命令以獲取集羣的狀態:

kubectl get nodes

您將看到相似於如下內容的輸出:

NAME      STATUS    ROLES     AGE       VERSION
master    Ready     master    1d        v1.10.1
worker1   Ready     <none>    1d        v1.10.1 
worker2   Ready     <none>    1d        v1.10.1

若是全部的節點都具備ReadySTATUS(狀態),這意味着它們是集羣的一部分,並準備運行工做負載。

可是,若是幾個節點擁有NotReadySTATUS(狀態),它可能意味着工做節點尚未完成本身的設置。等待大約五到十分鐘再從新運行kubectl get node並檢查新輸出。若是一些節點仍具備NotReady狀態,則須要驗證並從新運行前面步驟中的命令。

如今您的集羣已成功驗證,讓咱們在集羣上部署一個示例Nginx應用程序。

第6步 - 在羣集上運行應用程序

您如今能夠將任何容器化應用程序部署到您的羣集。讓咱們使用部署和服務部署Nginx,以瞭解如何將此應用程序部署到集羣。若是更改Docker鏡像名稱和任何相關標誌(例如portsvolumes),您也可使用如下命令用於其餘容器化應用程序。

在主節點內,執行如下命令以建立名爲nginx的部署:

kubectl run nginx --image=nginx --port 80

部署是一種Kubernetes對象,可確保始終根據已定義的模板運行指定數量的pod,即便pod在羣集生命週期內崩潰也是如此。上面的部署將使用Docker鏡像庫的Nginx Docker Image建立一個包含一個容器的pod 。

接下來,運行如下命令以建立名爲nginx將公開公共應用程序的服務。它將經過NodePort實現,該方案將經過在羣集的每一個節點上打開的任意端口訪問pod:

kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort

服務是另外一種類型的Kubernetes對象,它向內部和外部客戶端公開集羣內部服務。它們還可以對多個pod進行負載均衡請求,而且是Kubernetes中不可或缺的組件,常常與其餘組件交互。

運行如下命令:

kubectl get services

這將輸出相似於如下內容的文本:

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP           PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>                443/TCP        1d
nginx        NodePort    10.109.228.209   <none>                80:nginx_port/TCP   40m

從上面輸出的第三行,您能夠檢索運行Nginx的端口。Kubernetes將分配一個大於30000自動的隨機端口,同時確保該端口還沒有受到其餘服務的約束。

要測試一切正常,請訪問或經過本地計算機上的瀏覽器。您將看到Nginx熟悉的歡迎頁面。http://worker_1_ip:nginx_port或者http://worker_2_ip:nginx_port

若是要刪除Nginx應用程序,請先nginx從主節點刪除該服務:

kubectl delete service nginx

運行如下命令以確保已刪除該服務:

kubectl get services

您將看到如下輸出:

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP           PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>                443/TCP        1d

而後刪除部署:

kubectl delete deployment nginx

運行如下命令以確認這是否有效:

kubectl get deployments
No resources found.

結論

在本教程中,您已使用Kubeadm和Ansible成功在CentOS 7上設置Kubernetes集羣以實現自動化。

若是您想知道要在集羣設置的狀況下如何處理集羣,那麼下一步就是將本身的應用程序和服務部署到集羣上。這是一個連接列表,其中包含能夠指導您完成此過程的更多信息:

  • Dockerizing應用程序 - 列出了詳細說明如何使用Docker對應用程序進行容器化的示例。
  • Pod概述 - 詳細描述了Pod如何工做以及它們與其餘Kubernetes對象的關係。Pods在Kubernetes中無處不在,所以瞭解它們將有助於您的工做。
  • 部署概述 - 這提供了部署的概述。瞭解部署之類的控制器如何有效地工做,由於它們常常在無狀態應用程序中用於擴展和不健康應用程序的自動修復。
  • 服務概述 - 這包括服務,Kubernetes集羣中另外一個經常使用對象。瞭解服務類型及其選項對於運行無狀態和有狀態應用程序相當重要。

其餘重要概念是VolumesIngressesSecrets,全部這些在部署生產應用程序時都派上用場。Kubernetes提供了許多功能和特性。Kubernetes官方文檔是瞭解概念,查找特定於任務的教程以及查找各類對象的API參考的最佳位置。更多Linux教程請前往騰訊雲+社區學習更多知識。


參考文獻: 《How To Create a Kubernetes 1.10 Cluster Using Kubeadm on CentOS 7》 《只要用 kubeadm 小朋友都能部署 Kubernetes》

問答

如何使用Kubernetes?

相關閱讀

安全報告 | 2018上半年互聯網惡意爬蟲分析:從全景視角看爬蟲與反爬蟲

安全報告 | SSH 暴力破解趨勢:從雲平臺向物聯網設備遷移

給你的CVM安裝一個面板吧!

此文已由做者受權騰訊雲+社區發佈,原文連接:https://cloud.tencent.com/developer/article/1177930?fromSource=waitui

歡迎你們前往騰訊雲+社區或關注雲加社區微信公衆號(QcloudCommunity),第一時間獲取更多海量技術實踐乾貨哦~

海量技術實踐經驗,盡在雲加社區

相關文章
相關標籤/搜索