关于java:超详细教程一文入门Istio架构原理及实战应用

39次阅读

共计 25551 个字符,预计需要花费 64 分钟才能阅读完成。

Istio 简介

2.1、istio 架构

实际上 Istio 就是 Service Mesh 架构的一种实现,服务之间的通信(比方这里的 Service A 拜访 Service B)会通过代理(默认是 Envoy)来进行。

而且两头的网络协议反对 HTTP/1.1,HTTP/2,gRPC 或者 TCP,能够说笼罩了支流的通信协议。代理这一层,称之为数据立体。

管制立体做了进一步的细分,分成了 Pilot、Citadel 和 Galley,它们的各自性能如下:

  • Pilot:为 Envoy 提供了服务发现,流量治理和智能路由(AB 测试、金丝雀公布等),以及错误处理(超时、重试、熔断)性能。
  • Citadel:为服务之间提供认证和证书治理,能够让服务主动升级成 TLS 协定。
  • Galley:Galley 是 Istio 的配置验证、提取、解决和散发组件。它负责将其余的 Istio 组件与从底层平台(例如 Kubernetes)获取用户配置的细节隔离开来。

数据立体会和管制立体通信,一方面能够获取须要的服务之间的信息,另一方面也能够汇报服务调用的 Metrics 数据。

2.1、为什么应用 Istio?

通过负载平衡、服务间的身份验证、监控等办法,Istio 能够轻松地创立一个曾经部署了服务的网络,而服务的代码只需很少更改甚至无需更改。通过在整个环境中部署一个非凡的 sidecar 代理为服务增加 Istio 的反对,而代理会拦挡微服务之间的所有网络通信,而后应用其管制立体的性能来配置和治理 Istio,这包含:

  • 为 HTTP、gRPC、WebSocket 和 TCP 流量主动负载平衡。
  • 通过丰盛的路由规定、重试、故障转移和故障注入对流量行为进行细粒度管制。
  • 可插拔的策略层和配置 API,反对访问控制、速率限度和配额。
  • 集群内(包含集群的入口和进口)所有流量的自动化度量、日志记录和追踪。
  • 在具备弱小的基于身份验证和受权的集群中实现平安的服务间通信。

Istio 为可扩展性而设计,能够满足不同的部署需要。

2.2、外围个性

Istio 以对立的形式提供了许多跨服务网络的要害性能。

2.2.1、流量治理

Istio 简略的规定配置和流量路由容许您管制服务之间的流量和 API 调用过程。

Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻而易举的执行重要的工作(如 A/B 测试、金丝雀公布和按流量百分比划分的分阶段公布)。

有了更好的对流量的可视性和开箱即用的故障复原个性,就能够在问题产生之前捕捉它们,无论面对什么状况都能够使调用更牢靠,网络更强壮。

2.2.2、平安

Istio 的平安个性解放了开发人员,使其只须要专一于应用程序级别的平安。

Istio 提供了底层的平安通信通道,并为大规模的服务通信治理认证、受权和加密。有了 Istio,服务通信在默认状况下就是受爱护的,能够让您在跨不同协定和运行时的状况下施行统一的策略——而所有这些都只须要很少甚至不须要批改应用程序。

Istio 是独立于平台的,能够与 Kubernetes(或基础设施)的网络策略一起应用。但它更弱小,可能在网络和利用层面爱护 pod 到 pod 或者服务到服务之间的通信。

2.2.3、可察看性

Istio 强壮的追踪、监控和日志个性让您可能深刻的理解服务网格部署。

通过 Istio 的监控能力,能够真正的理解到服务的性能是如何影响上游和上游的;而它的定制 Dashboard 提供了对所有服务性能的可视化能力,并让您看到它如何影响其余过程。

Istio 的 Mixer 组件负责策略管制和遥测数据收集。它提供了后端形象和中介,将一部分 Istio 与后端的基础设施实现细节隔离开来,并为运维人员提供了对网格与后端根底施行之间交互的细粒度管制。

所有这些个性都使您可能更无效地设置、监控和增强服务的 SLO。当然,底线是您能够疾速无效地检测到并修复呈现的问题。

2.3、平台反对

Istio 独立于平台,被设计为能够在各种环境中运行,包含跨云、外部环境、Kubernetes、Mesos 等等。您能够在 Kubernetes 或是装有 Consul 的 Nomad 环境上部署 Istio。Istio 目前反对:

  • Kubernetes 上的服务部署
  • 基于 Consul 的服务注册
  • 服务运行在独立的虚拟机上

3、Istio 疾速入门

上面咱们将 Istio 进行部署装置,来体验下它的魅力。

3.1、搭建 kubernetes 集群

Istio 运行在 kubernetes 平台是最佳的抉择,所以咱们先搭建 kubernetes 环境。

留神:初学者请参考课程材料提供的 一键装置文档

3.1.1、环境筹备

筹备 3 台 Centos7 虚拟机:

