最近開始閱讀《Kubernetes權威指南》這本書,書上有一個單節點k8s的小例子,因此就跟着書上的步驟以及這篇博客http://lihaoquan.me/2017/2/25/create-kubernetes-single-node-mode.html操做了一遍,如今把這個過程記錄下來,對k8s有一個較直觀的認識。
html
這是一個簡單的Java Web應用,結構簡單,是一個運行在Tomcat裏的Web App,JSP頁面經過JDBC直接訪問MySQL數據庫並展現數據。node
此應用須要啓動兩個容器:Web App容器和MySQL容器,而且Web App容器須要訪問MySQL容器。mysql
1.環境準備linux
此次實驗使用的環境是Centos7, IP地址爲10.0.0.73web
(1)yum源sql
剛開始我虛擬機的yum源是清華大學的,後面換了個阿里雲的yum源。我是爲了和博客保持一致,不換源應該也是能夠的(有待驗證)。docker
換源操做:數據庫
備份json
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
下載新的CentOS-Base.repo到 /etc/yum.repos.dsegmentfault
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
最後運行
yum makecache
(2)關閉防火牆
centos7自帶firewall的防火牆業務,而k8s的master與工做node之間會有大量的網絡通訊,安全的作法實在防火牆上配置各類須要相互通訊的端口號,好比後面用到的3306,30001等端口。本文僅作一個學習過程,因此直接關閉防火牆服務。
systemctl disable firewalld.service
systemctl stop firewalld.service
2.安裝和配置k8s
(1)安裝etcd和k8s軟件(安裝過程當中會自動安裝Docker軟件)
yum install -y etcd kubernetes
(2)配置修改
安裝完成後,須要修改相關配置
nano /etc/sysconfig/docker
將其中的OPTIONS的內容設置爲:OPTIONS='--selinux-enabled=false --insecure-registry gcr.io'
nano /etc/kubernetes/apiserver
在KUBE_ADMISSION_CONTROL選項中去掉ServiceAccount選項。不然在後面的pod建立中,會報錯。
(3)切換docker hub鏡像源
爲了穩定pull鏡像,使用Daocloud的鏡像服務
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://dbe35452.m.daocloud.io
(4)按順序啓動全部服務
systemctl start etcd
systemctl start docker
在啓動docker是遇到了以下錯誤:
運行命令查看docker服務
systemctl status docker.service
試了不少方法都不行後,在這個連接下面找到了答案https://segmentfault.com/q/1010000002392472。原來因爲上面切換了docker hub源致使的問題。將/etc/docker/daemon.json中 {"registry-mirrors": ["http://34df6785.m.daocloud.io"],} 後面的逗號去掉就能夠。
nano /etc/docker/daemon.json
繼續啓動剩下的服務
systemctl start kube-apiserver.service systemctl start kube-controller-manager.service systemctl start kube-scheduler.service systemctl start kubelet.service systemctl start kube-proxy.service
到目前爲止,一個單機版的k8s環境就跑起來了。
3.啓動MySQL容器服務
(1)先拉去mysql的服務鏡像:
docker pull mysql
(2)啓動MySQL服務
首先爲MySQL服務建立一個RC定義文件:mysql-rc.yaml。RC(Replication Controller)定義文件中有3個關鍵信息:
apiVersion: v1 kind: ReplicationController #副本控制器RC metadata: name: mysql #RC的名稱,全局惟一 spec: replicas: 1 #Pod副本的期待數量 selector: app: mysql #符合目標的Pod擁有此標籤 template: #根據此模板建立Pod的副本(實例) metadata: labels: app: mysql #Pod副本擁有的標籤,對應RC的Selector spec: containers: #Pod內容器的定義部分 - name: mysql #容器的名稱 image: hub.c.163.com/library/mysql #容器對應的Docker image ports: - containerPort: 3306 #容器應用監聽的端口號 env: #注入容器內的環境變量 - name: MYSQL_ROOT_PASSWORD value: "123456"
建立好mysql-rc.yaml後,在master節點使用kubectl命令將它發佈到k8s集羣中。
kubectl create -f mysql-rc.yaml
接下來使用kubectl命令查看剛剛建立的RC:
使用下面命令查看Pod的建立狀況:
可見Pod的狀態處於ContainerCreating,須要等到狀態爲Runing纔算成功。我在這裏碰到了一個bug,Pod一直處在ContainerCreating狀態。博客http://blog.csdn.net/xts_huangxin/article/details/51130223提供了定位這種問題的方法。經過「kubectl describe pod PodName」指令查看pod發生的事件,從輸出中查看錯誤信息。我這邊的輸出是:
而後根據博客http://blog.csdn.net/learner198461/article/details/78036854提供的解決辦法,安裝rhsm(我也不知道這個是幹什麼的,就是紅帽的一個軟件)
yum install *rhsm*
而後再運行
kubectl delete -f mysql-rc.yaml
kubectl create -f mysql-rc.yaml
kubectl get pods
發現Pod已經跑起來了。
(3)建立關聯Service
最後,咱們建立一個與之關聯的Kubernetes Service-MySQL的定義文件:mysql-svc.yaml
apiVersion: v1 kind: Service #代表是K8s Service metadata: name: mysql #Service的全局惟一名稱 spec: ports: - port: 3306 #Service提供服務的端口號 selector: #Service對應的Pod擁有這裏定義的標籤 app: mysql
spec.selector肯定了哪些Pod副本(實例)對應到本服務。相似地,咱們經過kubectl create命令建立Service對象。
運行kubectl命令,建立service:
kubectl create -f mysql-svc.yaml
再運行以下狀態,查看剛剛建立的service:
kubectl get svc
注意到MySQL服務被分配到了一個值爲10.254.152.247的Cluster IP地址,這是一個虛地址,隨後,k8s集羣中其餘新建立的Pod就能夠經過Service的Cluster IP+端口號3306來鏈接和訪問它了。如今咱們只需知道,根據Service的惟一名字,容器能夠從環境變量中獲取到Service對應的Cluster IP地址和端口,從而發起TCP/IP鏈接請求了。
到這裏,MySQL容器服務就啓動了。小結下建立過程,首先,拉取服務鏡像,而後建立RC定義文件,再發布到k8s中,能夠看到pod被建立。最後建立一個與之關聯的k8s Service,也是經過.yaml文件和kubectl create命令建立。固然,這其中還牽扯到不少概念,好比說Pod和Service之間的聯繫等等,這個要另起篇幅。
4.啓動Web容器服務
有了上面啓動MySQL容器服務的經驗,咱們來啓動Web容器服務,過程是同樣的。
(1)先拉取一個測試鏡像到本地
docker pull kubeguide/tomcat-app:v1
(2)建立對應的RC文件myweb-rc.yaml,內容以下:
apiVersion: v1 kind: ReplicationController metadata: name: myweb spec: replicas: 5 #Pod副本期待數量爲5 selector: app: myweb template: metadata: labels: app: myweb spec: containers: - name: myweb image: docker.io/kubeguide/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: "mysql" - name: MYSQL_SERVICE_PORT value: "3306"
而後經過kubectl create命令完成RC的建立和驗證工做:
kubectl create -f myweb-rc.yaml
kubectl get rc
kubectl get pods
從輸出看到,在RC中聲明瞭5個Pod期待的數量,如今都已經創建並運行起來了,能夠看出k8s在自動升級,擴容等方面帶來的優點了。
(3)建立對應的Service
最後,建立對應的Service,如下是完整的yaml定義文件(myweb-svc.yaml):
apiVersion: v1 kind: Service metadata: name: myweb spec: type: NodePort ports: - port: 8080 nodePort: 30001 selector: app: myweb
type=NodePort和nodePort=30001的兩個屬性,代表此Service開啓了NodePort方式的外網訪問模式。在k8s集羣以外,好比在本機的瀏覽器裏,能夠經過30001這個端口訪問myweb(對應到8080的虛端口上)。因此前面要關閉防火牆。
運行kubectl create命令進行建立:
kubectl create -f myweb-svc.yaml
最後,使用kubectl查看前面建立的Service
kubectl get services
5.驗證與總結
經過上面的幾個步驟,咱們能夠成功實現了一個簡單的k8s單機版例子。有兩種方法驗證咱們的結果。
首先,能夠在本機瀏覽器中輸入http://10.0.0.73:30001/demo/來測試咱們發的web應用。然而,很不幸,報錯了:
報了一個JDBC鏈接的錯誤。若是網頁能打開的話,是有一個表格而且能夠進行操做的。按書上的說法,看不到網頁有幾個緣由:好比防火牆的問題,沒法訪問30001端口,或者是由於經過代理上網的,瀏覽器錯把這個虛擬機的IP地址當成遠程地址了。因此有了第二種驗證方法,直接運行以下命令:
curl http://10.0.0.73:30001
輸出爲:
我網上看其餘教程也大都是採起這種方式驗證的,因此就這樣吧,雖然成就感小了一點,但畢竟仍是跑起來了。重要的是對k8s有一個瞭解,學習使用它。
本文參考:
《Kubernetes權威指南》
http://blog.csdn.net/xts_huangxin/article/details/51130223