美文网首页
Kubernetes 服务发布之traefik ingress

Kubernetes 服务发布之traefik ingress

作者: JaeGwen | 来源:发表于2018-11-01 14:57 被阅读183次

    介绍

    Ingress其实就是从 kuberenets 集群外部访问集群的一个入口,将外部的请求转发到集群内不同的 Service 上,其实就相当于 nginx、haproxy 等负载均衡代理服务器,有的同学可能觉得我们直接使用 nginx 就实现了,但是只使用 nginx 这种方式有很大缺陷,每次有新服务加入的时候怎么改 Nginx 配置?不可能让我们去手动更改或者滚动更新前端的 Nginx Pod 吧?那我们再加上一个服务发现的工具比如 consul 如何?貌似是可以,对吧?而且在之前单独使用 docker 的时候,这种方式已经使用得很普遍了,Ingress 实际上就是这样实现的,只是服务发现的功能自己实现了,不需要使用第三方的服务了,然后再加上一个域名规则定义,路由信息的刷新需要一个靠 Ingress controller 来提供。

    Ingress controller 可以理解为一个监听器,通过不断地与 kube-apiserver 打交道,实时的感知后端 service、pod 的变化,当得到这些变化信息后,Ingress controller 再结合 Ingress 的配置,更新反向代理负载均衡器,达到服务发现的作用。其实这点和服务发现工具 consul consul-template 非常类似。

    现在可以供大家使用的 Ingress controller 有很多,比如 traefiknginx-controllerKubernetes Ingress Controller for KongHAProxy Ingress controller,当然你也可以自己实现一个 Ingress Controller,现在普遍用得较多的是 traefik 和 nginx-controller,traefik 的性能较 nginx-controller 差,但是配置使用要简单许多,我们这里会以更简单的 traefik 为例给大家介绍 ingress 的使用。

    应用场景

    对于小规模的应用我们使用NodePort或许能够满足我们的需求,但是当你的应用越来越多的时候,你就会发现对于 NodePort 的管理就非常麻烦了,这个时候使用 ingress 就非常方便了,可以避免管理大量的 Port
    我们知道前面我们使用 NodePort 和 LoadBlancer 类型的 Service 可以实现把应用暴露给外部用户使用,除此之外,Kubernetes 还为我们提供了一个非常重要的资源对象可以用来暴露服务给外部用户,那就是 ingress

    通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。


    image.png

    而 Ingress 就是为进入集群的请求提供路由规则的集合


    image.png

    Traefik

    Traefik是一款开源的反向代理与负载均衡工具。它最大的优点是能够与常见的微服务系统直接整合,可以实现自动化动态配置。目前支持Docker, Swarm, Mesos/Marathon, Mesos, Kubernetes, Consul, Etcd, Zookeeper, BoltDB, Rest API等等后端模型。

    创建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
    

    创建traefik-ds.yaml 基于TLS 证书认证(自签发)

    使用openssl命令生成 CA 证书
    openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -out tls.crt
    
    使用 kubectl 创建一个 secret 对象来存储上面的证书
    kubectl create secret generic traefik-cert --from-file=tls.crt --from-file=tls.key -n kube-system
    
    使用 kubectl 创建一个 configmap对象来配置traefik 配置

    traefik.toml

    defaultEntryPoints = ["http", "https"]
    insecureSkipVerify = true
    [entryPoints]
      [entryPoints.http]
      address = ":80"
        [entryPoints.http.redirect]
          entryPoint = "https"
      [entryPoints.https]
      address = ":443"
        [entryPoints.https.tls]
          [[entryPoints.https.tls.certificates]]
          CertFile = "/ssl/tls.crt"
          KeyFile = "/ssl/tls.key"
    
    创建configmap
    kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
    
    创建traefik-ds.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:
          nodeSelector:
            traefik: "svc"
          serviceAccountName: traefik-ingress-controller
          terminationGracePeriodSeconds: 60
          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: admin
              containerPort: 8080
              hostPort: 8080
            securityContext:
              capabilities:
                drop:
                - ALL
                add:
                - NET_BIND_SERVICE
            args:
            - --configfile=/config/traefik.toml
            - --api
            - --kubernetes
            - --logLevel=DEBUG
    ---
    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: 8080
          name: admin
        - protocol: TCP
          port: 443
          name: https
    
    

    由于以daemonset 守护进程方式部署,会在集群内所有的node上都会部署,这边通过nodeselector的方式 来选择1-2个节点部署,这样就需要给node打label kubectl label node example-node traefik=svc

    创建service和Ingress

    一、Traefik web ui

    ---
    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-ui.minikube
       http:
         paths:
         - path: /
           backend:
             serviceName: traefik-web-ui
             servicePort: web
    

    二、Kubernetes Dashboard

    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
      name: kubernetes-dashboard
      namespace: kube-system
    spec:
      ports:
        - port: 443
          targetPort: 8443
      selector:
        k8s-app: kubernetes-dashboard
      type: NodePort
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: kubernetes-dashboard-ingress
      namespace: kube-system
      annotations:
        kubernetes.io/ingress.class: "traefik"
    spec:
      rules:
      - host: k8s-dashboard-ui.com
        http:
          paths:
          - backend:
              serviceName: kubernetes-dashboard
              servicePort: 443
    

    三、Path 的用法
    创建3个web deployment和service

    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: svc1
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: svc1
        spec:
          containers:
          - name: svc1
            image: cnych/example-web-service
            env:
            - name: APP_SVC
              value: svc1
            ports:
            - containerPort: 8080
              protocol: TCP
    
    ---
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: svc2
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: svc2
        spec:
          containers:
          - name: svc2
            image: cnych/example-web-service
            env:
            - name: APP_SVC
              value: svc2
            ports:
            - containerPort: 8080
              protocol: TCP
    
    ---
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: svc3
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: svc3
        spec:
          containers:
          - name: svc3
            image: cnych/example-web-service
            env:
            - name: APP_SVC
              value: svc3
            ports:
            - containerPort: 8080
              protocol: TCP
    
    ---
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        app: svc1
      name: svc1
    spec:
      type: ClusterIP
      ports:
      - port: 8080
        name: http
      selector:
        app: svc1
    
    ---
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        app: svc2
      name: svc2
    spec:
      type: ClusterIP
      ports:
      - port: 8080
        name: http
      selector:
        app: svc2
    
    ---
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        app: svc3
      name: svc3
    spec:
      type: ClusterIP
      ports:
      - port: 8080
        name: http
      selector:
        app: svc3
    

    创建相应的Ingress

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: example-web-app
      annotations:
        kubernetes.io/ingress.class: "traefik"
    spec:
      rules:
      - host: example.haimaxy.com
        http:
          paths:
          - path: /s1
            backend:
              serviceName: svc1
              servicePort: 8080
          - path: /s2
            backend:
              serviceName: svc2
              servicePort: 8080
          - path: /
            backend:
              serviceName: svc3
              servicePort: 8080
    

    验证:

    需要修改本地hosts文件 做好IP与域名的映射关系

    image.png
    image.png image.png image.png image.png image.png image.png
    image.png

    参考文档:
    https://www.qikqiak.com/post/ingress-traefik2/
    https://www.centos.bz/2018/07/k8s%E4%B9%8Btraefik/
    https://feisky.gitbooks.io/kubernetes/content/practice/apps/helm.html
    https://jimmysong.io/posts/kubernetes-ingress-resource/

    相关文章

      网友评论

          本文标题:Kubernetes 服务发布之traefik ingress

          本文链接:https://www.haomeiwen.com/subject/ohqxxqtx.html