1. 程式人生 > >Kubernetes持久卷實戰兩部曲之一:極速體驗

Kubernetes持久卷實戰兩部曲之一:極速體驗

章節列表

整個《Kubernetes持久卷實戰》由以下兩篇文章組成:
1. 極速體驗靜態持久化儲存,也就是本章的內容;
2. 瞭解k8s的pod、service、pv、pvc的細節;

本章內容

本章目標是用最少的步驟和時間體驗PV,所以先不展開每個配置和開發的細節,主要完成以下操作:
1. 準備知識列表;
2. 實戰網路環境介紹;
3. 搭建NFS Server;
4. 建立靜態PV;
5. Kubernetes上部署Tomcat的service;
6. 執行客戶端,上傳本地檔案到Tomcat;
7. 去NFS Server檢查上傳的檔案;

準備知識列表

實戰環境

整個實戰環境如下圖:
這裡寫圖片描述

  1. NFS Server對Kubernetes環境提供遠端儲存服務;
  2. PV1是個靜態的PersistentVolume,型別為NFS,對應著NFS Server的/usr/local/work/nfs目錄;
  3. Client是個java的程式,可以將本地檔案POST到伺服器上;
  4. Kubernetes環境中部署了一個Pod,裡面有個Tomcat容器執行springboot應用,收到Client上傳的檔案後儲存在本地的/usr/local/uploadfiles目錄下;
  5. Tomcat容器的本地目錄/usr/local/uploadfiles,在容器的儲存卷配置中設定為mount到PV1;

本章用到的檔案下載

您可以在GitHub下載本章用到的4個檔案,地址和連結資訊如下表所示:

名稱 連結 備註
git倉庫地址(ssh) [email protected]:zq2599/blog_demos.git 該專案原始碼的倉庫地址,ssh協議


這個git專案中有多個目錄,本次所需的資源放在k8spvdemofiles目錄下,如下圖紅框所示:
這裡寫圖片描述

這個資料夾下面有四個檔案,功能如下所示,請下載下來,稍後會用到:
1. pv1.yaml—建立pv時用到的配置檔案;
2. pvc1.yaml—建立pvc時用到的配置檔案;
3. k8spvdemo.yaml—建立web服務的Pod用到的配置檔案;
4. k8spvdemo-svc.yaml—暴露web服務到外部用到的配置檔案;

準備工作已經完成,接下來可以實戰體驗了;

搭建NFS Server

找一臺電腦,部署NFS Server,具體操作可以參照《Ubuntu16環境安裝和使用NFS》,假設該電腦的IP地址是192.168.119.128,共享目錄是/usr/local/work/nfs

建立靜態PV

將下載好的pv1.yaml和pvc1.yaml檔案放在一個目錄下,然後執行命令kubectl create -f pv1.yaml,pvc1.yaml即可建立PV和PVC,再執行命令kubectl get pv檢視是否建立成功,如下:

root@maven:/usr/local/work/k8spv# kubectl create -f pv1.yaml,pvc1.yaml  
persistentvolume "pv1" created
persistentvolumeclaim "pvc1" created
root@maven:/usr/local/work/k8spv# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM          STORAGECLASS   REASON    AGE
pv1       1Gi        RWO            Recycle          Bound     default/pvc1                            1m

可見pv1已經繫結到pvc1,接下來建立Pod掛載pvc1;

Kubernetes上部署Tomcat的service

將下載好的k8spvdemo.yaml和k8spvdemo-svc.yaml檔案放在一個目錄下,然後執行命令kubectl create -f k8spvdemo.yaml,k8spvdemo-svc.yaml即可建立Pod和Service,開啟dashboard頁面,可以看到已經部署好的容器情況,如下圖:
這裡寫圖片描述

服務部署完畢了,接下來試試上傳檔案到服務端,看是PV是否有效;

