本教學將引導您設定 Kubernetes 叢集,從頭開始使用 Ansible 和 Kubeadm 並進一步部署容器化的 Nginx 應用程式。
簡介
Kubernetes(也稱為 k8s 或 “kube”)是一個開源的容器協調平台,可自動化部署、管理和擴充容器化應用程式所涉及的許多手動流程。Kubernetes 擁有一個快速成長的開源社群,並積極為該專案做出貢獻。請閱讀我們的部落格文章,它將向您介紹您需要了解的關於Kubernetes 平台的基本概念.
Kubeadm 是一個工具,用於設定多個整合元素、部件和組件,例如 API 伺服器、Controller Manager 和 Kube DNS。它也有助於自動化安裝。然而,它不會建立使用者,也不會處理作業系統級別依賴項的安裝及其設定,且無法佈署您的基礎架構。
Ansible 是一款用於軟體配置和應用程式部署的開源工具。Saltstack 是一款由事件驅動的資訊科技自動化開源軟體。這兩款工具可以降低建立額外叢集或重建現有叢集時出錯的可能性,並可用於這些初步任務。
目標:
您的叢集將包含以下實體資源:
1. 一個主節點:
主節點是控制和管理一組工作節點(工作負載執行期)的節點,並在 Kubernetes 中代表一個叢集。它還保存節點的資源計劃,以確定針對觸發事件的適當操作。它執行 etcd,這是一個開源的分散式鍵值儲存,用於在將工作負載排程到工作節點的組件之間保存和管理叢集資料。
例如,排程器會確定哪個工作節點將託管新排程的 POD。
2. 兩個工作節點:
工作節點是在排程完成後,即使主節點故障也能繼續執行其分配工作的節點。工作節點是執行您的工作負載(即容器化應用程式和服務)的伺服器。您也可以透過增加工作節點來提升叢集的容量。
完成本教學後,假設叢集中的伺服器具有足夠的 CPU 和 RAM 資源供您的應用程式執行,您將擁有一個功能齊全的叢集,隨時可以執行工作負載(即容器化應用程式和服務)。成功設定叢集後,您幾乎可以執行任何傳統的 UNIX 應用程式。它可以在您的叢集上進行容器化,包括網頁應用程式、資料庫、精靈程序(daemons)和命令列工具。
叢集本身在每個節點上將消耗大約 300-500MB 的記憶體和 10% 的 CPU。
先決條件:
- 您必須在本地 Linux 機器上擁有 SSH 金鑰組,並了解如何使用 SSH 金鑰。然而,如果您以前未使用過 SSH 金鑰,可以參考本教學以協助您在本地機器上設定 SSH 金鑰.
- 三台執行 Ubuntu 18.04 的伺服器,每台至少配備 4GB RAM 和 4 個 vCPU。您應該能夠使用您的 SSH 金鑰組以 root 使用者身份 SSH 登入每台伺服器。請遵循本教學來安裝您的 Ubuntu 伺服器.
- 在您的本地機器上安裝 Ansible。
- 您還必須熟悉 Ansible playbook。
- 您還需要知道如何從 Docker 映像檔啟動容器。如果您需要複習,請參閱 “步驟 5 — 在 Ubuntu 中使用 Docker 映像檔” 於 如何在 Ubuntu 18.04 上安裝和使用 Docker ,如果您需要複習的話。
步驟 1 — 設定工作區目錄和 Ansible 清單檔案
您首先需要在本地機器上設定 Ansible。它將協助您在遠端伺服器上執行命令。它還透過自動化來簡化手動部署的工作。為此,您需要在本地機器上建立一個目錄,作為您的臨時數位儲存區域(工作區)。
建立目錄後,您將建立一個 hosts 檔案,用於儲存每個伺服器的 IP 位址和群組的所有資訊。它將協助您在其中儲存清單資訊。如前所述,將有三台伺服器,一台 master 和兩台 worker。master 伺服器將作為 master,其顯示的 IP 為 master_ip. 另外兩台伺服器將作為 worker,其 IP 為 worker_1_ip 和 worker_2_ip.
您需要在本機電腦的家目錄中建立一個名為 ~/kube-cluster 的目錄,並使用 cd 指令進入該目錄:
|
1 2 |
mkdir ~/kube-cluster cd ~/kube-cluster |
這個 ~/kube-cluster 目錄現在將作為臨時數位儲存區域(工作區),您將在其中執行所有本機指令,以使用 kubeadm 建立 Kubernetes 叢集。該目錄將包含您所有的 Ansible playbook,並在教學的其餘部分中使用。
建立 Hosts 檔案
建立一個名為 ~/kube-cluster/hosts 的檔案,使用 nano 或您喜愛的文字編輯器:
|
1 |
nano ~/kube-cluster/hosts |
現在您需要新增以下文字,這將指定有關叢集邏輯結構的資訊:
|
1 2 3 4 5 6 7 8 9 |
[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 [all:vars] ansible_python_interpreter=/usr/bin/python3 |
如前所述,該清單檔案將協助您儲存有關伺服器 IP 位址以及每個伺服器所屬群組的所有資訊。 ~/kube-cluster/hosts 將是您的清單檔案,而 (masters 和 workers) 將是您新增至其中以指定叢集邏輯結構的兩個 Ansible 群組。
這個 Master 群組是指定 Ansible 應以 root 使用者身分執行遠端指令的群組。它還列出了 master 節點的 IP (master_ip),該 IP 可以由名為 “master” 的伺服器項目列出。同樣地,Workers 群組有兩個 worker 伺服器的項目 (worker_1_ip 和 worker_2_ip),它們也指定 ansible_user 為 root。
檔案的最後一行告訴 Ansible 使用遠端伺服器的 Python 3 解譯器進行其管理操作。最後,在新增文字後,您需要儲存並關閉檔案。設定好工作區目錄和 Ansible 清單檔案後,讓我們繼續進行下一步:安裝作業系統層級的相依性並建立組態設定。
步驟 2 — 在所有遠端伺服器上建立非 Root 使用者
在此步驟中,您將學習如何在所有伺服器上建立具有 sudo 權限的非 root 使用者,以便您可以作為非特權使用者手動 SSH 進入它們。
這對於維護叢集時經常執行的操作非常有用。此外,此步驟將協助您更準確且更不易出錯地執行任務,從而減少無意中修改或刪除重要檔案的機率。如果您想變更 root 擁有的檔案設定,或使用諸如 top/htop 之類的指令查看系統資訊並檢視執行中容器的清單,以下步驟將協助您完成所有任務。
建立 Playbook
建立一個名為 ~/kube-cluster/initial.yml 的檔案,位於工作區中:
|
1 |
nano ~/kube-cluster/initial.yml |
接下來,您需要新增以下 play。Ansible 中的 play 是針對特定伺服器和群組要執行的一系列步驟。一個 playbook 中可以有一個或多個 play。
以下 play 將建立一個非 root 的 sudo 使用者:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
- hosts: all become: yes tasks: - name: 建立 該 'ubuntu' 使用者 user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash - name: 允許 'ubuntu' 擁有 have 免密碼 sudo lineinfile: dest: /etc/sudoers line: 'ubuntu ALL=(ALL) NOPASSWD: ALL' validate: 'visudo -cf %s' - name: 設定 up 授權 金鑰 給 該 ubuntu 使用者 authorized_key: user=ubuntu key="{{item}}" with_file: - ~/.ssh/id_rsa.pub |
以下是我們 Playbook 的詳細說明:
- 此 Playbook 將建立非 root 使用者
ubuntu. - 由於您需要執行
sudo指令而無需輸入密碼,此 Play 將設定sudoers檔案以允許ubuntu使用者執行此操作。 - 上述任務的主要目的是讓您能夠以
ubuntu使用者身分 SSH 登入每台伺服器。此 Playbook 會將您本機機器的公鑰(通常是~/.ssh/id_rsa.pub)新增至遠端ubuntu使用者’的已授權金鑰清單中。
現在,新增文字後,您需要儲存並關閉該檔案。
執行 Playbook
之後,我們需要執行我們的 Playbook,只需在本機機器上執行以下指令即可建立非 root 使用者 ubuntu:
|
1 |
ansible-playbook -i hosts ~/kube-cluster/initial.yml |
執行此指令需要一些時間,之後您將看到以下輸出:

完成此步驟後,您可以在下一步中繼續安裝 Kubernetes 特定的相依套件。
步驟 3 — 安裝 Kubernetes’ 相依套件
在此步驟中,您將學習如何使用 Ubuntu’s 套件管理員安裝 Kubernetes 所需的作業系統級套件。
這些套件包括:
- Docker: Docker 是一個用於建置、分發和執行 Docker 容器的平台與工具。您可以透過參考我們的教學輕鬆設定 Docker:如何在公有雲的 Ubuntu 上安裝 & 操作 Docker。然而,對其他執行階段(如 rkt)的支援在 Kubernetes 中仍處於積極開發階段。
Kubeadm: kubeadm 是一個 CLI 工具,用於執行建立並執行最小可行叢集所需的動作。這將協助您以標準方式安裝和建置叢集的各種元件。kubelet: 該 kubelet 是在每個節點上執行並處理節點級操作的主要“節點代理”。kubectl: kubectl 也是一個 CLI 工具,用於與您的叢集進行通訊,並透過其 API 伺服器發送指令。
建立 Playbook
建立一個名為 ~/kube-cluster/kube-dependencies.yml 的檔案於工作區中:
|
1 |
nano ~/kube-cluster/kube-dependencies.yml |
現在您需要將以下 Play 新增至檔案中,以便在您的伺服器上安裝以下套件:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
- hosts: all become: yes tasks: - name: 安裝 Docker apt: name: docker.io state: present update_cache: true - name: 安裝 APT Transport HTTPS apt: name: apt-transport-https state: present - name: 新增 Kubernetes apt-key apt_key: url: https://packages.cloud.google.com/apt/doc/apt-key.gpg validate_certs: false state: present - name: 新增 Kubernetes 的 APT 軟體庫 apt_repository: repo: deb http://apt.kubernetes.io/ kubernetes-xenial main state: present filename: 'kubernetes' - name: 安裝 kubelet apt: name: kubelet=1.16.0-00 state: present update_cache: true - name: 安裝 kubeadm apt: name: kubeadm=1.16.0-00 state: present - hosts: master become: yes tasks: - name: 安裝 kubectl apt: name: kubectl=1.16.0-00 state: present force: yes |
Playbook 中的第一個 play 執行以下操作:
- 此 play 將協助您安裝作業系統層級的套件,即 Docker – 容器執行階段。
- 它會安裝
apt-transport-https,這允許您將外部 HTTPS 來源新增至您的 APT 來源清單。 - 新增 Kubernetes APT 軟體庫的 apt-key 以進行金鑰驗證。
- 將 Kubernetes APT 軟體庫新增至遠端伺服器的 APT 來源清單。
- 安裝
kubelet和kubeadm.
第二個 play 執行一項重要且獨立的工作,其中包括在您的 master 節點上安裝 kubectl。現在,在新增文字後,您需要儲存並關閉檔案。
執行 Playbook
之後,我們只需要在本地機器上執行以下命令來執行我們的 Playbook:
|
1 |
ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml |
執行此命令需要一些時間,之後您將看到以下輸出:

執行後,Docker、kubeadm 和 kubelet 將安裝在所有遠端伺服器上。Kubectl 不是必要元件,僅在執行叢集命令時需要。在此情境下,僅在 master 節點上安裝它是合理的,因為您只會從 master 執行 kubectl 命令。然而,請注意 kubectl 指令可以從任何工作節點或任何可以安裝並配置為指向叢集的機器上執行。
所有系統相依性現已安裝完畢。讓我們來設定主節點並初始化叢集。
步驟 4 — 設定主節點
在此步驟中,您將學習一些概念,例如 Pods 和 Pod 網路外掛程式 ,因為一旦您設定好主節點,您的叢集就會包含這兩者。
Pod 是 Kubernetes 中最小、最基本的部署對象。Pod 包含一個或多個容器,例如 Docker 容器。當一個 Pod 運行多個容器時,這些容器會被作為單一實體進行管理,並共享該 Pod’s 的資源。
每個 Pod 都有自己的 IP 地址,且某個節點上的 Pod 應該要能夠使用該 Pod’s IP 來存取另一個節點上的 Pod。然而,Pod 之間的通訊更為複雜。它需要一個獨立的組件,能夠透明地將流量從一個節點上的 Pod 路由到另一個節點上的 Pod。Pod 網路外掛程式就是用於此功能。目前有許多 Pod 網路外掛程式可用,但我們將使用 Flannel ,因為它是一個穩定且高效的選擇。
建立 Playbook
建立一個名為 master.yml 的 Ansible playbook 於您的本機機器上:
|
1 |
nano ~/kube-cluster/master.yml |
此外,您需要將以下 play 新增至檔案中,以初始化叢集並安裝 Flannel:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
- hosts: master become: yes tasks: - name: 初始化 the 叢集 shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt args: chdir: $HOME creates: cluster_initialized.txt become: yes become_user: root - name: 建立 .kube 目錄 become: yes become_user: ubuntu file: path: $HOME/.kube state: directory mode: 0755 - name: 複製 admin.conf 至 使用者'的 kube 設定 copy: src: /etc/kubernetes/admin.conf dest: /home/ubuntu/.kube/config remote_src: yes owner: ubuntu - name: 安裝 Pod 網路 become: yes become_user: ubuntu shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml >> pod_network_setup.txt args: chdir: $HOME creates: pod_network_setup.txt |
以下是此 play 的分解說明:
- 此 play 中的第一個任務將透過執行
kubeadm init來設置叢集。為了指定分配 pod IP 的私有子網路,我們傳遞參數--pod-network-cidr=10.244.0.0/16。Flannel 預設使用上述子網路。我們使用它來告訴kubeadm使用相同的子網路。 - 第二個任務用於建立
.kube目錄,位於/home/ubuntu。此目錄將保存配置資訊,例如連接到叢集所需的管理員金鑰檔案以及叢集的 API 位址。 - 第三個任務用於將
/etc/kubernetes/admin.conf檔案(由kubeadm init產生)複製到您的非 root 使用者的家目錄。這將允許您使用kubectl來存取新建立的叢集。 - 最後一個任務執行
kubectl apply來安裝Flannel.kubectl apply -f descriptor.[yml|json]是用來告訴kubectl去建立描述於descriptor.[yml|json]檔案中的物件。kube-flannel.yml檔案包含設置Flannel於叢集中所需的物件描述。
現在,在新增文字後,您需要儲存並關閉檔案。
執行 Playbook
之後,您只需在本地機器上執行以下命令來執行我們的 playbook:
|
1 |
ansible-playbook -i hosts ~/kube-cluster/master.yml |
執行此命令需要一些時間,之後您將看到以下輸出:

現在使用以下命令透過 SSH 連線到其中,以檢查 master 節點的狀態:
|
1 |
ssh ubuntu@master_ip |
進入 master 節點後,執行:
|
1 |
kubectl get nodes |
您現在將看到以下輸出:

獲得上述輸出後,您可以宣告 master 節點已完成所有設置任務,並且在進入 Ready 狀態後可以開始接受 worker 節點並執行任務。您現在可以從本地機器新增 worker。
步驟 5 — 設置 Worker 節點
在設置好 master 節點後,現在我們可以進入下一步:設置 worker 節點。將 worker 節點新增到叢集中,只需在每個 worker 伺服器上執行單個命令即可。此命令中包含重要資訊,例如 IP 位址、master 的 API 伺服器連接埠以及安全權杖。但您應該注意,並非所有節點都能加入叢集,只有傳入安全權杖的節點才能加入叢集。
建立 playbook
此命令將協助您返回工作空間並建立一個名為 workers.yml:
|
1 |
nano ~/kube-cluster/workers.yml |
將以下文字新增到檔案中,以將 worker 新增到叢集:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
- hosts: master become: yes gather_facts: false tasks: - name: 取得 加入 命令 shell: kubeadm token create --print-join-command register: join_command_raw - name: 設定 加入 命令 set_fact: join_command: "{{ join_command_raw.stdout_lines[0] }}" - hosts: workers become: yes tasks: - name: 加入 叢集 shell: "{{ hostvars['master'].join_command }} >> node_joined.txt" args: chdir: $HOME creates: node_joined.txt |
以下是該 playbook 的作用。上述程式碼中有兩個 play:
- 第一個 play 用於獲取需要在工作節點上執行的加入命令。該命令的格式為:
kubeadm join --token sha256:<hash><token><master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>;。該任務需要獲取正確的 token 和 hash 值。一旦獲取到正確的輸入,該任務會將其設置為 fact,以便第二個 play 能夠存取該資訊。 - 第二個 play 僅用於執行單一任務 – 通過在所有工作節點上執行加入命令,使這兩個工作節點成為叢集的一部分。
新增文字後,您需要儲存並關閉檔案。
執行 playbook
之後,我們需要透過在工作機器上執行以下命令來執行我們的 playbook:
|
1 |
ansible-playbook -i hosts ~/kube-cluster/workers.yml |
執行此命令需要一些時間,之後您將看到以下輸出:

現在,您的 Kubernetes 叢集已完全設定好並正常運作,工作節點已準備好執行工作負載。在進入下一步之前,讓我們驗證叢集是否按計劃運作。
步驟 6 — 驗證叢集
在設定過程中,可能會出現叢集失敗的情況。這可能是由於主節點與工作節點之間的網路錯誤,或者是節點問題。因此,我們需要在排程應用程式之前驗證叢集,並確保沒有發生故障。為此,您需要從主節點檢查叢集的當前狀態,以確保節點已就緒。如果節點未就緒或您斷開了連線,您可以使用以下命令重新建立連線:
|
1 |
ssh ubuntu@master_ip |
使用以下命令獲取叢集的狀態:
|
1 |
kubectl get nodes |
執行此命令需要一些時間,之後您將看到以下輸出:

您需要檢查作為叢集一部分的所有節點是否都處於就緒狀態。如果少數節點的Not Ready 作為 STATUS,這表示工作節點尚未完成設定。然而,在重新執行 kubectl get nodes 並檢查更新的輸出之前,您應該再等待五到十分鐘。如果某些節點仍顯示 Not Ready 作為其狀態,您應該去驗證先前的步驟並重新執行命令。只有當節點的 STATUS 值為 Ready 時,它們才是叢集的一部分並準備好執行工作負載。成功執行第 6 步後,您的叢集現在已通過驗證。現在讓我們在叢集上排程一個 Nginx 範例應用程式。
步驟 7 — 在叢集上執行應用程式
建立 Deployment
成功建立叢集後,您可以將任何容器化應用程式部署到您的叢集中。如果您在主節點內,可以將以下命令用於其他容器化應用程式。接下來,執行以下命令建立一個名為 nginx :
|
1 |
kubectl create deployment nginx --image=nginx |
您需要變更 Docker 映像檔名稱和任何相關的 flag(例如連接埠和磁碟卷)。為了讓您熟悉操作,您可以使用 deployment 和 service 來部署 Nginx,以了解如何將應用程式部署到叢集中。
一個 Kubernetes 部署 是 Kubernetes 中的一種資源物件,用於為應用程式提供宣告式更新。部署(deployment)允許您描述應用程式的生命週期,例如容器映像檔、複本(replicas)和更新策略。部署可確保在任何時候都有所需數量的 Pod 正在運行且可用。如果 Pod 在叢集的生命週期內崩潰,它會重新產生。更新過程也會被完整記錄並進行版本控制,並提供暫停、繼續和復原到先前版本的選項。上述建立名為 Nginx 的部署的指令將幫助您從 Docker 登錄檔的 Nginx Docker 映像檔部署一個包含單個容器的 Pod。
設定 Node Port
接下來,我們需要建立一個 NodePort. NodePort 是您叢集中每個節點上的開放連接埠。Kubernetes 會將傳入的流量透明地路由到 NodePort 上的服務,即使您的應用程式正在另一個節點上運行。為此,我們可以使用此指令建立一個名為 Nginx 的 NodePort 資源,這將公開該應用程式:
|
1 |
kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort |
服務(Service)是另一個 Kubernetes 物件,負責向這些 Pod 公開介面,從而允許從叢集內部或外部程序與服務之間進行網路存取。它可以被定義為 Pod 之上的一種抽象,提供單一 IP 地址和 DNS 名稱,以便存取 Pod。透過服務,可以非常輕鬆地管理負載平衡設定。
執行以下指令:
|
1 |
kubectl get services |
這將輸出類似於以下的文字:

取得輸出後,Kubernetes 將自動分配一個大於 30000 的隨機連接埠,同時也確保分配的連接埠未被其他服務綁定。上述輸出的第三行將幫助您檢索 Nginx 正在運行的連接埠。
要驗證其是否正常運作,請透過您本機電腦上的瀏覽器造訪 http://worker_1_ip:nginx_port 或 http://worker_2_ip:nginx_port 。您將會看到 Nginx 熟悉的歡迎頁面。
移除部署
如果您想移除 Nginx 應用程式,您需要先從主節點(master node)刪除 nginx 服務:
|
1 |
kubectl delete service nginx |
要驗證應用程式是否最終已被刪除,您需要執行此指令:
|
1 |
kubectl get services |
您將獲得以下輸出:

之後,您需要使用以下指令刪除部署:
|
1 |
kubectl delete deployment nginx |
您可以使用此指令來驗證部署是否最終已被刪除:
|
1 |
kubectl get deployments |
![]()
結論:
本教學將幫助您使用 Kubeadm 和 Ansible 在 Ubuntu 18.04 上正確設定叢集。現在您的叢集已設定完畢,您可以輕鬆開始部署自己的應用程式和服務。
以下是包含其他詳細資訊的連結清單,將在此過程中為您提供指引:
- Docker 化應用程式 – 此連結包含引導您如何使用 Docker 載入應用程式的範例。例如將 PostgreSQL、CouchDB 服務等進行 Docker 化。
- Pod 總覽 – 此連結展示了如何使用 Pod、Pod 的運作方式,以及 Pod 與其他 Kubernetes 物件的關係。Pod 是 Kubernetes 的重要組成部分,因此了解它們將有助於您成功完成任務。
- 部署總覽 – 這將幫助您了解部署。部署為 Pod 和 ReplicaSet 提供宣告式更新。您將學習如何更新、輪替和復原部署。
- 服務總覽 -此連結將引導您了解服務,這是 Kubernetes 叢集中另一個常用的物件。Kubernetes 中的服務是一種抽象,它定義了一組邏輯 Pod 以及存取它們的策略。了解服務的類型及其擁有的選項,對於運行無狀態和有狀態應用程式都至關重要。
此外,歡迎查看我們其他專注於 Docker 和 Kubernetes 的教學課程,這些內容都發佈在我們的部落格:
- 認識 Kubernetes
- 清理 Docker 資源 – 映像檔、容器與磁碟卷
- 如何在 CloudSigma 上執行 Docker (搭配 CloudInit) 更新版
- 在 CentOS 7 上安裝與設定 Docker
- 如何在公有雲的 Ubuntu 上安裝 & 操作 Docker
還有許多其他重要的概念,例如 磁碟卷, Ingresses,以及 機密,您可以在部署生產環境應用程式時使用。
祝您運算愉快!
留言
目前尚無留言。成為第一個留言的人吧。