本文介紹如何在ubuntu
上部署k8s
集群,大致可以分為如下幾個步驟:
-
修改
ubuntu
配置 -
安裝
docker
-
安裝
kubeadm
、kubectl
以及kubelet
-
初始化
master
節點 -
將
slave
節點加入網絡
如果你對上面的某些名字感到陌生,沒關系,下文會一一進行講解,如果你想先了解一下 docker 和 k8s,可以參考
主機名 | 主機ip | 版本 | CPU | 內存 |
---|---|---|---|---|
master1 | 192.168.56.11 | Ubuntu server 18.04 | 2核 | 1G |
worker1 | 192.168.56.21 | Ubuntu server 18.04 | 2核 | 1G |
因為k8s
分為管理節點和工作節點,所以我們將要 在master1
上部署管理節點,在worker1
上部署工作節點。如果想了解如何創建這兩個節點,可以參考
注意,本文的 docker、k8s 等軟件安裝均未指定具體版本,在本文完成時2021/11/11
,下載到的版本如下,如有特殊版本需要請自行指定版本。
軟件名 | 版本 |
---|---|
docker | 20.10.10 |
kubectl | 1.22.3 |
kubeadm | 1.22.3 |
kubelet | 1.22.3 |
一. 修改 ubuntu 配置
首先,k8s 要求我們的 ubuntu 進行一些符合它要求的配置。很簡單,包括以下兩步:關閉 Swap
內存 以及 配置免密登錄,這一步兩台主機都需要進行配置。
關閉 swap 內存
這個swap
其實可以類比成 windows 上的虛擬內存,它可以讓服務器在內存吃滿的情況下可以保持低效運行,而不是直接卡死。但是 k8s 的較新版本都要求關閉swap
。所以咱們直接動手,修改/etc/fstab
文件:
sudo vi /etc/fstab
你應該可以看到如下內容,把第二條用#
注釋掉就好了,注意第一條別注釋了,不然重啟之后系統有可能會報file system read-only
錯誤。
UUID=e2048966-750b-4795-a9a2-7b477d6681bf / ext4 errors=remount-ro 0 1
# /dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0
然后輸入reboot
重啟即可,重啟后使用top
命令查看任務管理器,如果看到如下KiB Swap
后均為 0
就說明關閉成功了。
關閉swap之后的任務管理器
上面說的是永久關閉swap
內存,其實也可以暫時關閉,使用swapoff -a
命令即可,效果會在重啟后消失。
配置免密登錄
k8s 要求 管理節點可以直接免密登錄工作節點 的原因是:在集群搭建完成后,管理節點的 kubelet 需要登陸工作節點進行操作。而至於怎么操作很簡單,這里就不詳提了,可以參見文章
二. 安裝 docker
docker 是 k8s 的基礎,在安裝完成之后也需要修改一些配置來適配 k8s ,所以本章分為 docker 的安裝 與 docker 的配置 兩部分。如果你已經安裝並使用了一段時間的 docker 了話,建議使用docker -v
查看已安裝的 docker 版本,並在 k8s 官網上查詢適合該版本的 k8s 進行安裝。這一步兩台主機都需要進行安裝。
docker 的安裝
docker 在 ubuntu 的安裝上真是再簡單不過了,執行如下命令即可,在安裝之前請記得把鏡像源切換到國內。
sudo apt install docker.io
等安裝完成之后使用docker -v
來驗證 docker是否可用。
docker 的配置
安裝完成之后需要進行一些配置,包括 切換docker下載源為國內鏡像站 以及 修改cgroups。
這個cgroups
是啥呢,你可以把它理解成一個進程隔離工具,docker
就是用它來實現容器的隔離的。docker 默認使用的是cgroupfs
,而 k8s 也用到了一個進程隔離工具systemd
,如果使用兩個隔離組的話可能會引起異常,所以我們要把 docker 的也改成systemd
。
這兩者都是在/etc/docker/daemon.json
里修改的,所以我們一起配置了就好了,首先執行下述命令編輯daemon.json
:
sudo vi /etc/docker/daemon.json
打開后輸入以下內容:
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com",
"https://quay-mirror.qiniu.com"
],
"exec-opts": [ "native.cgroupdriver=systemd" ]
}
然后:wq
保存后重啟 docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
然后就可以通過docker info | grep Cgroup
來查看修改后的 docker cgroup 狀態,發現變為systemd
即為修改成功。
三. 安裝 k8s
安裝完了 docker 就可以下載 k8s 的三個主要組件kubelet
、kubeadm
以及kubectl
了。這一步兩台主機都需要進行安裝。先來簡單介紹一下這三者:
-
kubelet
: k8s 的核心服務 -
kubeadm
: 這個是用於快速安裝 k8s 的一個集成工具,我們在master1
和worker1
上的 k8s 部署都將使用它來完成。 -
kubectl
: k8s 的命令行工具,部署完成之后后續的操作都要用它來執行
其實這三個的下載很簡單,直接用apt-get
就好了,但是因為某些原因,它們的下載地址不存在了。所以我們需要用國內的鏡像站來下載,也很簡單,依次執行下面五條命令即可:
# 使得 apt 支持 ssl 傳輸
apt-get update && apt-get install -y apt-transport-https
# 下載 gpg 密鑰
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
# 添加 k8s 鏡像源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
# 更新源列表
apt-get update
# 下載 kubectl,kubeadm以及 kubelet
apt-get install -y kubelet kubeadm kubectl
直接在/etc/apt/sources.list
里添加https://mirrors.aliyun.com/kubernetes/apt/
是不行的,因為這個阿里鏡像站使用的ssl
進行傳輸的,所以要先安裝apt-transport-https
並下載鏡像站的密鑰才可以進行下載。
四. 安裝 master 節點
下載完成后就要迎來重頭戲了,初始化master
節點,這一章節只需要在管理節點上配置即可,大致可以分為如下幾步:
-
初始化
master
節點 -
部署
flannel
網絡 -
配置
kubectl
工具
初始化 master 節點
使用kubeadm
的init
命令就可以輕松的完成初始化,不過需要攜帶幾個參數,如下。先不要直接復制執行,將賦值給--apiserver-advertise-address
參數的 ip 地址修改為自己的master
主機地址,然后再執行。
kubeadm init \
--apiserver-advertise-address=192.168.56.11 \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16
這里介紹一下一些常用參數的含義:
-
--apiserver-advertise-address
: k8s 中的主要服務apiserver
的部署地址,填自己的管理節點 ip -
--image-repository
: 拉取的 docker 鏡像源,因為初始化的時候kubeadm
會去拉 k8s 的很多組件來進行部署,所以需要指定國內鏡像源,下不然會拉取不到鏡像。 -
--pod-network-cidr
: 這個是 k8s 采用的節點網絡,因為我們將要使用flannel
作為 k8s 的網絡,所以這里填10.244.0.0/16
就好 -
--kubernetes-version
: 這個是用來指定你要部署的 k8s 版本的,一般不用填,不過如果初始化過程中出現了因為版本不對導致的安裝錯誤的話,可以用這個參數手動指定。 -
--ignore-preflight-errors
: 忽略初始化時遇到的錯誤,比如說我想忽略 cpu 數量不夠 2 核引起的錯誤,就可以用--ignore-preflight-errors=CpuNum
。錯誤名稱在初始化錯誤時會給出來。
當你看到如下字樣是,就說明初始化成功了,請把最后那行以kubeadm join
開頭的命令復制下來,之后安裝工作節點時要用到的,如果你不慎遺失了該命令,可以在master
節點上使用kubeadm token create --print-join-command
命令來重新生成一條。
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 192.168.56.11:6443 --token wbryr0.am1n476fgjsno6wa --discovery-token-ca-cert-hash sha256:7640582747efefe7c2d537655e428faa6275dbaff631de37822eb8fd4c054807
如果在初始化過程中出現了任何Error
導致初始化終止了,使用kubeadm reset
重置之后再重新進行初始化。
配置 kubectl 工具
這一步就比較簡單了,直接執行如下命令即可:
mkdir -p /root/.kube && \
cp /etc/kubernetes/admin.conf /root/.kube/config
執行完成后並不會刷新出什么信息,可以通過下面兩條命令測試 kubectl
是否可用:
# 查看已加入的節點
kubectl get nodes
# 查看集群狀態
kubectl get cs
部署 flannel 網絡
flannel
是什么?它是一個專門為 k8s 設置的網絡規划服務,可以讓集群中的不同節點主機創建的 docker 容器都具有全集群唯一的虛擬IP地址。想要部署flannel
的話直接執行下述命令即可:
flannel地址:
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
輸出如下內容即為安裝完成:
至此,k8s 管理節點部署完成。
五. 將 slave 節點加入網絡
首先需要重復步驟 1 ~ 3 來安裝 docker 、k8s 以及修改服務器配置,之后執行從步驟 4 中保存的命令即可完成加入,注意,這條命令每個人的都不一樣,不要直接復制執行:
kubeadm join 192.168.56.11:6443 --token wbryr0.am1n476fgjsno6wa --discovery-token-ca-cert-hash sha256:7640582747efefe7c2d537655e428faa6275dbaff631de37822eb8fd4c054807
待控制台中輸出以下內容后即為加入成功:
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
隨后登錄master1
查看已加入節點狀態,可以看到worker1
已加入,並且狀態均為就緒。至此,k8s 搭建完成:
root@master1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1 Ready master 145m v1.22.3
worker1 Ready <none> 87m v1.22.3
默認網卡問題修復
如果你是使用virtualBox
部署的虛擬機,並且虛擬機直接無法使用網卡1的 ip 地址互相訪問的話(例如組建雙網卡,網卡1為 NAT 地址轉換用來上網,網卡2為Host-only
,用於虛擬機之間訪問)。就需要執行本節的內容來修改 k8s 的默認網卡。不然會出現一些命令無法使用的問題。如果你的默認網卡可以進行虛擬機之間的相互訪問,則沒有該問題。
修改 kubelet 默認地址
訪問kubelet
配置文件:
sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
在最后一行ExecStart
之前 添加如下內容:
Environment="KUBELET_EXTRA_ARGS=--node-ip=192.168.56.21"
重啟kubelet
:
systemctl stop kubelet.service && \
systemctl daemon-reload && \
systemctl start kubelet.service
至此修改完成,更多信息詳見
修改 flannel 的默認網卡
編輯flannel
配置文件
sudo kubectl edit daemonset kube-flannel-ds -n kube-system
找到spec.template.spec.containers.args
字段並添加--iface=網卡名
,例如我的網卡是enp0s8
:
- args:
- --ip-masq
- --kube-subnet-mgr
# 添加到這里
- --iface=enp0s8
:wq
保存修改后輸入以下內容刪除所有 flannel,k8s 會自動重建:
kubectl delete pod -n kube-system -l app=flannel
至此修改完成,更多內容請見
測試
docker get node
docker pull nginx
kubectl create deployment nginx --image=nginx
kubectl get pod
1- 安裝dashboard
dashboard地址:https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort # 添加內容
ports:
- port: 443
nodePort: 30001 # 添加內容
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
2- 修改后完整文件內容:
kubectl apply -f recommended.yml
3- 查看
kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.105.240.105 <none> 8000/TCP 2m53s
kubernetes-dashboard NodePort 10.105.193.180 <none> 443:30043/TCP 2m53s
4- 瀏覽器登錄
https://192.168.56.111:30043/
5- 生成dashboard登陸的token
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:dashboard-admin
kubectl get secret -n kube-system
# 找到dashboard-admin-token-klk6z
kubectl describe secret dashboard-admin-token-klk6z -n kube-system
# 把token輸入,登陸
以上內容,基本安裝完成。
6- 加入節點
加入節點:
# 查看節點加入命令
kubeadm token create --print-join-commandkubeadm join 192.168.177.6:6443 --token 5wmpns.84ltuxc6fgydsum9 \
--discovery-token-ca-cert-hash sha256:b0bf6365b53672f4f1cb40c4558105e43023348f1fc98a3a61ef2a683d294b2c
# token過期后,新節點的加入方法
kubeadm token list# 創建token
kubeadm token create# 創建加密
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
# join時可以加 --node-name k8s-new-node,節點名
kubeadm join --token aa78f6.8b4cafc8ed26c34f --discovery-token-ca-cert-hash sha256:0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538 192.168.177.6:6443
踩坑:解決
1:默認是從谷歌下載,我們可以添加阿里的k8s源
cat <<EOF > /etc/apt/sources.list.d/kubernetes.list
deb Index of /kubernetes/apt/ kubernetes-xenial main
EOF
2:執行以下命令進行下載
apt-get update && apt-get install -y apt-transport-https curl
apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated
1):可能報錯
Err:6 https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease
The following signatures couldn't be verified because the public key is not available: NO_PUBKEY FEEA9169307EA071 NO_PUBKEY 8B57C5C2836F4BEB
Reading package lists... Done
W: GPG error: https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY FEEA9169307EA071 NO_PUBKEY 8B57C5C2836F4BEB
E: The repository 'https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
解決方法:
執行以下命令,給阿里雲源添加key:
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys FEEA9169307EA071
3:執行下面命令測試是否正常
kubeadm init --image-repository registry.aliyuncs.com/google_containers
1):可能報錯
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR Swap]: running with swap on is not supported. Please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
解決方法:
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
2):可能報錯
HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused.
解決辦法:
create daemon.json
vim /etc/docker/daemon.json
{"exec-opts": ["native.cgroupdriver=systemd"]}
systemctl daemon-reload
systemctl restart docker
systemctl restart kubelet
sudo kubeadm reset
sudo kubeadm init --image-repository registry.aliyuncs.com/google_containers
4:修改TAG標簽(根據自己打情況)
查看當前從阿里雲獲取的鏡像
docker images
registry.aliyuncs.com/google_containers/kube-apiserver v1.22.3
然后執行,查看需要修改成什么tag標簽
kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.22.3
使用 docker tag {舊名稱:版本} {新名稱:版本} ,將鏡像改名。
例:
docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.22.3 k8s.gcr.io/kube-apiserver:v1.22.3
5:使主節點生效
添加環境變量
export KUBECONFIG=/etc/kubernetes/admin.conf
添加網絡插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
此時如果顯示無法找到 raw.githubusercontent.com,則需要找到其對應的IP,放在/etc/hosts文件內,該文件默認為只讀,需要先修改該文件的權限
185.199.108.133 raw.githubusercontent.com
185.199.109.133 raw.githubusercontent.com
185.199.110.133 raw.githubusercontent.com
185.199.111.133 raw.githubusercontent.com
如果仍舊不行,那就搞個VPN試試吧
flannel鏡像
#每個節點都需要拉取鏡像
docker pull lwolf/flannel:v0.12.0
為什么要打tag,
因為kube-flannel.yaml文件里面的鏡像名稱就是
quay.io/coreos/flannel:v0.12.0-amd64
docker tag lwolf/flannel:v0.12.0 quay.io/coreos/flannel:v0.12.0-amd64
dns插件的安裝與應用
沒有網絡插件的話,dns也不能正常起作用
kubectl get svc -n kube-system -o wide #獲取dns服務的ip地址
nslookup svc-nginx.default.svc.cluster.local 10.96.0.10 #只能完整域名查找,並且要包含dns服務器的ip