服务网与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

相关文章
相关标签/搜索