专栏首页一个番茄说# 一篇文章让你搞懂如何在K8s 里使用 Traefik 2.0作为Ingress Controller(上)

# 一篇文章让你搞懂如何在K8s 里使用 Traefik 2.0作为Ingress Controller(上)

原文链接

了解K8s的同学应该都知道,如果想要把应用暴露到公网上供外部访问,那么不可避免的会接触到Ingress资源。本文以Traefik为例,让大家对Ingress和Traefik的使用有一定的了解。

Ingress是什么

我们来看看官方对于Ingress的解释

An API object that manages external access to the services in a cluster, typically HTTP. Ingress can provide load balancing, SSL termination and name-based virtual hosting.

  1. 它也是一个API对象,就如同其他的API对象Service、Deployment一样。
  2. 负责管理外部流量对于集群内部的访问,比如典型通过HTTP协议。
  3. 能承担负载均衡,SSL等职责

简单来说,它承担的就是一个边缘路由的职责,负责按照你期望的规则管理外部的访问请求,如下面所示:

    internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]

Traefik 是什么

上面我们简单说明了什么是Ingress,它是一个API资源对象。得益于K8s高度抽象的设计,可以让我们很方便地做技术选型去实现Ingress的工作。在这里,完成具体工作的组件就是Ingress Controller,Traefik就是其中之一。

traefik-architecture.png

市面上有非常多的Ingress Controller,比如Nginx Ingress、kong、istio等等。我之所以选择Traefik的原因是目前项目不算太复杂traefik足够应付,提供了较为简洁的UI界面,能够满足我目前的需求。不过稍微有点坑的地方就是Traefik 2.0的版本发布不久,文档的支持上稍微有点弱,有时候看文档会比较懵。因此,接下来的文章,我就以Traefik 2.0来说明如何在K8s中使用Ingress Controller。

在K8s集群中部署Traefik

在这里我没有使用Helm来部署Traefik(因为此时Helm上的Traefik版本还是低于2.0的),先来看看目录下有哪些yaml文件。

> #ls
> #traefik-config.yaml  traefik-crd.yaml  traefik-deploy.yaml  traefik-rbac.yaml

接下来我会展示这些文件中的重点内容,限于篇幅的原因,部分内容省略表示,可以在公众号留言我给出完整示例。

  • 先看看 traefik-config.yaml里面的内容:
kind: ConfigMap
apiVersion: v1
metadata:
  name: traefik-config
  namespace: kube-system
data:
  traefik.yaml: |-
    serversTransport:
      insecureSkipVerify: true
    api:
      ...
    metrics:
      ...
    entryPoints:
      web:
        address: ":80"
      websecure:
        address: ":443"
    providers:
      kubernetesCRD: ""
    log:
        ...
    accessLog:
        ...

这里面都是关于Traefik的一些配置,基本上看名字也能知道各个字段的含义,这里可能需要稍微注意一点的是entryPoints。在这里定义了两条入口,一条叫做web负责监听80端口的访问,一条叫做websecure负责监听443端口,也就是Https的请求。

  • 再来看看traefik-crd.yaml里面的内容
## IngressRoute
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutes.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRoute
    plural: ingressroutes
    singular: ingressroute
---
## IngressRouteTCP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressroutetcps.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteTCP
    plural: ingressroutetcps
    singular: ingressroutetcp
---
## Middleware
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: middlewares.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: Middleware
    plural: middlewares
    singular: middleware
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsoptions.traefik.containo.us
spec:
  scope: Namespaced
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSOption
    plural: tlsoptions
    singular: tlsoption

这里的crd也就是CustomResourceDefinition,在Kubernetes 1.7 之后增加了对 CRD 资源二次开发能力来扩展 Kubernetes API,通过 CRD 我们可以向 Kubernetes API 中增加新资源类型,而不需要修改 Kubernetes 源码来创建自定义的 API server,该功能大大提高了 Kubernetes 的扩展能力。 在这里,Traefik从2.0的版本不在直接监听Ingress资源,而是通过自定的一个叫做IngressRoute的资源在进行工作,这点是需要注意的地方。除此之外,我们可以看到Traefik还申明了一些自定义的资源。这些资源的使用范围是namespace级别的,在k8s中还支持集群级别的crd。

  • traefik-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress
  namespace: kube-system
---
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"]
  - apiGroups: ["extensions"]
    resources: ["ingresses/status"]
    verbs: ["update"]
      ... 
---
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: ingress
    namespace: kube-system

在这个文件里定义的是Traefik会涉及到的角色和权限,因为可能要代理各个命名空间的各个服务的流量,因此可以看到有Cluster级别的权限申明。

  • 最重要的traefik-deploy.yaml 前面的一系列准备工作准备完成之后,就是真正的部署Traefik了,由于内容比较多,为了方便理解我直接在相关的字段后添加注释来说明
apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: kube-system
spec:
  ports:
    - name: web
      port: 80
    - name: websecure
      port: 443
    - name: admin
      port: 8080
  selector:
    app: traefik
