跳转至

准备工作 安装istio 对istio这个namespace自动注入 内部访问 1.创建两个deploy 分别让他们指向 c1 和 c2 2. 定义一个svc让能负载到这两个deploy 3.定义一...

准备工作

安装istio

# curl -L https://istio.io/downloadIstio | sh -
# cd istio-1.*
# export PATH=$PWD/bin:$PATH
安装istio基础组件
# istioctl install --set profile=demo -y
验证是否成功
# kubectl get pods -n istio-system

对istio这个namespace自动注入

# kubectl label namespace default istio-injection=enabled

内部访问

1.创建两个deploy 分别让他们指向 c1 和 c2

# cat 01.deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apps-v1
  namespace: istio
spec:
  replicas: 1
  selector:
    matchLabels:
      app: istio
      version: v1
  template:
    metadata:
      labels:
        app: istio
        version: v1
    spec:
      containers:
      - name: c1
        ports:
        - containerPort: 80
        image: 192.168.85.128/nb/nginx:latest 
        command: ["/bin/sh", "-c", "echo 'c1' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"]

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apps-v2
  namespace: istio
spec:
  replicas: 1
  selector:
    matchLabels:
      app: istio
      version: v2
  template:
    metadata:
      labels:
        app: istio
        version: v2
    spec:
      containers:
      - name: c2
        ports:
        - containerPort: 80
        image: 192.168.85.128/nb/nginx:latest 
        command: ["/bin/sh", "-c", "echo 'c2' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"]

2. 定义一个svc让能负载到这两个deploy

# cat 02.svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: apps-svc-all
  namespace: istio
spec:
  selector:
    #关联两个版本
    app: istio 
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    name: http

3.定义一个组

# cat 03.rule.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: rule
  namespace: istio
spec:
  host: apps-svc-all   #匹配svc的name
  subsets:
  - name: v1
    labels:
      version: v1     #匹配deploy下面的pod的标签 分成v1,v2两个组
  - name: v2
    labels:
      version: v2

4.给两个实例分权重

# cat 04.vs.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vs
  namespace: istio
spec:
  hosts:
  - apps-svc-all   #匹配svc的名字
  http:
  - route:
    - destination:
        host: apps-svc-all
        subset: v1
      weight: 90
    - destination:
        host: apps-svc-all
        subset: v2
      weight: 10

5.测试

# kubectl exec -it apps-v1-86d85445dc-hgzpm -n istio  -- bash
# while true;do curl apps-svc-all >>a.txt;sleep 0.1s;done
# cat a.txt|sort|uniq -c
     55 c1
      5 c2

6.请求头划分权限 带istio的都请求v1

#cat 05.vs.yaml 
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vs2
  namespace: istio 
spec:
  hosts:
  - apps-svc-all
  http:
    # 定义匹配规则
  - match:
      # 基于header信息匹配将其进行路由,header信息自定义即可。
    - headers:
        # 匹配用户名包含"istio"的用户,这个KEY是咱们自定义的。
        username:
          # "eaxct"关键词是包含,也可以使用"prefix"进行前缀匹配。
          exact: istio 
    route:
    - destination:
        host: apps-svc-all
        subset: v1
  - route: 
    - destination:
        host: apps-svc-all
        subset: v2

外部访问

通过访问网关

kubectl -n istio-system get svc --show-labels|grep ingress
istio-ingressgateway   NodePort    10.107.199.69    <none>        15021:31838/TCP,80:32590/TCP,443:32047/TCP,31400:30896/TCP,15443:31643/TCP   12d   
istio=ingressgateway
-------------------------------------------------------------
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: my-gateway
  namespace: istio
spec:
  selector:
    istio: ingressgateway #匹配上面标签
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "tian.com"    #只允许头是tian.com的 可以写*代表所有

vs

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vs
  namespace: istio
spec:
  hosts:
  - "tian.com" #只接收这个的流量
  gateways:
  - my-gateway #匹配gw的名字
  http:
  - route:
    - destination:
        host: apps-svc-all
        subset: v1
      weight: 90
    - destination:
        host: apps-svc-all
        subset: v2
      weight: 10

在 Istio 中,VirtualService.spec.hosts 指的是接收到的 HTTP 请求中的 Host 头(即域名)。

  • 如果你写了 "*",理论上是匹配所有 Host,但在 Ingress Gateway 上,它通常不会匹配任意 Host,因为 Envoy 比较严格

dr

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: rule
  namespace: istio
spec:
  host: apps-svc-all   #匹配svc的name
  trafficPolicy:       #禁用tls
   tls:
    mode: DISABLE
  subsets:
  - name: v1
    labels:
      version: v1     #匹配deploy下面的pod的标签 分成v1,v2两个组
  - name: v2
    labels:
      version: v2

测试

#kubectl -n istio-system get svc |grep ingress
istio-ingressgateway   NodePort    10.107.199.69    <none>        15021:31838/TCP,80:32590/TCP,443:32047/TCP,31400:30896/TCP,15443:31643/TCP   12d
#curl -H "Host: tian.com" 10.107.199.69 
c1 - v1
# curl -H "Host: tian.com" 10.107.199.69 
c1 - v2

可视化kiali

# cd istio-1.25.2
# kubectl apply -f samples/addons
# kubectl apply -f samples/addons/extras

配置Kiali控制面板对外访问

查看kiali服务,发现其类型为ClusterIP,没有对外暴露端口,无法从外部访问:将类型改NodePort

# kubectl -n istio-system get svc
kiali                  NodePort       10.99.64.99      <none>        20001:30021/TCP,9090:30830/TCP   

访问ip:30021即可