名称 IP 角色 CPU 内存 硬盘
node1 192.168.31.106 master 2 核 4GB 100GB
node2 192.168.31.107 node 2 核 4GB 100GB
node3 192.168.31.108 node 2 核 4GB 100GB

3.1.2、前置工作

搭建 K8S 之前,须要一些前置的筹备工作,否则不能实现集群的搭建。yum 如果不能用,则应用 yum -y install yum-utils 或者curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo,而后再应用 yum。

# 批改主机名
hostnamectl  set-hostname node2
hostnamectl  set-hostname node3
# 更新 yum 源,并且实现 yum update 操作
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
#如果 wget 无奈应用间接输出 yum install wget 装置即可
yum makecache
yum -y update
# 装置 docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum -y install docker-ce

#启动 docker 服务
systemctl start docker.service
#开机自启
systemctl enable docker.service

#增加 docker 阿里云加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://c6n8vys4.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

#测试一下,看下载速度怎么样
docker pull redis
docker rmi redis:latest
# 敞开防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service

#增加 hosts 映射 可略过 这里设置的目标是为了后续操作中通过 scp 将某一个节点上的文件传到别的节点上
vim /etc/hosts
192.168.31.106 node1
192.168.31.107 node2
192.168.31.108 node3

scp /etc/hosts node2:/etc/
scp /etc/hosts node3:/etc/
# 设置 node1 到 node2、node3 免登陆
ssh-keygen #一路下一步操作
ssh-copy-id node2
ssh-copy-id node3

#测试
ssh node2
ssh node3

3.1.3、搭建集群

# 批改零碎参数
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# 禁用 swap 文件,编辑 /etc/fstab,正文掉援用 swap 的行
vim /etc/fstab
swapoff -a

# 设置网桥参数
vim /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.ipv4.tcp_tw_recycle = 0

scp /etc/sysctl.conf node2:/etc/
scp /etc/sysctl.conf node3:/etc/

#立刻失效
sysctl -p
#如果呈现 /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory
#执行 modprobe br_netfilter,再试即可

#装置 kubectl
vim /etc/yum.repos.d/kubernetes.repo

