服務網與Kubernetes上的Istio分5步

在本文中,我將向您展現一些基本和更高級的示例,說明如何使用Istio平臺來提供部署在Kubernetes上的微服務之間的通訊。按照Istio網站上的描述,它是:java

一個開放的平臺,用於鏈接,管理和保護微服務。Istio提供了一種經過負載平衡,服務到服務身份驗證,監控等建立已部署服務網絡的簡便方法,無需更改服務代碼。git

Istio提供流量管理機制,如請求路由,發現,負載平衡,處理故障和故障注入。此外,您能夠啓用istio-auth,它提供RBAC(基於角色的訪問控制)和相互TLS身份驗證。在本文中,咱們將僅討論流量管理機制。github

步驟1.在Minikube平臺上安裝Istio

在Kubernetes上測試Istio最溫馨的方法是經過Minikube。我已經在本文中描述瞭如何在本地計算機上配置Minikube:  使用Kubernetes和Docker的微服務。在Minikube上安裝Istio時,首先應該在啓動時啓用一些Minikube的插件。docker

1api

minikube start --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/certs/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/certs/ca.key" --extra-config=apiserver.Admission.PluginNames=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota瀏覽器

Istio安裝在名爲的專用命名空間中istio-system,但可以管理來自全部其餘命名空間的服務。首先,您應該去發佈頁面並下載與您的操做系統相對應的安裝文件。對我而言,它是Windows,全部後續步驟都將在假設咱們正在使用此操做系統的狀況下進行描述。在運行Minikube以後,在Minikube的VM上啓用Docker會頗有用。多虧了你,你將可以執行docker命令。網絡

1架構

@FOR /f "tokens=* delims=^L" %i IN ('minikube docker-env') DO @call %iapp

如今,將Istio文件提取到本地文件系統。文件istioctl.exe,這是在現有${ISTIO_HOME}/bin的目錄應該被添加到您的PATH。Istio包含一些Kubernetes平臺的安裝文件  ${ISTIO_HOME}/install/kubernetes。要在Minikube上安裝Istio的核心組件,只需應用如下YAML定義文件。wordpress

1

kubectl apply -f install/kubernetes/istio.yaml

如今,您已在Minikube實例上部署了Istio的核心組件。這些組件是:

Envoy - 它是一個開源邊緣和服務代理,專爲雲原生應用程序而設計。Istio使用Envoy代理的擴展版本。若是您對Envoy和微服務的一些細節感興趣,請閱讀個人文章  Envoy Proxy with Microservices,它描述瞭如何將Envoy網關與服務發現集成。

混合器 - 它是一個獨立於平臺的組件,負責跨服務網格實施訪問控制和使用策略。

Pilot - 它爲Envoy邊車提供服務發現,爲智能路由和彈性提供流量管理功能。

istio.yaml定義文件中提供的配置部署了與上述組件相關的一些pod和服務。您可使用kubectl命令驗證安裝,也能夠在執行命令後訪問Web Dashboard minikube dashboard

istio-2

步驟2.基於Spring Boot構建示例應用程序

在咱們開始使用Istio配置任何流量規則以前,咱們須要建立將相互通訊的示例應用程序。這些都是很是簡單的服務。這些應用程序的源代碼能夠在個人GitHub賬戶中的repository sample-istio-services中找到。有兩種服務:caller-servicecallme-service。它們都暴露了端點ping,它打印了應用程序的名稱和版本。這兩個值都取自Spring Boot build-info文件,該文件是在應用程序構建期間生成的。這是端點的實現GET /callme/ping

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

@RestController

@RequestMapping("/callme")

public class CallmeController {

 

    private static final Logger LOGGER = LoggerFactory.getLogger(CallmeController.class);

 

    @Autowired

    BuildProperties buildProperties;

 

    @GetMapping("/ping")

    public String ping() {

        LOGGER.info("Ping: name={}, version={}", buildProperties.getName(), buildProperties.getVersion());

        return buildProperties.getName() + ":" + buildProperties.getVersion();

    }

 

}

