咱們一塊兒回顧上一篇文章《Bees平臺的微服務架構(1)docker和docker-compose》,一共經過Dockerfile構建了三個docker鏡像:mysql數據庫,部署angular前端頁面的nginx,和springboot接口。而後使用docker-compose來作容器服務的編排,以保障不一樣容器之間能夠互訪。爲了提升開發的效率,咱們還寫了一個自動部署的腳本,實際是隻是經過docker-compose.yml啓動和關閉容器,在本地鏡像庫中生成或刪除鏡像。前端
不能否認,docker-compose服務編排的小巧靈活性讓人愛不釋手,那咱們今天爲何要遷移到k8s(kubernetes)上呢?由於k8s的編排能力更強,由於k8s能夠作跨主機的分佈式集羣,由於k8s搭載rancher將更有利於微服務架構的統一管理,等等。node
本文將不講解k8s和rancher的安裝和配置,相關的安裝文檔和配置文檔網上有不少。最近阿里雲產品春節大促銷,我一時沒忍住又買了一臺服務器,打完折扣仍是很貴。心疼歸心疼,不過這樣我就有兩臺服務器了,就順便搭建了k8s的集羣環境。mysql
分佈式集羣帶來的複雜度就增長了。你沒辦法直接使用本地的鏡像庫地址了,我不想搭建鏡像倉庫,好在阿里的docker鏡像倉庫是免費的,就將最終版的docker鏡像推送到阿里的容器倉庫裏面。當須要啓動容器時,容器的地址就寫阿里容器倉庫裏的地址,後文中會出現。nginx
分佈式的另外一個問題就是宿主機的掛載卷,若是對上一篇文章印象深入的話,應該記得mysql數據庫的數據文件和nginx代理的圖片文件等,都是掛載在宿主機上的。由於docker容器的特性,若是不使用掛載卷,在重啓容器以後容器內的數據都會丟失。分佈式環境中,不一樣主機之間是沒辦法互訪目錄的。我是經過在一臺機器上搭建了nfs服務器,將單臺機器上的目錄開放爲共享目錄,具體內容下文有介紹。git
不一樣服務之間免不了要相互訪問,例如:springboot要訪問數據庫和redis,angualr要調用springboot接口。並且考慮到k8s上常常要對某個服務作多節點的集羣,因此要在註冊中心開放給外界訪問的地址應該是集羣的地址。github
咱們在docker-compose上是怎麼作的呢?在docker-compose.yml 上定義多個服務service,每一個service對應於一個鏡像。容器啓動後,對應容器的服務名稱便可以做爲 hostname來使用。redis
k8s上也有相似的用法,它使用yaml文件,kind類型有不少,例如:Pod表示啓動的服務是一個pod;ReplicationController則會根據Pod模板生成一批pod做爲集羣;Service則至關於服務的註冊,可給與之對應的pod副本集羣提供訪問地址,等等還有不少。那這個問題Service就能解決,咱們給不一樣的服務都建立一個Service,這樣就也能同docker-compose同樣經過服務的名稱就能訪問與之對應服務的pod副本集羣。spring
由於業務須要,在以前的三個鏡像的基礎上又加了一個redis鏡像。那麼分佈式redis、分佈式mysql環境搭建就太麻煩了,若是之後有機會再單獨寫文章來介紹,此次我乾脆就只啓動單節點的mysql和redis。sql
NFS是Network File System的簡寫,即網絡文件系統,NFS是FreeBSD支持的文件系統中的一種。NFS基於RPC(Remote Procedure Call)遠程過程調用實現,其容許一個系統在網絡上與它人共享目錄和文件。經過使用NFS,用戶和程序就能夠像訪問本地文件同樣訪問遠端系統上的文件。NFS是一個很是穩定的,可移植的網絡文件系統。docker
選用nfs的另外一個緣由是,nfs服務在k8s上能夠直接做爲存儲卷使用,十分方便。
nfs是基於rpc的,安裝nfs就須要確保已安裝rpcbind,不過通常CentOS都默認已安裝了rpcbind
##查找是否已安裝nfs 和 rpcbind [mpaas@kerry1 k8s]$ rpm -qa | grep nfs [mpaas@kerry1 k8s]$ rpm -qa | grep rpcbind ##若是沒安裝,則經過有yum安裝 [mpaas@kerry1 k8s]$ yum -y install nfs-utils [mpaas@kerry1 k8s]$ yum -y install rpcbind
安裝完成後,必需要先啓動rpcbind服務,再啓動nfs服務
[mpaas@kerry1 k8s]$ systemctl start rpcbind [mpaas@kerry1 k8s]$ systemctl start nfs-server
設置開機啓動
[mpaas@kerry1 k8s]$ systemctl enable rpcbind [mpaas@kerry1 k8s]$ systemctl enable nfs-server
經過修改 /etc/exports 文件,設置nfs的共享目錄
/home/nfs/bees/mysql/data *(rw,no_root_squash,no_all_squash,sync)
如上,將 /home/nfs/bees/mysql/data做爲共享目錄
星號* 表明可在任意服務器上訪問該共享目錄,也能夠指定特色的ip和端口訪問
括號內是參數設置,常見的參數則有:
rw ro 該目錄分享的權限是可擦寫 (read-write) 或只讀 (read-only),但最終能不能讀寫,仍是與文件系統的 rwx 及身份有關。 sync async sync 表明數據會同步寫入到內存與硬盤中,async 則表明數據會先暫存於內存當中,而非直接寫入硬盤! no_root_squash root_squash 客戶端使用 NFS 文件系統的帳號若爲 root 時,系統該如何判斷這個帳號的身份?預設的狀況下,客戶端 root 的身份會由 root_squash 的設定壓縮成 nfsnobody, 如此對服務器的系統會較有保障。但若是你想要開放客戶端使用 root 身份來操做服務器的文件系統,那麼這裏就得要開 no_root_squash 才行! all_squash 不論登入 NFS 的使用者身份爲什麼, 他的身份都會被壓縮成爲匿名用戶,一般也就是 nobody(nfsnobody) 啦! anonuid anongid anon 意指 anonymous (匿名者) 前面關於 *_squash 提到的匿名用戶的 UID 設定值,一般爲 nobody(nfsnobody),可是你能夠自行設定這個 UID 的值!固然,這個 UID 必須要存在於你的 /etc/passwd 當中! anonuid 指的是 UID 而 anongid 則是羣組的 GID 囉。
編輯完 /etc/exports 文件後,執行下列命令生效
[mpaas@kerry1 k8s]$ exportfs -r
在服務器端,可執行下列命令查看目錄是否共享成功
[mpaas@kerry1 k8s]$ showmount -e localhost Export list for localhost: /home/nfs/bees/mysql/data *
也能夠在另一臺機器上安裝nfs後執行上述命令,只須要將localhost換成目標服務器的ip地址便可。
先啓動nginx來部署angualr,咱們須要建立一個RC,根據模板建立pods,暫時只建立一個pod,後續若是須要擴展再在rancher上管理。
建立bees_angular_rc.yaml,開放pod的80端口
apiVersion: v1 kind: ReplicationController metadata: name: bees-angular spec: replicas: 1 selector: app: bees-angular template: metadata: labels: app: bees-angular spec: containers: - name: bees-angular image: registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-nginx:v1.0 ports: - containerPort: 80
建立bees_angualr_svc.yaml,設置nodePort,將pod的80端口映射給宿主機的30000端口
apiVersion: v1 kind: Service metadata: name: bees-angular spec: type: NodePort ports: - port: 80 nodePort: 30000 selector: app: bees-angular
那麼執行下列命令便可建立rc和service,與之對應的pod也會運行起來
##啓動rc [mpaas@kerry1 k8s]$ kubectl create -f bees-angular-rc.yaml ##啓動service [mpaas@kerry1 k8s]$ kubectl create -f bees-angular-svc.yaml ##查看pod是否啓動成功 [mpaas@kerry1 k8s]$ kubectl get pods
建立bees_mysql_rc.yaml,開放pod的3306端口,並將nfs服務器上的共享目錄 /home/nfs/bees/mysql/data 掛載到容器中
apiVersion: v1 kind: ReplicationController metadata: name: bees-mysql spec: replicas: 1 selector: app: bees-mysql template: metadata: labels: app: bees-mysql spec: containers: - name: bees-mysql image: registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-mysql:v1.0 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: 數據庫密碼 volumeMounts: - name: mysql-data-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-data-persistent-storage nfs: path: /home/nfs/bees/mysql/data server: nfs服務器的ip
建立bees_mysql_svc.yaml
apiVersion: v1 kind: Service metadata: name: bees-mysql spec: type: NodePort ports: - port: 3306 nodePort: 30003 selector: app: bees-mysql
bees_springboot_rc.yaml
kind: ReplicationController metadata: name: bees-springboot spec: replicas: 1 selector: app: bees-springboot template: metadata: labels: app: bees-springboot spec: containers: - name: bees-springboot image: registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-springboot:v1.0 ports: - containerPort: 8010
bees_springboot_svc.yaml
apiVersion: v1 kind: Service metadata: name: bees-springboot spec: type: NodePort ports: - port: 8010 nodePort: 30004 selector: app: bees-springboot
都是一些基礎的代碼使用,這裏就不過多寫了。
#!/bin/bash echo "nginx版本:"$1 echo "springboot版本:"$2 v_springboot_jar=`find /bees/devops/upload/ -name "*.jar"` echo "找到jar:"$v_springboot_jar v_angular_zip=`find /bees/devops/upload/ -name "dist.zip"` echo "找到dist:"$v_angular_zip docker rmi -f $(docker images|grep "paperbee-nginx" | awk '{print $3}') docker rmi -f $(docker images|grep "paperbee-springboot" | awk '{print $3}') echo "刪除原鏡像" cd /bees/devops/dockerfiles/springboot-k8s/ rm -f *.jar cp $v_springboot_jar ./bees-0.0.1-SNAPSHOT.jar docker build -t paperbee-springboot . echo "生成springboot鏡像" cd /bees/devops/dockerfiles/angular-k8s/ rm -rf dist/ cp $v_angular_zip ./dist.zip unzip dist.zip rm -f dist.zip docker build -t paperbee-nginx . echo "生成angular鏡像" docker login --username=帳號 --password=密碼 registry.cn-hangzhou.aliyuncs.com echo "登陸docker容器倉庫" v_nginx_image=$(docker images|grep "paperbee-nginx" | awk '{print $3}') v_springboot_image=$(docker images|grep "paperbee-springboot" | awk '{print $3}') docker tag $v_nginx_image registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-nginx:$1 docker push registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-nginx:$1 echo "推送 bees-nginx:"$1 docker tag $v_springboot_image registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-springboot:$2 docker push registry.cn-hangzhou.aliyuncs.com/kerry2019/bees-springboot:$2 echo "推送 bees-springboot:"$2