執行客戶端,上傳本地檔案到Tomcat

  1. 建立一個maven工程,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bolingcavalry</groupId>
    <artifactId>uploadfileclient</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 指明編譯原始碼時使用的字元編碼,maven編譯的時候預設使用的GBK編碼, 通過project.build.sourceEncoding屬性設定字元編碼,告訴maven這個專案使用UTF-8來編譯 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.3.5</version>
        </dependency>
    </dependencies>

</project>


2. 工程中建立一個java類,原始碼如下:

package com.bolingcavalry;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;

/**
 * @Description : 上傳檔案的類,將本地檔案POST到server
 * @Author : [email protected]
 * @Date : 2018-02-24 18:12
 */
public class UploadFileClient {

    /**
     * 檔案服務的ULR
     */
    private static final String POST_URL = "http://192.168.119.153:30010//upload";

    /**
     * 要上傳的本地檔案的完整路徑加檔名
     */
    private static final String UPLOAD_FILE_FULLPATH = "D:\\temp\\201802\\21\\abc.zip";

    public static void main(String[] args) throws Exception{
        System.out.println("start upload");
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost(POST_URL);

            //基本的配置資訊
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(200000).setSocketTimeout(200000).build();

            httppost.setConfig(requestConfig);

            //要上傳的檔案
            FileBody bin = new FileBody(new File(UPLOAD_FILE_FULLPATH));

            //在POST中新增一個字串請求引數
            StringBody comment = new StringBody("This is comment", ContentType.TEXT_PLAIN);

            HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("file", bin).addPart("comment", comment).build();

            httppost.setEntity(reqEntity);

            System.out.println("executing request " + httppost.getRequestLine());

            //發起POST
            CloseableHttpResponse response = httpclient.execute(httppost);

            try {

                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    String responseEntityStr = EntityUtils.toString(response.getEntity());
                    System.out.println("response status : " + response.getStatusLine());
                    System.out.println("response content length: " + resEntity.getContentLength());
                    System.out.println("response entity str : " + responseEntityStr);
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println("end upload");
    }
}

以上原始碼中,有兩處要注意:
第一,中的192.168.119.153是Pod所在的節點機器的IP地址,請替換為您的k8s環境中的節點IP地址;
第二,UPLOAD_FILE_FULLPATH = “D:\temp\201802\21\abc.zip”,這裡配置的是要上傳的本地檔案的路徑,請替換為您要上傳的檔案路徑;
3. 直接執行UploadFileClient.java,看到控制檯輸出如下資訊表示上傳成功:

start upload
executing request POST http://192.168.119.153:30010//upload HTTP/1.1
response status : HTTP/1.1 200 
response content length: 40
response entity str : SpringBoot環境下,上傳檔案成功
end upload

Process finished with exit code 0

上傳成功了,在dashboard上檢視容器的日誌,能看到上傳有關的日誌如下圖紅框所示:
這裡寫圖片描述

現在理論上現在檔案已經儲存在NFS Server的/usr/local/work/nfs目錄下了,去檢查一下;

去NFS Server檢查上傳的檔案

登入NFS Server,進入/usr/local/work/nfs,檢視檔案資訊如下:

root@nfs:/usr/local/work/nfs# ll
total 160
drwxrwxrwx 2 root   root      4096 Mar 11 06:02 ./
drwxr-xr-x 5 root   root      4096 Mar  8 20:31 ../
-rw-r--r-- 1 nobody nogroup 153035 Mar 11 03:24 abc.zip

可見k8s上的tomcat應用可以通過PVC的方式將客戶端上傳的檔案儲存在NFS伺服器上;

至此,對k8s持久卷服務的體驗就完成了,後續章節我們將深入以上內容的細節,對PV做進一步瞭解;

相關推薦

Kubernetes持久實戰之一體驗

章節列表 整個《Kubernetes持久卷實戰》由以下兩篇文章組成: 1. 極速體驗靜態持久化儲存,也就是本章的內容; 2. 瞭解k8s的pod、service、pv、pvc的細節; 本章內容 本章目標是用最少的步驟和時間體驗PV,所以先不展開

Docker下RabbitMQ延時佇列實戰之一體驗

有的應用場景中,向RabbitMQ發出訊息後,我們希望消費方不要立即消費,可以通過延時佇列來實現,思路是將訊息傳送到A佇列,此佇列沒有消費者,等訊息過期後會進入A佇列的Dead Letter Exchange中,B佇列綁定了這個Dead Letter Excha

Kubernetes持久實戰之二細說開發

在上一章《Kubernetes持久卷實戰兩部曲之一:極速體驗》我們體驗了K8S環境下基於NFS的持久卷讀寫,今天我們一起來了解整個體驗環境背後的細節; 全文概要 要完成上一章的體驗,需要做以下事情: 1. 建立PV; 2. 建立PVC; 3. 開發we

docker-compose下的java應用啟動順序之一問題分析

在docker-compose編排多個容器時,需要按實際情況控制各容器的啟動順序,本文是《docker-compose下的java應用啟動順序兩部曲》的第一篇,文中會分析啟動順序的重要性,以及啟動順序有問題時會有什麼樣的影響,再給出臨時解決的和官方推薦的兩種解決方案,為下一篇的實戰做好鋪墊。 環境資訊 本次實

Docker下實戰zabbix三部曲之一體驗

對於想學習和實踐zabbix的讀者來說,在真實環境搭建一套zabbix系統是件費時費力的事情,本文內容就是用docker來縮減搭建時間,目標是讓讀者們儘快投入zabbix系統的體驗和實踐; 環境資訊 以下是本次操作的環境: 作業系統:MacBook Pro Docker:19.03.2 全系列文章連結: 三

Docker下ELK三部曲之一體驗

《Docker下ELK三部曲》一共三篇文章,為您揭示如何快速搭建ELK環境,以及如何將web應用的日誌上報到ELK用,三部曲內容簡述如下: 1. 極速體驗ELK服務,即本章的內容; 2. 細說技術詳情,例如集成了filebeat服務的映象如何製作,web應用

Docker下RabbitMQ四部曲之一體驗(單機和叢集)

從本章開始,我們一起在Docker環境實戰RabbitMQ環境部署和對應的Java開發,當前是《Docker下RabbitMQ四部曲》系列的第一篇,整個系列由以下四篇文章組成: 1. 第一篇,即本章,我們用最快的方式體驗RabbitMQ單機環境下生產和消費訊息

Docker下RabbitMQ延時佇列實戰之二細說開發

本章是《Docker下RabbitMQ延時佇列實戰兩部曲》的終篇,上一章《Docker下RabbitMQ延時佇列實戰兩部曲之一:極速體驗》我們快速體驗了延時佇列的生產和消費,今天來實戰整個開發過程; SpringBoot框架下進行RabbitMQ開發,相關

docker-compose下的java應用啟動順序之二實戰

上篇回顧 本文是《docker-compose下的java應用啟動順序兩部曲》的終篇,在上一篇《docker-compose下的java應用啟動順序兩部曲之一:問題分析》中,我們以SpringCloud環境下的註冊中心和業務服務為例,展示了docker-compose.yml中depends_on引數的不足

Python基礎知識:二

思想 你在 com 計算器 檢查 結果 條件 繼承 ddl 如果沒有看基礎部分第一章,請前往Python基礎知識兩部曲:一 8.函數 1.定義函數: 使用關鍵字def來告訴python你要定義一個函數 接著指出函數名:如下面函數名是--greet_user ()是必須帶上

自學Linux Shell9.3-基於Red Hat系統工具包存在種方式之一原始碼包

9.3-基於Red Hat系統工具包存在兩種方式之一:原始碼包 本節主要介紹基於Red Had的系統(測試系統centos) 1. 工具包存在兩種方式:RPM包與原始碼包 1.1.RPM包與原始碼包區別 安裝之前的區別:概念上的區別    原始碼包是開源的,比RPM包安裝更自由,但是它安裝更慢,更容易報錯

給出一個含有n個數字的序列a1,a2,a3,...an,可以進行以下操作 一次操作定義為對這個序列的每個數字進行以下種改變之一 1.ai ÷ 2 2.ai × 3 每一次的操作中,必須保證至少有

JAVA 給出一個含有n個數字的序列a1,a2,a3,…an,可以進行以下操作: 一次操作定義為對這個序列的每個數字進行以下兩種改變之一: 1.ai ÷ 2 2.ai × 3 每一次的操作中,必須保證至少有一個數字是第1種改變;並且經過每次操作後,每一

《Java 併發程式設計實戰》讀書筆記之一可重入內建鎖

每個Java物件都可以用做一個實現同步的鎖,這些鎖被稱為內建鎖或監視器鎖。執行緒在進入同步程式碼塊之前會自動獲取鎖,並且在退出同步程式碼塊時會自動釋放鎖。獲得內建鎖的唯一途徑就是進入由這個鎖保護的同步程式碼塊或方法。 當某個執行緒請求一個由其他執行緒持有的鎖時,發出請求的

實戰Kubernetes動態儲存(NFS)

之前的《 Kubernetes持久卷實戰兩部曲》系列中,我們實戰了先宣告一個儲存卷,再使用這個儲存卷,這種方式要求每次都要提前申明儲存,不是很方便,而動態卷儲存不需要提前申明,而是使用時自動申明,今天我們就來一起實戰; 參考資料 本章

如何在Kubernetes集群動態使用 NAS 持久

per nor control exists ber data href 閱讀 clas 1. 介紹: 本文介紹的動態生成NAS存儲卷的方案:在一個已有文件系統上,自動生成一個目錄,這個目錄定義為目標存儲卷; 鏡像地址:registry.cn-hangzhou.aliyun

通過搭建MySQL掌握k8s(Kubernetes)重要概念(上)網路與持久

上一篇"通過例項快速掌握k8s(Kubernetes)核心概念"講解了k8s的核心概念,有了核心概念整個骨架就完整了,應付無狀態程式已經夠了,但還不夠豐滿。應用程式分成兩種,無狀態和有狀態的。一般的前段和後端程式都是無狀態的,而資料庫是有狀態的,他需要把資料儲存起來,這樣即使斷電,資料也不會丟失。要建立有狀態

JDBC六-1

jdbc//創建db.properties文件,來配置對數據庫的訪問方式 dbname=MySQL /Oracle //通過讀取文件來實現對不同的數據庫不同訪問 import java.io.*; import java.util.*; public class JDBCTestProgrammer1{

關於unix環境高級編程、Linux程序設計書淺談

是我 界面 clas 代碼量 概念 圖形 都是 淺談 相關 unix環境高級編程的術語很多,概念內容,也很多,不過學習概念性質、標準規則類的東西,想必都是這樣吧——需要進行拓展的內容很多。 Linux程序設計,圖文並茂,代碼量夠足,看起來,感覺難度還可以。 linux程序設

《從Docker到Kubernetes企業應用實戰課程 - 集訓班》【招生中】

docker課程簡介 本課程是一個Docker技術集訓班,實戰為主,幫助你快速掌握這門主流的技術,能勝任Docker相關工作,同時為簡歷添上靚麗一筆。 Docker是一個開源的應用容器引擎,將項目及依賴打包到一個容器中,然後發布到任意Linux服務器上。 Docker主要特點:開箱即用,快速

深度視覺經典重讀之一積網絡的蠻荒時代

complete red which Y軸 shift initial 變化 minor 數量 最近在找下一篇文章的研究方向,於是重新拿起了入學前看過的一些經典老文,沒想到其中蘊含的信息量這麽大,原來當初naive的我根本沒有領悟其中的精髓。 相對於一些瑣碎的技術細節,我更