華為鯤鵬云calico網絡組件適配aarch64架構攻關報告
問題現象
華為鯤鵬云環境,解放云盤測試部同事將k8s(1.9.2)集群移植到aarch64架構平臺上,使用calico作為集群的網絡組件時,集群pods之間無法通信,集群異常。
環境信息
類別
子項
版本
獲取地址(方法)
華為云
虛擬機
RC3(916)
NA
OS
CentOS
7.6.1810
Kernel
4.14.0-49.el7a.aarch6464
iso 自帶
軟件包
kubelet
1.9.2
https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-aarch64/
docker-ce
18.06.03
https://mirrors.aliyun.com/docker-ce/linux/centos/7/aarch64/stable/Packages/docker-ce-18.06.3.ce-3.el7.aarch64.rpm
Calico
v3.2
https://docs.projectcalico.org/v3.8/introduction/
定位分析
calico是什么?
calico利用Linux內核原生的路由和iptables防火墻功能。進出各個容器,虛擬機和主機的所有流量都會在路由到目標之前遍歷這些內核路由規則。它是一個純三層路由方案。參考http://ju.outofmemory.cn/entry/367749
calico與k8s的關系,在k8s集群中的角色?
callico可以作為k8s的網絡組件,為k8s集群間通信提供解決方案。由以下幾部分組成:
etcd: calico后端存儲,Calico使用etcd提供組件之間的數據通信,并作為可以保證一致性的數據存儲,以確保Calico始終可以構建出一個準確的網絡。
Flex:對應容器Calico-node即Calico agent,運行在每臺node上,為容器設置網絡信息,IP,路由規則,iptable規則等
BIRD:? BGP Client: 負責把Felix在各node上設置的路由信息廣播到Calico網絡(通過BGP協議)。
BGP Route Reflector: 大規模集群的分級路由分發。
calicoctl:calico命令行管理工具
依照官網https://docs.projectcalico.org/v3.2/getting-started/kubernetes/requirements
指導文檔給出的x86_64平臺部署方法(k8s 1.9版本適配calico3.1或者3.2版本),在華為鯤鵬云上進行部署,移植過程中遇到問題再進行解決。
部署環境:master節點和node節點 centos7.5 arm64
1.???? 部署基礎環境
(1)部署之前關閉selinux和防火墻
終端執行getenforce 如果返回Disabled說明selinux已經關閉;否則修改配置文件后,重啟后生效,具體方法如下
vi 編輯/etc/selinux/config,修改其中的SELINUX值為disabled,參考下圖
完成后保存退出,執行reboot,重啟機器,關閉selinux,必須重啟主機才能生效
(2)編輯/etc/hosts 寫上主機名和ip;集群所有節點之間都能相互解析,參考下圖寫法
(3)關閉swap分區
執行命令
swapoff -a
命令free -h 看到的swap總量一定是0
2.???? 執行以下命令關閉防火墻,并設置開機不自啟
systemctl stop ? firewalld.service
systemctl disable ? firewalld.service
3.???? 安裝docker
配置docker的阿里云repo源,請確保你的主機能夠訪問外網
vi編輯 /etc/yum.repos.d/docker.repo,該文件默認沒有,需要自行編寫保存
依次寫入
[Docker]
name=Docker repo
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/aarch64/stable/
gpgcheck=0
完成后執行以下命令
yum clean all
yum repolist
預期會顯示Docker源中的rpm包數量
執行以下命令安裝docker 18.06.03
yum install ? docker-ce-18.06*
預期安裝成功
添加谷歌代理進行加速
vi 編輯/usr/lib/systemd/system/docker.service,在[Service]標簽后添加以下內容
Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
Environment="HTTPS_PROXY=socks5://10.10.64.7:1080"
Environment="HTTP_PROXY=socks5://10.10.64.7:1080"
Environment="NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,::1,/var/run/docker.sock"
參考下圖
編輯完成后,保存退出執行以下命令使修改配置生效
systemctl ? daemon-reload
啟動docker
systemctl start ? docker
systemctl enable ? docker
執行systemctl status docker 查看當前docker服務狀態,處于運行中
可以通過docker info命令獲取docker詳細信息
4.???? 安裝kubelet
配置kubelet的阿里云repo源,請確保你的主機能夠訪問外網
vi編輯 /etc/yum.repos.d/kubelet.repo,該文件默認沒有,需要自行編寫保存
依次寫入
[kubelet]
name=Kubelet repo
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-aarch64/
gpgcheck=0
完成后,執行以下命令
yum clean all
yum repolist
預期會顯示kubelet源中的rpm包數量
執行以下命令完成kubelet 1.9.2版本的安裝,請分別安裝,否則會報錯
yum install ? kubelet-1.9.2 -y
yum install ? kubectl-1.9.2 kubeadm-1.9.2 -y
完成后執行以下命令設置開機自啟動
systemctl enable ? kubelet
5.???? 初始化k8s集群
執行
kubeadm init ? --kubernetes-version=v1.9.2? ? --pod-network-cidr=192.168.0.0/16
遇到下圖的報錯
解決方案:
vi編輯文件/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
修改Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=systemd"
為Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"
完成后執行systemctl daemon-reload 是修改生效
執行rm -f /etc/kubernetes/* 后再次執行kubeadm init --kubernetes-version=v1.9.2? --pod-network-cidr=192.168.0.0/16進行初始化,成功后,保存token
復制kubelet的配置文件
mkdir -p ? $HOME/.kube
cp -i ? /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl get pods --all-namespaces -o wide 查看各pod的狀態kube-dns處于Pending狀態,是由于還沒安裝網絡組建
6.???? 安裝網絡組件calico
calico 3.1版本,該版本是x86_64架構上與kubelet 1.9.2匹配的版本
執行
kubectl apply -f \
https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml
預期見下圖
去除master污點將其納入集群
kubectl taint ? nodes --all node-role.kubernetes.io/master-
到此,原則上如果移植成功,那么執行kubectl get pods --all-namespaces -o wide應該看到所有pod都是running狀態,
實際結果calico-node容器error,calicoetcd容器異常
執行kubectl get pods 查看 master狀態應該是Ready狀態。實際結果是Notready
7. 定位分析
對集群中異常狀態的三個容器進行分析
##Calico-etcd容器異常
執行journalctl -f 動態查看日志,存在下圖中的報錯
分析該段日志只是報告了啟動容器calico-etcd重啟失敗了,原因也沒有明確的說明。嘗試從容器自身入手,尋找原因。
docker ps -a |grep etcd 找到calico-etcd容器
可以看出正式日志中所報重啟失敗的容器,名稱為etcd_calico-etcd-nqvbh 確認后,發現該容器執行/usr/local/bin/etcd命令,那么很有可能是該二進制出問題了
執行dcoker ps -a |grep etcd 拿到id后,即刻復制出來二進制文件etcd,該id隨著容器的不斷重啟會改變。
ls 查看bin目錄下有哪些文件
考慮到架構的差異,使用file命看一下etcd和etcdctl的架構,是x86_64架構
解決該容器的二進制架構問題
docker image ls 找到該容器
將該容器運行起來,把容器中/usr/local/bin目錄復制到本地重命名為test,使用file命令查看二進制架構,為x86_64
執行以下操作
docker run ? --name test -itd quay.io/coreos/etcd:v3.1.10
docker cp ? test:/usr/local/bin/ ./test
file test/*
更換該容器
wget把calico的yaml文件下載到本地
到docker.hub上查找arm64架構的calico-etcd的鏡像
https://hub.docker.com/r/quayio/coreos-etcd
取版本接近的鏡像
修改calico.yaml文件v3.1.10標簽為v3.2.1-arm64
重新初始化集群,執行
kubeadm reset
iptables -F
kubeadm init ? --kubernetes-version=v1.9.2? ? --pod-network-cidr=192.168.0.0/16
cp -i ? /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl apply -f ? calico.yaml
再次查看各pods狀態,發現仍是異常的
同樣的辦法復制異常容器中的/usr/local/bin/etcd 發現架構沒問題,已經是aarch64架構的了
執行journalctl -f 查看相關日志和之前一樣也是重啟失敗
更換容器這條路子行不通
查看異常容器calico-cni的執行腳本,未發現端倪
查看calico-node的容器中文件屬性,發現同樣是x86_64架構
該容器在dockerhub上暫無arm64架構,二進制calico-felix容易編譯,其他二進制文件編譯起來,工量較大,且是否可用也未知。
根據在k8s 1.15.2上使用calico3.8版本,移植arm64平臺成功的經驗,采用calico 3.8來適配k8s 1.9.2
使用calico最新版本3.8
重新初始化集群,執行
kubeadm reset
iptables -F
kubeadm init ? --kubernetes-version=v1.9.2? ? --pod-network-cidr=192.168.0.0/16
cp -i ? /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl apply -f ? https://docs.projectcalico.org/v3.8/manifests/calico.yaml
查看節點狀態全部running
kubectl get pods ? --all-namespaces -o wide
將master納入集群,查看mater狀態已經Ready
kubectl taint ? nodes --all node-role.kubernetes.io/master-
kubectl get ? nodes -o wide
將node節點進入集群
kubeadm join ? --token df2842.dd1c942841b38f1f 10.10.64.71:6443 ? --discovery-token-ca-cert-hash ? sha256:69e5e0c33064b8a5017ddc0a20c5ed2eb1fb2d1ccb996f966205e1ad72f40c31
到matser節點查看集群狀態,所有容器全部running
kubectl get pods ? --all-namespaces -o wide
查看master與node是否Ready
kubectl get ? nodes
在master節點執行journactl -f動態觀察日志打印,無異常錯誤日志輸出
iptables -nL查看路由規則,發現已經部署上了。
整個集群狀態已經正常
實例化的nginx已經正常運行10小時
kubectl run ? --image=nginx nginx-app --port=8099
根因分析
calico 3.2 版本,官方提供的calico.yaml文件,所獲取的鏡像,僅適配x86_64架構,未提供aarch64架構的容器鏡像。
解決方案
k8s 1.9.2版本建議使用calico版本3.8作為網絡組件。
問題擴展
嘗試k8s最高版本1.15,適配calico3.8版本進行測試,發現依然存在問題?pod2daemon-flexvol容器中的flexvol架構為x86_64,需要手動編譯出arm64架構的二進制文件去替換鏡像中的x86架構的flexvol。或者重新制作pod2daemon-flexvol容器鏡像。
二進制文件flexvol編譯
1.?????? 從github下載源碼
執行以下命令
git clone https://github.com/projectcalico/pod2daemon.git
2.?????? 進入git clone下來的目錄中pod2daemon
cd pod2daemon-3.8.1
修改Makefile文件
vi編輯Makefile
修改GO_BUILD_VER?=master-arm64
DOCKER_RUN后添加golang的代理
-e GOPROXY=https://goproxy.io \
3.?????? 保存退出Makefile后,執行make build構建二進制
預期在bin目錄下會構建出來flexvol-arm64的二進制文件,file 查看為arm64架構
Docker鏡像制作
從github下載源碼
執行以下命令
git clone https://github.com/projectcalico/pod2daemon.git
2.?????? 進入git clone下來的目錄中pod2daemon
cd pod2daemon-3.8.1
修改Makefile文件
vi編輯Makefile
修改GO_BUILD_VER?=master-arm64
DOCKER_RUN后添加golang的代理
-e GOPROXY=https://goproxy.io \
3.?????? 保存退出Makefile后,執行make image構建docker鏡像
預期構建成功,并保存本地,使用docker images 可以查看到
附件: 華為鯤鵬云calico網絡組件適配aarch64架構攻關報告.pdf 1.35M 下載次數:7次
容器 鯤鵬 Kubernetes 網絡
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。