這裏是端點的實現GET /caller/ping。它GET /callme/ping使用Spring 調用端點RestTemplate。咱們假設callme-service能夠在callme-service:8091Kubernetes的地址下找到。此服務將在端口8091下的Minikube節點內公開。

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@RestController

@RequestMapping("/caller")

public class CallerController {

 

    private static final Logger LOGGER = LoggerFactory.getLogger(CallerController.class);

 

    @Autowired

    BuildProperties buildProperties;

    @Autowired

    RestTemplate restTemplate;

 

    @GetMapping("/ping")

    public String ping() {

        LOGGER.info("Ping: name={}, version={}", buildProperties.getName(), buildProperties.getVersion());

        String response = restTemplate.getForObject("http://callme-service:8091/callme/ping", String.class);

        LOGGER.info("Calling: response={}", response);

        return buildProperties.getName() + ":" + buildProperties.getVersion() + ". Calling... " + response;

    }

 

}

必須在Docker容器上啓動示例應用程序。這是Dockerfile,負責使用caller-service應用程序構建映像。

1

2

3

4

6

7

8

FROM openjdk:8-jre-alpine

ENV APP_FILE caller-service-1.0.0-SNAPSHOT.jar

ENV APP_HOME /usr/app

EXPOSE 8090

COPY target/$APP_FILE $APP_HOME/

WORKDIR $APP_HOME

ENTRYPOINT ["sh", "-c"]

CMD ["exec java -jar $APP_FILE"]

相似Dockerfile的可用callme-service。如今,咱們惟一須要的是構建Docker鏡像。

1

2

docker build -t piomin/callme-service:1.0 .

docker build -t piomin/caller-service:1.0 .

還有一個版本2.0.0-SNAPSHOTcallme-service可用分支v2。切換到此分支,構建整個應用程序,而後使用2.0標記構建docker鏡像。爲何咱們須要2.0版本?我將在下一節中對其進行描述。

1

docker build -t piomin/callme-service:2.0 .

步驟3.在Minikube上部署示例應用程序

在咱們開始在Minikube上部署應用程序以前,讓咱們看看下圖中可見的示例系統架構。咱們將部署callme-service兩個版本:1.02.0。應用程序caller-service只是調用callme-service,因此我對目標服務的不一樣版本一無所知。若是咱們想callme-service在20%到80%的兩個版本之間路由流量,咱們必須配置正確的Istio路由器。還有一件事。因爲Minikube不支持Istio Ingress,咱們將只提供Kubernetes服務。若是咱們須要在Minikube集羣以外公開它,咱們應該將類型設置爲  NodePort

istio-1

讓咱們進入部署階段。這是callme-service版本中的部署定義1.0

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

三十

31

32

apiVersion: v1

kind: Service

metadata:

  name: callme-service

  labels:

    app: callme-service

spec:

  type: NodePort

  ports:

  - port: 8091

    name: http

  selector:

    app: callme-service

---

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: callme-service

spec:

  replicas: 1

  template:

    metadata:

      labels:

        app: callme-service

        version: v1

    spec:

      containers:

      - name: callme-service

        image: piomin/callme-service:1.0

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 8091

在Minikube上部署它以前,咱們必須注入一些Istio屬性。下面顯示的命令打印了一個富含Istio配置的新版本的部署定義。咱們能夠複製它並保存爲deployment-with-istio.yaml文件。

1

istioctl kube-inject -f deployment.yaml

如今,讓咱們將配置應用於Kubernetes。

1

kubectl apply -f deployment-with-istio.yaml

一樣的步驟應進行caller-service換版,而且還2.0callme-service。全部YAML配置文件都與應用程序一塊兒提交,而且位於每一個應用程序模塊的根目錄中。若是您已成功部署了全部必需的組件,則應在Minikube的儀表板中看到如下元素。

istio-3

步驟4.應用Istio路由規則

Istio提供了一種簡單的特定於域的語言(DSL),容許您配置一些有趣的規則來控制請求在服務網格中的路由方式。我將向您展現如下規則:

  • 拆分不一樣服務版本之間的流量
  • 在請求路徑中注入延遲
  • 注入HTTP錯誤做爲服務的響應

