在openstack上有一個(gè)centos7.2版本的系統(tǒng),通過(guò)離線源更新后,升級(jí)到了7.5版本,在安裝k8s集群過(guò)程中,遇到了如下錯(cuò)誤
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出泰興免費(fèi)做網(wǎng)站回饋大家。
br_netfilter模塊未發(fā)現(xiàn)
安裝該模塊
重新執(zhí)行加載命令,結(jié)果還是原來(lái)的錯(cuò)誤
考慮到跟內(nèi)核相關(guān)配置,重啟了服務(wù)器,恢復(fù)正常
Kubernetes?是一個(gè)跨主機(jī)集群的開(kāi)源的容器調(diào)度平臺(tái),它可以自動(dòng)化應(yīng)用容器的部署、擴(kuò)展和操作?,?提供以容器為中心的基礎(chǔ)架構(gòu)。谷歌旗下開(kāi)源軟件,江湖人稱K8S。
上圖是一個(gè)通過(guò)K8S搭建的集群環(huán)境,采用三臺(tái)物理機(jī)搭建(三臺(tái)機(jī)器是K8S搭建集群的最低要求),我先簡(jiǎn)單介紹一下幾個(gè)重點(diǎn)名詞。
Centos?7?Master?*?1?(注意必須是雙核以上的CPU,否則無(wú)法初始化K8S)
Centos?7?Node?*?2
將文件上傳至該目錄
網(wǎng)盤地址:?
提取碼:aew7
執(zhí)行以下命令
如果不是groupfs,執(zhí)行下列語(yǔ)句
將最后一行注釋
運(yùn)行docker?images可以看到以下幾個(gè)關(guān)鍵應(yīng)用
kube-proxy?容器間通訊代理、kube-apiserver?API服務(wù)端、kube-scheduler?任務(wù)調(diào)度器、kube-controller-manager?集群控制器、coredns??K8S內(nèi)置的?DNS?服務(wù)器、etcd?用于保存集群所有的網(wǎng)絡(luò)配置和對(duì)象的狀態(tài)信息、pause前面已經(jīng)提到用于容器間的通訊以及數(shù)據(jù)卷的掛載。至此K8S安裝完成
圖中的第一個(gè)紅框的命令是需要管理員手動(dòng)復(fù)制,然后在master服務(wù)器上執(zhí)行的。
PS:?admin.conf是kubeadm集群管理的核心配置文件,包含整個(gè)集群各個(gè)節(jié)點(diǎn)的授權(quán)信息,以及本身的一些配置信息
第二個(gè)紅框中的命令是在node節(jié)點(diǎn)上執(zhí)行,里面包含了一個(gè)加入集群的token認(rèn)證信息以及ca證書的hashcode。通過(guò)該token可以加入K8S集群.
從圖中看到master節(jié)點(diǎn)處于NotReady狀態(tài),說(shuō)明節(jié)點(diǎn)中存在有問(wèn)題的Pod,查看存在問(wèn)題的pod,執(zhí)行以下命令查看所有Pod狀態(tài)
如果某個(gè)Pod的STATUS處于CrashLoopBackOff狀態(tài)表示創(chuàng)建失敗了,那么它會(huì)不斷自動(dòng)重新創(chuàng)建。上圖中兩個(gè)coredns處于pending狀態(tài),原因是我們沒(méi)有配置K8S網(wǎng)絡(luò)通訊協(xié)議fannel,從上傳的文件中加載并創(chuàng)建flannel網(wǎng)絡(luò)組件
3.在node節(jié)點(diǎn)上執(zhí)行剛剛由kubeadm生成的節(jié)點(diǎn)加入命令
如果出現(xiàn)反復(fù)無(wú)法加入節(jié)點(diǎn)的情況,運(yùn)行?kubeadm?reset?這條命令還原當(dāng)前節(jié)點(diǎn)上?kubeadm?init?或者?kubeadm?join?所做的所有更改。當(dāng)想加入新節(jié)點(diǎn)忘記token時(shí)可以使用?kubeadm?token?list?查看token,或者?kubeadm?token?create創(chuàng)建token,采用跳過(guò)ca安全認(rèn)證的方式加入節(jié)點(diǎn)。
4.三臺(tái)機(jī)器設(shè)置kubelet開(kāi)機(jī)自啟,至此通過(guò)kubeadm集群配置完成
在主節(jié)點(diǎn)上執(zhí)行以下命令,以下三個(gè)配件都是已經(jīng)配置好的,裝載即可。
圖中dashboard服務(wù)已經(jīng)被創(chuàng)建,配置文件中關(guān)閉了密碼驗(yàn)證,只需要瀏覽器打開(kāi)?無(wú)需登錄。
K8s集群搭建
1 centos版本信息查看
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
k8s集群機(jī)器關(guān)閉防火墻
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
2 安裝必要的包
k8s集群安裝以下安裝包
[root@k8s-node ~]# yum -y install net-tools wget vim ntpd
[root@k8s-node ~]# systemctl enable ntpd
[root@k8s-node ~]# systemctl start ntpd
3配置hosts
[root@k8s-node ~]# cat /etc/hosts
127.0.0.1?? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1???????? localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.248.141 k8s-master
192.168.248.142 k8s-node
4 部署master節(jié)點(diǎn)
4.1 Master節(jié)點(diǎn)安裝必要的安裝包
[root@k8s-master ~]# yum -y install etcd
4.2更改/etc/etcd/etcd.conf配置文件
[root@k8s-master etcd]# cat /etc/etcd/etcd.conf | grep -v "^#"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS=""
ETCD_NAME="master"
ETCD_ADVERTISE_CLIENT_URLS=
4.3設(shè)置開(kāi)機(jī)啟動(dòng)并驗(yàn)證狀態(tài)
[root@k8s-master ~]#systemctl enable etcd
[root@k8s-master ~]#systemctl start etcd
etcd檢查
[root@k8s_master ~]# etcdctl -C cluster-health
member 8e9e05c52164694d is healthy: got healthy result from cluster is healthy
[root@k8s_master ~]# etcdctl -C cluster-health
member 8e9e05c52164694d is healthy: got healthy result from cluster is healthy
5 安裝部署docker環(huán)境(略)
6 安裝kubernetes
[root@k8s_master ~]# yum install kubernetes
安裝過(guò)程中報(bào)錯(cuò)如下
Error: docker-ce conflicts with 2:docker-1.13.1-75.git8633870.el7.centos.x86_64
可以執(zhí)行如下命令解決
1、查看安裝過(guò)的docker:yum list installed | grep docker
2、卸載docker:yum remove -y?docker-ce.x86_64 0:18.03.0.ce-1.el7.centos
3、刪除容器鏡像:rm -rf /var/lib/docker
再次安裝kubernetes,安裝成功,而且會(huì)自動(dòng)安裝docker
6.1修改apiserver服務(wù)的配置文件
[root@k8s-master kubernetes]# cat /etc/kubernetes/apiserver | grep -v "^#"
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBE_ETCD_SERVERS="--etcd-servers="
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
KUBE_API_ARGS=""
6.2修改config配置文件:
[root@k8s-master kubernetes]# cat /etc/kubernetes/config | grep -v "^#"
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master="
設(shè)置開(kāi)機(jī)啟動(dòng),開(kāi)啟服務(wù)
[root@k8s-master ~]#systemctl enable kube-apiserver kube-controller-manager kube-scheduler docker
[root@k8s-master ~]#systemctl start kube-apiserver kube-controller-manager kube-scheduler docker
6.3查看服務(wù)端口:
[root@k8s-master ~]# netstat –tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address?????????? Foreign Address???????? State?????? PID/Program name???
tcp??????? 0????? 0 127.0.0.1:25??????????? 0.0.0.0:*?????????????? LISTEN????? 1273/master????????
tcp??????? 0????? 0 127.0.0.1:2380????????? 0.0.0.0:* ??????????????LISTEN????? 2126/etcd??????????
tcp??????? 0????? 0 0.0.0.0:111???????????? 0.0.0.0:*?????????????? LISTEN????? 571/rpcbind????????
tcp??????? 0????? 0 192.168.122.1:53??????? 0.0.0.0:*?????????????? LISTEN????? 1362/dnsmasq???????
tcp??? ????0????? 0 0.0.0.0:22????????????? 0.0.0.0:*?????????????? LISTEN????? 998/sshd???????????
tcp??????? 0????? 0 127.0.0.1:631?????????? 0.0.0.0:*?????????????? LISTEN????? 996/cupsd??????????
tcp6?????? 0????? 0 ::1:25????????????????? :::*???????????? ???????LISTEN????? 1273/master????????
tcp6?????? 0????? 0 :::4001???????????????? :::*??????????????????? LISTEN????? 2126/etcd??????????
tcp6?????? 0????? 0 :::6443???????????????? :::*??????????????????? LISTEN????? 3216/kube-apiserver
tcp6?????? 0? ????0 :::10251??????????????? :::*??????????????????? LISTEN????? 3222/kube-scheduler
tcp6?????? 0????? 0 :::2379???????????????? :::*??????????????????? LISTEN????? 2126/etcd??????????
tcp6?????? 0????? 0 :::10252??????????????? :::*??????????????????? LISTEN????? 3221/kube-controlle
tcp6?????? 0????? 0 :::111????????????????? :::*??????????????????? LISTEN????? 571/rpcbind????????
tcp6?????? 0????? 0 :::8080???????????????? :::*??????????????????? LISTEN????? 3216/kube-apiserver
tcp6?????? 0????? 0 :::22?????????????????? :::*??????????????????? LISTEN????? 998/sshd???????????
tcp6?????? 0????? 0 ::1:631???????????????? :::*??????????????????? LISTEN????? 996/cupsd?
7部署node節(jié)點(diǎn)
7.1安裝docker(略)安裝k8s(略)
7.2 Node節(jié)點(diǎn)主機(jī)做以下配置:
修改config配置文件
[root@k8s-node kubernetes]# cat /etc/kubernetes/config | grep -v "^#"
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master="
修改kubelet配置文件
[root@k8s-node kubernetes]# cat /etc/kubernetes/kubelet | grep -v "^#"
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_HOSTNAME="--hostname-override=192.168.248.142"
KUBELET_API_SERVER="--api-servers="
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS=""
設(shè)置開(kāi)機(jī)啟動(dòng)、開(kāi)啟服務(wù)
[root@k8s_client1 ~]# systemctl enable kubelet kube-proxy
[root@k8s_client1 ~]# systemctl start kubelet kube-proxy
查看端口:
[root@k8s_client1 ~]# netstat –ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address?????????? Foreign Address???????? State?????? PID/Program name???
tcp??????? 0????? 0 127.0.0.1:25??????????? 0.0.0.0:*???????????? ??LISTEN????? 1277/master????????
tcp??????? 0????? 0 127.0.0.1:10248???????? 0.0.0.0:*?????????????? LISTEN????? 3246/kubelet???????
tcp??????? 0????? 0 127.0.0.1:10249???????? 0.0.0.0:*?????????????? LISTEN????? 3133/kube-proxy????
tcp??????? 0????? 0 0.0.0.0:111???????????? 0.0.0.0:*?????????????? LISTEN????? 575/rpcbind????????
tcp??????? 0????? 0 192.168.122.1:53??????? 0.0.0.0:*?????????????? LISTEN????? 1332/dnsmasq???????
tcp??????? 0????? 0 0.0.0.0:22????????????? 0.0.0.0:*?????????????? LISTEN????? 1000/sshd??????????
tcp??????? 0????? 0 127.0.0.1:631?????????? 0.0.0.0:*?????????????? LISTEN????? 998/cupsd??????????
tcp6?????? 0????? 0 ::1:25????????????????? :::*??????????????????? LISTEN????? 1277/master????????
tcp6?????? 0????? 0 :::4194???????????????? :::*??????????????????? LISTEN????? 3246/kubelet???????
tcp6?????? 0????? 0 :::10250??????????????? :::*??????????????????? LISTEN????? 3246/kubelet???????
tcp6?????? 0????? 0 :::10255??????????????? :::*????? ??????????????LISTEN????? 3246/kubelet???????
tcp6?????? 0????? 0 :::111????????????????? :::*??????????????????? LISTEN????? 575/rpcbind????????
tcp6?????? 0????? 0 :::22?????????????????? :::*??????????????????? LISTEN????? 1000/sshd??????????
tcp6?? ????0????? 0 ::1:631???????????????? :::*??????????????????? LISTEN????? 998/cupsd??????
Master上查看集群中的節(jié)點(diǎn)及節(jié)點(diǎn)狀態(tài)
[root@k8s-master kubernetes]# kubectl get node
NAME????????????? STATUS??? AGE
192.168.248.142?? Ready???? 2m
[root@k8s-master kubernetes]# kubectl -s get node
NAME????????????? STATUS??? AGE
192.168.248.142?? Ready???? 2m
kubernetes集群搭建完成。
在k8s集群中創(chuàng)建pod,如果出現(xiàn)如下錯(cuò)誤
其中最主要的問(wèn)題是:details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)
解決方案:
查看/etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt (該鏈接就是上圖中的說(shuō)明) 是一個(gè)軟鏈接,但是鏈接過(guò)去后并沒(méi)有真實(shí)的/etc/rhsm,所以需要使用yum安裝:
yum install *rhsm*
安裝完成后,執(zhí)行一下docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
如果依然報(bào)錯(cuò),可參考下面的方案:
wget
rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee /etc/rhsm/ca/redhat-uep.pem
注釋:rpm2cpio命令用于將rpm軟件包轉(zhuǎn)換為cpio格式的文件
cpio命令主要是用來(lái)建立或者還原備份檔的工具程序,cpio命令可以復(fù)制文件到歸檔包中,或者從歸檔包中復(fù)文件。? ? ? ? ??
? ? ? ?-i ? 還原備份檔 ?
? ? ? ?-v? 詳細(xì)顯示指令的執(zhí)行過(guò)程
這兩個(gè)命令會(huì)生成/etc/rhsm/ca/redhat-uep.pem文件.
[root@k8s-node ~]# docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
在master節(jié)點(diǎn)新建pod并查看起狀態(tài)為正常
flannel是CoreOS提供用于解決Dokcer集群跨主機(jī)通訊的覆蓋網(wǎng)絡(luò)工具。它的主要思路是:預(yù)先留出一個(gè)網(wǎng)段,每個(gè)主機(jī)使用其中一部分,然后每個(gè)容器被分配不同的ip;讓所有的容器認(rèn)為大家在同一個(gè)直連的網(wǎng)絡(luò),底層通過(guò)UDP/VxLAN等進(jìn)行報(bào)文的封裝和轉(zhuǎn)發(fā)。
在 Kubernetes 的監(jiān)控方案中我們經(jīng)常會(huì)使用到一個(gè)Promethues Operator的項(xiàng)目,該項(xiàng)目可以讓我們更加方便的去使用 Prometheus,而不需要直接去使用最原始的一些資源對(duì)象,比如 Pod、Deployment,隨著 Prometheus Operator 項(xiàng)目的成功,CoreOS 公司開(kāi)源了一個(gè)比較厲害的工具:Operator Framework,該工具可以讓開(kāi)發(fā)人員更加容易的開(kāi)發(fā) Operator 應(yīng)用。
在本篇文章中我們會(huì)為大家介紹一個(gè)簡(jiǎn)單示例來(lái)演示如何使用 Operator Framework 框架來(lái)開(kāi)發(fā)一個(gè) Operator 應(yīng)用。
Kubernetes Operator
Operator 是由 CoreOS 開(kāi)發(fā)的,用來(lái)擴(kuò)展 Kubernetes API,特定的應(yīng)用程序控制器,它用來(lái)創(chuàng)建、配置和管理復(fù)雜的有狀態(tài)應(yīng)用,如數(shù)據(jù)庫(kù)、緩存和監(jiān)控系統(tǒng)。Operator 基于 Kubernetes 的資源和控制器概念之上構(gòu)建,但同時(shí)又包含了應(yīng)用程序特定的領(lǐng)域知識(shí)。創(chuàng)建Operator 的關(guān)鍵是CRD(自定義資源)的設(shè)計(jì)。
Kubernetes 1.7 版本以來(lái)就引入了自定義控制器的概念,該功能可以讓開(kāi)發(fā)人員擴(kuò)展添加新功能,更新現(xiàn)有的功能,并且可以自動(dòng)執(zhí)行一些管理任務(wù),這些自定義的控制器就像 Kubernetes 原生的組件一樣,Operator 直接使用 Kubernetes API進(jìn)行開(kāi)發(fā),也就是說(shuō)他們可以根據(jù)這些控制器內(nèi)部編寫的自定義規(guī)則來(lái)監(jiān)控集群、更改 Pods/Services、對(duì)正在運(yùn)行的應(yīng)用進(jìn)行擴(kuò)縮容。
Operator Framework
Operator Framework 同樣也是 CoreOS 開(kāi)源的一個(gè)用于快速開(kāi)發(fā) Operator 的工具包,該框架包含兩個(gè)主要的部分:
Workflow
Operator SDK 提供以下工作流來(lái)開(kāi)發(fā)一個(gè)新的 Operator:
Demo
我們平時(shí)在部署一個(gè)簡(jiǎn)單的 Webserver 到 Kubernetes 集群中的時(shí)候,都需要先編寫一個(gè) Deployment 的控制器,然后創(chuàng)建一個(gè) Service 對(duì)象,通過(guò) Pod 的 label 標(biāo)簽進(jìn)行關(guān)聯(lián),最后通過(guò) Ingress 或者 type=NodePort 類型的 Service 來(lái)暴露服務(wù),每次都需要這樣操作,是不是略顯麻煩,我們就可以創(chuàng)建一個(gè)自定義的資源對(duì)象,通過(guò)我們的 CRD 來(lái)描述我們要部署的應(yīng)用信息,比如鏡像、服務(wù)端口、環(huán)境變量等等,然后創(chuàng)建我們的自定義類型的資源對(duì)象的時(shí)候,通過(guò)控制器去創(chuàng)建對(duì)應(yīng)的 Deployment 和 Service,是不是就方便很多了,相當(dāng)于我們用一個(gè)資源清單去描述了 Deployment 和 Service 要做的兩件事情。
這里我們將創(chuàng)建一個(gè)名為 AppService 的 CRD 資源對(duì)象,然后定義如下的資源清單進(jìn)行應(yīng)用部署:
通過(guò)這里的自定義的 AppService 資源對(duì)象去創(chuàng)建副本數(shù)為2的 Pod,然后通過(guò) nodePort=30002 的端口去暴露服務(wù),接下來(lái)我們就來(lái)一步一步的實(shí)現(xiàn)我們這里的這個(gè)簡(jiǎn)單的 Operator 應(yīng)用。
開(kāi)發(fā)環(huán)境
環(huán)境需求
要開(kāi)發(fā) Operator 自然 Kubernetes 集群是少不了的,還需要 Golang 的環(huán)境,這里的安裝就不多說(shuō)了,然后還需要一個(gè) Go 語(yǔ)言的依賴管理工具包:dep,由于 Operator SDK 是使用的 dep 該工具包,所以需要我們提前安裝好,可以查看資料:,另外一個(gè)需要說(shuō)明的是,由于 dep 去安裝的時(shí)候需要去谷歌的網(wǎng)站拉取很多代碼,所以正常情況下的話是會(huì)失敗的,需要做什么工作大家應(yīng)該清楚吧?要科學(xué)。
安裝 operator-sdk
operator sdk 安裝方法非常多,我們可以直接在 github 上面下載需要使用的版本,然后放置到 PATH 環(huán)境下面即可,當(dāng)然也可以將源碼 clone 到本地手動(dòng)編譯安裝即可,如果你是 Mac,當(dāng)然還可以使用常用的 brew 工具進(jìn)行安裝:
我們這里使用的 sdk 版本是v0.7.0,其他安裝方法可以參考文檔:
演示
創(chuàng)建新項(xiàng)目
環(huán)境準(zhǔn)備好了,接下來(lái)就可以使用 operator-sdk 直接創(chuàng)建一個(gè)新的項(xiàng)目了,命令格式為: operator-sdk new
按照上面我們預(yù)先定義的 CRD 資源清單,我們這里可以這樣創(chuàng)建:
到這里一個(gè)全新的 Operator 項(xiàng)目就新建完成了。
項(xiàng)目結(jié)構(gòu)
使用operator-sdk new命令創(chuàng)建新的 Operator 項(xiàng)目后,項(xiàng)目目錄就包含了很多生成的文件夾和文件。
我們主要需要編寫的是 pkg 目錄下面的 api 定義以及對(duì)應(yīng)的 controller 實(shí)現(xiàn)。
添加 API
接下來(lái)為我們的自定義資源添加一個(gè)新的 API,按照上面我們預(yù)定義的資源清單文件,在 Operator 相關(guān)根目錄下面執(zhí)行如下命令:
添加完成后,我們可以看到類似于下面的這樣項(xiàng)目結(jié)構(gòu):
添加控制器
上面我們添加自定義的 API,接下來(lái)可以添加對(duì)應(yīng)的自定義 API 的具體實(shí)現(xiàn) Controller,同樣在項(xiàng)目根目錄下面執(zhí)行如下命令:
這樣整個(gè) Operator 項(xiàng)目的腳手架就已經(jīng)搭建完成了,接下來(lái)就是具體的實(shí)現(xiàn)了。
自定義 API
打開(kāi)源文件pkg/apis/app/v1/appservice_types.go,需要我們根據(jù)我們的需求去自定義結(jié)構(gòu)體 AppServiceSpec,我們最上面預(yù)定義的資源清單中就有 size、image、ports 這些屬性,所有我們需要用到的屬性都需要在這個(gè)結(jié)構(gòu)體中進(jìn)行定義:
代碼中會(huì)涉及到一些包名的導(dǎo)入,由于包名較多,所以我們會(huì)使用一些別名進(jìn)行區(qū)分,主要的包含下面幾個(gè):
這里的 resources、envs、ports 的定義都是直接引用的"k8s.io/api/core/v1"中定義的結(jié)構(gòu)體,而且需要注意的是我們這里使用的是ServicePort,而不是像傳統(tǒng)的 Pod 中定義的 ContanerPort,這是因?yàn)槲覀兊馁Y源清單中不僅要描述容器的 Port,還要描述 Service 的 Port。
然后一個(gè)比較重要的結(jié)構(gòu)體AppServiceStatus用來(lái)描述資源的狀態(tài),當(dāng)然我們可以根據(jù)需要去自定義狀態(tài)的描述,我這里就偷懶直接使用 Deployment 的狀態(tài)了:
定義完成后,在項(xiàng)目根目錄下面執(zhí)行如下命令:
改命令是用來(lái)根據(jù)我們自定義的 API 描述來(lái)自動(dòng)生成一些代碼,目錄pkg/apis/app/v1/下面以zz_generated開(kāi)頭的文件就是自動(dòng)生成的代碼,里面的內(nèi)容并不需要我們?nèi)ナ謩?dòng)編寫。
實(shí)現(xiàn)業(yè)務(wù)邏輯
NewDeploy 方法實(shí)現(xiàn)如下:
newService 對(duì)應(yīng)的方法實(shí)現(xiàn)如下:
這樣我們就實(shí)現(xiàn)了 AppService 這種資源對(duì)象的業(yè)務(wù)邏輯。
調(diào)試
如果我們本地有一個(gè)可以訪問(wèn)的 Kubernetes 集群,我們也可以直接進(jìn)行調(diào)試,在本地用戶~/.kube/config文件中配置集群訪問(wèn)信息,下面的信息表明可以訪問(wèn) Kubernetes 集群:
首先,在集群中安裝 CRD 對(duì)象:
上面的命令會(huì)在本地運(yùn)行 Operator 應(yīng)用,通過(guò)~/.kube/config去關(guān)聯(lián)集群信息,現(xiàn)在我們?nèi)ヌ砑右粋€(gè) AppService 類型的資源然后觀察本地 Operator 的變化情況,資源清單文件就是我們上面預(yù)定義的(deploy/crds/app_v1_appservice_cr.yaml)
直接創(chuàng)建這個(gè)資源對(duì)象:
我們可以看到我們的應(yīng)用創(chuàng)建成功了,這個(gè)時(shí)候查看 Operator 的調(diào)試窗口會(huì)有如下的信息出現(xiàn):
然后我們可以去查看集群中是否有符合我們預(yù)期的資源出現(xiàn):
看到了吧,我們定義了兩個(gè)副本(size=2),這里就出現(xiàn)了兩個(gè) Pod,還有一個(gè) NodePort=30002 的 Service 對(duì)象,我們可以通過(guò)該端口去訪問(wèn)下應(yīng)用:
如果應(yīng)用在安裝過(guò)程中出現(xiàn)了任何問(wèn)題,我們都可以通過(guò)本地的 Operator 調(diào)試窗口找到有用的信息,然后調(diào)試修改即可。
清理:
部署
自定義的資源對(duì)象現(xiàn)在測(cè)試通過(guò)了,但是如果我們將本地的operator-sdk up local命令終止掉,我們可以猜想到就沒(méi)辦法處理 AppService 資源對(duì)象的一些操作了,所以我們需要將我們的業(yè)務(wù)邏輯實(shí)現(xiàn)部署到集群中去。
執(zhí)行下面的命令構(gòu)建 Operator 應(yīng)用打包成 Docker 鏡像:
鏡像構(gòu)建成功后,推送到 docker hub:
鏡像推送成功后,使用上面的鏡像地址更新 Operator 的資源清單:
現(xiàn)在 Operator 的資源清單文件準(zhǔn)備好了,然后創(chuàng)建對(duì)應(yīng)的 RBAC 的對(duì)象:
到這里我們的 CRD 和 Operator 實(shí)現(xiàn)都已經(jīng)安裝成功了。
現(xiàn)在我們?cè)賮?lái)部署我們的 AppService 資源清單文件,現(xiàn)在的業(yè)務(wù)邏輯就會(huì)在上面的opdemo-64db96d575-9vtq6的 Pod 中去處理了。
然后同樣的可以通過(guò) 30002 這個(gè) NodePort 端口去訪問(wèn)應(yīng)用,到這里應(yīng)用就部署成功了。
清理
有資源清單文件,直接刪除即可:
開(kāi)發(fā)
Operator SDK 為我們創(chuàng)建了一個(gè)快速啟動(dòng)的代碼和相關(guān)配置,如果我們要開(kāi)始處理相關(guān)的邏輯,我們可以在項(xiàng)目中搜索TODO(user)這個(gè)注釋來(lái)實(shí)現(xiàn)我們自己的邏輯,比如在我的 VSCode 環(huán)境中,看上去是這樣的:
本篇文章示例代碼地址:
參考資料