歡迎光臨
每天分享高質量文章

Java程式員如何快速理解Kubernetes

我們希望微服務是可複製的,可替換的工作節點,這樣可以輕鬆進行升級或降級,同時無需任何停機時間,並花費最少代價的管理。我們可以說我們希望他們成為我們的小黃人(minions)。本文我們將透過一個簡單的例子來瞭解Kubernetes可以透過建立和編排一群“小黃人”來為我們做些什麼。您可以與本文一起編碼或從此處[1]克隆專案。
先決條件

需要將使用Docker容器化微服務以便在Kubernetes中執行它們。我們將使用Minikube,而不是使用雲託管的Kubernetes,以便可以在本地沙箱執行。
目的

我們的小黃人軍團將是Java微服務。我們希望軍團中有不同型別的工作角色,以便能夠瞭解Kubernetes可以為我們做些什麼。因此,我們的標的是讓每個微服務都響應一個簡單的http請求,其響應如下:
使用ASCII字來表示minion的型別。
構建Java Minion服務

我們可以透過Spring Boot Web應用程式來啟動我們的微服務,程式使用具有Web啟動依賴性的Spring Initializr初始化:
在專案中,建立一個使用@RestController註釋的Controller來處理請求。使用@RequestMapping(method = GET)來提供響應主體。所以首先我們可以這樣做:
@RequestMapping( method=GET)

@ResponseBody

public String minion() throws UnknownHostException {

   StringBuilder stringBuilder = new StringBuilder();

   stringBuilder.append("Host: ").append(InetAddress.getLocalHost().getHostName()).append("
"
);

   return stringBuilder.toString();

}

但這並不能完全滿足需求。我們可以輸出ASCII字,但選擇哪種minion型別?為此可以使用一個技巧。建立一個可以採用我們選擇的任何minion型別的應用程式。要做到這一點,需要它包含一個ASCII藝術字型檔。因此,我們建立了一個名為MinionsLibrary的類,使用@Component註解,在內部我們建立了一個地圖,我們使用此部落格[2]中的一些minions初始化:
@Component

public class MinionsLibrary {

    private Map map = new HashMap<>();

    public MinionsLibrary(){

      map.put("one-eyed-minion",);

      map.put("two-eyed-minion",);

      map.put("sad-minion",);

      map.put("happy-minion",);

    }

}

或者你可以從https://github.com/ryandawsonuk/minions/tree/master/src/main/java/org/minions/demo獲取。
然後告訴微服務是哪種minion型別。使用Spring應用程式的名稱屬性(我們稍後可以使用Docker環境變數設定)來執行此操作。它還將幫助我們稍後在響應中顯示我們的應用程式版本,所以現在的Controller變為:
@RestController

public class Controller {

    private final String version = "0.1";

    private MinionsLibrary minionsLibrary;

    @Value("${spring.application.name}")

    private String appName;

    public Controller(MinionsLibrary minionsLibrary){

        this.minionsLibrary=minionsLibrary;

    }

    @RequestMapping( method=GET)

    @ResponseBody

    public String minion() throws UnknownHostException {

        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.append("Host: ").append(InetAddress.getLocalHost().getHostName()).append("
"
);

        stringBuilder.append("Minion Type: ").append(appName).append("
"
);

        stringBuilder.append("IP: ").append(InetAddress.getLocalHost().getHostAddress()).append("
"
);

        stringBuilder.append("Version: ").append(version).append("
"
);

        stringBuilder.append(minionsLibrary.getMinion(appName));

        return stringBuilder.toString();

    }

}

現在選擇’image’包以匹配應用程式名稱,該名稱將是minion型別名稱(例如’單眼小黃人’)。
容器化並部署

需要為我們的應用程式建立一個Docker映象。我們想在Docker映象中構建可執行的jar,然後在容器啟動時啟動Java應用程式。可以使用多階段Docker構建來完成此任務。 Dockerfile是:
FROM maven:3.5-jdk-8 as BUILDMINION

COPY src /usr/src/myapp/src

COPY pom.xml /usr/src/myapp

RUN mvn -f /usr/src/myapp/pom.xml clean package -DskipTests

FROM openjdk:alpine