如下是示例路由規則定義callme-service。它在服務的版本1.0和2.0之間以20:80的比例分割流量。它還在10%的請求中增長了3秒的延遲,併爲10%的請求返回HTTP 500錯誤代碼。

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

apiVersion: config.istio.io/v1alpha2

kind: RouteRule

metadata:

  name: callme-service

spec:

  destination:

    name: callme-service

  route:

  - labels:

      version: v1

    weight: 20

  - labels:

      version: v2

    weight: 80

  httpFault:

    delay:

      percent: 10

      fixedDelay: 3s

    abort:

      percent: 10

      httpStatus: 500

讓咱們爲Kubernetes應用新的路線規則。

1

kubectl apply -f routerule.yaml

如今,咱們能夠經過執行命令輕鬆驗證該規則  istioctl get routerule

istio -6-

步驟5.測試解決方案

在咱們開始測試以前,讓咱們在Minikube上部署Zipkin。Istio zipkin.yaml在目錄中提供部署定義文件${ISTIO_HOME}/install/kubernetes/addons

1

kubectl apply -f zipkin.yaml

咱們來看看Minikube上部署的服務列表。應用程序調用者服務提供的API在端口30873下  可用

istio-4

咱們能夠經過調用URL http://192.168.99.100:30873/caller/ping輕鬆測試Web瀏覽器的服務  。它打印服務的名稱和版本,以及調用者服務調用的callme-service的名稱和版本。因爲80%的流量路由到2.0版的callme-service,您可能會看到如下響應。

istio-7

可是,有時可能會調用1.0版的callme-service ...

istio-8

在本文中,我將向您展現一些基本和更高級的示例,說明如何使用Istio平臺來提供部署在Kubernetes上的微服務之間的通訊。按照Istio網站上的描述,它是:

一個開放的平臺,用於鏈接,管理和保護微服務。Istio提供了一種經過負載平衡,服務到服務身份驗證,監控等建立已部署服務網絡的簡便方法,無需更改服務代碼。

Istio提供流量管理機制,如請求路由,發現,負載平衡,處理故障和故障注入。此外,您能夠啓用istio-auth,它提供RBAC(基於角色的訪問控制)和相互TLS身份驗證。在本文中,咱們將僅討論流量管理機制。

步驟1.在Minikube平臺上安裝Istio

在Kubernetes上測試Istio最溫馨的方法是經過Minikube。我已經在本文中描述瞭如何在本地計算機上配置Minikube:  使用Kubernetes和Docker的微服務。在Minikube上安裝Istio時,首先應該在啓動時啓用一些Minikube的插件。

1

minikube start --extra-config=controller-manager.ClusterSigningCertFile="/var/lib/localkube/certs/ca.crt" --extra-config=controller-manager.ClusterSigningKeyFile="/var/lib/localkube/certs/ca.key" --extra-config=apiserver.Admission.PluginNames=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota

Istio安裝在名爲的專用命名空間中istio-system,但可以管理來自全部其餘命名空間的服務。首先,您應該去發佈頁面並下載與您的操做系統相對應的安裝文件。對我而言,它是Windows,全部後續步驟都將在假設咱們正在使用此操做系統的狀況下進行描述。在運行Minikube以後,在Minikube的VM上啓用Docker會頗有用。多虧了你,你將可以執行docker命令。

1

@FOR /f "tokens=* delims=^L" %i IN ('minikube docker-env') DO @call %i

如今,將Istio文件提取到本地文件系統。文件istioctl.exe,這是在現有${ISTIO_HOME}/bin的目錄應該被添加到您的PATH。Istio包含一些Kubernetes平臺的安裝文件  ${ISTIO_HOME}/install/kubernetes。要在Minikube上安裝Istio的核心組件,只需應用如下YAML定義文件。

1

kubectl apply -f install/kubernetes/istio.yaml

如今,您已在Minikube實例上部署了Istio的核心組件。這些組件是:

Envoy - 它是一個開源邊緣和服務代理,專爲雲原生應用程序而設計。Istio使用Envoy代理的擴展版本。若是您對Envoy和微服務的一些細節感興趣,請閱讀個人文章  Envoy Proxy with Microservices,它描述瞭如何將Envoy網關與服務發現集成。

混合器 - 它是一個獨立於平臺的組件,負責跨服務網格實施訪問控制和使用策略。

Pilot - 它爲Envoy邊車提供服務發現,爲智能路由和彈性提供流量管理功能。

istio.yaml定義文件中提供的配置部署了與上述組件相關的一些pod和服務。您可使用kubectl命令驗證安裝,也能夠在執行命令後訪問Web Dashboard minikube dashboard

istio-2

步驟2.基於Spring Boot構建示例應用程序

在咱們開始使用Istio配置任何流量規則以前,咱們須要建立將相互通訊的示例應用程序。這些都是很是簡單的服務。這些應用程序的源代碼能夠在個人GitHub賬戶中的repository sample-istio-services中找到。有兩種服務:caller-servicecallme-service。它們都暴露了端點ping,它打印了應用程序的名稱和版本。這兩個值都取自Spring Boot build-info文件,該文件是在應用程序構建期間生成的。這是端點的實現GET /callme/ping

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

@RestController

@RequestMapping("/callme")

public class CallmeController {

 

    private static final Logger LOGGER = LoggerFactory.getLogger(CallmeController.class);

 

    @Autowired

    BuildProperties buildProperties;

 

    @GetMapping("/ping")

    public String ping() {

        LOGGER.info("Ping: name={}, version={}", buildProperties.getName(), buildProperties.getVersion());

        return buildProperties.getName() + ":" + buildProperties.getVersion();

    }

 

}

這裏是端點的實現GET /caller/ping。它GET /callme/ping使用Spring 調用端點RestTemplate。咱們假設callme-service能夠在callme-service:8091Kubernetes的地址下找到。此服務將在端口8091下的Minikube節點內公開。

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@RestController

@RequestMapping("/caller")

public class CallerController {

 

    private static final Logger LOGGER = LoggerFactory.getLogger(CallerController.class);

 

    @Autowired

    BuildProperties buildProperties;

    @Autowired

    RestTemplate restTemplate;

 

    @GetMapping("/ping")

    public String ping() {

        LOGGER.info("Ping: name={}, version={}", buildProperties.getName(), buildProperties.getVersion());

        String response = restTemplate.getForObject("http://callme-service:8091/callme/ping", String.class);

        LOGGER.info("Calling: response={}", response);

        return buildProperties.getName() + ":" + buildProperties.getVersion() + ". Calling... " + response;

    }

 

}

必須在Docker容器上啓動示例應用程序。這是Dockerfile,負責使用caller-service應用程序構建映像。

1

2

3

4

6

7

8

FROM openjdk:8-jre-alpine

ENV APP_FILE caller-service-1.0.0-SNAPSHOT.jar

ENV APP_HOME /usr/app

EXPOSE 8090

COPY target/$APP_FILE $APP_HOME/

WORKDIR $APP_HOME

ENTRYPOINT ["sh", "-c"]

CMD ["exec java -jar $APP_FILE"]

相似Dockerfile的可用callme-service。如今,咱們惟一須要的是構建Docker鏡像。

1

2

docker build -t piomin/callme-service:1.0 .

docker build -t piomin/caller-service:1.0 .

還有一個版本2.0.0-SNAPSHOTcallme-service可用分支v2。切換到此分支,構建整個應用程序,而後使用2.0標記構建docker鏡像。爲何咱們須要2.0版本?我將在下一節中對其進行描述。

1

docker build -t piomin/callme-service:2.0 .

步驟3.在Minikube上部署示例應用程序

