如何在CentOS上創建Kubernetes集群


歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐干貨哦~

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

介紹

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

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

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

目標

您的群集將包含以下物理資源:

  • 一個主節點

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

  • 兩個工作節點

工作節點是運行工作負載(即容器化應用程序和服務)的服務器。一旦工作節點分配了工作負載,工作節點將繼續運行您的工作負載,即使計划在調度完成后停止工作也是如此。通過添加工作節點可以增加群集的容量。

完成本教程后,您將擁有一個可以運行容器化應用程序的集群,前提是集群中的服務器具有足夠的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),第一時間獲取更多海量技術實踐干貨哦~

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


免責聲明!

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



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