Istio 基础概念学习整理

Istio 基础概念学习整理

流量管理

为了在网格中导流,Istio 需要知道所有的 endpoint 在哪以及它们属于哪些服务。 为了定位到 service registry(服务注册中心), Istio 会连接到一个服务发现系统(Istio不提供服务发现系统)。例如,如果您在 Kubernetes 集群上安装了 Istio, 那么它将自动检测该集群中的服务和 endpoint。

虚拟服务(Virtual Service)目标规则(Destination Rule) 是 Istio 流量路由功能的核心构建模块。每个虚拟服务包含一组按顺序评估的路由规则,通过这些规则,Istio 将每个到虚拟服务的给定请求匹配到特定的、真实的目标地址。

使用 Istio实现金丝雀发布

Kubernetes中使用istio流量路由和副本部署是两个完全独立的功能,可以轻松实现细粒度控制流量百分比(例如路由 1% 的流量而不需要 100 个 Pod)。

定义svc,Istio是基于svc来实现服务注册的

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
  app: helloworld
spec:
  selector:
    app: helloworld
  ...

添加 2 个 Deployment,包含相同的标签app=helloworld,版本分别为 v1v2

yaml 复制代码
kind: Deployment
metadata:
  name: helloworld-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
        version: v1
    spec:
      containers:
      - image: helloworld-v1
        ...
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: helloworld-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
        version: v2
    spec:
      containers:
      - image: helloworld-v2
        ...

使用普通 Kubernetes 进行金丝雀部署需要调整每个 Deployment 的副本数目。例如,将 10% 的流量发送到金丝雀版本(v2),v1 和 v2 的副本可以分别设置为 9 和 1。

使用istio我们可以通过设置路由规则来控制流量分配:

yaml 复制代码
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
    - helloworld
  http:
  - route:
    - destination:
        host: helloworld
        subset: v1
        weight: 90 # 90%的流量给v1
    - destination:
        host: helloworld
        subset: v2
        weight: 10
    timeout: 10s # 默认15秒
    retries:
      attempts: 3 # 默认重试2次
      perTryTimeout: 2s # 每次重试都有 2 秒的超时
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: helloworld
spec:
  host: helloworld
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
EOF

我们基于流量来控制后,我们就可以放心的使用hpa了

shell 复制代码
$ kubectl autoscale deployment helloworld-v1 --cpu-percent=50 --min=1 --max=10
$ kubectl autoscale deployment helloworld-v2 --cpu-percent=50 --min=1 --max=10

我们还可以通过匹配headers来实现将特定用户的流量引入到金丝雀版本中

yaml 复制代码
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
    - helloworld
  http:
  - match:
    - headers:
        cookie:
          regex: "^(.*?;)?(email=[^;]*@some-company-name.com)(;.*)?$"
    route:
    - destination:
        host: helloworld
        subset: v1
        weight: 50
    - destination:
        host: helloworld
        subset: v2
        weight: 50
  - route:
    - destination:
        host: helloworld
        subset: v1
EOF

Istio网关

Istio 的网关资源可以来管理网格的入站和出站流量,可以配置 4-6 层的负载均衡属性,如对外暴露的端口、TLS 设置等。网关主要用于管理进入的流量。

示例:让 HTTPS 流量从 ext-host.example.com 通过 443 端口流入网格

yaml 复制代码
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    app: my-gateway-controller
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE
      credentialName: ext-host-cert
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtual-svc
spec:
  hosts:
  - ext-host.example.com
  gateways:
    - ext-host-gwy

服务入口

配置服务入口允许您管理运行在网格外的服务的流量

示例:添加一个外部dns到服务中心

yaml 复制代码
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: svc-entry
spec:
  hosts:
  - ext-svc.example.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS
---
# 接下来就可以把其添加为DestinationRule了
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ext-res-dr
spec:
  host: ext-svc.example.com
  trafficPolicy:
    connectionPool:
      tcp:
        connectTimeout: 1s

Sidecar

