traefik ingress反向代理部署

Traefik介绍

Traefik是一个现代HTTP反向代理和负载均衡器,可以轻松部署微服务。Traefik与您现有的基础架构组件(Docker,Swarm模式,Kubernetes,Marathon,Consul,Etcd,Rancher,Amazon ECS ……)集成,并自动和动态地配置自身。在您的协调器上指向Traefik应该是您需要的唯一配置步骤。同 nginx 等相比,traefik 能够自动感知后端容器变化,从而实现自动服务发现。

 

Kubernetes 服务暴露介绍

从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务;到目前为止 kubernetes 总共有三种暴露服务的方式:

  • LoadBlancer Service
  • NodePort Service
  • Ingress

 

LoadBlancer Service

LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务;目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用

 

NodePort Service

NodePort Service 顾名思义,实质上就是通过在集群的每个 node 上暴露一个端口,然后将这个端口映射到某个具体的 service 来实现的,虽然每个 node 的端口有很多(0~65535),但是由于安全性和易用性(服务多了就乱了,还有端口冲突问题)实际使用可能并不多

 

Ingress

Ingress 这个东西是 1.2 后才出现的,通过 Ingress 用户可以实现使用 nginx 等开源的反向代理负载均衡器实现对外暴露服务,以下详细说一下 Ingress,毕竟 traefik 用的就是 Ingress

使用 Ingress 时一般会有三个组件:

  • 反向代理负载均衡器
  • Ingress Controller
  • Ingress

 

功能

  • 不断更新其配置(无重启!)
  • 支持多种负载均衡算法
  • 利用Let’s Encrypt(通配符证书支持)为您的微服务提供HTTPS
  • 断路器,重试
  • Websocket,HTTP / 2,GRPC
  • 提供指标(Rest,Prometheus,Datadog,Statsd,InfluxDB)
  • Keeps access logs (JSON, CLF)
  • Exposes a Rest API

 

原理

虽然k8s集群内部署的podserver都有自己的IP,但是却无法提供外网访问,以前我们可以通过监听NodePort的方式暴露服务,但是这种方式并不灵活,生产环境也不建议使用。Ingresssk8s集群中的一个API资源对象,扮演边缘路由器(edge router)的角色,也可以理解为集群防火墙集群网关,我们可以自定义路由规则来转发、管理、暴露服务(一组pod),非常灵活,生产环境建议使用这种方式。另外LoadBlancer也可以暴露服务,不过这种方式需要向云平台申请负载均衡器。

 

特性配置

traefik支持强大的annotations配置,需要添加到kubernetes相应资源对象的annotations下面。至于具体配置到的哪个对象,先弄清楚三个概念:

  • EntryPoint(入口点)
    顾名思义,这是外部网络进入traefik的入口,我们上面就是通过监听主机端口拦截请求。
  • FrontEnd(前端)
    traefik拦截请求后,会转发给FrontEnd。前端定义EntryPoint映射到BackEnd的路由规则集,字段包括HostPathHeaders等,匹配请求后,默认通过加权轮询负载算法路由到一个可用的BackEnd,然后进入指定的微服务,这就是服务发现。

    备注:这些路由规则可以来自不同的后端存储,如Kubernetes、zookeeper、eureka、consul等,Kubernetes使用的Ingress资源对象定义路由规则集。建议大家自行去官网学习Kubernetes Ingress Backend

  • BackEnd(后端)
    一组http服务集,kubernetes中对应一个service对象下的一组pod地址。对于后端的服务发现,可配置负载均衡策略熔断器等特性。

 

 

 

部署Traefik

首先以 DaemonSet 的方式在每个 node 上启动一个 traefik,并使用 hostPort 的方式让其监听每个 node 的 80 、443端口

mkdir $HOME/traefik ; cd $HOME/traefik

vi Traefik-DaemonSet.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      hostNetwork: true
      restartPolicy: Always
      volumes:
       - name: ssl
         secret:
          secretName: traefik-cert
       - name: config
         configMap:
          name: traefik-conf
      containers:
      - image: traefik
        name: traefik-ingress-lb
        volumeMounts:
        - mountPath: "/ssl"
          name: "ssl"
        - mountPath: "/config"
          name: "config"
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: https
          containerPort: 443
          hostPort: 443
        - name: public1
          containerPort: 8888
          hostPort: 8888
        - name: public2
          containerPort: 9999
          hostPort: 9999
        - name: admin
          containerPort: 8080
          hostPort: 8080
        #securityContext:
        #  capabilities:
        #    drop:
        #    - ALL
        #    add:
        #    - NET_BIND_SERVICE
        args:
        - --configfile=/config/traefik.toml
        - --web
        - --web.address=:8080
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 443
      name: https
    - protocol: TCP
      port: 8080
      name: admin
    - protocol: TCP
      port: 8888
      name: public1
    - protocol: TCP
      port: 9999
      name: public2

创建rbac文件

vi traefik-rbac.yaml

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  name: traefik-ingress-controller
  namespace: kube-system

导入域名证书到集群的secret中
kubectl create secret tls traefik-cert --cert=1537424366118.pem --key=1537424366118.key

 

创建traefik.toml配置文件

vi traefik.toml
insecureSkipVerify = true
defaultEntryPoints = ["http","https"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    regex = "^http://kubernetes.srv-slb.flybycs.com/(.*)"
    replacement = "https://kubernetes.srv-slb.flybycs.com/$1"


  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
    minVersion = "VersionTLS12"
    cipherSuites = [
      "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
      "TLS_RSA_WITH_AES_256_GCM_SHA384"
    ]


      [[entryPoints.https.tls.certificates]]
      CertFile = "/ssl/kubernetes.srv-slb.flybycs.com.pem"
      KeyFile = "/ssl/kubernetes.srv-slb.flybycs.com.key"

以configmap方式创建配置文件

kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system

 

启动Traefik-DaemonSet.yaml

kubectl apply -f  Traefik-DaemonSet.yaml
serviceaccount/traefik-ingress-controller changed
daemonset.extensions/traefik-ingress-controller changed
service/traefik-ingress-service changed

 

[root@feiba-k8s-master1-192-168-1-16 traefik]# kubectl  get pod,svc -n kube-system  -o wide
NAME                                       READY     STATUS    RESTARTS   AGE       IP           NODE           NOMINATED NODE
pod/coredns-5579c78574-dgrsp               1/1       Running   1          2d        10.96.32.2   192.168.1.17   
pod/coredns-5579c78574-ss4xb               1/1       Running   1          2d        10.96.66.4   192.168.1.18   
pod/coredns-5579c78574-v4bw9               1/1       Running   0          2d        10.96.66.8   192.168.1.18   
pod/kubernetes-dashboard-d6cc8d98f-ngbls   1/1       Running   1          2d        10.96.66.2   192.168.1.18   
pod/traefik-ingress-controller-8d4vz       1/1       Running   1          2d        10.96.66.6   192.168.1.18   
pod/traefik-ingress-controller-8twpd       1/1       Running   1          2d        10.96.20.4   192.168.1.19   
pod/traefik-ingress-controller-vs5nf       1/1       Running   1          2d        10.96.32.5   192.168.1.17   

NAME                              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                     AGE       SELECTOR
service/kube-dns                  ClusterIP   10.96.0.114            53/UDP,53/TCP                               2d        k8s-app=kube-dns
service/kubelet                   ClusterIP   None                   10250/TCP                                   5d        
service/kubernetes-dashboard      NodePort    10.96.44.102           443:31072/TCP                               2d        k8s-app=kubernetes-dashboard
service/traefik-ingress-service   ClusterIP   10.96.76.48            80/TCP,443/TCP,8080/TCP,8888/TCP,9999/TCP   2d        k8s-app=traefik-ingress-lb
service/traefik-web-ui            ClusterIP   10.96.17.109           80/TCP                                      2d        k8s-app=traefik-ingress-lb

其中 traefik 监听 node 的 80 和 443 端口,80 提供正常服务,8080 是其自带的 UI 界面

vi  traefik-web-ui.yaml   #为traefik创建ingress代理
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - name: web
    port: 80
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  rules:
  - host: traefik.srv-slb.flybycs.com
    http:
      paths:
      - path: /
        backend:
          serviceName: traefik-web-ui
          servicePort: web

#~  kubectl  create  -f  traefik-web-ui.yaml

 

测试ingress-nginx是否安装成功

将域名解析到任意node节点即可。 生产环境建议将traefik部署到kubernetes边缘节点, 并使用keepalived保证业务高可用。

 

 

 

部署kubernetes dashboard样例:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dashboard
  namespace: kube-system
  annotations:
    #ingress.kubernetes.io/ssl-passthrough: "true"
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: kubernetes.srv-slb.ziji.work
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
  #tls:
   #- secretName: ziji-ui-tls-cert

kubectl apply -f kubernetes.srv-slb.ziji.work.yaml

注意: 如不使用生成默认证书, 需要手动创建、 并打开tls: – secretName参数选项

创建证书, 多个证书后面请使用–from-file指定文件路径
kubectl create secret generic ziji-ui-tls-cert --from-file=kubernetes.srv-slb.ziji.work.pem --from-file=kubernetes.srv-slb.ziji.work.key -n kube-system

 

延伸阅读

https://docs.traefik.io/

https://docs.traefik.io/configuration/entrypoints/

https://docs.traefik.io/user-guide/kubernetes/#disable-per-ingress

发表评论