一、k8s簡介
1.1、步入容器部署時代
傳統部署時代,程序直接部署在物理服務器之上,傳統的方式帶來了幾個問題
1、物理資源的浪費,CPU與內存資源等計算資源;
2、對於不可靠的應用程序,因爲程序的問題佔用全部系統資源,導致服務器之上的其他程序無法工作;
3、擴容縮容操作需要新加物理設備,還需要割接,造成大量的金錢和人力的浪費
4、集成,部署操作相對於雲時代過於複雜
容器部署時代:因爲容器所具有的諸多優勢,所以我們開始學習容器與容器編排工具
1.2、k8s的前世今生
容器時代,我們要使用容器部署集羣應用,就離不開容器編排工具;而在業界,k8s佔據了80%的市場份額,並且k8s的前身borg已經在谷歌穩定運行數十年,可以說,k8s是站在巨人的肩膀上。
1.3、k8s的功能
K8s可以自動裝箱,自我修復,水平擴展,服務發現和負載均衡,自動發佈和回滾
密鑰和配置管理,存儲編排,批處理執行。
二、k8s集羣
(架構圖引自馬哥文檔)
2.1、k8s集羣物理架構
Master :API server scheduler,controller-manager,etcd
一組master作爲集羣唯一入口,每一個node節點向集羣貢獻計算,存儲等資源;客戶端請求先發給master,master使用 scheduler(調度器)分析各node現有的可用資源,找一個最佳適配運行用戶所請求容器的節點,調度該node負責實現用戶請求;k8s可以自託管。
master上的API server是負責接收解析請求,scheduler負責分析各node上的計算和存儲資源,並根據用戶的請求進行兩級調度,第一級預選有幾個節點符合用戶請求,第二級在符合用戶請求的幾個節點中優選出最佳節點來響應用戶請求;
master上的組件controller-manager負責監控着每一個controller的健康狀態,如果controller宕機,controller-manager會向API server請求重新創建controller
在一個集羣中,master一般有三個,作成高可用,這樣不管是API server scheduler,controller-manager中的哪一個宕機,都能保證服務的不間斷穩定運行
每一個master的數據都是存在一個共享存儲etcd上的,etcd是一個鍵值存儲數據庫,比較像是zookeeper,etcd中存儲了整個集羣的狀態信息,所以etcd一般要作高可用,同時,etcd之間通信一般用https的方式,所以etcd內部通信需要一套CA和簽署證書,etcd與API Server通信需要一套CA和簽署證書,API Server與客戶端通信需要一套CA和簽署證書,API Server與kubelet、API Server與kube-proxy通信同樣需要一套CA和簽署證書。
Node:kubelet,docker(或其他容器引擎),kube-proxy,service,controller
kube-proxy用來管理service,當pod發生改變後,Label selector將消息報告給
API Server,API Server將這一事件通知給所有關聯的組件知悉, kube-proxy知悉後改變本地node的iptables規則(service);service的改變需要依靠kube-proxy改變本地的iptables規則。
每一個node上都有一個kubelet,kubelet負責保證node始終處於健康運行狀態,當node節點宕機時,controller會向API server發送請求,請求重新創建node;controller會在本地不斷循環,週期性探測容器的健康狀態,確保服務的不間斷運行。
2.2、k8s集羣邏輯架構
邏輯架構:pod,label,label selector,namespace
pod:k8s上的最小調度單元,一個pod可以包含多個容器,這些容器共享同一個底層的namespace,pod更像是一個虛擬機,而pod上的各容器就像是運行在虛擬機之上的各個服務;同一個pod還可共享存儲卷;一個pod中的容器一般以一個爲主,其他爲輔;
label: pod之上可以打上label,用label來識別pod,label是一個key=value形式的值
label selector:根據label來過濾符合條件的資源
namespace:namespace 可以將一個物理的 Cluster 邏輯上劃分成多個虛擬 Cluster,每個 Cluster 就是一個 namespace。不同 namespace 裏的資源是完全隔離的。
2.3、pod控制器
集羣通過pod控制器管理pod
ReplicaSet(副本控制集):pod的多副本管理
Deployment:只能管理無狀態應用,通過ReplicaSet管理pod的多副本
StatefulSet:管理有狀態應用,保證pod的每個副本在整個生命週期名稱不變
DaemonSet:在指定node上運行一個pod的場景
Job,ctonjob :用於任務結束後pod生命週期結束的場景
2.4、service
service爲pod提供一個穩定的訪問入口,做到了服務發現與服務註冊功能,同時還有控制器的功能
客戶端訪問service,service將客戶端的請求代理到後端的pod上,在後端pod改變時,service能動態發現新的pod,並將其加入。
service在1.10版本之前通過iptables deny規則實現,1.11版本後通過ipvs實現
2.5、附件
附件是爲集羣提供功能,附件的namespace在kube-system中
coreDNS:用於集羣內名稱解析
Web UI:集羣管理UI
Container Resource Monitoring:資源檢測
Cluster-level Logging:集羣級日誌記錄
2.6、集羣網絡類型
CNI:第三方網絡組件
flannel:網絡配置,三層隧道疊加網絡,簡單
calico:網絡配置,網絡策略,支持BGP協議的路由直通模型,複雜
canel:flannel與calico結合,flannel提供網絡配置,calico提供網絡策略
三、offline部署準備
3.1、版本
系統:CentOS 7
Docker-ce:18.09
K8s:1.15.1
3.2、準備工作
使用flannel網絡
節點網絡:192.168.118.0/24
pod網絡:10.244.0.0/16(flannel默認的)
service網絡:10.96.0.0/12
master:192.168.118.220
Node1:192.168.118.221
Node2:192.168.118.222
各節點主機名稱解析
配置DNS或/etc/hosts文件
192.168.118.220 k8s-master
192.168.118.221 k8s-node1
192.168.118.222 k8s-node2
各節點時間同步
uptime 192.168.118.220
關閉防火牆和selinux
systemctl stop firewalld.service
systemctl disable firewalld.service
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
reboot
各節點公鑰免密
ssh-copy-id 192.168.118.221
ssh-copy-id 192.168.118.222
四、公網機rpm包及鏡像準備
4.1、rpm包準備
下載地址: https://pkgs.org/download/
下載yum-utils以及其依賴包
4.2、配置k8s谷歌源下載k8s包
[root@k8s-master k8s]# cat > /etc/yum.repos.d/kubernetes.repo << EOF
> [kubernetes]
> name=Kubernetes
> baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
> enabled=1
> gpgcheck=1
> repo_gpgcheck=1
> gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
> EOF
4.3、安裝yum-utils使用yumdownloader下載k8s包
yumdownloader --resolve kubelet kubeadm kubectl kubernetes-cni conntrack-tools libnetfil
ter_cthelper libnetfilter_cttimeout libnetfilter_queue socat
4.4、下載docker-ce
當前k8s認證的docker-ce版本爲18.09
下載地址: https://pkgs.org/download/
4.5、安裝docker
yum localinstall containerd.io-1.2.5-3.1.el7.x86_64.rpm docker-ce-18.09.8-3.el7.x86_6
4.rpm docker-ce-cli-18.09.8-3.el7.x86_64.rpm container-selinux-2.99-1.el7_6.noarch.rpm
systemctl start docker
4.6、下載k8s鏡像
docker pull k8s.gcr.io/kube-apiserver:v1.15.1
docker pull k8s.gcr.io/kube-controller-manager:v1.15.1
docker pull k8s.gcr.io/kube-scheduler:v1.15.1
docker pull k8s.gcr.io/kube-proxy:v1.15.1
docker pull k8s.gcr.io/coredns:1.3.1
docker pull k8s.gcr.io/pause:3.1
docker pull k8s.gcr.io/etcd:3.3.10
4.7、保存鏡像包
docker save k8s.gcr.io/kube-apiserver:v1.15.1 > ~/k8s-image/kube-apiserver.tar
docker save k8s.gcr.io/kube-controller-manager:v1.15.1 > ~/k8s-image/kube-controller-manager.tar
docker save k8s.gcr.io/kube-scheduler:v1.15.1 > ~/k8s-image/kube-scheduler.tar
docker save k8s.gcr.io/kube-proxy:v1.15.1 > ~/k8s-image/kube-proxy.tar
docker save k8s.gcr.io/coredns:1.3.1 > ~/k8s-image/coredns.tar
docker save k8s.gcr.io/pause:3.1 > ~/k8s-image/pause.tar
docker save k8s.gcr.io/etcd:3.3.10 > ~/k8s-image/etcd.tar
4.8、準備fannel yaml文件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
4.9、集羣準備rpm包
將下載的依賴包,以及docker-ce,k8s的rpm包,k8s的鏡像包放在集羣所有節點上
scp -r docker [email protected]:/root
scp -r k8s [email protected]:/root
scp -r k8s-image [email protected]:/root
五、offline部署kubernetes
5.1、根據k8s的要求修改內核參數(所有節點)
[root@k8s-master ~]# cat > /etc/sysctl.d/kubernetes.conf << EOF
> net.ipv4.ip_forword = 1
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> EOF
5.2、重載內核配置(所有節點)
modprobe br_netfilter
sysctl --system
5.3、配置集羣初始化不檢查swap(所有節點)
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
5.4、部署
安裝4.5步驟
yum localinstall ./docker/*.rpm
systemctl start docker
安裝4.3步驟下載的rpm包(所有節點)
yum localinstall ./k8s/*.rpm
K8s命令補全(所有節點)
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
導入鏡像(所有節點)
find . -name "*.tar" -exec docker image load -i {} \;
kubelet開機啓動(所有節點)
systemctl enable kubelet
初始化master節點
kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap,NumCPU --apiserver-advertise-address=192.168.118.220 --kubernetes-version v1.15.1
提示需要將docker的cgroup driver改爲systemd
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
提示需要關閉swap以及cpu個數爲2,我這裏是虛擬機環境,所以跳過
重置初始化
kubeadm reset
繼續初始化
kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap,NumCPU --apiserver-advertise-address=192.168.118.220 --kubernetes-version v1.15.1
保存加入集羣信息
kubeadm join 192.168.118.220:6443 --token ioiy2e.w5c73hie10whtrx0 \
--discovery-token-ca-cert-hash sha256:0b309b3968902b155097c24912bdf7e695f9dba7523db6b7b854b40f0532f39a
普通用戶要使用k8s 需要執行下面操作
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
如果是root 可以直接執行
export KUBECONFIG=/etc/kubernetes/admin.conf
以上兩個二選一即可,我這裏用root
export KUBECONFIG=/etc/kubernetes/admin.conf
確認master各組件狀態
[root@k8s-master docker]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
將admin配置文件複製到所有node節點
scp /etc/kubernetes/admin.conf k8s-node1:/etc/kubernetes/
scp /etc/kubernetes/admin.conf k8s-node2:/etc/kubernetes/
配置環境變量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
立即生效
source ~/.bash_profile
5.5、master添加flannel網絡
kubectl apply -f kube-flannel.yml
5.6、查看node以及pod狀態
[root@k8s-master k8s]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 7m42s v1.15.1
[root@k8s-master k8s]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/kube-scheduler v1.15.1 b0b3c4c404da 6 days ago 81.1MB
k8s.gcr.io/kube-controller-manager v1.15.1 d75082f1d121 6 days ago 159MB
k8s.gcr.io/kube-apiserver v1.15.1 68c3eb07bfc3 6 days ago 207MB
k8s.gcr.io/kube-proxy v1.15.1 89a062da739d 6 days ago 82.4MB
quay.io/coreos/flannel v0.11.0-amd64 ff281650a721 5 months ago 52.6MB
k8s.gcr.io/coredns 1.3.1 eb516548c180 6 months ago 40.3MB
k8s.gcr.io/etcd 3.3.10 2c4adeb21b4f 7 months ago 258MB
k8s.gcr.io/pause 3.1 da86e6ba6ca1 19 months ago 742kB
5.7、node節點部署
將docker的cgroup driver改爲systemd
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
加入集羣(跳過swap)
kubeadm join 192.168.118.220:6443 --token ioiy2e.w5c73hie10whtrx0 --discovery-token-ca-cert-hash sha256:0b309b3968902b155097c24912bdf7e695f9dba7523db6b7b854b40f0532f39a --ignore-preflight-errors=Swap
配置環境變量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
立即生效
source ~/.bash_profile
5.8、查看node
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 29m v1.15.1
k8s-node1 Ready <none> 110s v1.15.1
k8s-node2 Ready <none> 107s v1.15.1
六、node擴容
使用kubeadm方式部署k8s集羣,要添加新的node加入集羣,而默認token 24小時就會過期,所以超出24小時就要重新創建token
創建token
[root@k8s-master manifests]# kubeadm token create
3llex6.jb3l5afms93aexj5
獲取ca證書sha256編碼hash值
[root@k8s-master manifests]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* /
/'
0b309b3968902b155097c24912bdf7e695f9dba7523db6b7b854b40f0532f39a
加入集羣新的命令
kubeadm join 192.168.118.220:6443 --token 3llex6.jb3l5afms93aexj5 --discovery-token-ca-cert-hash sha256:0b309b3968902b155097c24912bdf7e695f9dba7523db6b7b854b40f0532f39a --ignore-preflight-errors=Swap
七、kube-proxy使用ipvs負載均衡
7.1、k8s版本 在 v1.11版之後
7.2、下載並安裝ipset以及ipvsadm包(所有節點)
yumdownloader --resolve ipset ipvsadm
yum localinstall ./ipvs/ip*
scp -r /root/ipvs k8s-node1:/root/
scp -r /root/ipvs k8s-node2:/root/
Node1:yum localinstall ./ipvs/ip*
Node2:yum localinstall ./ipvs/ip*
7.3、加載內核模塊(所有節點)
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
7.4、檢查加載的模塊
lsmod | grep -e ipvs -e nf_conntrack_ipv4
7.5、更改configmap的mode配置爲ipvs
kubectl edit configmap kube-proxy -n kube-system
7.6、刪除所有kube-proxy的pod
kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
7.7、查看pod日誌
kubectl get pod -n kube-system | grep kube-proxy
kubectl logs kube-proxy-7fsrg -n kube-system
出現Using ipvs Proxier即可
參考文章
https://www.jianshu.com/p/89f126b241db ipvs與iptables對比
https://ahmermansoor.blogspot.com/2019/04/install-kubernetes-k8s-offline-on-centos-7.html offline方式部署k8s
https://www.kubernetes.org.cn/5551.html 使用kubeadm安裝Kubernetes 1.15
https://www.kubernetes.org.cn/doc-4 k8s中文文檔
馬哥文檔