Istio练习题
# Bookinfo练习
# 部署Bookinfo
第一步我们只需要部署我们的Bookinfo微服务就行了,包括网关路由规则等我们都不需要做,因为后面分开练习。
成功跑起所有的Pod之后我们需要创建入口网关,使用虚拟服务绑定入口网关
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-pvjjl 2/2 Running 0 29m
productpage-v1-6b746f74dc-kg9lk 2/2 Running 0 29m
ratings-v1-b6994bb9-sd7lj 2/2 Running 0 29m
reviews-v1-545db77b95-mwnmd 2/2 Running 0 29m
reviews-v2-7bf8c9648f-jbgqb 2/2 Running 0 29m
reviews-v3-84779c7bbc-n67ph 2/2 Running 0 29m
# 入口网关
- 配置入口网关为istio默认的ingressgateway(已经绑定到NodePort)
- 配置Bookinfo服务器使用HTTP,端口是80
- 公开的范围为所有的主机(使用bookinfo.app就访问不了)
$ cat gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector: #选择器,选择默认istio的ingressgateway
istio: ingressgateway
servers: #服务器选择列表的规范
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
执行gateway查看详细
$ kubectl get gateway
NAME AGE
bookinfo-gateway 9d
$ kubectl describe gateway bookinfo-gateway
Name: bookinfo-gateway
Namespace: default
Labels: <none>
Annotations: API Version: networking.istio.io/v1beta1
Kind: Gateway
...
Spec:
Selector:
Istio: ingressgateway
Servers:
Hosts:
bookinfo.app
Port:
Name: http
Number: 80
Protocol: HTTP
Events: <none>
# 虚拟服务
如下是Bookinfo的虚拟服务架构图
可以看到bookinfo的所有访问地址如下
http://bookinfo.app /productpage
http://bookinfo.app/static/*
http://bookinfo.app /login
http://bookinfo.app/logout
http://bookinfo.app/api/v1/products
所以请如下操作:
- 虚拟服务需要绑定入口网关bookinfo-gateway
- 发送流量的目的主机是范围是所有
- 你需要创建一个HTTP流量的有序路由规则列表
- 匹配准确的路径是 /productpage /login /logout 前缀是/status /api/v1/products
- 重定向转发的默认为流量目的地是主机是productpage 端口9080
[root@master istio-1.9.5]# cat virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "bookinfo.app"
gateways:
- bookinfo-gateway
http: #有序路由表
- match: #匹配规则
- uri:
exact: /productpage
- uri:
prefix: /status
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route: #默认转发的流量
- destination: #目的地
host: productpage #目的主机
port:
number: 9080
# 目的地规则
如下是bookinfo的目的地规则,需要经过v1、 v2、v3的流量
可以看出ProductPage经过Reviewsv1是60%的流量,Reviewsv2和Reviewsv3是一样的20%的流量。
DestinationRule
定义在路由发生后应用于服务流量的策略。这些规则指定负载平衡的配置、来自 sidecar 的连接池大小以及异常检测设置,以检测和从负载平衡池中驱逐不健康的主机。
可以通过定义命名subset
和覆盖在服务级别指定的设置来指定特定于版本的策略 。以上规则对所有流向名为v1、v2、v3的子集的流量使用循环负载平衡策略。
所以需要做如下操作
- 创建一个目的地规则productpage默认选择v1的流量
- 创建一个reviews目的地规则有三个版本策略,对名为v1,v2,v3的子集流量负载。
- 创建一个ratings目的地规则有三个版本策略,对名为v1,v2,v2-mysql,v2-mysql-lvm的子集流量负载。
- 创建一个details目的地规则有三个版本策略,对名为v1,v2的子集流量负载。
$ cat destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ratings
spec:
host: ratings
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v2-mysql
labels:
version: v2-mysql
- name: v2-mysql-vm
labels:
version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: details
spec:
host: details
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
执行后查看生效
$ kubectl apply -f destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
$ kubectl get destinationrules.networking.istio.io
NAME HOST AGE
details details 68m
productpage productpage 68m
ratings ratings 68m
reviews reviews 68m
# httpbin练习
# Istio网关配置入口
- 配置网关的名称为Gateway
- 选择调度在默认的gateway
- 配置网关外部HTTP入口流量
- 在端口80上为HTTP流量配置网关,主机值应为httpbin.example.com。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "httpbin.example.com"
# 虚拟服务配置
- 现在为 httpbin 服务创建一个虚拟服务配置,其中包含两个允许路径 /status 和 /delay 流量的路由规则。
- 虚拟服务的名称为httpbin
- 主机使用httpbin.example.com
- 目标端口和主机应分别为8000和httpbin。
- 添加match.uri 和route部分。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "httpbin.example.com"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
# 其他
# 添加目的地规则
root@controlplane:/# kubectl get pods
NAME READY STATUS RESTARTS AGE
app-v1-5f5f5d55cd-drspk 2/2 Running 0 11m
app-v2-8bb879574-khfp5 2/2 Running 0 11m
在两个版本的 myapp 之间配置加权路由。但首先,让我们创建一个具有以下规范的 DestinationRule。
1. name:
myapp
2. host:
myapp
3. subset 1
:
name:
v1labels:
version=v1
3. subset 2
:
name:
v2labels:
version=v2
使用以下 YAML 创建 DestinationRule:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
# 流量控制
更新名为 myapp 的 VirtualService,将 80% 的流量路由到 v1 子集,将 20% 路由到 v2 子集。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
namespace: default
spec:
gateways:
- myapp-gateway
hosts:
- myapp.example.com
http:
- match:
- uri:
prefix: /myapp
rewrite:
uri: /
route:
- destination:
port:
number: 8080
host: myapp
subset: v1
weight: 80
- destination:
port:
number: 8080
host: myapp
subset: v2
weight: 20
# 故障注入
更新故障注入以中止 50% 返回码为 HTTP 400 的请求
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
namespace: default
spec:
gateways:
- httpbin-gateway
hosts:
- httpbin.example.com
http:
- fault:
abort:
httpStatus: 400
percentage:
value: 50
match:
- uri:
prefix: /status
- uri:
prefix: /delay
- uri:
prefix: /html
route:
- destination:
host: httpbin
port:
number: 8000
# 请求超时
最后,将 virtualservice 配置更新为在 3 秒后对 httpbin 服务的所有调用超时。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
namespace: default
spec:
gateways:
- httpbin-gateway
hosts:
- httpbin.example.com
http:
- fault:
abort:
httpStatus: 400
percentage:
value: 50
timeout: 3s
match:
- uri:
prefix: /status
- uri:
prefix: /delay
- uri:
prefix: /html
route:
- destination:
host: httpbin
port:
number: 8000
# 金丝雀发布
# 【题目1】金丝雀发布-安装
由于 Kubernetes 使用的 IPVS 模块需要系统内核版本支持,试使用提供的软件包 (Canary_v1.0.tar.gz 在 http 服务下)将系统内核进行升级,在 Kubernetes 集群上完成 Istio 的安装,并将 default Namespace 设置自动注入。
$ yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm -y
$ yum --enablerepo="elrepo-kernel" -y install kernel-ml.x86_64
$ grub2-set-default 0
$ grub2-mkconfig -o /boot/grub2/grub.cfg #重启电脑
$ tar -zxvf istio-1.9.5-linux-amd64.tar.gz
$ cd istio-1.9.5/
$ cp bin/istioctl /usr/local/bin/
$ kubectl create ns istio-system
$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
$ kubectl label namespace default istio-injection=enabled
使用检测命令检查:
$ kubectl -n istio-system get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
istio-egressgateway 1/1 1 1 25s
istio-ingressgateway 1/1 1 1 24s
istiod 1/1 1 1 20s
$ kubectl get ns --show-labels=true|grep default
default Active 121m istio-injection=enabled
$ uname -r
5.12.0-1.el7.elrepo.x86_64
# 【题目2】金丝雀发布-流量控制
使用赛项提供的文件(istio-1.9.5/samples/helloworld/helloworld.yaml)在 default 命名空间 下完成 hellworld 服务的部署,然后设置路由规则来控制流量分配,创建一个虚拟服务 helloworld;再创建一个目标规则 helloworld,将 10%的流量发送到金丝雀版本(v2)。
$ kubectl apply -f samples/helloworld/helloworld.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
helloworld-v1-776f57d5f6-m5xqg 2/2 Running 0 100m
helloworld-v2-54df5f84b-mwsf6 2/2 Running 0 100m
$ cat helloworld-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- "*"
gateways:
- helloworld
http:
- match:
- uri:
exact: /hello
route:
- destination:
host: helloworld
subset: v1
weight: 90
- destination:
host: helloworld
subset: v2
weight: 10
$ cat DestinationRule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloword
spec:
host: helloword
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
使用检测命令检查
$ kubectl get VirtualService,DestinationRule
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/helloworld ["helloworld"] ["*"] 95m
NAME HOST AGE
destinationrule.networking.istio.io/helloword helloword 57m
$ kubectl describe VirtualService helloworld |grep Route -A 10 | xargs
Route: Destination: Host: helloworld Subset: v1 Weight: 90 Destination: Host: helloworld Subset: v2 Weight: 10 Events: <none>
# 【题目3】金丝雀发布-熔断
使用赛项提供的文件(istio-1.9.5/samples/httpbin/httpbin-fortio.yaml)在 default 命名空间下 完成 httpbin 服务的部署,创建一个目标规则 httpbin,在调用 httpbin 服务时应用熔断设置, 具体要求为
(1)定义到目标主机的 HTTP1/TCP 最大连接数为 1;
(2)定义针对一个目标的 HTTP 请求的最大排队数量为 1;
(3)定义对某一后端的请求中,一个连接内能够发出的最大请求数量为 1。
$ kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
service/fortio created
deployment.apps/fortio-deploy created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
fortio-deploy-576dbdfbc4-rdtrd 2/2 Running 0 2m28s
$ 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
maxRequestsPerConnection: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
EOF
destinationrule.networking.istio.io/httpbin created
使用检测命令检查
$ kubectl describe DestinationRule httpbin
···
Spec:
Host: httpbin
Traffic Policy:
Connection Pool:
Http:
http1MaxPendingRequests: 1
Max Requests Per Connection: 1
Tcp:
Max Connections: 1
Outlier Detection:
Base Ejection Time: 3m
consecutive5xxErrors: 1
Interval: 1s
Max Ejection Percent: 100
Events: <none>
# 【题目 4】金丝雀发布-流量镜像
使用赛项提供的文件(istio-1.9.5/samples/httpbin/httpbin-sleep.yaml)在 default 命名空间下 完成 httpbin-v1、httpbin-v2 以及 sleep 服务的部署,创建一个虚拟服务 httpbin 和一个目标规 则 httpbin,将所有流量路由到 httpbin-v1 服务,然后将 100%的相同流量镜像(即发送)到 httpbin-v2 服务。
这是httpbin.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v1
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"]
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v2
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v2
template:
metadata:
labels:
app: httpbin
version: v2
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"]
ports:
- containerPort: 80
---
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: sleep
spec:
replicas: 1
selector:
matchLabels:
app: sleep
template:
metadata:
labels:
app: sleep
spec:
containers:
- name: sleep
image: curlimages/curl
command: ["/bin/sleep","3650d"]
imagePullPolicy: IfNotPresent
如下是解答
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination:
host: httpbin
subset: v1
weight: 100
mirror:
host: httpbin
subset: v2
mirrorPercentage:
value: 100.0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
EOF
使用检测命令检查
$ kubectl describe virtualservice httpbin | grep Mirror -A 2
Mirror:
Host: httpbin
Subset: v2
Mirror Percentage:
Value: 100
Route:
# 【题目 5】金丝雀发布-Ingress Gateway
使用赛项提供的文件(istio-1.9.5/samples/httpbin/httpbin.yaml)在 default 命名空间下完成 httpbin 服务的部署,在 80 端口为 HTTP 流量配置一个网关 httpbin-gateway,并为 httpbin 服 务创建了虚拟服务配置 httpbin,包含 1 个路由规则,允许流量流向路径/headers,并允许通 过浏览器访问服务。
$ kubectl apply -f samples/httpbin/httpbin.yaml
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway #使用Istio的默认网关
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /headers
route:
- destination:
port:
number: 8000
host: httpbin
EOF
使用检测命令检查
$ kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
httpbin ["httpbin-gateway"] ["*"] 6m51s
$ kubectl describe virtualservice httpbin
···
Spec:
Gateways:
httpbin-gateway
Hosts:
*
Http:
Match:
Uri:
Prefix: /headers
Route:
Destination:
Host: httpbin
Port:
Number: 8000
Events: <none>
$ curl -s -I -HHost:httpbin.example.com "http://node:$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')/headers"
HTTP/1.1 200 OK
server: istio-envoy
date: Thu, 16 Dec 2021 05:32:00 GMT
content-type: application/json
content-length: 627
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 23