上一次接觸到kubernetes集群的時候已經是一年以前了,那個時候官方的版本還只是v1.10
,而現在過去一年的時間了,官方版本已經快速的迭代到了v1.17
了,社區也越來越成熟、相關的生態組件也越來越豐富,可見在過去的K8S元年
,它發展是多么迅猛。最近想把自己寫的一些小東西封裝成開放API暴露出來,于是想把自己的幾臺機器搞成個kubernetes集群,所以這里想重溫下集群構建的流程。以下的所有文件都可以在Githubhttps://github.com/lateautumn4lin/KubernetesResearch
的ClusterEcology目錄
中尋找到
kubernetes集群搭建實戰
首先要做的是搭建一個最基本的Kubernetes集群。
準備階段
準備階段主要包括兩個方面,一是準備好至少兩臺機器,做master-worker的集群架構,二是了解我們需要安裝好哪些軟件才能構建最基本的集群。
- 機器配置
這次實驗我選用的是騰訊云的云服務器CVM
,由于我是通過不同的賬號購買的,所以我選用的機器之間是通過外網來進行互通,配置方面的話選擇官方默認的最低配置2核4GB
。
服務器IP | CPU | 內存 | 硬盤 | 系統版本 | Hostname |
---|---|---|---|---|---|
192.144.152.23 | 2核 | 4GB | 50GB | Cent OS 7.6 | master1 |
49.233.81.20 | 2核 | 4GB | 50GB | Cent OS 7.6 | worker1 |
- 軟件配置
需要安裝的軟件 | 版本 |
---|---|
Kubernetes | v1.17.x |
Docker | 18.09.7 |
基本的軟件我們需要安裝Kubernetes與Docker,安裝Kubernetes我們需要使用到其中的Kubeadm與Kubectl工具,Kubeadm是官方推薦的初始化工具,并且在v1.13版本中已經正式GA(General Availability)了,也就是說可以在生產環境中使用。而需要Docker是因為Kubernetes中的Pod需要使用到CRI(Container Runtime),也就是容器運行時,Docker是非常標準且通用的CRI,其他的例如Containerd、CRI-O并且在v1.14版本之后如果你的機器中有多種CRI,那么Kubernetes也會默認使用Docker的,所以我們這里就選擇Docker。
檢查與配置階段
這個階段我們主要是檢查我們的服務器配置以及把我們幾個服務器給串聯起來。
- 修改Hostname,配置Host文件
使用hostnamectl分別對worker1和master1進行hostname的永久性修改,并且配置host,之所以這么做是因為我們要統一給各個機器標記,這樣我們在之后的集群管理中能夠更好的通過hostname了解每臺機器的作用。
hostnamectl set-hostname master1
echo "127.0.0.1 $(hostname)" > > /etc/hosts
echo "192.144.152.23 master1" > > /etc/hosts
echo "49.233.81.20 worker1" > > /etc/hosts
- 檢查CPU核數與內存
這一步我們使用lscpu命令來查看我們的服務器的架構以及我們系統的內核數,因為我們要搭建一個Kubernetes集群,master節點不能低于2核,這點是必須要保證的,如果內核數過低會導致整個集群的不穩定和高延遲。
lscpu
# 請使用 lscpu 命令,核對 CPU 信息
# Architecture: x86_64 本安裝文檔不支持 arm 架構
# CPU(s): 2 CPU 內核數量不能低于 2
- 檢查網絡
在所有節點執行命令
[root@master1 ~]# ip route show
default via 172.21.0.1 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.21.0.0/20 dev eth0 proto kernel scope link src 172.21.0.11
[root@master1 ~]# ip address
1: lo: LOOPBACK,UP,LOWER_UP > mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: BROADCAST,MULTICAST,UP,LOWER_UP > mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 52:54:00:2c:42:7d brd ff:ff:ff:ff:ff:ff
inet 172.21.0.11/20 brd 172.21.15.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe2c:427d/64 scope link
valid_lft forever preferred_lft forever
3.1 kubelet使用的IP地址
- ip route show 命令中,可以知道機器的默認網卡,通常是
eth0
,如default via 172.21.0.1 dev eth0
- ip address 命令中,可顯示默認網卡的 IP 地址,Kubernetes 將使用此 IP 地址與集群內的其他節點通信,如
172.21.0.11
- 所有節點上 Kubernetes 所使用的 IP 地址必須可以互通(無需 NAT 映射、無安全組或防火墻隔離)
如果兩臺機器是在共同的內網中可以使用內網IP
進行直接通信,不過我們這次的機器是在兩個不同的騰訊云賬號之中,彼此內網隔離,所以我們直接使用機器的外網IP
進行通信,不建議大家在生產環境中使用。
- 配置機器之間的免登錄
這一步我們要通過配置各機器之間的免登錄打通各個機器,把各個機器串聯起來,這樣方便于我們之后在各臺機器之間的操作。
4.1 每臺服務器生成公私鑰
ssh-keygen –t rsa
4.2 將id_rsa.pub追加到授權的key里面去
cat id_rsa.pub > > authorized_keys
4.3 修改.ssh文件夾和其文件的權限,并重啟SSH服務
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*
service sshd restart
4.4 將.ssh文件夾中三個文件拷貝到目標服務器
scp ~/.ssh/authorized_keys root@192.144.152.23:~/.ssh/
scp ~/.ssh/id* root@192.144.152.23:~/.ssh/
上面是兩臺機器之間如何進行免登錄配置,同理可以用于其他某兩臺機器。
正式安裝階段
準備好上面的機器并且檢查、配置好各個參數之后我們就可以開始正式安裝了。
- 安裝Kubelet以及Docker
切換到ClusterEcology目錄中,可以看到install_kubelet.sh腳本,使用如下命令快速安裝。
cat install_kubelet.sh | sh -s 1.17.2
我們快速看看這個腳本中的代碼,了解具體每一步的作用
#!/bin/bash
# 在 master 節點和 worker 節點都要執行
# 安裝 docker
# 參考文檔如下
# https://docs.docker.com/install/linux/docker-ce/centos/
# https://docs.docker.com/install/linux/linux-postinstall/
# 卸載舊版本
yum remove -y docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
# 設置 yum repository
yum install -y yum-utils
device-mapper-persistent-data
lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安裝并啟動 docker
yum install -y docker-ce-18.09.7 docker-ce-cli-18.09.7 containerd.io
systemctl enable docker
systemctl start docker
# 安裝 nfs-utils
# 必須先安裝 nfs-utils 才能掛載 nfs 網絡存儲
yum install -y nfs-utils
yum install -y wget
# 關閉 防火墻
systemctl stop firewalld
systemctl disable firewalld
# 關閉 SeLinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 關閉 swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
# 修改 /etc/sysctl.conf
# 如果有配置,則修改
sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf
# 可能沒有,追加
echo "net.ipv4.ip_forward = 1" > > /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" > > /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" > > /etc/sysctl.conf
# 執行命令以應用
sysctl -p
# 配置K8S的yum源
cat <
執行如上的命令之后,如果執行正確的話我們會得到Docker的版本信息
Client:
Version: 18.09.7
API version: 1.39
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:56:06 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.7
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:26:28 2019
OS/Arch: linux/amd64
Experimental: false
- 初始化 master 節點
切換到ClusterEcology目錄中,可以看到init_master.sh腳本,我們首先配置好環境變量,然后使用執行腳本快速安裝。
# 只在 master 節點執行
# 替換 x.x.x.x 為 master 節點實際 IP(生產請使用內網 IP)
# export 命令只在當前 shell 會話中有效,開啟新的 shell 窗口后,如果要繼續安裝過程,請重新執行此處的 export 命令
export MASTER_IP=192.144.152.23
# 替換 apiserver.demo 為 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器組所在的網段,該網段安裝完成后,由 kubernetes 創建,事先并不存在于您的物理網絡中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" > > /etc/hosts
cat init_master.sh | sh -s 1.17.2
- 檢查 master 初始化結果
上一步安裝好之后我們要檢驗Kubernetes集群的成果,按下面的命令進行執行。
# 只在 master 節點執行
# 執行如下命令,等待 3-10 分鐘,直到所有的容器組處于 Running 狀態
watch kubectl get pod -n kube-system -o wide
# 查看 master 節點初始化結果
kubectl get nodes -o wide
如果成功的話可以看到以下輸出
[root@master1 dashboard]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master1 Ready master 7h26m v1.17.2 172.21.0.11 < none > CentOS Linux 7 (Core) 3.10.0-862.el7.x86_64 docker://18.9.7
表示我們的集群中master節點已經正式可用
- 獲得 join命令參數
下面我們要將我們的其余worker節點加入集群,worker加入集群需要得到整個集群的token和ca證書,我們首先需要在master節點上面去獲取,包括加入的token和ca證書。
kubeadm token create --print-join-command
# 我們會得到如下輸出,這是我們加入集群的憑證
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
- 初始化 worker節點
針對所有的 worker 節點執行
# 只在 master 節點執行
# 替換 x.x.x.x 為 master 節點實際 IP(生產請使用內網 IP)
# export 命令只在當前 shell 會話中有效,開啟新的 shell 窗口后,如果要繼續安裝過程,請重新執行此處的 export 命令
export MASTER_IP=192.144.152.23
# 替換 apiserver.demo 為 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
echo "${MASTER_IP} ${APISERVER_NAME}" > > /etc/hosts
# 替換為 master 節點上 kubeadm token create 命令的輸出
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
加入之后我們再使用下面的命令來查看worker是否正確加入集群
kubectl get nodes
- 查看集群整體的狀況
查看集群整體狀況只能在master節點執行如下命令
kubectl get nodes -o wide
可以看到如下的輸出,集群都Ready就表示節點可用
[root@master1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready master 5m3s v1.17.2
worker1 Ready < none > 2m26s v1.17.2
生態組件構建
安裝好Kubernetes集群之后,我們得到的只是一個最基本的集群,還有很多問題我們沒有解決,比如說我們想要通過可視化的方式通過頁面點擊的方式來操作整個集群,或者說我們想要一個類似于Python中的pip那樣的包管理工具那樣利用類似工具來管理我們部署在Kubernetes集群的應用,再或者我們想要讓我們的集群和外網能夠進行很方便的通信等等,所以這就需要我們利用其它的組件來不斷完善我們的Kubernetes生態。
我們選用的是如下的軟件
需要安裝的軟件 | 版本 |
---|---|
Kubernetes Dashboard | v2.0.3 |
Helm | v3.0.3 |
Traefik | xxx |
metrics-server | xxx |
- Dashboard插件
安裝Dashboard是因為它是一個綜合性的管理平臺,也是屬于Kubernetes 的官方項目,具體可以在這個倉庫去看https://github.com/kubernetes/dashboard
,雖然之前Dashboard因為操作不人性化,界面丑而廣泛被人詬病,但是經過Kubernetes Dashboard團隊半年多閉關研發,Dashboardv2.0版本新鮮出爐,界面和操作性也有很大提升,也是官方推薦的管理界面之一。
1.1 Dashboard插件安裝
具體的部署方案我根據官方的方案整理成了幾個Yaml文件,項目都在目錄ClusterEcology/InitDashboard
下面
kubectl apply -f k8s-dashboard-rbac.yaml
kubectl apply -f k8s-dashboard-configmap-secret.yaml
kubectl apply -f k8s-dashboard-deploy.yaml
kubectl apply -f k8s-dashboard-metrics.yaml
kubectl apply -f k8s-dashboard-token.yaml
執行好上面的命令之后Dashboard的服務以及用戶基本已經創建好,下面我們需要獲取用戶token來登錄我們的Dashboard
1.2 獲取用戶Token
kubectl describe secret/$(kubectl get secret -n kube-system |grep admin|awk '{print $1}') -n kube-system
1.3 檢查服務是否可用
在之前的Yaml文件中設置了NodePort端口為31001和類型為NodePort方式訪問 Dashboard,所以訪問地址:https://192.144.152.23:31001/
進入 Kubernetes Dashboard頁面,然后輸入上一步中創建的ServiceAccount的Token進入 Dashboard,可以看到新的Dashboard。
輸入Token我們可以看到Dashboard的界面,如下所示是正常的Dashboard界面
- Helm組件
Helm
組件的產生也是源于一個關鍵痛點,就是我們雖然已經部署好Kubernetes集群環境,但是每個微服務也得維護一套Yaml文件,而且每個環境下的配置文件也不太一樣,所以想要重新部署新的環境或者做環境移植的成本是真的很高。如果我們能使用類似于yum那樣的工具來安裝我們的應用的話豈不是會方便很多?基于這點,Helm
就誕生了,從此讓Kubernetes集群擁有一個正式的應用市場
。
舊版本Helm整體分為兩個部分,包括Helm Client和Tiller Server,Helm Client主要是用戶命令行工具,負責管理用戶自定義的包文件,而Tiller Server服務接受Client的請求并且解析請求之后與Kubernetes集群進行交互。
而新版本,也就是Helm3之后,Helm移除了Tiller組件,使用Helm命令會直接使用了kubeconfig來與Kubernetes集群通信,這樣就可以做更細粒度的權限控制,這樣方便了完成和使用,另一個好處是Release name范圍縮小至Namespace,這樣就能夠保證不同的NameSpace可以使用相同的Release name。
2.1 Helm Client組件安裝
我們首先要去官網https://github.com/kubernetes/helm/releases
去下載Helm的壓縮包。
解壓后將可執行文件Helm拷貝到/usr/local/bin目錄下即可,這樣Helm客戶端就在這臺機器上安裝完成了。
cp helm /usr/local/bin/
2.2 Helm使用
初始化Helm
helm init --client-only --stable-repo-url https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts/
helm repo add incubator https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/
helm repo add seldon https://storage.googleapis.com/seldon-charts
helm repo update
安裝一個最簡單的服務
helm install seldon-core seldon/seldon-core-operator
可以看到Helm已經和Kubernetes集群交互從而生成一個seldon-core的服務了
[root@master1 linux-amd64]# helm install seldon-core seldon/seldon-core-operator
NAME: seldon-core
LAST DEPLOYED: Tue Feb 4 22:43:58 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
[root@master1 linux-amd64]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
seldon-core default 1 2020-02-04 22:43:58.232906547 +0800 CST deployed seldon-core-operator-1.0.1
- Traefik組件
3.1 Traefik組件安裝
Traefik是另一個Kubernetes集群中必備的組件,可以把它認為是Nginx的替代品,做一個統一網關的管理工具,它的優點也是有幾個方面,比如有漂亮的dashboard 界面、可基于容器標簽進行配置、新添服務簡單,不用像 nginx 一樣復雜配置,并且不用頻繁重啟等等,雖然性能方面和Nginx會有些許差距,但是作為個人使用的話,還是很讓人愛不釋手的。
- metrics-server插件
metrics-server
是Kubernetes 官方的集群資源利用率信息收集器,是Heapster瘦身后的替代品。metrics-server收集的是集群內由各個節點上kubelet暴露出來的利用率信息,算是集群中基礎的監控信息了,主要是提供給例如調度邏輯等核心系統使用。
git clone https://github.com/kubernetes-incubator/metrics-server.git
cd metrics-server/
kubectl create -f deploy/1.8+/
安裝成功后,過一段時間我們就可以在Dashboard中看到具體的監控信息了
疑難故障分析
有關于Kubernetes集群的疑難故障主要分為幾類:
(1)資源調度類
(2)網絡通信類
(3)配置參數類
大多數問題都是圍繞這三點來進行的(不全是,大佬勿噴),下面列舉我這次安裝中某些問題,有些問題在此次安裝中沒有涉及到,所以以后涉及到的話會講解。
- 節點不允許被調度
我們在安裝過程中會遇到下面這個問題
1 node(s) had taints that the pod didn't tolerate
這個表示某個節點被標記為不可調度,這個是K8S官方默認的,因為這個是確保Master節點不會被調度到額外的容器從而消耗資源,不過我們這個實驗中可以設置所有節點允許調度來避免出現這個問題。
kubectl taint nodes --all node-role.kubernetes.io/master-
- 鏡像問題
按照上面的安裝步驟理論上是可以完全正確的部署好K8S集群的,不過安裝速度會根據網速的情況有差異,我在安裝的時候也安裝了一個多小時,原因也是因為鏡像下載的慢,當我們看到某些pod
一直在pending
的時候,我們可以通過如下命令查看具體的情況。
kubectl describe pod calico-node-ndwqv -n kube-system
使用到describe
命令來查看具體組件的情況,雖然也可以使用logs
命令來查看,不過不如describe
方便。
- Chrome 您的連接不是私密連接
創建好Dashboard之后,第一次通過Chrome登錄Dashboard我們會發現報出這個錯誤您的連接不是私密連接
,這個是由于Chrome最新版本的錯誤導致,我們修改啟動參數就可以了。
-
服務器
+關注
關注
12文章
9164瀏覽量
85429 -
機器
+關注
關注
0文章
782瀏覽量
40729 -
容器
+關注
關注
0文章
495瀏覽量
22062 -
kubernetes
+關注
關注
0文章
224瀏覽量
8720
發布評論請先 登錄
相關推薦
評論