---
apiVersion: apps/v1
kind: DaemonSet # 以DaemonSet的形式运行Traefik
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    app: traefik
spec:
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      name: traefik
      labels:
        app: traefik
    spec:
      serviceAccountName: ingress       #使用了前文中定义的service account,以便具备相关的权限
      terminationGracePeriodSeconds: 1
      containers:
        - image: traefik:2.0        #使用的是traefik 2.0的版本
          name: traefik-ingress-lb
          env:  # 由于我的服务器是阿里云的ECS,我需要使用阿里云的Access Key以便能够使用Traefik的自动Https签名功能
          - name: ALICLOUD_ACCESS_KEY              # 添加环境变量ALICLOUD_ACCESS_KEY
            value: <根据你自己的情况调整>                 # 阿里云RAM账号的access_key
          - name: ALICLOUD_SECRET_KEY              # 添加环境变量ALICLOUD_SECRET_KEY
            value: <根据你自己的情况调整>                   # 阿里云RAM账号的access_secret
          ports:
            - name: web
              containerPort: 80
              hostPort: 80           #hostPort方式,将端口暴露到集群节点
            - name: websecure
              containerPort: 443
              hostPort: 443          #hostPort方式,将端口暴露到集群节点
            - name: admin
              containerPort: 8080
          resources:
            limits:
              cpu: 2000m
              memory: 1024Mi
            requests:
              cpu: 1000m
              memory: 1024Mi
          securityContext:
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
          args:
            - --entrypoints.web.Address=:80
            - --entrypoints.websecure.Address=:443
            - --api.insecure  # 开启webui需要该参数
            - --providers.kubernetescrd
            - --api
            - --api.dashboard=true
            - --accesslog
            # 使用acme.sh通过dns验证域名的所有权,以便能够自动签发https证书
            - --certificatesresolvers.default.acme.dnsChallenge=true
            - --certificatesresolvers.default.acme.dnsChallenge.provider=alidns
            # 邮箱配置
            - --certificatesResolvers.default.acme.email=你的邮箱@gmail.com
            # 保存ACME 证书的位置
            - --certificatesResolvers.default.acme.storage="acme.json"
            - --metrics.prometheus=true
          volumeMounts:
            - mountPath: "/config"
              name: "config"
      volumes:
        - name: config
          configMap:
            name: traefik-config
      tolerations:              #设置容忍所有污点,防止节点被设置污点
        - operator: "Exists"
      nodeSelector:             #设置node筛选器,在特定label的节点上启动,我为具有公网IP的节点打上了这个标签
        IngressProxy: "true"

到此为止,所有的准备工作都完成了,接下来在目录执行命令kubectl apply -f *,正常的话你可以看到上面几个文件内申明的所有资源都被正确的创建了,我们也可以通过命令验证下traefik是不是在正常运行。

屏幕快照 2020-01-14 下午3.33.52.png

正常情况下的话,你可以看到一个daemonset,一个service,和至少一个pod在运行。如果走到这步的话,那说明已经大功告成 了。

结语

在本文中,阐述了如何使用Traefik作为Ingress Controller来监听集群外部的网络请求,在接下来的文章中,我将通过一个具体的例子展示如何暴露一个内部的服务到外网访问,以及如何进行自动Https证书签发等内容。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一篇文章让你搞懂K8s Ingress,Traefik 2.0为例(上)

    了解K8s的同学应该都知道,如果想要把应用暴露到公网上供外部访问,那么不可避免的会接触到Ingress资源。本文以Traefik为例,让大家对Ingress和T...

    100000798482
  • 基于K8s的Jenkins持续集成实战(上)

    Jenkins是一款广泛受到的欢迎的持续集成工具,有着丰富的插件以及扩展能力,基本上能够满足大多数团队的需求。本文将从工具使用的角度,来讲述如何在kuberne...

    100000798482
  • 函数式编程漫谈

    最近在思考一个问题,函数式编程对于我们的软件开发的意义到底有多大?到底值不值得我们花时间去学习。因此,写下这篇文章来记录自己的思考。文章包含了前后端开发中的一些...

    100000798482
  • 一篇文章让你搞懂K8s Ingress,Traefik 2.0为例(上)

    了解K8s的同学应该都知道,如果想要把应用暴露到公网上供外部访问,那么不可避免的会接触到Ingress资源。本文以Traefik为例,让大家对Ingress和T...

    100000798482
  • TKE上部署treafik2

    腾讯云上有默认的提供的ingress服务,如果你不想用提供的,想用最新的treafik来暴露服务通过域名访问也是可以的。下面我们来部署操作下。

    聂小星
  • Traefik2.2从坑出发

    Traefik 2.2新增的功能如下: 1. 支持了udp 2. traefik2.2 支持使用K/V存储做为动态配置的源,分别是 consul, etcd, ...

    极客运维圈
  • Jenkins在kubernetes上的初体验

    创建 pv/pvc 对象,这里我们要注意 nfs 提供给 jenkins 的存储目录的权限问题,否则服务因为权限无法写入数据:

    云原生生态圈
  • gitflow 开发流程 转

    目前有专业提供gitflow开发流程的开发工具 SourceTree,推荐大家可以用用,mac和windows客户端都有的。

    henrylee2cn
  • Outlook清理邮件

    林万程
  • 这两年:我的数据竞赛之路

    大家好,我是鱼遇雨欲语与余,本次我将带来不一样的分享,这将是我的个人竞赛历程。将从三个部分展开分享,主要竞赛经历、关于我的竞赛和未来竞赛的我。一位竞赛小白是如何...

    石晓文

扫码关注云+社区

领取腾讯云代金券