初識Kubernetes(K8s):從一個單機部署實現Java Web應用例子開始

本文是通過yum方式安裝Kubernetes,並部署tomcat+mysql實現Jave Web應用。此應用是JSP頁面通過JDBC訪問Mysql數據庫,只要程序正確連接到數據庫上,就會自動完成對應的Table的創建與初始化數據的準備工作。當我們通過瀏覽器訪問此應用時,就會顯示一個表格的頁面,數據則來自數據庫。
初識Kubernetes(K8s):從一個單機部署實現Java Web應用例子開始
此應用需要啓動兩個容器:Web App容器和MySQL容器,並且Web App容器需要訪問MySQL容器。現在我們就來看看通過Kubernetes是如何實現Java Web應用的。
在繼續閱讀之前,我們需要對Kubernetes有一個基本的認識,需要了解它的原理、核心架構、核心組件和對象、以及各組件之間的聯繫等基礎概念,可以參考我的上一篇博文《初識Kubernetes(K8s):理論基礎》,http://blog.51cto.com/andyxu/2308937
系統環境
操作系統:Centos 7.5 64位
IP地址:192.168.2.238

一、安裝部署Kubernetes(K8s)

1、關閉Centos自帶的防火牆服務
注:Kubernetes集羣之間會有大量的網絡通信,在一個安全的內部網絡環境中建議關閉防火牆服務

[root@andyxu-test ~]# systemctl disable firewalld
[root@andyxu-test ~]# systemctl stop firewalld

2、安裝etcd和Kubernetes軟件(會自動安裝Docker軟件)

[root@andyxu-test ~]# yum -y install etcd kubernetes

注:yum方式安裝的kubernetes的版本是1.5.2
初識Kubernetes(K8s):從一個單機部署實現Java Web應用例子開始
3、生成rhsm證書文件

[root@andyxu-test ~]# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm
[root@andyxu-test ~]# 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

注:創建容器時需要從redhat站點下載pod-infrastructure:latest鏡像,如果沒有此證書文件會報錯,Pod會一直顯示ContainerCreating狀態。
4、修改docker和kube-apiserver的配置文件
docker配置文件爲/etc/sysconfig/docker,將OPTIONS的內容修改爲

OPTIONS='--selinux-enabled=false --insecure-registry gcr.io'

kube-apiserver配置文件爲/etc/kubernetes/apiserver,修改KUBE_ADMISSION_CONTROL的內容,將--admission-control參數中的ServiceAccount刪除。

KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

5、按順序啓動所有服務

[root@andyxu-test ~]# systemctl start etcd
[root@andyxu-test ~]# systemctl start docker
[root@andyxu-test ~]# systemctl start kube-apiserver
[root@andyxu-test ~]# systemctl start kube-controller-manager
[root@andyxu-test ~]# systemctl start kube-scheduler
[root@andyxu-test ~]# systemctl start kubelet
[root@andyxu-test ~]# systemctl start kube-proxy

二、創建並配置mysql容器

1、創建mysql的Deployment定義文件
mysql-dep.yaml文件內容如下:

apiVersion: extensions/v1beta1                  #apiserver的版本
kind: Deployment                                      #副本控制器deployment,管理pod和RS
metadata:
  name: mysql                                            #deployment的名稱,全局唯一
