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"