1.安裝前說明
服務器必須是Centos 7.2及以上,Kubernetes 我們采用1.15.*版本
Docker-ce v18.06.3,Etcd 3.2.9,Flanneld v0.7.0-amd64
TLS 認證通信(所有組件,如etcd、kubernetes master 和node)
RBAC 授權,kubedns、dashboard
注意事項:
Docker安裝的版本需與K8s版本批配,不然會出問題
Kubernetes 1.15.2 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.15.1 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.15.0 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.5 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.4 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.3 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.2 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.1 -->Docker版本1.13.1、17.03、17.06、17.09、18.06、18.09
Kubernetes 1.14.0 -->Docker版本1.1
2.環境準備
之前在本機筆記本開VMWare跑集群,感覺資源有些吃緊,看到某公有云在搞促銷,直接下手三臺服務器(2核+4G+5M帶寬)
分別登錄三臺服務器修改Host Name
hostnamectl set-hostname k8s-master \#Master節點
hostnamectl set-hostname k8s-node1 \#node1節點
hostnamectl set-hostname k8s-node2 \#node2節點
修改后,我們三臺主機如下:
name | IP | 數量 |
---|---|---|
k8s-master | 192.168.0.66 | Master節點 |
k8s-node1 | 192.168.0.137 | 工作節點1 |
k8s-node2 | 192.168.0.230 | 工作節點2 |
3.環境初始化
以下步驟在三臺服務器上均執行一遍
關閉selinux
setenforce 0
\# sed -i 's@^\(SELINUX=\).*@\1disabled@' /etc/selinux/config
關閉防火墻及IP TABLE
systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl disable iptables
systemctl stop iptables
設置host
vim /etc/hosts
192.168.0.66 k8s-master
192.168.0.137 k8s-node1
192.168.0.230 k8s-node2
4.安裝Docker
備份源
sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
修改OS源為阿里的倉庫
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
安裝常用命令
yum -y install conntrack ipvsadm ipset jq sysstat curl iptables libseccomp wget lrzsz nmap lsof net-tools zip unzip vim telnet
安裝依賴項
yum install -y yum-utils device-mapper-persistent-data lvm2
安裝Docker源為阿里
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
清理緩存
yum clean all
** 重新生成緩存**
yum makecache
再次查看yum源信息
yum repolist
可以看出,我們的源已經更新到aliyun.com。
下一步我們開始安裝Docker
安裝指定版本的Docker,如果不知道版本名稱,可以用如下命令查看
yum list docker-ce --showduplicates | sort -r
我們安裝18.06.3版本,k8s對應1.15.*
sudo yum install docker-ce-18.06.3.ce-3.el7
安裝完畢后,我們測試下
[root@k8s-master ~]# docker version
Client:
Version: 18.06.3-ce
API version: 1.38
Go version: go1.10.3
Git commit: d7080c1
Built: Wed Feb 20 02:26:51 2019
OS/Arch: linux/amd64
Experimental: false
啟動Docker
sudo chkconfig docker on
#設置開機啟動
systemctl start docker
修改Docker鏡像倉庫為國內鏡像
部分系統安裝后未生成daemon.json,請執行以下命令
[root@promote ~]# mkdir -p /etc/docker
[root@promote ~]# touch /etc/docker/daemon.json
[root@promote ~]# vim /etc/docker/daemon.json
配置文件內容格式如下:
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors":["公網倉庫地址"]
}
公網倉庫地址以下三個任選其一,也可以找其他開放的倉庫地址或自建倉庫
https://docker.mirrors.ustc.edu.cn
https://registry.docker-cn.com
http://hub-mirror.c.163.com
修改后刷新daemon.json,重啟docker服務使配置生效
systemctl daemon-reload
sudo systemctl restart docker.service
執行完后,可以查看下docker狀態及詳細信息
service docker status
docker info
如果不能正常啟動docker,大概率是daemon.json文件有問題
我檢查了好幾次該文件的內容,因為是復制的內容,所以符號是中文的,單詞也拼寫錯誤,需要注意的幾點如下:
1、注意符號是否是英文符號
2、單詞是否拼寫正確
3、json文件格式是否正確
以上步驟在三臺機器均執行完畢后,且Docker狀態正常,我們就開始安裝K8S集群了
5.安裝K8S
以下安裝步驟在3臺服務器上均執行一遍
安裝K8S源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
導入公鑰
wget https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
rpm --import yum-key.gpg
wget https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
rpm --import rpm-package-key.gpg
安裝
yum install -y kubelet-1.15.9-0 kubeadm-1.15.9-0 kubectl-1.15.9-0
啟動
systemctl enable kubelet && systemctl start kubelet
# 自啟動kubelet
systemctl status kubelet
#查看狀態
說明
kubectl 是命令行工具,所以不用啟動
kubeadm 是集群搭建工具,也不用啟動
kubelet 是節點管理工具,需要在所有節點啟動
注意 : 以上所有教程,都需要在集群所有機器上均操作一遍,包括安裝 kubectl kubeadm kubelet,啟動 kubelet
在虛擬機上部署k8s 1.9版本需要關閉操作系統交換分區
# swapoff -a
初始化K8S集群
在master節點上執行如下命令,其他節點不執行
注意命令的master ip及主機名,我的master主機名是k8s-master
kubeadm init --kubernetes-version=v1.15.9 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.66 --apiserver-cert-extra-sans=192.168.0.66,k8s-master --image-repository registry.aliyuncs.com/google_containers
參數含義:
--kubernetes-version:指定kubeadm版本;
--pod-network-cidr:指定pod所屬網絡
--image-repository 指定下載源
--service-cidr:指定service網段,負載均衡ip
--ignore-preflight-errors=Swap/all:忽略 swap/所有 報錯
--apiserver-advertise-address 指明用 Master 的哪個 interface 與 Cluster 的其他節點通信。如果 Master 有多個 interface,建議明確指定,如果不指定,kubeadm 會自動選擇有默認網關的 interface。
--pod-network-cidr 指定 Pod 網絡的范圍。Kubernetes 支持多種網絡方案,而且不同網絡方案對 --pod-network-cidr 有自己的要求,這里設置為 10.244.0.0/16 是因為我們將使用 flannel 網絡方案,必須設置成這個 CIDR。在后面的實踐中我們會切換到其他網絡方案,比如 Canal。
初始化過程簡要如下:
① kubeadm 執行初始化前的檢查。
② 生成 token 和證書。
③ 生成 KubeConfig 文件,kubelet 需要這個文件與 Master 通信。
④ 安裝 Master 組件,會從 goolge 的 Registry 下載組件的 Docker 鏡像,這一步可能會花一些時間,主要取決于網絡質量。
⑤ 安裝附加組件 kube-proxy 和 kube-dns。
⑥ Kubernetes Master 初始化成功。
⑦ 提示如何配置 kubectl,后面會實踐。
⑧ 提示如何安裝 Pod 網絡,后面會實踐。
⑨ 提示如何注冊其他節點到 Cluster,后面會實踐。
我們執行初始化時報了一個錯誤:
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
error execution phase preflight: [preflight] Some fatal errors occurred:
出現[WARNING IsDockerSystemdCheck],是由于docker的Cgroup Driver和kubelet的Cgroup Driver不一致導致的,此處選擇修改docker的和kubelet一致
docker info | grep Cgroup
#查看當前的cgroup
默認系統返回:Cgroup Driver: cgroupfs,我們要修改為systemd
vim /etc/docker/daemon.json
加入下面這一行
"exec-opts": ["native.cgroupdriver=systemd"]
我本機修改后的daemon.json如下,配置了多個國內的鏡像源
{
"registry-mirrors":["https://mirror.ccs.tencentyun.com","https://docker.mirrors.ustc.edu.cn", "https://dockerhub.azk8s.cn", "https://reg-mirror.qiniu.com","https://registry.docker-cn.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
刷新并重啟docker
systemctl daemon-reload
systemctl restart docker
然后我們重新執行初始化命令提示
[ERROR FileAvailable--etc-kubernetes-manifests-kube-apiserver.yaml]: /etc/kubernetes/manifests/kube-apiserver.yaml already exists
由于第一次沒初始化成功,但相關文件沒有清理,我們執行下面的命令,重置下環境,再初始化
kubeadm reset
重新執行初始化,約半分鐘,系統提示成功,系統生成的加入節點的命令和token自行保存下備用
以下信息自行保存起來備用
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
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.66:6443 --token 46lv86.ts6k9yc4p0dwsu1c \
--discovery-token-ca-cert-hash sha256:956c98d52f3a0981a5b44d70317b89696f03418eef4efe921a991b31a3644727
新版本的k8s初始化時會提示,因為官方要求鏡像從k8s.gcr.io官方獲取,但我們可以自己手動操作。
'''docker pull coredns/coredns
docker tag coredns/coredns:latest registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
docker rmi coredns/coredns:latest
kubeadm init --kubernetes-version=v1.21.1 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.0.16.8 --apiserver-cert-extra-sans=10.0.16.8,k8s-master --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
'''
6.配置K8S
將當前用戶配置為集群管理員(如果不配置,下次連接時會無法使用kubectl)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
部署flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
加入子節點
然后到其他兩個節點執行如下命令,添加節點到master.
前面保存的加入節點命令和token,這個環節使用,后續有新服務器加入同樣在新節點執行該命令即可
kubeadm join 192.168.0.66:6443 --token 46lv86.ts6k9yc4p0dwsu1c \
--discovery-token-ca-cert-hash sha256:956c98d52f3 ****
加入完畢后,我們用命令kubectl get nodes獲取所有節點
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 115m v1.15.9
k8s-node1 NotReady <none> 111m v1.15.9
k8s-node2 Ready <none> 111m v1.15.9
驗證安裝信息
檢查系統基礎模塊健康度
[root@k8s-master ~]# kubectl get componentstatus
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
檢查node狀態,如果有工作節點NotReady,等幾分鐘一般就會正常
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 115m v1.15.9
k8s-node1 NotReady <none> 111m v1.15.9
k8s-node2 Ready <none> 111m v1.15.9
檢查系統pod狀態
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-94d74667-l8lqt 1/1 Running 0 115m
coredns-94d74667-svgrk 1/1 Running 0 115m
etcd-k8s-master 1/1 Running 0 115m
kube-apiserver-k8s-master 1/1 Running 0 114m
kube-controller-manager-k8s-master 1/1 Running 0 115m
kube-flannel-ds-amd64-64zsm 1/1 Running 0 2m5s
kube-flannel-ds-amd64-csb8h 1/1 Running 0 2m5s
kube-flannel-ds-amd64-nfcsh 1/1 Running 0 2m5s
kube-proxy-b669n 1/1 Running 0 112m
kube-proxy-d84cb 1/1 Running 0 115m
kube-proxy-w7tv7 1/1 Running 0 111m
kube-scheduler-k8s-master 1/1 Running 0 115m
可能會遇到的錯誤:
FileContent--proc-sys-net-bridge-bridge-nf-call-iptables
解決命令:
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
測試K8S集群
這里為了快速地驗證一下我們的K8S集群是否可用,創建一個示例Pod:
[root@k8s-master ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
[root@k8s-master ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
[root@k8s-master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-554b9c67f9-n9rsv 1/1 Running 0 17s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 129m
service/nginx NodePort 10.98.172.7 <none> 80:30030/TCP 9s
如果想要看到Pod更多的信息,比如pod被部署在了哪個Node上,可以通過 kubectl get pods,svc -o wide來查看。
因為我們采用的是NodePort方式,該模式會直接將服務映射為主機的一個端口,用戶通過主機IP+端口可以訪問到該服務,其映射暴露出的端口號會在30000-32767范圍內隨機取一個,上面部署的nginx我們看到其端口是30030,那么我們用公網122.112.xx.xx:30030測試,如下圖所示,已經可以訪問到nginx默認頁。
PS:公有云服務默認有防火墻,需要自行到云管理界面開放這些端口的訪問,否則會認為k8s問題,排查起來很浪費時間。
7.安裝Dashboard
Dashboard是k8s的管理UI界面,其安裝過程最復雜的是證書的處理。
獲取并修改Dashboard安裝的Yaml文件
wget http://mirror.faasx.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
修改該文件配置
vim kubernetes-dashboard.yaml
按i,然后按方向鍵滾動到最后,節點是kind: service這部分
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
type: NodePort 插入這一行,注意對齊及空格
ports:
- port: 443
nodePort: 30000 插入一行,如果指定,則K8S會自動分配一個端口,注意手工填寫端口范圍不能超出k8s默認限制,
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
esc wq保存
以下開始處理證書
mkdir key && cd key
生成證書
openssl genrsa -out dashboard.key 2048
我這里寫的自己的node1節點,因為我是通過nodeport訪問的;如果通過apiserver訪問,可以寫成自己的master節點ip
openssl req -new -out dashboard.csr -key dashboard.key -subj '/CN=192.168.0.66'
openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt
創建新的證書secret
kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kube-system
執行安裝
kubectl apply -f kubernetes-dashboard.yaml
安裝可能需要幾分鐘,通過kubectl get pod -n kube-system查看狀態
創建用戶信息
1.創建一個叫admin-user的服務賬號:
[root@k8s01 ~]# vim dashboard-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
然后執行創建用戶
kubectl create -f dashboard-admin.yaml
2.直接綁定admin角色:
vim admin-user-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
執行綁定:
kubectl create -f admin-user-role-binding.yaml
3.查看綁定是否成功
kubectl get clusterrolebinding
驗證安裝
查看pod運行狀態
kubectl get pod -n kube-system | grep dashboard
kubernetes-dashboard-8594bd9565-rx5xg 1/1 Running 0 5m57s
查看dashborad service
kubectl get svc -n kube-system|grep dashboard
kubernetes-dashboard NodePort 10.110.157.149 <none> 443:30000/TCP 6m26s
查看pod運行日志,關注有沒有錯誤
kubernetes-dashboard-8594bd9565-zjwgv是pod的名稱,每個環境產生的名稱各不相同
kubectl logs kubernetes-dashboard-8594bd9565-zjwgv -n kube-system
獲取登錄Dashboard的Token
找到admin-user-token用戶
kubectl -n kube-system get secret
如上圖所示,我們環境的這個帳戶名是admin-user-token-mmc64
獲取token串
kubectl -n kube-system describe secret admin-user-token-mmc64
如上圖所示,該帳戶的登錄token已經產生,自行復制保存下來,后面登錄dashboard就使用這個token,我們輸入https://ip:30000測試下登錄,注意dahsboard是使用的https協議。
輸入前面我們獲取到的token進行登錄
至此,我們K8S集群的基本安裝完成。
8.后記
如果由于其它原因,或者想再搭建一次,可以執行kubeadm reset 操作,重置所有配置,恢復到剛安裝好 kubectl kubeadm kubelet 的狀態,再來一次。
配置k8s忽略使用swap
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
配置docker代理
[Service]
Environment="HTTPS_PROXY=http://www.ik8s.io:10080"
Environment="NO_PROXY=127.0.0.0/8"
systemctl daemon-reload
systemctl restart docker
如果要卸載dashboard
sudo kubectl delete deployment kubernetes-dashboard --namespace=kube-system
sudo kubectl delete service kubernetes-dashboard --namespace=kube-system
sudo kubectl delete role kubernetes-dashboard-minimal --namespace=kube-system
sudo kubectl delete rolebinding kubernetes-dashboard-minimal --namespace=kube-system
sudo kubectl delete sa kubernetes-dashboard --namespace=kube-system
sudo kubectl delete secret kubernetes-dashboard-certs --namespace=kube-system
sudo kubectl delete secret kubernetes-dashboard-csrf --namespace=kube-system
sudo kubectl delete secret kubernetes-dashboard-key-holder --namespace=kube-system