[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0

yum list kubectl –showduplicates
yum install -y kubectl.x86_64
#指定版本 肯定要指定版本
# yum install -y kubectl-1.18.6
#查看版本
kubectl version

yum install -y kubelet kubeadm --disableexcludes=kubernetes
#指定版本 肯定要指定版本
#yum install -y kubelet-1.18.6 kubeadm-1.18.6 --disableexcludes=kubernetes

#如果装置错了,能够用以下命令移除
#yum remove kubectl kubelet kubeadm

#拉取所须要的镜像
kubeadm config images pull --image-repository=registry.cn-hangzhou.aliyuncs.com/itcast --kubernetes-version=v1.18.6
#如果拉取失败,尝试这个:kubeadm config images pull --image-repository=lank8s.cn --kubernetes-version=v1.18.6

#开始初始化,如果应用 lank8s.cn 拉取的镜像,须要指定 --image-repository=lank8s.cn
kubeadm init --apiserver-advertise-address 192.168.31.106 --pod-network-cidr=10.244.0.0/16 --image-repository=registry.cn-hangzhou.aliyuncs.com/itcast  --kubernetes-version=v1.18.6

#当看到 Your Kubernetes control-plane has initialized successfully! 阐明初始化胜利了!#拷贝 admin.conf 到 home 目录,否则出错:The connection to the server localhost:8080 was refused - did you specify the right host or port?
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

#设置网络 kube-flannel.yml 文件在材料中
kubectl apply -f kube-flannel.yml

#测试
[root@node1 k8s]# kubectl get nodes
NAME    STATUS   ROLES    AGE   VERSION
node1   Ready    master   23m   v1.18.6

#将 node2、node3 退出到集群,token 要替换成本人的
kubeadm join 192.168.31.106:6443 --token ekw4eu.cfi77sji1jyczhj6 --discovery-token-ca-cert-hash sha256:21de4177eaf76353dd060f2a783c9dafe17636437ade020bc40d60a8ab903483

#测试
[root@node1 k8s]# kubectl get nodes
NAME    STATUS   ROLES    AGE     VERSION
node1   Ready    master   31m     v1.18.6
node2   Ready    <none>   6m46s   v1.18.6
node3   Ready    <none>   2m21s   v1.18.6

#阐明集群组件胜利了

#如果须要删除集群,执行 kubeadm reset,3 台机器都须要执行

#查看正在执行的 pod
kubectl get pod --all-namespaces -o wide

查看正在执行的 pod,kubectl get pod –all-namespaces -o wide

留神:如果虚拟机重启导致 k8s 敞开,能够采纳 systemctl status kubelet 查看状态,采纳 systemctl start kubelet 启动 k8s,无论是主节点还是工作节点,都须要执行。

kubeadm join 192.168.211.151:6443 --token zkkd3y.iompmpb402kyvdq6 \
    --discovery-token-ca-cert-hash sha256:3c500a7df3a3e6857b50c31f9a9a209d57e669d7acd69905f040023094945c04

registry.cn-hangzhou.aliyuncs.com/itcast/kube-proxy   v1.18.6
registry.cn-hangzhou.aliyuncs.com/itcast/pause        3.2 


registry.cn-hangzhou.aliyuncs.com/itcast/kube-proxy   v1.18.6
quay.io/coreos/flannel                                v0.12.0-amd64
registry.cn-hangzhou.aliyuncs.com/itcast/pause        3.2

3.2、搭建 Istio 环境

3.2.1、下载 Istio

下载 Istio,下载内容将蕴含:安装文件、示例和 istioctl 命令行工具。

  1. 拜访 Istio release 页面下载与您操作系统对应的安装文件。在 macOS 或 Linux 零碎中,也能够通过以下命令下载最新版本的 Istio:

    $ curl -L https://istio.io/downloadIstio | sh -

    可用指定版本:

    $ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.5 sh -
  1. 切换到 Istio 包所在目录下。例如:Istio 包名为 istio-1.6.5,则:

    $ cd istio-1.6.5

    装置目录蕴含如下内容:

    • samples/ 目录下,有示例应用程序
    • bin/ 目录下,蕴含 istioctl 的客户端文件。istioctl 工具用于手动注入 Envoy sidecar 代理。
  2. istioctl 客户端门路减少到 path 环境变量中,macOS 或 Linux 零碎的减少形式如下:

    $ export PATH=$PWD/bin:$PATH

装置 bash 主动补全文件

如果您应用 bash,istioctl 主动补全的文件位于 tools 目录。通过复制 istioctl.bash 文件到您的 home 目录,而后增加上行内容到您的 .bashrc 文件执行 istioctl tab 补全文件:

source ~/istio-1.6.5/tools/istioctl.bash

如果 istioctl 补全文件曾经正确装置,在您输出 istioctl 命令时通过按 Tab 键,它会返回一组举荐命令供您抉择:

$ istioctl proxy-<TAB>
proxy-config proxy-status

3.2.2、装置 Istio

请依照以下步骤在您所选的平台上应用 demo 配置文件装置 Istio。

  1. 装置 demo 配置

    $ istioctl manifest apply --set profile=demo

    抉择要装置的组件在 istio-1.6.5/manifests/profiles 中!

  2. 为了验证是否装置胜利,须要先确保以下 Kubernetes 服务正确部署,而后验证除 jaeger-agent 服务外的其余服务,是否均有正确的 CLUSTER-IP

    [root@k8-master ~]# kubectl get svc -n istio-system
    NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                      AGE
    grafana                     ClusterIP      10.1.88.100    <none>        3000/TCP                                                                     2m8s
    istio-egressgateway         ClusterIP      10.1.62.15     <none>        80/TCP,443/TCP,15443/TCP                                                     2m8s
    istio-ingressgateway        LoadBalancer   10.1.37.204    <pending>     15020:32010/TCP,80:32672/TCP,443:32187/TCP,31400:32038/TCP,15443:32460/TCP   2m8s
    istiod                      ClusterIP      10.1.233.207   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP,853/TCP                                2m12s
    jaeger-agent                ClusterIP      None           <none>        5775/UDP,6831/UDP,6832/UDP                                                   2m7s
    jaeger-collector            ClusterIP      10.1.149.13    <none>        14267/TCP,14268/TCP,14250/TCP                                                2m7s
    jaeger-collector-headless   ClusterIP      None           <none>        14250/TCP                                                                    2m7s
    jaeger-query                ClusterIP      10.1.147.252   <none>        16686/TCP                                                                    2m7s
    kiali                       ClusterIP      10.1.165.21    <none>        20001/TCP                                                                    2m7s
    prometheus                  ClusterIP      10.1.180.211   <none>        9090/TCP                                                                     2m7s
    tracing                     ClusterIP      10.1.43.36     <none>        80/TCP                                                                       2m7s
    zipkin                      ClusterIP      10.1.159.254   <none>        9411/TCP                                                                     2m7s

    如果集群运行在一个不反对内部负载均衡器的环境中(例如:minikube),istio-ingressgatewayEXTERNAL-IP 将显示为 <pending> 状态。请应用服务的 NodePort 或 端口转发来拜访网关。

    请确保关联的 Kubernetes pod 曾经部署,并且 STATUSRunning

    [root@k8-master ~]# kubectl get pods -n istio-system
    NAME                                    READY   STATUS    RESTARTS   AGE
    grafana-b54bb57b9-lt4jn                 1/1     Running   0          2m31s
    istio-egressgateway-7486cf8c97-4nxnm    1/1     Running   0          2m31s
    istio-ingressgateway-6bcb9d7bbf-pxnl5   1/1     Running   0          2m31s
    istio-tracing-9dd6c4f7c-zq2hh           1/1     Running   0          2m31s
    istiod-788f76c8fc-z8bqx                 1/1     Running   0          2m35s
    kiali-d45468dc4-v6w9p                   1/1     Running   0          2m31s
    prometheus-6477cfb669-tn272             2/2     Running   0          2m31s

3.2.3、卸载 Istio

istioctl manifest generate --set profile=demo | kubectl delete -f -

3.3、Bookinfo 示例

3.3.1、利用阐明

这个示例部署了一个用于演示多种 Istio 个性的利用,该利用由四个独自的微服务形成。这个利用模拟在线书店的一个分类,显示一本书的信息。页面上会显示一本书的形容,书籍的细节(ISBN、页数等),以及对于这本书的一些评论。

Bookinfo 利用分为四个独自的微服务:

  • productpage. 这个微服务会调用 detailsreviews 两个微服务,用来生成页面。
  • details. 这个微服务中蕴含了书籍的信息。
  • reviews. 这个微服务中蕴含了书籍相干的评论。它还会调用 ratings 微服务。
  • ratings. 这个微服务中蕴含了由书籍评估组成的评级信息。

reviews 微服务有 3 个版本:

  • v1 版本不会调用 ratings 服务。
  • v2 版本会调用 ratings 服务,并应用 1 到 5 个彩色星形图标来显示评分信息。
  • v3 版本会调用 ratings 服务,并应用 1 到 5 个红色星形图标来显示评分信息。

下图展现了这个利用的端到端架构。

Bookinfo 利用中的几个微服务是由不同的语言编写的。这些服务对 Istio 并无依赖,然而形成了一个有代表性的服务网格的例子:它由多个服务、多个语言形成,并且 reviews 服务具备多个版本。

3.3.2、部署利用

要在 Istio 中运行这一利用,无需对利用本身做出任何扭转。您只有简略的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar 注入到每个服务之中。最终的部署后果将如下图所示:

所有的微服务都和 Envoy sidecar 集成在一起,被集成服务所有的出入流量都被 sidecar 所劫持,这样就为内部管制筹备了所需的 Hook,而后就能够利用 Istio 管制立体为利用提供服务路由、遥测数据收集以及策略施行等性能。

3.3.3、启动应用服务

  1. 进入 Istio 装置目录。
  2. Istio 默认主动注入 Sidecar. 请为 default 命名空间打上标签 istio-injection=enabled

    $ kubectl label namespace default istio-injection=enabled
  3. 应用 kubectl 部署利用:

    $ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

    如果您在装置过程中禁用了 Sidecar 主动注入性能而抉择手动注入 Sidecar,请在部署利用之前应用 istioctl kube-inject 命令批改 bookinfo.yaml 文件。

    $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)

    下面的命令会启动全副的四个服务,其中也包含了 reviews 服务的三个版本(v1、v2 以及 v3)。

    在理论部署中,微服务版本的启动过程须要继续一段时间,并不是同时实现的。

  4. 确认所有的服务和 Pod 都曾经正确的定义和启动:

    $ kubectl get services
    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)              AGE
    details                    10.0.0.31    <none>        9080/TCP             6m
    kubernetes                 10.0.0.1     <none>        443/TCP              7d
    productpage                10.0.0.120   <none>        9080/TCP             6m
    ratings                    10.0.0.15    <none>        9080/TCP             6m
    reviews                    10.0.0.170   <none>        9080/TCP             6m

    还有:

    $ kubectl get pods
    NAME                                        READY     STATUS    RESTARTS   AGE
    details-v1-1520924117-48z17                 2/2       Running   0          6m
    productpage-v1-560495357-jk1lz              2/2       Running   0          6m
    ratings-v1-734492171-rnr5l                  2/2       Running   0          6m
    reviews-v1-874083890-f0qf0                  2/2       Running   0          6m
    reviews-v2-1343845940-b34q5                 2/2       Running   0          6m
    reviews-v3-1813607990-8ch52                 2/2       Running   0          6m

  1. 要确认 Bookinfo 利用是否正在运行,请在某个 Pod 中用 curl 命令对利用发送申请,例如 ratings

    $ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
    <title>Simple Bookstore App</title>