spec:
  replicas: 1                                                #Pod副本期待數量
  selector:
    matchLabels:                                         #定義RS的標籤
      app: mysql                                          #符合目標的Pod擁有此標籤
  strategy:                                                  #定義升級的策略
    type: RollingUpdate                               #滾動升級,逐步替換的策略
  template:                                                #根據此模板創建Pod的副本(實例)
    metadata:
      labels:
        app: mysql                                        #Pod副本的標籤,對應RS的Selector
    spec:
      containers:                                          #Pod裏容器的定義部分
      - name: mysql                                     #容器的名稱
        image: mysql:5.7                               #容器對應的docker鏡像
        volumeMounts:                                #容器內掛載點的定義部分
        - name: time-zone                            #容器內掛載點名稱
          mountPath: /etc/localtime              #容器內掛載點路徑,可以是文件或目錄
        - name: mysql-data
          mountPath: /var/lib/mysql               #容器內mysql的數據目錄
        - name: mysql-logs
          mountPath: /var/log/mysql              #容器內mysql的日誌目錄
        ports:
        - containerPort: 3306                         #容器暴露的端口號
        env:                                                   #寫入到容器內的環境容量
        - name: MYSQL_ROOT_PASSWORD   #定義了一個mysql的root密碼的變量
          value: "123456"
      volumes:                                             #本地需要掛載到容器裏的數據卷定義部分
      - name: time-zone                              #數據卷名稱,需要與容器內掛載點名稱一致
        hostPath:
          path: /etc/localtime                        #掛載到容器裏的路徑,將localtime文件掛載到容器裏,可讓容器使用本地的時區
      - name: mysql-data
        hostPath:
          path: /data/mysql/data                   #本地存放mysql數據的目錄
      - name: mysql-logs
        hostPath:
          path: /data/mysql/logs                    #本地存入mysql日誌的目錄
  • apiVersion:定義使用apiserver的哪個版本,可通過kubectl api-versions命令查看apiserver有哪些版本;
  • kind:用來表明此資源對象的類型,比如這裏的值爲“Deployment”,表示這是一個deployment;
  • spec:RS相關屬性定義,spec.selector是RS的Pod標籤(Label)選擇器,即監控和管理擁有這些標籤的Pod實例,確保當前集羣上始終有且僅有replicas個Pod實例在運行,這裏設置replicas=1表示只能運行一個Mysql Pod實例。
  • spec.strategy:定義Pod的升級方案,Recreate表示刪除所有已存在的Pod,重新創建新的;RollingUpdate表示滾動升級,逐步替換的策略,滾動升級時支持更多的附加參數,例如設置最大不可用Pod數量,最小升級間隔時間等等。
  • spec.template:當集羣中運行的Pod數量小於replicas時,RS會根據spec.template中定義的Pod模板來生成一個新的Pod實例,spec.template.metadata.labels指定了該Pod的標籤,需要特別注意的是,這裏的labels必須匹配之前的spec.selector。
  • spec.template.spec.containers:容器的定義部分,包括容器的名稱、使用的docker鏡像、掛載數據卷、服務的端口號、變量等內容。
  • spec.template.spec.volumes:需要掛載到容器裏的本地數據卷的定義部分,數據卷的名稱要與容器內掛載點的名稱一致,path定義本地的數據卷路徑。

2、創建deployment、RS、Pod和容器
創建過程需要先下載鏡像,時間會比較久,可喝杯茶撩撩旁邊的妹子,哈哈,請耐心等待

[root@andyxu-test ~]# kubectl create -f mysql-dep.yaml
deployment "mysql" created

3、查看創建好的deployment運行情況

[root@andyxu-test ~]# kubectl get deployment 
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mysql     1         1         1            1           8s

注:都是1表示運行正常
4、查看ReplicaSet(RS)的運行情況

[root@andyxu-test ~]# kubectl get rs
NAME               DESIRED   CURRENT   READY     AGE
mysql-3238461207   1         1         1         6m

注:都是1表示運行正常
5、查看Pod的運行情況

[root@andyxu-test ~]# kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
mysql-3238461207-vvwt8   1/1       Running   0          56m

注:READY的值是1/1,並且STATUS的值是Running,表示運行正常
由於Pod的創建需要花費一些時間,在還沒有創建好容器時,STATUS的狀態會是ContainerCreating,表示正在創建容器,這時只需要等待。Pod創建好後,STATUS的狀態會是Running,這時可以通過docker ps命令查看容器運行的情況。
6、查看容器的運行情況

[root@andyxu-test ~]# docker ps
CONTAINER ID        IMAGE                                                        COMMAND                  CREATED             STATUS              PORTS               NAMES
5252cd76009a        mysql:5.7                                                    "docker-entrypoint..."   55 minutes ago      Up 55 minutes                           k8s_mysql.23f88726_mysql-3238461207-vvwt8_default_72d7bff7-d81c-11e8-a729-000c29dabb02_6b15dcfc
f026e79ddad9        registry.access.redhat.com/rhel7/pod-infrastructure:latest   "/usr/bin/pod"           55 minutes ago      Up 55 minutes                           k8s_POD.1d520ba5_mysql-3238461207-vvwt8_default_72d7bff7-d81c-11e8-a729-000c29dabb02_668a091e

7、查看Pod裏容器的時間,檢查時間是否與本地時間一致

[root@andyxu-test ~]# kubectl exec mysql-3238461207-vvwt8 date
Thu Oct 25 15:06:15 CST 2018

注:exec後面跟pod的名稱
8、創建mysql的service定義文件
mysql-svc.yaml文件內容如下:

