本機搭建三節點k8s叢集
畢業設計題目是寫一個基於微服務的高可用應用系統。微服務的部署使用 docker + k8s,所以前提是要有一個 k8s 叢集。搭建過程中遇到了一些坑,把整個流程 記錄下來一是回顧搭建過程,二是希望能儘可能的幫助後來的 k8s beginners 少走些彎路。
本文的側重點在實際操作,k8s 元件基本概念相關的資訊請參考 ofollow,noindex" target="_blank">k8s 官方文件 或 Kubernetes 指南 – by feiskyer
如果對於本文有什麼建議、意見及疑問,歡迎提 issue,或直接發郵件交流(郵箱很容易能找到,不再提供)。
環境依賴
本文假設讀者會使用 Linux 命令列。
k8s 的映象源在牆外,所以需要讀者掌握科學上網的技能。這個部分不屬於本文的描述範圍,我使用的方案是 Shadowsocks + Privoxy,有需要可以跟我交流。
- Docker: 1.13.1 - kube*: 1.10 - flannel: 0.10.0 - virtualBox: 5.2.8 - OS: ubuntu-16.04.4-server-amd64.iso
virtualBox 的版本不太重要,Docker 和 kube* 的版本最好使用 k8s 推薦的版本,否則可能會有問題,推薦的 Docker 版本可以在版本的 release
文件中檢視。OS 的版本不同,後面的一些配置的方法會略有不同。
搭建目標
主機名 | 主機 IP | flannel.1 | OS | 叢集角色 |
---|---|---|---|---|
master | 192.168.99.200 | 10.244.0.0 | Ubuntu 16.04 | master |
node1 | 192.168.99.201 | 10.244.1.0 | Ubuntu 16.04 | node |
node2 | 192.168.99.202 | 10.244.2.0 | Ubuntu 16.04 | node |
flannel.1 是 每臺機器上的一個 VNI,通過 ifconfig
命令可以檢視該介面的資訊。
從任意一臺機器 ping 另外兩臺機器 flanel.1 的 IP 能通就算叢集搭建成功。
# from master $ ping 10.244.1.0 PING 10.244.1.0 (10.244.1.0) 56(84) bytes of data. 64 bytes from 10.244.1.0: icmp_seq=1 ttl=64 time=0.659 ms 64 bytes from 10.244.1.0: icmp_seq=2 ttl=64 time=0.478 ms 64 bytes from 10.244.1.0: icmp_seq=3 ttl=64 time=0.613 ms ^C --- 10.244.1.0 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.478/0.583/0.659/0.079 ms $ ping 10.244.2.0 PING 10.244.2.0 (10.244.2.0) 56(84) bytes of data. 64 bytes from 10.244.2.0: icmp_seq=1 ttl=64 time=0.459 ms 64 bytes from 10.244.2.0: icmp_seq=2 ttl=64 time=0.504 ms 64 bytes from 10.244.2.0: icmp_seq=3 ttl=64 time=0.553 ms ^C --- 10.244.2.0 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2058ms rtt min/avg/max/mdev = 0.459/0.505/0.553/0.042 ms
k8s 個元件之間的關係
其實這個沒必要多說, Kubernetes Components 或 Kubernetes 核心元件 – by feiskyer 講的已經非常好了,這裡提到只是強調一下這部分的重要性。
k8s Pod 網路模型簡介
- 圖片來源: 一次Flannel和Docker網路不通定位問題
為了省事,我直接引用了別人畫的模型圖。對於本次搭建的叢集模型簡單描述如下:
-
cni0
和flannel.1
都是 VNI,由 flannel 元件建立,叢集搭建完成後可以通過ifconfig
進行檢視。 - flannel 元件 在每臺機器上運行了一個
flanneld
,它是用來轉發流量,解決主機間通訊的問題。 -
enp0s8
是 virtualBox 的 Host-Only 介面卡。
配置流程
使用 virtualBox 建立三臺虛擬機器
virtualBox 安裝比較簡單,不再介紹,GUI 工具用起來也很方便,這部分只介紹我認為需要提示的部分。
- 記憶體推薦 2048M, CPU 推薦 2個
- 預設只有一個 NAT 介面卡,新增一個 Host-Only Adapter。NAT 介面卡是虛擬機器用來訪問網際網路的,Host-Only 介面卡是用來虛擬機器之間通訊的。
- 以 Normal Start 方式啟動虛擬機器安裝完系統以後,因為是 server 版映象,所以沒有圖形介面,直接使用使用者名稱密碼登入即可。
- 修改配置,
enp0s8
使用靜態 IP。配置請參考 SSH between Mac OS X host and Virtual Box guest 。注意配置時將其中的網路介面名改成你自己的 Host-Only Adapter 對應的介面。 - 一臺虛擬機器建立完成以後可以使用 clone 方法複製出兩臺節點出來,注意 clone 時為新機器的網絡卡重新初始化 MAC 地址。
- 三臺虛擬機器的靜態 IP 都配置好以後就可以使用 ssh 在本地主機的終端上操作三臺虛機了。虛機使用 Headless Start 模式啟動
安裝 Docker
- 三臺都裝
當前 Ubuntu 的 docker 版本剛好合適,所以可以直接安裝,但是有必要提前檢視一下 docker 版本,以免裝錯。
# apt search docker.io apt-get update apt-get install -y docker.io systemctl enable docker systemctl start docker
official Docker installation guides
- docker 配置代理。映象源在牆外,docker pull image 需要代理
mkdir -p /etc/systemd/system/docker.service.d cat <<EOF >/etc/systemd/system/docker.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=https://192.168.99.1:8118/" Environment="HTTPS_PROXY=https://192.168.99.1:8118/" Environment="NO_PROXY=localhost,127.0.0.1,localaddress,.localdomain.com" EOF systemctl daemon-reload systemctl restart docker
- 測試配置
docker info | grep Proxy# 有輸出說明配置成功 docker pull gcr.io/google-containers/busybox:1.27 # pull 成功代表工作正常。
安裝 kube* 元件
- 三臺都裝
apt-get update && apt-get install -y apt-transport-https curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update apt-get install -y kubelet kubeadm kubectl systemctl enable kubelet systemctl start kubelet
- Master 節點配置 cgroup driver
docker info | grep -i cgroup# 一般是 cgroupfs cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf# --cgroup-driver 對應值預設是 systemd #兩個值不一致的話使用以下命令修改 sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf #重啟 kubelet systemctl daemon-reload systemctl restart kubelet
- curl 訪問的是牆外的網站,無法訪問的話可以配置系統代理。
http://192.168.99.1:8118/
是我本地使用的 HTTP 代理,Privoxy 監聽 8118 埠,按照實際情況修改該地址。
# 全域性代理,不推薦 cat <<EOF >>/etc/environment http_proxy="http://192.168.99.1:8118/" https_proxy="http://192.168.99.1:8118/" no_proxy="master, node1, node2, 192.168.99.1" EOF source /etc/environment #當前 shell,推薦 export http_proxy="http://192.168.99.1:8118/" export https_proxy="http://192.168.99.1:8118/" export no_proxy="master, node1, node2, 192.168.99.1"
-
apt
使用代理
cat <<EOF >>/etc/apt/apt.conf Acquire::http::Proxy "http://192.168.99.1:8118/"; Acquire::https::Proxy "https://192.168.99.1:8118/"; EOF
搭建叢集
禁用交換區
k8s 文件明確要求的。
- 三臺都禁用
swapoff -a
初始化 master 節點
- 初始化過程會訪問牆外網站,如果 init 不能順利執行,請配置全域性代理
kubeadm init --apiserver-advertise-address=192.168.99.200 --pod-network-cidr=10.244.0.0/16
-
--apiserver-advertise-address=192.168.99.200
繫結 apiserver 到 master 節點的 Host-Only 介面卡的地址,預設是綁到 NAT 的地址上,這樣其他機器是永遠也訪問不到的。 -
--pod-network-cidr=10.244.0.0/16
指定 pod 網路地址空間,我們使用 flannel 元件必須使用這個空間。 - kubeadm 的完整參考手冊 kubeadm reference guide
- 推薦儲存最後輸出的 join 命令到檔案(以免忘記或找不到了),方便新增節點到叢集。如果忘了也找不到輸出了,網上有方法生成雜湊值,請自行查詢。
- 配置 kubectl 訪問叢集
# root user export KUBECONFIG=/etc/kubernetes/admin.conf # non-root user mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # 從本地主機操作,需要在本地安裝 kubectl 客戶端 mkdir -p ~/.kube scp <username>@192.168.99.200:/home/<username>/.kube/config ~/.kube/config # 從 master 複製配置檔案到本地
- 測試配置
kubectl cluster-info #有正常輸出即可
安裝 flannel 網路
- flannel 預設的監聽介面是 NAT 介面卡的介面,我們需要的是 Host-Only 介面卡的介面,所以需要修改 kube-flannel.yml 檔案
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml 給 /opt/bin/flanneld 命令新增 --iface="enp0s8" 引數 # enp0s8 是 Host-Only 介面卡對應的介面 kubectl apply -f kube-flannel.yml
- 測試配置
kubectl get pods --all-namespaces -o wide # 稍等一會,下載映象需要一定時間,最後應該顯示 flannel pods 是 Running 狀態, kube-dns 也是 Running 狀態
- 消除 master 隔離。預設 master 上不排程 pods,要允許另外的 pods 在 master 上執行請執行該命令
kubectl taint nodes --all node-role.kubernetes.io/master-
新增節點到叢集
- 在節點上執行
kubeadm init
最後輸出的 join 命令
kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>
最後
feiskyer 為該搭建過程寫了 自動化指令碼 ,有興趣可以嘗試一下。
參考
- k8s 官方文件
- Kubernetes 指南 – by feiskyer
- 一次Flannel和Docker網路不通定位問題
- coreos/flannel – README
- Installing kubeadm
- 360/docker-ubuntu-behind-proxy?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa" rel="nofollow,noindex" target="_blank">Docker Ubuntu Behind Proxy
- Using kubeadm to Create a Cluster