單節點k8s的一個小例子


最近開始閱讀《Kubernetes權威指南》這本書,書上有一個單節點k8s的小例子,所以就跟着書上的步驟以及這篇博客http://lihaoquan.me/2017/2/25/create-kubernetes-single-node-mode.html操作了一遍,現在把這個過程記錄下來,對k8s有一個較直觀的認識。

這是一個簡單的Java Web應用,結構簡單,是一個運行在Tomcat里的Web App,JSP頁面通過JDBC直接訪問MySQL數據庫並展示數據。

此應用需要啟動兩個容器:Web App容器和MySQL容器,並且Web App容器需要訪問MySQL容器。

1.環境准備

這次實驗使用的環境是Centos7, IP地址為10.0.0.73

(1)yum源

剛開始我虛擬機的yum源是清華大學的,后面換了個阿里雲的yum源。我是為了和博客保持一致,不換源應該也是可以的(有待驗證)。

換源操作:

備份

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

下載新的CentOS-Base.repo到 /etc/yum.repos.d

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個關鍵信息:

  • 目標Pod的定義。
  • 目標Pod需要運行的副本數量(Replicas)
  • 要監控的目標Pod的標簽(Label),Label是Service和Pod之間的紐帶
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(一):單節點k8s安裝

《Kubernetes權威指南》

http://blog.csdn.net/xts_huangxin/article/details/51130223

https://segmentfault.com/q/1010000002392472

http://blog.csdn.net/learner198461/article/details/78036854

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM