The original link

Those of you who know K8s well know that if you want to put your application on the public network for external access, you will inevitably have access to Ingress resources. This article uses Traefik as an example to give you some understanding of the use of Ingress and Traefik.

What is the Ingress

Let’s look at the official explanation for 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. It is also an API object, just like the other API objects Service, Deployment.
  2. Manages access to the cluster by external traffic, typically through HTTP.
  3. Capable of load balancing, SSL, etc

Simply put, it takes on the responsibility of an edge route to manage external access requests according to the rules you expect, as shown below:

    internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]
Copy the code

What is Traefik

Above we briefly explained what Ingress is, which is an API resource object. Thanks to the highly abstract design of K8s, it is easy for us to select the technology to realize Ingress. In this case, the component that does the specific work is the Ingress Controller, of which Traefik is one.

There are many Ingress controllers on the market, such as Nginx Ingress, Kong, Istio, etc. The reason why I choose Traefik is that the current project is not too complicated. Traefik is enough to deal with and provides a relatively simple UI interface, which can meet my current needs. Traefik 2.0 has just been released, and the documentation is a bit weak, which can be confusing at times. Therefore, in the following article, I will use Traefik 2.0 to illustrate how to use Ingress Controller in K8s.

Deploy Traefik in a K8s cluster

Instead of using Helm to deploy Traefik (because Traefik is still under version 2.0 on Helm at this point), let’s see what YAML files are in the directory.

> #ls
> #traefik-config.yaml traefik-crd.yaml traefik-deploy.yaml traefik-rbac.yaml
Copy the code

Next, I will show the key content of these files. Due to the reason of space, some content is omitted. You can leave a message on the official account and I will give a complete example.

  • First take a look attraefik-config.yamlWhat it says:
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: ...Copy the code

Traefik: entryPoints Traefik: entryPoints Traefik: entryPoints Traefik: entryPoints Two entries are defined here, one called Web that listens for port 80 and one called WebSecure that listens for port 443, or Https requests.

  • Take a look attraefik-crd.yamlWhat’s inside
## 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
Copy the code

In Kubernetes 1.7, we added the ability to re-develop CRD resources to extend the Kubernetes API. CRD allows us to add new resource types to the Kubernetes API without having to modify the Kubernetes source code to create a custom API Server, which greatly improves the scalability of Kubernetes. It is important to note that Traefik from version 2.0 does not listen for Ingress resources directly, but instead works through a custom resource called IngressRoute. In addition, we can see that Traefik also declares some custom resources. These resources are scoped at the namespace level, and cluster-level CRDS are supported in K8S.

  • 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-systemCopy the code

In this file are defined the roles and permissions that Traefik will be involved in, as you can see cluster-level permissions declared because you may want to broker traffic for services in various namespaces.

  • Traefik -deploy.yaml is ready to deploy traefik. It is time to deploy 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	# Run Traefik as DaemonSet
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		# Use the service account defined in the previous articleContainers terminationGracePeriodSeconds: 1: - image: traefik: 2.0Traefik 2.0 is used
          name: traefik-ingress-lb
          env:	# Since my server is Ali's ECS, I need to configure the Access Key to be able to use Traefik's automatic Https signature- name: ALICLOUD_SECRET_KEY value: < Adjust according to your own conditions > - name: ALICLOUD_SECRET_KEY value: < adjust according to your own conditions > Ports: -name: web containerPort: 80 hostPort: 80#hostPort exposes ports to cluster nodes
            - name: websecure
              containerPort: 443
              hostPort: 443          #hostPort exposes ports to cluster nodes
            - 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  # This parameter is required for enabling the webui
            - --providers.kubernetescrd
            - --api
            - --api.dashboard=true
            - --accesslog
            Use acme.sh to verify domain name ownership through DNS so that HTTPS certificates can be automatically issued
            - --certificatesresolvers.default.acme.dnsChallenge=true
            - --certificatesresolvers.default.acme.dnsChallenge.provider=alidns
            # email configuration- - certificatesResolvers. Default. Acme. Email = your email @ gmail.com# Where to save the ACME certificate
            - --certificatesResolvers.default.acme.storage="acme.json"
            - --metrics.prometheus=true
          volumeMounts:
            - mountPath: "/config"
              name: "config"
      volumes:
        - name: config
          configMap:
            name: traefik-config
      tolerations:              Set to tolerate all stains to prevent nodes from being stained
        - operator: "Exists"
      nodeSelector:             Set the node filter and start it on nodes with a specific label. I tagged this label for nodes with public IP addresses
        IngressProxy: "true"
Copy the code

Kubectl apply -f * is now in the directory. You can see that traefik is working correctly if all resources specified in the preceding files are created correctly.

Normally, you should see a Daemonset, a Service, and at least one POD running. If we go this far, we’re done.

conclusion

In this article, I explained how to use Traefik as the Ingress Controller to listen for network requests outside the cluster. In the following article, I will show a concrete example of how to expose an internal service to external network access and how to automatically issue Https certificates.