COPY --from=BUILDMINION /usr/src/myapp/target/*.jar /maven/

CMD java $JAVA_OPTS -jar maven/*.jar

從開始到’FROM openjdk:alpine’是構建JAR,然後jar包被複製到基於輕量的openjdk:alpine映象的下一階段構建。使用JAVA_OPTS引數來限製程式的記憶體佔用(關於降低記憶體,可以參考該文章[3])。
然後使用命令“docker build . -t minion”構建一個映象。
透過建立Kubernetes部署檔案來部署它。我們稱之為“minion-army.yml”。這將包含每個minion型別的條目。這是其中的一個minion型別:
apiVersion: apps/v1beta1

kind: Deployment

metadata:

 name: one-eyed-minion

labels:

   serviceType: one-eyed-minion

spec:

 replicas: 2

template:

   metadata:

     name: one-eyed-minion

     labels:

       serviceType: one-eyed-minion

   spec:

     containers:

       - name: one-eyed-minion

         image: minion:latest

         imagePullPolicy: Never

         ports:

         - containerPort: 8080

         env:

         - name: JAVA_OPTS

           value: -Xmx64m -Xms64m

         - name: SPRING_APPLICATION_NAME

           value: "one-eyed-minion"

---

apiVersion: v1

kind: Service

metadata:

 name: one-eyed-minion-entrypoint

namespace: default

spec:

 selector:

   serviceType: one-eyed-minion

ports:
   - port: 8080

     targetPort: 8080

     nodePort: 30080

type: NodePort

請註意,“SPRING_APPLICATION_NAME”變數會自動與spring.application.name屬性匹配,以便此minion服務成為單眼小黃人型別。有兩個這種minion型別的實體(副本)可用,Kubernetes服務將自動將請求路由到其中一個或另一個。
該服務將透過Minikube以埠30080暴露對外提供服務 (對於真正的Kubernetes,該服務的這一點會有所不同,因為我們使用LoadBalancer而不是NodePort,並且不會限制在minikube埠範圍)。服務將使用與服務匹配的Pod來處理它。我們將為每種型別提供一種服務。
minion型別的部署將建立兩個Pod。每個人都是這種型別的工作節點。
我們可以為每個minion型別重覆上面的配置,每次增加外部埠號以便使用不同的埠,或者我們可以使用這個GitHub儲存庫,它還具有其他配置,可以在不停機的情況下進行小型版本升級(如果我們使用Helm,我們可以避免重覆,但我們不想新增比我們更多的工具)。
建立軍團

首先啟動mMinikube:
minikube start --memory 4000 --cpus 3

等待它開始,然後將您的Docker registry連結到Minikube,併為Minikube構建minion影象:
eval $(minikube docker-env)

docker build . -t minion

然後我們可以部署軍團:
kubectl create -f minion-army.yml

並看到型別:
open http://$(minikube ip):30080

open http://$(minikube ip):30081

open http://$(minikube ip):30082

open http://$(minikube ip):30083

每個看起來都很像文章開頭的快樂小黃人頁面。
我們可以透過“kubectl get pods”來檢視整個軍隊,或者“minikube dashboard”進到Pods頁面:
創造更多的部隊

我們可以在minikube dashboard的Deployments部分下建立更多特定型別的minions:
一個小黃人倒下,另一個替補他的位置

假設從瀏覽器點選快樂小黃人服務時得到的:
如果殺死“happy-minion-58c9c46d67-j84s9”會發生什麼?可以透過儀錶板的Pod部分刪除:
kubectl delete pod happy-minion-58c9c46d67-j84s9

如果你在瀏覽器中點選掃清幾次(殺死小黃人兵可能需要一點時間),你會看到該服務會使用該型別的另一個小黃人。如果瀏覽Pod部分,您將看到Kubernetes建立了一個新的Pod來代替您刪除的那個,以保證該部署中有兩個節點。
Minion升級

我們還可以為小黃人進行滾動升級。為此,我們應該在minions-army.yml檔案的每個Deployment部分的’spec’部分下麵(它可以直接位於同一級別的’replicas’下麵):

minReadySeconds: 10

strategy:

   type: RollingUpdate

   rollingUpdate:

     maxUnavailable: 1

     maxSurge: 1

然後將Controller類中的版本更改為0.2,儲存它然後執行:
docker build . -t minion:0.2

然後開啟minion-army.yml並找到 – 用“0.2”替換所有“最新”,儲存更改並執行:
kubectl apply -f minion-army.yml --record

掃清其中一個minion型別的瀏覽器,以檢視版本更改是否與kubectl rollout status部署中看到的內容一致,其中是minion型別(例如one-eyed-minion)。
小黃人回滾

要檢視已部署的歷史記錄,請執行kubectl rollout history deployment ,回滾執行 kubectl rollout undo deployment –to-revision = 1(可能需要一段時間)。
銷毀軍團

用以下方法摧毀軍隊:
kubectl delete -f minion-army.yml

用“minikube stop”停止minikube。
相關連結:
  1. https://github.com/ryandawsonuk/minions/blob/master/minion-army.yml

  2. http://textart4u.blogspot.co.uk/2013/08/minions-emoticons-text-art-for-facebook.html

  3. https://dzone.com/articles/how-to-decrease-jvm-memory-consumption-in-docker-u

原文連結:https://dzone.com/articles/minions-in-minikube-a-kubernetes-intro-for-java-de

Kubernetes實戰培訓

Kubernetes應用實戰培訓將於2018年10月12日在深圳開課,3天時間帶你係統學習Kubernetes本次培訓包括:容器基礎、Docker基礎、Docker進階、Kubernetes架構及部署、Kubernetes常用物件、Kubernetes網路、儲存、服務發現、Kubernetes的排程和服務質量保證、監控和日誌、Helm、專案實踐等,點選下方圖片檢視詳情。

贊(0)

分享創造快樂