【问题标题】:Why my canary deployment does not work with istio?为什么我的金丝雀部署不适用于 istio?
【发布时间】:2021-05-21 17:38:33
【问题描述】:

我正在尝试学习有关 istio 的基础知识,因此我阅读了官方文档 here 以创建 80/20 的金丝雀部署,我还遵循了 digitalocean 的这个指南,它解释了它非常简单部署https://www.digitalocean.com/community/tutorials/how-to-do-canary-deployments-with-istio-and-kubernetes

我在主页上创建了一个包含 2 条不同消息的简单应用程序,然后创建了 virtualService、Gateway 和目标规则。我(如指南中所述)使用kubectl -n istio-system get svc 获取外部IP,并尝试导航到该地址,但出现503 错误。这看起来很简单,但我必须遗漏一些东西。这些是我的 3 个文件(据我所知,没有更多必要的文件):

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  namespace: istio
  name: flask-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - "*"
    port:
      name: http
      number: 80
      protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: flask-app
  namespace: istio
spec:
  hosts:
  - "*"
  gateways:
  - flask-gateway
  http:
  - route:
    - destination:
        host: flask-app
        subset: v1
      weight: 80
    - destination:
        host: flask-app
        subset: v2
      weight: 20
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: flask-app
  namespace: istio
spec:
  host: flask-app
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

这里是带有 v1 和 v2 部署和服务的 yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    version: v1
  name: flask-deployment-v1
  namespace: istio
spec:
  replicas: 1
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        version: v1
        app: flask-app
    spec:
      containers:
      - name: flask-app
        image: latalavera/flask-app:1.3
        ports:
          - containerPort: 5000
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi

---
apiVersion: v1
kind: Service
metadata:
  name: flask-service
  namespace: istio
spec:
  selector:
    app: flask-app
  ports:
  - port: 5000
    protocol: TCP
    targetPort: 5000
  type: ClusterIP


apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    version: v2
  name: flask-deployment-v2
  namespace: istio
spec:
  replicas: 1
  selector:
    matchLabels:
      app: flask-app
  template:
    metadata:
      labels:
        app: flask-app
        version: v2
    spec:
      containers:
      - name: flask-app
        image: latalavera/flask-app:2.0
        ports:
          - containerPort: 5000
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi

---
apiVersion: v1
kind: Service
metadata:
  name: flask-service2
  namespace: istio
spec:
  selector:
    app: flask-app
  ports:
  - port: 5000
    protocol: TCP
    targetPort: 5000
  type: ClusterIP

我已将标签 version: v1 version: v2 添加到我的部署中,并且我还使用了 kubectl label ns istio istio-injection=enabled 命令,但它们无论如何都不起作用

【问题讨论】:

  • 您的flask-app 是否部署在istio-system 命名空间中?
  • 它部署在我创建的 istio 命名空间中,我认为 kubectl label ns istio istio-injection=enabled 使资源在其他命名空间中可用
  • 我刚刚尝试在 ns istio-system 中部署所有内容,但我一直收到 503...根据 guid,我只需要从 istio-ingressgateway 复制粘贴外部 ip,我通过了kubectl -n istio-system get svc 命令权
  • 不抱歉,问题是它是否部署在那里。我不应该在 istio-system ns 中运行。你能添加清单以进行部署和服务吗
  • @ChristophRaab 我已经更新了它。感谢您的帮助!

标签: docker kubernetes istio


【解决方案1】:

您将服务命名为flask-service,并将VirtualService 中的host 设置为flask-app

host 字段不是选择器,而是您要将流量路由到的服务的FQDN。所以应该叫flask-service或者更好的flask-service.istio.svc.cluster.local

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: flask-app
  namespace: istio
spec:
  hosts:
  - "*"
  gateways:
  - flask-gateway
  http:
  - route:
    - destination:
        host: flask-service.istio.svc.cluster.local
        subset: v1
      weight: 80
    - destination:
        host: flask-service.istio.svc.cluster.local
        subset: v2
      weight: 20

或者,您也可以像 Deployment 一样调用服务 flask-app。但是在任何情况下都建议使用完整的FQDN<service-name>.<namespace-name>.svc.cluster.local。来自文档:

Kubernetes 用户注意事项:当使用短名称时(例如“reviews”而不是“reviews.default.svc.cluster.local”),Istio 将根据规则的命名空间而不是服务来解释短名称.包含主机“reviews”的“default”命名空间中的规则将被解释为“reviews.default.svc.cluster.local”,而与与评论服务关联的实际命名空间无关。为避免潜在的错误配置,建议始终使用完全限定域名而不是短名称。

https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService -> 主机

顺便说一句,您不需要 2 项服务,只需要一项。您的服务有一个 selector 代表 app: flask-app,因此它可以将流量路由到 v1 和 v2。流量的路由方式由VirtualServiceDestionationRule 定义。我建议删除服务flask-service2。如果您需要在网格内部路由流量,请将mesh 添加为gatewaysVirtualService 中或为网格内部流量创建一个新的,以达到两个版本。有关该主题的更多信息:

https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService -> 网关

【讨论】:

  • 非常感谢你提到的我已经改变的解释,但我仍然收到 503 错误。我只需要从service/istio-ingressgateway 复制粘贴外部IP 地址,它应该可以正常工作吗?这就是digitalocean指南中的做法
  • 对 istio-ingressgateway 执行 ping 操作,但尝试在浏览器中访问时得到 503
  • 您是在数字海洋或其他云提供商上运行,还是在本地或类似 minikube 上运行?您是否尝试过在没有 istio 的情况下访问工作负载?将其部署在不同的命名空间中并将服务的类型设置为 LoadBalancer。该服务获得一个可以使用的外部 ip。如果可行,我建议设置 prometheus/kiali 以进一步调查。肯定有什么地方出了点问题,因为现在设置似乎是正确的。
  • 我在 GCP 中使用了一个集群,我已经使用了带有 helm 图表的应用程序以及带有 nginx 入口控制器的 k8s(没有 istio),并且两者都工作正常。不幸的是,正如我所说,我正在学习 k8s 和 istio(我已经练习了 2-3 周)并且我不知道如何使用 prometheus 或 kiali
  • 运行kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yamlhelm install --namespace istio-system --set auth.strategy="anonymous" --repo https://kiali.org/helm-charts kiali-server kiali-server安装基本设置,设置成功后,您可以通过istioctl dashboard kiali代理到kilai并在浏览器中打开显示的链接。检查所有部分是否有警告和错误。
猜你喜欢
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
相关资源
最近更新 更多