如何藉助OpenStack Kolla-K8S項目,
通過K8S對OpenStack進行容器化部署?
並最終部署一套All-In-One類型的OpenStack容器雲?
Openstack、Docker和Kubernetes是當前IaaS和PaaS領域最爲火熱的技術。隨着Docker容器技術的興起,容器編排調度引擎成爲當前十分搶眼的技術,這其中尤以Google開源的Kubernetes(K8S)以Production-ready和各種完善的功能而最爲人熟知。
在容器及其編排引擎的推動下,Openstack的主流部署模式也在發生變化,目前的Openstack與Docker容器和Kubernetes已經形成了一種你中有我,我中有你的局面,本文主要探討如何藉助Openstack的Kolla-kubernets項目,通過Kubernetes對Openstack進行容器化部署,並最終部署一套All-In-One類型的Openstack容器雲。
Kubernetes集羣部署主機及系統軟件需求
■ 主機配置需求
1、操作系統:CentOS7.3,最小安裝方式安裝
2、網卡:2個物理網卡
3、內存:8GB可用內存
4、硬盤:40GB
5、主機:VMware虛擬機
■ 軟件依賴
1、docker==1.12.5
2、helm >= 2.4.1
3、kubectl >=1.6.1
4、kubeadm >=1.6.1
5、kubelet >=1.6.1
6、kubernets-cni >=0.5.1
7、kolla-ansible==4.0.0
8、kolla-kubernets==0.6.0
9、kolla==4.0.0
注意:本文所有操作都在非root用戶權限下進行,如果以root用戶權限進行本文介紹的部署操作,則在helm安裝部分會出錯。
Kubernetes集羣部署
■ 系統環境配置
1、關閉系統防火牆
sudo systemctl stop firewalld
sudo systemctl disable firewalld
2、關閉SELinux
sudo setenforce 0
sudo sed -i ‘s/enforcing/disabled/g’ /etc/selinux/config
3、網絡配置
修改/etc/sysctl.conf,如下:
net.ipv4.ip_forward=1
net.ipv4.ip_nonlocal_bind=1
net.unix.max_dgram_qlen=128
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
■ Docker運行時環境安裝準備
1、準備Docker安裝源並安裝Docker
sudo tee /etc/yum.repos.d/docker.repo << ‘EOF’
[docker_repo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=0
EOF
//安裝相關的依賴包
sudo yum install python-devel libffi-devel gcc openssl-devel git python-pip epel-release
//安裝Docker
sudo yum install docker-engine-1.12.5 docker-engine-selinux-1.12.5
2、配置Docker引擎
Docker在CentOS中安裝後默認的StorageDrive爲lvm-loop模式的DeviceMapper,這裏推薦採用lvm-direct模式的DeviceMapper。假設系統中規劃由於存儲Docker鏡像的存儲塊爲/dev/sdb,則Docker的lvm-direct模式DeviceMapper存儲引擎配置如下:
sudo pvcreate /dev/sdb
sudo vgcreate docker /dev/sdb
sudo lvcreate –wipesignatures y -n thinpool docker -l 95%VG
sudo lvcreate –wipesignatures y -n thinpoolmeta docker -l 1%VG
sudo lvconvert -y –zero n -c 512K –thinpool docker/thinpool –poolmetadata docker/thinpoolmeta
sudo echo -e “activation {\nthin_pool_autoextend_threshold=80 \nthin_pool_autoextend_percent=20\n}” >/etc/lvm/profile/docker-thinpool.profile
sudo lvchange –metadataprofile docker-thinpooldocker/thinpool
sudo lvs -o+seg_monitor
配置Docker引擎的MountFlags標誌:
sudo mkdir /etc/systemd/system/docker.service.d
sudo echo -e “[Service]\n MountFlags=shared” >/etc/systemd/system/docker.service.d/kolla.conf
配置Docker使用lvm-direct存儲引擎、使用國內的DockerHub鏡像(這裏配置的爲阿里雲的DockerHub鏡像)以及使用本地的Docker鏡像Registry,如下:
sudo sed -i ‘s/\/usr\/bin\/dockerd/\/usr\/bin\/dockerd –registry-mirror=https:\/\/v4wev6hv.mirror.aliyuncs.com –insecure-registry 192.168.125.30:4000
–storage-driver=devicemapper –storage-opt=dm.thinpooldev=\/dev\/mapper\/docker-thinpool –storage-opt=dm.use_deferred_removal=true –storage-opt=dm.use_deferred_deletion=true/’ /usr/lib/systemd/system/docker.service
3、啓動Docker引擎
sudo /usr/bin/systemctl daemon-reload
sudo /usr/bin/systemctl start docker
sudo /usr/bin/systemctl enable docker
4、創建Docker本地Registry
sudo docker pull registry
sudo mkdir -p /data/registry
sudo docker run -d -v /data/registry:/var/lib/registry -p 4000:5000 –restart=always –name local_registry registry:latest
5、通過Kolla項目下載Openstack的Docker鏡像源
在正式通過Kubernetes編排部署之前,需要準備好Openstack各個服務項目的容器鏡像,本文采用基於Ocata版本的Kolla4.0編譯(編譯類型爲Source)得到的Openstack鏡像(http://tarballs.openstack.org/kolla/images/centos-source-registry-ocata.tar.gz),將centos-source-registry-ocata.tar.gz下載並上傳到系統後,將其直接解壓至Docker本地Registry的目錄/data/registry即可:
sudo tar zxvf centos-source-registry-ocata.tar.gz -C /data/registry/
可以通過curl來訪問驗證本地Registry是否正常:
curl http:// 192.168.125.30:4000/v2/_catalog
■ 安裝Kubernetes集羣軟件
官方推薦的Kubernetes集羣部署軟件安裝如下:
//準備kubernets安裝源,位於google的packages管理倉庫中
sudo tee /etc/yum.repos.d/kubernetes.repo<<EOF
[kubernetes]
name=Kubernetes
baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
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
//採用yum直接安裝
sudo yum install -y ebtables kubeadm kubectl kubelet kubernetes-cni
不翻牆的情況下,這種方式在國內幾乎是不可能安裝成功的,要訪問google的服務器簡直難於上青天!下面介紹一種相對簡單可行的Kubernetes安裝方式,首先確保你可以訪問www.google.com,然後訪問如下地址:
https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64/repodata/primary.xml
該地址顯示的是XML文本,在其中可以找到需要安裝的各個Kubernetes軟件包源地址.
利用該地址構造RPM包下載地址(添加),如下:
https://packages.cloud.google.com/yum/pool/23961d0f7dca1ed118b948195f2fb5dd7a07503d69d7d8ab4433219ea98d033e-kubeadm-1.6.1-0.x86_64.rpm
在瀏覽器中輸入上述地址,瀏覽器將會自動下載kubeadm-1.6.1-0.x86_64.rpm軟件包,重複上述過程,下載全部所需的RPM包。
注意:將上述軟件包全部上傳到CentOS系統中,可以製作一個本地YUM倉庫,然後通過YUM進行安裝,也可以通過rpm命令行進行安裝。記得通過yum形式安裝ebtables和socat!
■ Kubernetes鏡像獲取
在Kubernetes1.6中,Kubernetes集羣已經不再以系統進程形式部署在系統中了,而是以Docker容器形式部署。儘管kubeadm init命令會自動到Google容器倉庫中Pull所需的鏡像,但是這種方式絕對會讓你崩潰到想放棄Kubernetes!因此,最好在運行kubeadm init之前準備好全部所需的鏡像。
獲取上述鏡像的一個可行方法,就是通過github和dockerhub相互配合,在github上製作編譯鏡像的Dockerfile文件,然後自己賬戶下的dockerhub與github關聯起來,並通過dockerhub從github上提取Dockerfile文件並編譯Docker鏡像,由於Dockerhub服務器本身位於海外,因此編譯鏡像的速度還是可以接受的,待Dockerhub編譯完成後,便可通過docker pull命令將其抓取到本地,之後再通過docker tag命令對抓取到本地的鏡像進行重命名即可,具體制作過程可參考:https://mritd.me/2016/10/29/set-up-kubernetes-cluster-by-kubeadm/這篇博客。如果安裝的是Kubernetes1.6.1,則可直接到筆者的Dockerhub中下載上述Kubernetes鏡像(https://hub.docker.com/r/warrior/)。
可通過如下命令進行鏡像提取:
docker pull warrior/k8s-dns-dnsmasq-nanny-amd64:1.14.1
//鏡像重命名
docker tag warrior/k8s-dns-dnsmasq-nanny-amd64:1.14.1 gcr.io/ google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.1
注意:筆者在https://hub.docker.com/r/warrior/中的鏡像編譯Dockerfile文件位於Github項目https://github.com/ynwssjx/K8s-images中,有興趣的讀者可自行查看,其實Dockerfile文件內容非常簡單,僅有一個FROM語句,如:FROM gcr.io/google_containers/etcd-amd64:3.0.17
其實在製作Kubernetes鏡像時,有個問題就是如何知道kubeadm init命令所需的鏡像版本號。在/etc/kubernetes/manifests目錄中,有幾個yaml文件,其中的image字段定義了所需的版本號。
關於其他鏡像的版本號查詢,可參考前文提及的博客。
■ Kubernetes集羣初始化
在Kubernetes集羣中,POD和Service在創建時都會自動分配網絡IP地址,這裏假設POD網段爲10.1.0.0/16,Service網段爲10.3.3.0/24。設置Kubernetes集羣的DNS 服務器,如下:
sudo sed -i ‘s/10.96.0.10/10.3.3.10/g’ /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
Kubernetes使用服務網段的x.x.x.10IP地址來作爲DNS服務器地址,1到9被預留作爲Kubernetes後續基礎服務的擴展需求。啓動kubelet服務,如下:
sudo systemctl daemon-reload
sudo systemctl stop kubelet
sudo systemctl enable kubelet
sudo systemctl start kubelet
此時如果通過systemctl status kubelet來查看kubelet的啓動狀態,將會發現kubelet啓動失敗,這個時候先不用在意報錯,繼續後續操作。使用kubeadm命令行進行Kubernetes集羣初始化,如下:
sudo kubeadm init –pod-network-cidr=10.1.0.0/16 –service-cidr=10.3.3.0/24
–apiserver-advertise-address 192.168.125.30
注意:apiserver-advertise-address爲API Server的監聽地址
等待一段時間,看到successful即說明Kubernetes集羣初始化完成。加載kubeadm認證到系統環境變量中,如下:
mkdir -p $HOME/.kube
sudo -H cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo -H chown $(id -u):$(id -g) $HOME/.kube/config
此時,再開啓一個終端,su到部署Kubernetes集羣的用戶home目錄,輸入如下命令,即可觀察到Kubernetes集羣中PODs變化過程:
watch -d kubectl get pods –all-namespaces -o wide
在當前階段,Kolla-kubernets項目推介使用的Kubernetes集羣網絡驅動是Canal。部署Canal網絡驅動,如下:
sudo curl -L https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/rbac.yaml -o rbac.yaml
sudo kubectl apply -f rbac.yaml
sudo curl -L https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.6/canal.yaml -o canal.yaml\
sudo sed -i “[email protected]/[email protected]/16@” canal.yaml
sudo kubectl apply -f canal.yaml
Canal網絡驅動部署成功後,Kubernetes的kube-system命名空間中的全部pods應該是running狀態(在此之前,dns並非running狀態)。
因爲此處採用的是AIO部署模式,而默認情況下Kubernetes的Master節點是不會被kube-scheduler分配PODs到其上的運行的,爲了讓PODs在Master上也能夠運行,對Master進行untaint操作,如下:
kubectl taint nodes –all=true node-role.kubernetes.io/master:NoSchedule-
■ Kubernetes集羣驗證
待kube-system命名空間中全部pods處於running狀態之後,通過kubectl命令啓動一個busybox容器,在該容器中進行DNS查詢操作,如果操作成功則說明Kubernetes集羣部署成功,否則Kubernetes集羣是存在問題的,需要檢查上述各個步驟。驗證過程如下:
kubectl run -i -t $(uuidgen) –image=busybox –restart=Never
//進入容器後,執行nslookup操作
# nslookup kubernetes
Server: 10.3.3.10
Address 1: 10.3.3.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.3.3.1 kubernetes.default.svc.cluster.local