3.3.4、确定 Ingress 的 IP

当初 Bookinfo 服务启动并运行中,您须要使应用程序能够从内部拜访 Kubernetes 集群,例如应用浏览器。能够用 Istio Gateway 来实现这个指标。

  1. 为利用程序定义 Ingress 网关:

    $ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  2. 确认网关创立实现:

    $ kubectl get gateway
    NAME               AGE
    bookinfo-gateway   32s
  3. 设置拜访网关的 INGRESS_HOSTINGRESS_PORT 变量。确认并设置。

    # 设置 ingress 端口
    export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
    export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
    
    #设置 ingress IP
    export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
  4. 设置 GATEWAY_URL

    export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

能够用浏览器关上网址 http://$GATEWAY_URL/productpage,来浏览利用的 Web 页面。如果刷新几次利用的页面,就会看到 productpage 页面中会随机展现 reviews 服务的不同版本的成果(红色、彩色的星形或者没有显示)。reviews 服务呈现这种状况是因为咱们还没有应用 Istio 来管制版本的路由。

3.3.5、利用默认指标规定

给各个服务创立DestinationRule

在应用 Istio 管制 Bookinfo 版本路由之前,您须要在指标规定中定义好可用的版本,命名为 subsets

# 设置
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

#查问
kubectl get destinationrules -o yaml

至此,Istio 实现了全副的接管,第一个示例部署实现。

3.4、体验 Istio

3.4.1、申请路由

依照版本路由

目前 reviews 有三个版本,在浏览器中拜访 Bookinfo 应用程序的 /productpage 并刷新几次。咱们发现有时书评的输入蕴含星级评分,有时则不蕴含。这是因为没有明确的默认服务版本路由。

当初咱们要做就是让 istio 接管路由,比方将所有流量都路由到每个微服务的 v1 版本,Istio 实现起来是非常简单的,只须要增加虚构服务(VirtualService)即可。

示例:将所有流量都路由到各个微服务的 v1 版本

#virtual-service-all-v1.yaml 是官网提供的示例文件

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

其内容如下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1  #在这里指定了所有的 http 申请都通过 v1 实现,而 v1 在默认的规定中有定义
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - route:
    - destination:
        host: details
        subset: v1
---

通过测试,发现 reviews 不再切换款式。

依照不同用户身份路由

接下来,您将更改路由配置,以便将来自特定用户的所有流量路由到特定服务版本。在这,来自名为 Jason 的用户的所有流量将被路由到服务 reviews:v2

请留神,Istio 对用户身份没有任何非凡的内置机制。事实上,productpage 服务在所有到 reviews 服务的 HTTP 申请中都减少了一个自定义的 end-user 申请头,从而达到了本例子的成果。

请记住,reviews:v2 是蕴含星级评分性能的版本。

  1. 运行以下命令以启用基于用户的路由:

    $ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. 确认规定已创立:

    $ kubectl get virtualservice reviews -o yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews
      ...
    spec:
      hosts:
      - reviews
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        route:
        - destination:
            host: reviews
            subset: v2
      - route:
        - destination:
            host: reviews
            subset: v1
  3. 在 Bookinfo 应用程序的 /productpage 上,以用户 jason 身份登录。

    刷新浏览器。你看到了什么?星级评分显示在每个评论旁边。

  4. 以其余用户身份登录(抉择您想要的任何名称)。

    刷新浏览器。当初星星隐没了。这是因为除了 Jason 之外,所有用户的流量都被路由到 reviews:v1

您已胜利配置 Istio 以依据用户身份路由流量。

3.4.2、流量转移

还能够将 reviews 的局部流量转移到 v3 版本,基于此能够实现灰度公布、A/ B 测试等:

# 将所有流量都路由到每个服务的 v1 版本
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

#将 reviews 服务 50% 的流量转移到 v3
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

内容如下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50

刷新浏览器中的 /productpage 页面,大概有 50% 的几率会看到页面中出带 红色 星级的评估内容。这是因为 v3 版本的 reviews 拜访了带星级评级的 ratings 服务,但 v1 版本却没有。

如果认为 reviews:v3 微服务曾经稳固,能够通过利用此 virtual service 规定将 100% 的流量路由到 reviews:v3:

# 将 reviews 服务的全副流量都切换到 v3 版本

kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml

这样,所有的申请都转向到了 v3 了。

如果须要删除所有服务的虚构网络,能够执行:

kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml

virtual-service-all-v1.yaml配置文件中配置了所有服务的路由信息,如果删除了则所有的路由信息都删了

3.4.3、超时与重试

http 申请的超时能够用路由规定的 timeout 字段来指定。默认状况下,超时是禁用的

这里咱们来试验 reviews 服务的申请超时,将申请路由到 reviews 服务的 v2 版本,它会去调用 ratings 服务,咱们首先在 ratings 服务上人为的引入 2s 的提早(故障注入),再对 reviews 服务配置超时timeout

1、在istio-1.6.5/samples/bookinfo/networking 目录下创立配置文件

# 创立配置文件
vi virtual-service-reviews-v2-timeout.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percent: 100
        fixedDelay: 2s
    route:
    - destination:
        host: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
    #timeout: 0.5s

ratings 服务上注入 2s 的提早,

2、利用该路由配置,就在当前目录下执行即可

kubectl apply -f virtual-service-reviews-v2-timeout.yaml

3、拜访该网址, 这时能够看到 Bookinfo 利用运行失常(显示了评级的星型符号),然而每次刷新页面,都会有 2 秒的提早。

4、从新编辑该文件,放开对 reviews 服务的调用减少一个半秒的申请超时(去掉 timeout 的正文)

5、从新利用该配置,还是执行第 2 步的命令,而后通过如下命令查看配置是否更新

kubectl get virtualservice -o yaml

6、再次刷新网页

这时候应该看到 1 秒钟就会返回,而不是之前的 2 秒钟,但 reviews 是不可用的(页面没有 reviews 的数据)

即便超时配置为半秒,响应仍须要 1 秒,是因为 productpage 服务中存在硬编码重试,因而它在返回之前调用 reviews 服务超时两次(重试)。

对于重试:间接参考文档

https://istio.io/v1.6/zh/docs…

https://istio.io/v1.6/zh/docs…

3.4.4、熔断

熔断器是 Istio 为创立具备 弹性的微服务利用 提供的有用的机制。在熔断器中,设置一个对服务中的单个主机调用的限度,例如并发连贯的数量或对该主机调用失败的次数。一旦限度被触发,熔断器就会“跳闸”并进行连贯到该主机。

应用熔断模式能够疾速失败而不用让客户端尝试连贯到过载或有故障的主机。

部署 httpbin

httpbin 是一个开源我的项目,应用 Python+Flask 编写,利用它能够测试各种 HTTP 申请和响应。官网:http://httpbin.org/

kubectl apply -f samples/httpbin/httpbin.yaml

该配置文件的内容为:

##################################################################################################
# httpbin service
##################################################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      serviceAccountName: httpbin
      containers:
      - image: docker.io/kennethreitz/httpbin
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
配置熔断器

创立一个指标 熔断规定(DestinationRule),在调用 httpbin 服务时利用熔断设置:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1  #最大连接数
      http:
        http1MaxPendingRequests: 1  #http 申请 pending 状态的最大申请数
        maxRequestsPerConnection: 1  #在肯定工夫内限度对后端服务发动的最大申请数
    outlierDetection:  #熔断设置
      consecutiveErrors: 1  #从连接池开始回绝连贯,曾经连贯失败的次数,当通过 HTTP 拜访时,返回代码是 502、503 或 504 则视为谬误。interval: 1s  #回绝拜访扫描的工夫距离,即在 interval(1s)内间断产生 1 个 consecutiveErrors 谬误,则触发服务熔断,格局是 1h/1m/1s/1ms,但必须大于等于 1ms。即剖析是否须要剔除的频率,多久剖析一次,默认 10 秒。baseEjectionTime: 3m  #最短回绝拜访时长。这个工夫主机将放弃回绝拜访,且如果决绝拜访达到肯定的次数。格局:1h/1m/1s/1ms,但必须大于等于 1ms。实例被剔除后,至多多久不得返回负载平衡池,默认是 30 秒。maxEjectionPercent: 100  #服务在负载平衡池中被回绝拜访(被移除)的最大百分比,负载平衡池中最多有多大比例被剔除,默认是 10%。EOF

验证指标规定是否已正确创立:

kubectl get destinationrule httpbin -o yaml

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
  ...
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
      tcp:
        maxConnections: 1
    outlierDetection:
      baseEjectionTime: 180.000s
      consecutiveErrors: 1
      interval: 1.000s
      maxEjectionPercent: 100
客户端

创立客户端程序以发送流量到 httpbin 服务。这是一个名为 Fortio 的负载测试客户的,其能够管制连接数、并发数及发送 HTTP 申请的提早。通过 Fortio 可能无效的触发后面 在 DestinationRule 中设置的熔断策略。

  1. 向客户端注入 Istio Sidecar 代理,以便 Istio 对其网络交互进行治理:

    $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)

    两头稍等一会,让客户端部署胜利!!!

  2. 登入客户端 Pod 并应用 Fortio 工具调用 httpbin 服务。-curl 参数表明发送一次调用:

    $ FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1}')
    $ kubectl exec -it $FORTIO_POD  -c fortio -- /usr/bin/fortio load -curl  http://httpbin:8000/get
    HTTP/1.1 200 OK
    server: envoy
    date: Tue, 16 Jan 2018 23:47:00 GMT
    content-type: application/json
    access-control-allow-origin: *
    access-control-allow-credentials: true
    content-length: 445
    x-envoy-upstream-service-time: 36
    
    {"args": {},
      "headers": {
        "Content-Length": "0",
        "Host": "httpbin:8000",
        "User-Agent": "istio/fortio-0.6.2",
        "X-B3-Sampled": "1",
        "X-B3-Spanid": "824fbd828d809bf4",
        "X-B3-Traceid": "824fbd828d809bf4",
        "X-Ot-Span-Context": "824fbd828d809bf4;824fbd828d809bf4;0000000000000000",
        "X-Request-Id": "1ad2de20-806e-9622-949a-bd1d9735a3f4"
      },
      "origin": "127.0.0.1",
      "url": "http://httpbin:8000/get"
    }

能够看到调用后端服务的申请曾经胜利!接下来,能够测试熔断。