apiVersion: v1
kind: Service     #表示Kubernetes Service
metadata:
  name: mysql   #Service的名稱
spec:
  ports:
    - port: 3306   #Service提供服務的端口號
  selector:
    app: mysql    #Service對應的Pod的標籤
  • metadata.name:Service的服務名稱
  • spec.ports:Service提供的服務端口號,對應容器的服務端口號
  • spec.selector:確定哪些Pod副本(實例)對應到此Service

9、創建Service

[root@andyxu-test ~]# kubectl create -f mysql-svc.yaml 
service "mysql" created

10、查看Service的運行情況

[root@andyxu-test ~]# kubectl get svc
NAME         CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes   10.254.0.1      <none>        443/TCP    4h
mysql        10.254.144.64   <none>        3306/TCP   57s

kubernetes會給Service分配一個Cluster IP,這是個虛擬IP地址,此後集羣中的其他新創建的Pod就可以通過此Cluster IP+端口號的方式來連接和訪問mysql服務了。

三、創建並配置tomcat容器

1、創建tomcat的Deployment定義文件
myweb-dep.yaml文件的內容如下:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myweb
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
      - name: myweb
        image: kubeguide/tomcat-app:v1
        volumeMounts:
        - name: time-zone
          mountPath: /etc/localtime
        - name: tomcat-logs
          mountPath: /usr/local/tomcat/logs
        ports:
        - containerPort: 8080
        env:
        - name: MYSQL_SERVICE_HOST
          value: '10.254.144.64'               #此處爲mysql服務的Cluster IP
        - name: MYSQL_SERVICE_PORT
          value: '3306'
      volumes:
      - name: time-zone
        hostPath:
          path: /etc/localtime
      - name: tomcat-logs
        hostPath:
          path: /data/tomcat/logs

2、創建tomcat的deployment、RS、Pod和容器

[root@andyxu-test ~]# kubectl create -f myweb-dep.yaml 
deployment "myweb" created

創建過程比較久,請耐心等待,pod的STATUS狀態爲Running時表示創建成功。
3、創建tomcat的Service定義文件
myweb-svc.yaml文件的內容如下:

apiVersion: v1
kind: Service
metadata:
  name: myweb
spec:
  type: NodePort
  ports:
    - port: 8080
      nodePort: 30001
  selector:
    app: myweb

此Service開啓了NodePort方式的外網訪問模式,端口爲30001,此端口會映射到tomcat容器的8080端口上。
4、創建Service

[root@andyxu-test ~]# kubectl create -f myweb-svc.yaml 
service "myweb" created

5、查看Service的運行情況

[root@andyxu-test ~]# kubectl get svc
NAME         CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   10.254.0.1      <none>        443/TCP          5h
mysql        10.254.144.64   <none>        3306/TCP         24m
myweb        10.254.246.56   <nodes>       8080:30001/TCP   39s

6、可使用curl命令測試tomcat服務是否能正常訪問

[root@andyxu-test ~]# curl http://192.168.2.238:30001

四、通過瀏覽器訪問網頁

1、如果30001端口不通的話,重新啓動、關閉firewalld防火牆

[root@andyxu-test ~]# systemctl start firewalld
[root@andyxu-test ~]# systemctl stop firewalld

注:因爲kubernetes會在iptables裏添加一些策略,需要再重新開啓關閉防火牆纔會關閉掉這些策略。
2、通過瀏覽器訪問http://192.168.2.238:30001/demo/
初識Kubernetes(K8s):從一個單機部署實現Java Web應用例子開始
點擊“Add...”,添加一條記錄並提交
初識Kubernetes(K8s):從一個單機部署實現Java Web應用例子開始
提交以後,數據就被寫入mysql數據庫裏了。
3、登陸mysql數據庫驗證

[root@andyxu-test ~]# docker exec -it 5252cd76009a /bin/bash
root@mysql-3238461207-vvwt8:/# mysql -uroot -p123456
mysql> use HPE_APP
mysql> select * from T_USERS;

初識Kubernetes(K8s):從一個單機部署實現Java Web應用例子開始
我們可以繼續研究下這個例子,比如:

  • 研究RS、Service等文件的格式。
  • 熟悉kubectl的子命令。
  • 手工停止某個Service對應的容器,觀察有什麼現象發生。
  • 修改Deployment文件,改變pod副本的數量,重新創建,觀察結果。

此例子來源於《Kubernetes權威指南(第2版)》,我做了一些修改,以及報錯的處理,並且使用了Deployment來創建。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章