能否使用应用程序网关在 AKS 中同时公开 HTTP 端口和 TCP 端口?

Can you have both a HTTP port and a TCP port exposed in AKS using Application Gateway?

设置:

我们在 Azure 中有 kubernetes 集群,它使用应用程序网关来管理网络流量。我们在 Load Balancer 上使用 appgw,因为我们需要处理第 7 层的流量,因此需要基于路径的 http 规则。我们使用 kubernetes 入口控制器来配置 appgw。请参阅下面的配置。

现在我想要一个既接受 HTTP(第 7 层)请求又接受 TCP(第 4 层)请求的服务。

我该怎么做?暴露的端口在big internet上不应该是public,而在azure network上应该是public。我是否需要添加另一个未配置为使用 appgw 的入口控制器?

这就是我想要完成的:

这是使用 appgw 的入口控制器的配置:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: service1
  labels:
    app: service1
  annotations:
    appgw.ingress.kubernetes.io/backend-path-prefix: /
    appgw.ingress.kubernetes.io/use-private-ip: "false"
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  tls:
    - hosts:
      secretName: <somesecret>
  rules:
    - host: <somehost>
      http:
        paths:
          - path: /service1/*
            backend:
              serviceName: service1
              servicePort: http

当前设置:

The exposed port should not be public, but public in the kubernetes cluster.

我假设您的意思是您的应用程序应该为 Kubernetes 集群中的客户端公开一个端口。您无需在 Kubernetes 中为 Pods 做任何特殊操作,它们可以接受到任何端口的 TCP 连接。但是你可能想为此创建一个 Servicetype: ClusterIP,这样对客户来说会更容易。

仅此而已。

利用 Kubernetes 服务应该可以解决您的问题,您只需修改 YAML 文件即可。

利用 Kubernetes Service 应该可以解决您的问题,您只需修改 YAML 文件即可。

这是我创建服务的示例片段

api版本:v1 种类:服务 元数据: 名称:cafe-app-service 标签: 应用:cafe-app-service 规格: 端口:

  • 端口:80 协议:HTTP 目标端口:8080 名称:咖啡港
  • 端口:8081 协议:TCP 目标端口:8081 名称:茶港 选择器: 应用程序:咖啡馆应用程序

您可以在您创建的入口中引用您的服务

通常您有两个直接的选择。


使用直接 pod IP 或 Headless ClusterIP 服务。

我假设您的 AKS 集群使用 Azure CNI 或 Calico 作为网络结构。
在这两种情况下,您的 Pods 在 AKS 子网.
中获得可路由的 ip https://docs.microsoft.com/en-us/azure/aks/concepts-network#azure-cni-advanced-networking
因此,您可以直接通过 VNet 访问它们。


或者,您可以使用内部负载均衡器类型的服务。
您可以通过适当的注释构建内部 LB。

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
spec:
  type: LoadBalancer

当您查看服务详细信息时,内部负载平衡器的 IP 地址显示在 EXTERNAL-IP 列中。在此上下文中,外部与负载均衡器的外部接口有关,而不是它接收 public、外部 IP 地址。
https://docs.microsoft.com/en-us/azure/aks/internal-lb#create-an-internal-load-balancer

如果需要,您可以为 LB 分配预定义的 IP 地址和/或将其放入 VNet 中的不同子网,甚至放入私有子网,使用 VNet 对等互连等。
最终你可以让它从你需要的任何地方路由。

我为同一个 pod 使用了两个服务;一种用于 Ingress (appgw) 处理的 HTTP,另一种用于使用内部 Azure 负载均衡器的 TCP。

这是我最终使用的配置:

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-serviceA-cm
  namespace: default
data:
  8200: "default/serviceA:8200"

TCP 服务

apiVersion: v1
kind: Service
metadata:
  name: tcp-serviceA
  namespace: default
  labels:
    app.kubernetes.io/name: serviceA
    app.kubernetes.io/part-of: serviceA
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    service.beta.kubernetes.io/azure-load-balancer-internal-subnet: subnetA
spec:
  type: LoadBalancer
  ports:
    - name: tcp
      port: 8200
      targetPort: 8200
      protocol: TCP
  selector:
    app: serviceA
    release: serviceA

HTTP 入口

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: serviceA
  labels:
    app: serviceA
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  tls:
    - hosts:
      secretName: <somesecret>
  rules:
    - host: <somehost>
      http:
        paths:
          - path: /serviceA/*
            backend:
              serviceName: serviceA
              servicePort: http

部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: serviceA
  labels:
    app: serviceA
    release: serviceA
spec:
  replicas: 1
  selector:
    matchLabels:
      app: serviceA
      release: serviceA
  template:
    metadata:
      labels:
        app: serviceA
        release: serviceA
    spec:
      containers:
        - name: serviceA
          image: "serviceA:latest"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

HTTP 服务

apiVersion: v1
kind: Service
metadata:
  name: serviceA
  labels:
    app: serviceA
    release: serviceA
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: serviceA
    release: serviceA