触发熔断器

在 DestinationRule 配置中,定义了 maxConnections: 1 和 http1MaxPendingRequests: 1。这些规定意味着,如果并发的连贯和申请数超过一个,在 istio-proxy 进行进一步的申请和连贯时,后续申请或 连贯将被阻止。

  1. 发送并发数为 2 的连贯(-c 2),申请 20 次(-n 20):

    [root@node1 istio-1.6.5]# kubectl exec -it $FORTIO_POD  -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
    03:59:25 I logger.go:97> Log level is now 3 Warning (was 2 Info)
    Fortio 1.3.1 running at 0 queries per second, 2->2 procs, for 20 calls: http://httpbin:8000/get
    Starting at max qps with 2 thread(s) [gomax 2] for exactly 20 calls (10 per thread + 0)
    03:59:25 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    03:59:25 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    03:59:25 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    03:59:25 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    03:59:25 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    03:59:25 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 79.166124ms : 20 calls. qps=252.63
    Aggregated Function Time : count 20 avg 0.0064311497 +/- 0.007472 min 0.000340298 max 0.032824602 sum 0.128622994
    # range, mid point, percentile, count
    >= 0.000340298 <= 0.001 , 0.000670149 , 10.00, 2
    > 0.001 <= 0.002 , 0.0015 , 20.00, 2
    > 0.002 <= 0.003 , 0.0025 , 40.00, 4
    > 0.003 <= 0.004 , 0.0035 , 60.00, 4
    > 0.004 <= 0.005 , 0.0045 , 65.00, 1
    > 0.006 <= 0.007 , 0.0065 , 80.00, 3
    > 0.012 <= 0.014 , 0.013 , 85.00, 1
    > 0.014 <= 0.016 , 0.015 , 90.00, 1
    > 0.016 <= 0.018 , 0.017 , 95.00, 1
    > 0.03 <= 0.0328246 , 0.0314123 , 100.00, 1
    # target 50% 0.0035
    # target 75% 0.00666667
    # target 90% 0.016
    # target 99% 0.0322597
    # target 99.9% 0.0327681
    Sockets used: 8 (for perfect keepalive, would be 2)
    Code 200 : 14 (70.0 %)
    Code 503 : 6 (30.0 %)
    Response Header Sizes : count 20 avg 161.15 +/- 105.5 min 0 max 231 sum 3223
    Response Body/Total Sizes : count 20 avg 668.15 +/- 279.6 min 241 max 852 sum 13363
    All done 20 calls (plus 0 warmup) 6.431 ms avg, 252.6 qps
    

    后果:

    Code 200 : 14 (70.0 %)
    Code 503 : 6 (30.0 %)
  2. 将并发连接数进步到 3 个:

    [root@node1 istio-1.6.5]# kubectl exec -it $FORTIO_POD  -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://httpbin:8000/get
    04:01:42 I logger.go:97> Log level is now 3 Warning (was 2 Info)
    Fortio 1.3.1 running at 0 queries per second, 2->2 procs, for 30 calls: http://httpbin:8000/get
    Starting at max qps with 3 thread(s) [gomax 2] for exactly 30 calls (10 per thread + 0)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    04:01:42 W http_client.go:679> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 32.153704ms : 30 calls. qps=933.02
    Aggregated Function Time : count 30 avg 0.0019156712 +/- 0.001801 min 0.000270969 max 0.006581956 sum 0.057470135
    # range, mid point, percentile, count
    >= 0.000270969 <= 0.001 , 0.000635485 , 56.67, 17
    > 0.002 <= 0.003 , 0.0025 , 70.00, 4
    > 0.003 <= 0.004 , 0.0035 , 86.67, 5
    > 0.004 <= 0.005 , 0.0045 , 93.33, 2
    > 0.005 <= 0.006 , 0.0055 , 96.67, 1
    > 0.006 <= 0.00658196 , 0.00629098 , 100.00, 1
    # target 50% 0.000908871
    # target 75% 0.0033
    # target 90% 0.0045
    # target 99% 0.00640737
    # target 99.9% 0.0065645
    Sockets used: 20 (for perfect keepalive, would be 3)
    Code 200 : 11 (36.7 %)
    Code 503 : 19 (63.3 %)
    Response Header Sizes : count 30 avg 84.333333 +/- 110.8 min 0 max 230 sum 2530
    Response Body/Total Sizes : count 30 avg 464.66667 +/- 294 min 241 max 851 sum 13940
    All done 30 calls (plus 0 warmup) 1.916 ms avg, 933.0 qps

    能够看到,只有 36.7% 的申请胜利,其余的均被熔断器拦挡:

    Code 200 : 11 (36.7 %)
    Code 503 : 19 (63.3 %)
  3. 查问 istio-proxy 状态以理解更多熔断详情:

    [root@node1 istio-1.6.5]# kubectl exec $FORTIO_POD -c istio-proxy -- pilot-agent request GET stats | grep httpbin | grep pending
    cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
    cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
    cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_active: 0
    cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
    cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_overflow: 72
    cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_total: 59

    能够看到 upstream_rq_pending_overflow59,这意味着,目前为止已有 59 个调用被标记为熔断。

