An article makes you understand k8s progress and traifik 2.0 as an example

Posted by jockey_jockey on Thu, 27 Jan 2022 01:37:22 +0100

Now move!

Students who know K8s should know that if they want to expose the application to the public network for external access, they will inevitably be exposed to progress. This article takes traifik as an example to let you have a certain understanding of the use of Ingress and traifik.

What is Ingress

Let's take a look at the official explanation of progress:

> 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 other API objects such as Service and Deployment.
  2. It is responsible for managing the access of external traffic to the internal cluster, such as through HTTP protocol.
  3. Be able to undertake load balancing, SSL and other responsibilities

In short, it undertakes the responsibility of edge routing, which is responsible for managing external access requests according to your desired rules, as shown below:

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

What is Traefik

Above, we briefly explained what is progress, which is an API object. Thanks to the highly abstract design of K8s, the component that completes the specific work is the progress controller, and traifik is one of them.

There are many Ingress controllers on the market, such as Nginx Ingress, kong, istio and so on. The reason why I choose traifik is that the current project is not too complex. Traifik can cope with it enough and provides a relatively simple UI interface to meet my current needs. However, what's a bit of a hole is that the version of Traefik 2.0 was released soon, and the support of the document is a little weak. Sometimes it's confusing to read the document. Therefore, in the following article, I will use Traefik 2.0 to explain how to use Ingress in K8s.

Deploy traifik in K8s cluster

I didn't use Helm to deploy Traefik here (because the version of Traefik on Helm is still lower than 2.0 at this time). Let's see what yaml files are in the directory:

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

Next I will show the key points in these documents, which are limited to the reasons for the length. Some of the contents omitted to indicate that I can give a complete example in the official account of programmer's wealth.

  • Take a look at traefik config Yaml contents:
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:
    ...

This is all about the configuration of Traefik. Basically, you can know the meaning of each field according to the name. Here, you may need to pay a little attention to entryPoints. Two entries are defined here. One is called web, which is responsible for monitoring the access of port 80, and the other is called websecure, which is responsible for monitoring the requests of port 443, that is, Https.

  • Let's look at traefik CRD Yaml contents:
## 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 here is CustomResourceDefinition. After Kubernetes 1.7, the ability of secondary development of CRD resources is added to expand Kubernetes API. Through CRD, we can add new resource types to Kubernetes API without modifying Kubernetes source code to create a custom API Server. This function greatly improves the expansion ability of Kubernetes.

From version 2.0, Traefik no longer uses the Ingress resource directly, but uses a resource called ingresroute to work. This is something to pay attention to. In addition, we can see that Traefik also stated some other CRDs. The use scope of these resources is at the namespace level, and crd at the cluster level is also supported in k8s.

  • Next is 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

The roles and permissions that Traefik will involve are defined in this file. Because it may be necessary to proxy the traffic of various services in various namespaces, you can see the permission declaration at the Cluster level.

  • The most important is traefik deploy yaml

After the previous series of preparations are completed, the real deployment of traifik is completed. Due to the large amount of content, in order to facilitate understanding, I directly add notes after the relevant fields to explain

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 traifik as a daemon set
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    #The service account defined above is used to have relevant permissions
      terminationGracePeriodSeconds: 1
      containers:
        - image: traefik:2.0    #Traefik version 2.0 is used
          name: traefik-ingress-lb
          env:  # Since my server is an alicloud ECS, I need to use the alicloud Access Key so that I can use Traefik's automatic Https signature function
          - name: ALICLOUD_ACCESS_KEY              # Add environment variable ALICLOUD_ACCESS_KEY
            value: <Adjust according to your own situation>                 # Access of alicloud RAM account_ key
          - name: ALICLOUD_SECRET_KEY              # Add environment variable ALICLOUD_SECRET_KEY
            value: <Adjust according to your own situation>                   # Access of alicloud RAM account_ secret
          ports:
            - name: web
              containerPort: 80
              hostPort: 80           #hostPort mode, which exposes the port to the cluster node
            - name: websecure
              containerPort: 443
              hostPort: 443          #hostPort mode, which exposes the port to the cluster node
            - 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 to enable webui
            - --providers.kubernetescrd
            - --api
            - --api.dashboard=true
            - --accesslog
            # Use acme SH verifies the ownership of domain names through dns so that https certificates can be automatically issued
            - --certificatesresolvers.default.acme.dnsChallenge=true
            - --certificatesresolvers.default.acme.dnsChallenge.provider=alidns
            # Mailbox 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 and prevent nodes from being set with stains
        - operator: "Exists"
      nodeSelector:             #Set the node filter and start it on the node of a specific label. I marked this label for the node with public IP
        IngressProxy: "true"

So far, all preparations have been completed. Next, execute the command kubectl apply -f * in the directory. If normal, you can see that all resources declared in the above files have been created correctly. We can also verify whether traefik is running normally through the command.

Under normal circumstances, you can see a daemon, a service, and at least one pod running. If you come to this step, it means that you have achieved success.

epilogue

In this paper, we describe how to use traifik as the Ingress Controller to listen to network requests outside the cluster. In the next article, I will show how to expose an internal service to access the Internet through a specific example, and how to issue automatic Https authentication bookmarks.