ingress in k8s cluster--based on traefik

k8s supports two load balancing mechanisms for publishing applications within pod s
1. One is a service for four-tier TCP load balancing
service mainly implements communication within the cluster, as well as internal and external communication based on four layers (such as ports)
2. Another is ingress, which enables users to achieve seven-tier HTTP load balancing
ingress mainly implements seven-tier internal and external communication (such as URL s)
Ingress is simply a collection of routing rules that require an ingress controller to function
The ingress controller is not managed by controller-manager and runs directly on the k8s cluster as an attachment
The ingress controller itself runs as a pod, running on the same network as the proxy pod
Unlike service, to use ingress, you must first create the ingress-controller pod and the svc Based on it
We may be able to use NodePort for small-scale applications, but when you have more and more applications, you will find it very difficult to manage NodePort. It is very convenient to use ingress at this time to avoid managing a large number of ports.

igress type
1. Single service resource type
2. Forwarding based on URL path
3. Forwarding based on virtual host
4. TLS Type
The ingress controller can be implemented by the following reverse proxy program:
1,haproxy
2,nginx
3,envoy
4,traefik
5,Vulcand

Create treafik-based ingress
1. Create rbac certification

apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  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
---
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

$ kubectl create -f rbac.yaml
serviceaccount "traefik-ingress-controller" created
clusterrole.rbac.authorization.k8s.io "traefik-ingress-controller" created
clusterrolebinding.rbac.authorization.k8s.io "traefik-ingress-controller" created

2. Create treafik-based Ingres controllers pod and svc
Deploy this controller pod on master
$ docker pull traefik
$ vim traefik.yaml

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      tolerations:
      - operator: "Exists"        #Allow stains
      nodeSelector:
        kubernetes.io/hostname: master        #Deploy on master
      containers:
      - image: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
                    hostPort: 80        #Do not use nodePort port for external network access, just use domain name
        - name: admin
          containerPort: 8080
        args:
        - --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: 8080
      name: admin
  type: NodePort

Because traefik containers have two ports, 80 and 8080 (management ports), two ports 80 and 8080 are also required for their corresponding services.
$ kubectl apply -f traefik.yaml
deployment.extensions "traefik-ingress-controller" created
service "traefik-ingress-service" created
$ kubectl get svc -n kube-system
traefik-ingress-service NodePort 10.100.222.78 <none> 80:31657/TCP,8080:31572/TCP 79d
Access traefik's management interface via svc
http://192.168.1.243:31572/

3. Create an ingress instance for the ingress controller and its svc itself (8080)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik.example.com
    http:
      paths:
      - backend:
          serviceName: traefik-ingress-service
          servicePort: 8080

Analogue dns resolution
$ vim /etc/hosts
192.168.1.243 traefik.example.com
Because of hostPort: 80 in the pod, you can access traefik's management interface directly using the domain name in ingress mode
https://traefik.example.com
If you have multiple masters, you can deploy an ingress-controller service on each master, then hang a load balancer in front of the master, such as nginx, and use all masters as the backend of the load balancer so that ingress-controller is highly available and load balanced.

4. Define backend common application pod and its svc
The type of svc is ClusterIP

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

$ kubectl create -f backend.yaml
deployment.extensions "svc1" created
deployment.extensions "svc2" created
deployment.extensions "svc3" created
service "svc1" created
service "svc2" created
service "svc3" created

5. Define ingress policy for the above general application of pod and its svc
The backend of the ingress policy is the svc that applies the pod

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

$ kubectl create -f example-ingress.yaml
ingress.extensions "example-web-app" created
$ kubectl get ingress
$ kubectl describe ingress example-web-app
Analogue dns
$ vim /etc/hosts
192.168.1.243 www.example.com
http://www.example.com --Visit svc3
http://www.example.com/s1 --Access svc1
http://www.example.com/s2 --Access svc2

6. Enable traefik ingress to support TLS
Three aspects of support are required to support tls
1. Generating a ca certificate
$ mkdir /ssl
$ cd /ssl
$ openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -out tls.crt
$ ls
tls.crt tls.key
Then create secret to store the certificate
$ kubectl create secret generic traefik-cert --from-file=tls.crt --from-file=tls.key -n kube-system
$ kubectl get secret -n kube-system |grep traefik
2. Increase the default profile traefik.toml
This file is in the same directory as the traefik pod file
$ vim traefik.toml

defaultEntryPoints = ["http", "https"]

[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"

Create configmap to store the configuration file
$ kubectl create configmap traefik-conf --from-file=traefik.toml -n kube-system
$ kubectl get configmap -n kube-system |grep traefik
3. Modify the yaml file of traefik pod in step 2
$ vim traefik.yaml

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      volumes:
      - name: ssl
        secret:
          secretName: traefik-cert
      - name: config
        configMap:
          name: traefik-conf
      tolerations:
      - operator: "Exists"
      nodeSelector:
        kubernetes.io/hostname: master
      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
        args:
        - --configfile=/config/traefik.toml
        - --api
        - --kubernetes
        - --logLevel=INFO

$ kubectl apply -f traefik.yaml
$ kubectl logs -f traefik-ingress-controller-7dcfd9c6df-v58k7 -n kube-system
time="2018-08-26T11:26:44Z" level=info msg="Server configuration reloaded on :80"
time="2018-08-26T11:26:44Z" level=info msg="Server configuration reloaded on :443"
time="2018-08-26T11:26:44Z" level=info msg="Server configuration reloaded on :8080"

Keywords: SSL Kubernetes vim network

Added by nodi on Wed, 21 Aug 2019 20:12:56 +0300