清理
  1. 清理规定:

    $ kubectl delete destinationrule httpbin
  2. 下线 httpbin 服务和客户端:

    $ kubectl delete deploy httpbin fortio-deploy
    $ kubectl delete svc httpbin

3.4.5、可观测性

istio 的可观测性体现在:指标度量,日志,分布式追踪,网格可视化 等方面

网格可视化

咱们能够将 istio 网格以可视化的形式出现,基于 Web 的图形用户界面来查看网格和 Istio 配置对象的服务图,使咱们的操作更不便(解脱命令的困扰!!!)

在 Istio 中能够应用 Kiali 进行可视化的治理服务网格。Kiali 官网:https://www.kiali.io/

Kiali 的装置:在 demo 环境中曾经默认装置了 kiali,咱们能够通过如下命令查看

kubectl -n istio-system get services
kubectl -n istio-system get pod
kubectl -n istio-system get svc kiali

1、要关上 Kiali UI,请在您的 Kubernetes 环境中执行以下命令:

[root@k8-master ~]# istioctl dashboard kiali --address 192.168.200.200
http://localhost:38022/kiali
Failed to open browser; open http://localhost:38022/kiali in your browser.

将流量发送到网格,有三种抉择:

  • 在浏览器中拜访 http://$GATEWAY_URL/productpage
  • 屡次应用以下命令:
$ curl http://$GATEWAY_URL/productpage
  • 如果您在零碎中装置了 watch 命令,请通过以下形式间断发送申请,工夫距离为 1 秒:
$ watch -n 1 curl -o /dev/null -s -w %{http_code} $GATEWAY_URL/productpage

应用该地址关上,留神替换 localhost 为 address 地址,登录用户名和明码均为admin

图表

查看流量调配的百分比:

申请统计数据,RPS 数据(最小 / 最大的比值)

显示不同的图表类型,有四种类型:

  • App

    • 图形类型将一个应用程序的所有版本聚合到一个图形节点中。
  • Versioned App

    • 图类型显示每个应用程序版本的节点,然而特定应用程序的所有版本都组合在一起。
  • Workload

    • 图类型显示了服务网格中每个工作负载的节点。
  • Service

    • 图类型显示网格中每个服务的节点。
路由加权

默认路由规定会平均分配浏览到每个可用节点,通过 kiali 能够可行可视化的调节:

第一步,查看 servers 列表:

第二步,进入 reviews 服务:

第三步,删除原有路由规定:

第四步,创立权重的规定:

默认状况:

进行调整:

保留操作。

第五步,通过 watch 执行一段时间,察看成果:

能够看到,调配到 reviews 的 v1、v2、v3 的百分比产生了变动。

查看工作负载

入站、出站信息:

日志信息:

入站指标信息:

出站指标信息:

3.5、istio 实战

0、从材料中找到我的项目itcast-service-mesh2.zip,导入 ide,制作movie.tar

1、将 movie.tar 别离上传到 k8-node1(201 主机)k8-master(200 主机),而后别离解压

2、在 k8-node1 主机上,执行 build-images.sh 脚本,先构建镜像(留神是在 node 节点上)

3、在 k8-master 主机上,在 movie/movie-istio 目录下先进行部署

kubectl apply -f movie.yaml

期待启动

kubectl get service -o wide

#期待所有 pod 都成为运行状态
kubectl get pod
kubectl get pod -o wide

4、登录 neo4j 导入初始化数据,拜访:http://192.168.200.201:31001/…(拜访的地址是 node 节点的 ip)

用:neo4jneo4j登录,第一次登录后批改明码为:neo4j123,切记,切记,切记!

5、导入初始数据,从材料中找到 电影数据.txt,在 neo4j 中执行,执行实现后查问

match (n) return n

6、创立初始 指标规定,执行如下命令

kubectl apply -f destination-rule-all.yaml

7、创立网关,执行如下命令

kubectl apply -f movie-gateway.yaml

8、获取网关拜访地址,通过如下命令实现

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

echo $GATEWAY_URL

9、依据输入的地址拜访,比方:http://192.168.200.201:31557/…

进行测试,重复刷新几次,能够看到评分局部,红 / 黑 进行切换。

10、将流量全副导向评分的 v2 版本,只显示红色评分,则能够执行上面这个规定

kubectl apply -f virtual-service-rating-v2.yaml

再次查看网页的评分显示内容!!!

本文由传智教育博学谷 – 狂野架构师教研团队公布,转载请注明出处!

如果本文对您有帮忙,欢送关注和点赞;如果您有任何倡议也可留言评论或私信,您的反对是我保持创作的能源

正文完
 0