默认情况下,Istio 让每个 Envoy 代理都可以访问来自和它关联的工作负载的所有端口的请求,在大集群中会因此占用大量内存,所以sidecar支持特定namespace的访问

yaml 复制代码
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - "./*" # 当前ns的服务
    - "istio-system/*" # istio-system ns下的服务

故障注入

故障注入是一种将错误引入系统以确保系统能够承受并从错误条件中恢复的测试方法。

示例:千分之一的访问 5 秒延迟

yaml 复制代码
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percentage:
          value: 0.1
        fixedDelay: 5s
    route:
    - destination:
        host: ratings
        subset: v1

Kubernetes Gateway API

Kubernetes Gateway API负责南北流量,集群对外访问的流量。Istio关注的是服务之间的流量,包括集群内的东西向流量和南北向流量。

与 Ingress 不同,Kubernetes Gateway 不包含对目标服务的任何引用。使用 Gateway API 后,服务路由被定义在单独的配置资源中, 这些配置资源会附加到 Gateway 中,用于将流量子集定向到特定服务,例如我们示例中的 helloworld。这种分离允许我们在不同的命名空间中定义 Gateway 和路由, 并可以由不同的团队进行管理。

定义helloworld测试服务

shell 复制代码
$ kubectl create ns sample
$ kubectl apply -f samples/helloworld/helloworld.yaml -n sample

定义网关资源

shell 复制代码
$ kubectl create namespace sample-ingress
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: sample-gateway
  namespace: sample-ingress
spec:
  gatewayClassName: istio # 名为 istio 的gw
  listeners:
  - name: http
    hostname: "*.sample.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All # 所有ns
EOF

上面我们作为集群管理人员,在 sample-ingress 命名空间中应用了 Gateway,因为 Gateway 资源的所有权归于集群操作员,它可以很好地用于为多个团队的服务提供入口。

接下来,我们将代表开发人员为 sample-ingress/sample-gateway 添加路由。

shell 复制代码
kubectl apply -n sample -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: helloworld
spec:
  parentRefs: # 将 HTTPRoute 附加到 sample-gateway
  - name: sample-gateway
    namespace: sample-ingress
  hostnames: ["helloworld.sample.com"] # 子域名
  rules:
  - matches:
    - path:
        type: Exact
        value: /hello # 路径
    backendRefs:
    - name: helloworld # svc/helloworld
      port: 5000
EOF

基于权重的路由选择,创建v1、v2的svc

shell 复制代码
$ kubectl apply -n sample -f samples/helloworld/gateway-api/helloworld-versions.yaml

将流量 90% 转到 v1,10% 到 v2

shell 复制代码
$ kubectl apply -n sample -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: helloworld
spec:
  parentRefs:
  - name: sample-gateway
    namespace: sample-ingress
  hostnames: ["helloworld.sample.com"]
  rules:
  - matches:
    - path:
        type: Exact
        value: /hello
    backendRefs:
    - name: helloworld-v1
      port: 5000
      weight: 90
    - name: helloworld-v2
      port: 5000
      weight: 10
EOF
相关推荐
昌sit!6 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis9 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
北漂IT民工_程序员_ZG10 小时前
k8s集群安装(minikube)
云原生·容器·kubernetes
2301_8061313616 小时前
Kubernetes的基本构建块和最小可调度单元pod-0
云原生·容器·kubernetes
SilentCodeY17 小时前
containerd配置私有仓库registry
容器·kubernetes·containerd·镜像·crictl
binqian1 天前
【k8s】ClusterIP能http访问,但是不能ping 的原因
http·容器·kubernetes
探索云原生1 天前
GPU 环境搭建指南:如何在裸机、Docker、K8s 等环境中使用 GPU
ai·云原生·kubernetes·go·gpu
是垚不是土1 天前
Istio流量镜像测试
运维·kubernetes·云计算·istio
蚊子不吸吸1 天前
DevOps开发运维简述
linux·运维·ci/cd·oracle·kubernetes·gitlab·devops
林小果11 天前
K8S搭建
云原生·容器·kubernetes