K8S中服务暴露的方式有多种,包括Nodeport、Loadbalancer、Ingress等,其中Ingress就是从kubernetes集群外访问集群的入口,将用户的URL请求转发到不同的service上。

Ingress相当于nginx、apache等负载均衡反向代理服务器,其中还包括规则定义,即URL的路由信息,路由信息的刷新由Ingress controller来提供。

Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用。

Ingress Controller 有多种实现,有ingress-nginx、Kong Ingress Controller、traefik 等,本文章主要介绍traefik ingress的实现。

提前规划

  • traefik分业务网关和内部使用网关,分别为traefik-business和traefik-internal;
  • 使用阿里云的SLB,通过LoadBalancer方式部署service;
  • SLB使用私网地址类型,绑定EIP;
  • traefik部署到带标签ingress.k8s.icjl/internal的node上;
  • ingress通过标签匹配需要的网关是business还是internal;
  • traefik安装到traefik的namespace下;
  • dashboard使用internal网关,只允许内部访问,使用auth.basic方式认证;

helm安装部署traefik

Helm charts:https://github.com/helm/charts/tree/master/stable/traefik

阿里云:

使用阿里云的LoadBalancer方式,先创建阿里云的SLB,然后记住SLB的ID,推荐使用内网SLB绑定移动EIP的方式,配置charts的value文件,traefik-internal.yaml

image: traefik
imageTag: 1.7.12
serviceType: LoadBalancer
nodeSelector:
  ingress.k8s.icjl/internal: ''
kubernetes:
  labelSelector: ingress.k8s.icjl/internal=assigned
ssl:
  enabled: true
  enforced: false
  permanentRedirect: false
  insecureSkipVerify: true
service:
  annotations:
    service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet
    service.beta.kubernetes.io/alicloud-loadbalancer-id: 'xxxxxxxxxx'
dashboard:
  enabled: true
  domain: traefik-internal.changjinglu.net
  serviceType: ClusterIP
  auth:
    basic:
      root: 'xxxxxx'
  ingress:
    labels:
      ingress.k8s.icjl/internal: assigned
    annotations:
      kubernetes.io/ingress.class: "traefik"
rbac:
  enabled: true

serviceType: LoadBalancer #使用阿里云的SLB labelSelector: ingress.k8s.icjl/internal=assigned #traefik的标签选择,ingress只有带这个标签的才会起作用 service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet #使用内网SLB service.beta.kubernetes.io/alicloud-loadbalancer-id: ‘xxxxxxxxxx’ #SLB的ID

通过Helm安装,命令如下:

helm install stable/traefik -n traefik-internal --namespace traefik -f traefik-internal.yaml
自建K8S

如果是线下的K8S,没有LoadBalancer的方式,可以采用hostNetwork的方式。

这是一种直接定义Pod网络的方式,如果在POD中使用hostNetwork:true配置网络,pod中运行的应用程序可以直接看到宿主主机的网络接口,宿主主机所在的局域网上所有网络接口都可以访问到该应用程序。

因为现在官方的charts还不支持此参数,我们可以在安装好之后,修改Deployment参数,添加hostNetwork:true来解决;

ingress yaml文件示例

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  labels:
    name: test-ingress
    ingress.k8s.icjl/internal: assigned
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  rules:
  - host: test.hiningmeng.cn
    http:
      paths:
      - path: /
        backend:
          serviceName: test-config
          servicePort: http

需要指定ingress:kubernetes.io/ingress.class: “traefik” 需要labels:ingress.k8s.icjl/internal: assigned