在咱們開始在Minikube上部署應用程序以前,讓咱們看看下圖中可見的示例系統架構。咱們將部署callme-service兩個版本:1.02.0。應用程序caller-service只是調用callme-service,因此我對目標服務的不一樣版本一無所知。若是咱們想callme-service在20%到80%的兩個版本之間路由流量,咱們必須配置正確的Istio路由器。還有一件事。因爲Minikube不支持Istio Ingress,咱們將只提供Kubernetes服務。若是咱們須要在Minikube集羣以外公開它,咱們應該將類型設置爲  NodePort

istio-1

讓咱們進入部署階段。這是callme-service版本中的部署定義1.0

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

三十

31

32

apiVersion: v1

kind: Service

metadata:

  name: callme-service

  labels:

    app: callme-service

spec:

  type: NodePort

  ports:

  - port: 8091

    name: http

  selector:

    app: callme-service

---

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: callme-service

spec:

  replicas: 1

  template:

    metadata:

      labels:

        app: callme-service

        version: v1

    spec:

      containers:

      - name: callme-service

        image: piomin/callme-service:1.0

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 8091

在Minikube上部署它以前,咱們必須注入一些Istio屬性。下面顯示的命令打印了一個富含Istio配置的新版本的部署定義。咱們能夠複製它並保存爲deployment-with-istio.yaml文件。

1

istioctl kube-inject -f deployment.yaml

如今,讓咱們將配置應用於Kubernetes。

1

kubectl apply -f deployment-with-istio.yaml

一樣的步驟應進行caller-service換版,而且還2.0callme-service。全部YAML配置文件都與應用程序一塊兒提交,而且位於每一個應用程序模塊的根目錄中。若是您已成功部署了全部必需的組件,則應在Minikube的儀表板中看到如下元素。

istio-3

步驟4.應用Istio路由規則

Istio提供了一種簡單的特定於域的語言(DSL),容許您配置一些有趣的規則來控制請求在服務網格中的路由方式。我將向您展現如下規則:

  • 拆分不一樣服務版本之間的流量
  • 在請求路徑中注入延遲
  • 注入HTTP錯誤做爲服務的響應

如下是示例路由規則定義callme-service。它在服務的版本1.0和2.0之間以20:80的比例分割流量。它還在10%的請求中增長了3秒的延遲,併爲10%的請求返回HTTP 500錯誤代碼。

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

apiVersion: config.istio.io/v1alpha2

kind: RouteRule

metadata:

  name: callme-service

spec:

  destination:

    name: callme-service

  route:

  - labels:

      version: v1

    weight: 20

  - labels:

      version: v2

    weight: 80

  httpFault:

    delay:

      percent: 10

      fixedDelay: 3s

    abort:

      percent: 10

      httpStatus: 500

讓咱們爲Kubernetes應用新的路線規則。

1

kubectl apply -f routerule.yaml

如今,咱們能夠經過執行命令輕鬆驗證該規則  istioctl get routerule

istio -6-

步驟5.測試解決方案

在咱們開始測試以前,讓咱們在Minikube上部署Zipkin。Istio zipkin.yaml在目錄中提供部署定義文件${ISTIO_HOME}/install/kubernetes/addons

1

kubectl apply -f zipkin.yaml

咱們來看看Minikube上部署的服務列表。應用程序調用者服務提供的API在端口30873下  可用

istio-4

咱們能夠經過調用URL http://192.168.99.100:30873/caller/ping輕鬆測試Web瀏覽器的服務  。它打印服務的名稱和版本,以及調用者服務調用的callme-service的名稱和版本。因爲80%的流量路由到2.0版的callme-service,您可能會看到如下響應。

istio-7

可是,有時可能會調用1.0版的callme-service ...

istio-8

...或Istio能夠模擬HTTP 500代碼。

istio-9

您可使用Zipkin控制檯輕鬆分析流量統計信息。

istio-10

或者只是看看pod生成的日誌。

istio-11

...或Istio能夠模擬HTTP 500代碼。

istio-9

您可使用Zipkin控制檯輕鬆分析流量統計信息。

istio-10

或者只是看看pod生成的日誌。

istio-11

 

https://github.com/xiaomin0322/sample-istio-services

相關文章
相關標籤/搜索