1.
项目地址
https://docs.traefik.io/
获取配置文件
wget https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml
wget https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-deployment.yaml
wget https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml
wget https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/ui.yaml
[root@k8s-master1 traefik]# ls
traefik-deployment.yaml traefik-ds.yaml traefik-rbac.yaml ui.yaml
2.
配置文件简要说明
[root@k8s-master1 traefik]# cat traefik-rbac.yaml
---
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: traefik-ingress-controller
namespace: kube-system
[root@k8s-master1 traefik]#
指定sa traefik-ingress-controller的rbac权限
[root@k8s-master1 traefik]# cat traefik-deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
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
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
- 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
[root@k8s-master1 traefik]#
创建sa traefik-ingress-controller
创建svc 指定type为NodePort
创建deployment 指定只生成一个副本
[root@k8s-master1 traefik]# cat traefik-ds.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8080
hostPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
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
[root@k8s-master1 traefik]#
创建sa traefik-ingress-controller
创建svc 这里并没用指定type为NodePort
创建Daemonset,和deployment不同,每个节点都会创建一个pod
[root@k8s-master1 traefik]# cat ui.yaml
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- name: web
port: 80
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
rules:
- host: traefik-ui.minikube
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
[root@k8s-master1 traefik]#
这只是个测试用的svc而已.
3.
部署
这里部署用的是
traefik-rbac.yaml
traefik-ds.yaml
其中traefik-ds.yaml做了修改,指定svc的type类型为NodePort
[root@k8s-master1 traefik]# kubectl apply -f traefik-ds.yaml
serviceaccount "traefik-ingress-controller" created
daemonset.extensions "traefik-ingress-controller" created
service "traefik-ingress-service" created
[root@k8s-master1 traefik]# kubectl apply -f traefik-rbac.yaml
clusterrole.rbac.authorization.k8s.io "traefik-ingress-controller" created
clusterrolebinding.rbac.authorization.k8s.io "traefik-ingress-controller" created
[root@k8s-master1 traefik]#
[root@k8s-master1 traefik]# kubectl get svc,pod -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-dns ClusterIP 10.254.0.2 53/UDP,53/TCP 14d
service/kubernetes-dashboard ClusterIP 10.254.64.196 443/TCP 3h
service/traefik-ingress-service NodePort 10.254.201.201 80:8437/TCP,8080:8950/TCP 1m
NAME READY STATUS RESTARTS AGE
pod/coredns-779ffd89bd-k6r7l 1/1 Running 8 14d
pod/kubernetes-dashboard-65c76f6c97-2b2qd 1/1 Running 0 3h
pod/traefik-ingress-controller-69962 1/1 Running 0 1m
pod/traefik-ingress-controller-6xf47 1/1 Running 0 1m
pod/traefik-ingress-controller-tshc9 1/1 Running 0 1m
pod/traefik-ingress-controller-zmpw2 1/1 Running 0 1m
[root@k8s-master1 traefik]#
用浏览器通过任意一个node的ip:8950,即可访问traefik.
一片空白,因为没有生成启用任何规则.
启用测试ui看看.
[root@k8s-master1 traefik]# kubectl apply -f ui.yaml
service "traefik-web-ui" created
ingress.extensions "traefik-web-ui" created
[root@k8s-master1 traefik]#
创建个httpd的svc来测试traefik功能
[root@k8s-master1 test]# cat httpd-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
ports:
- port: 80
selector:
app: httpd-app
type: NodePort
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: httpd-app
spec:
template:
metadata:
labels:
app: httpd-app
spec:
containers:
- image: httpd
name: httpd-app
[root@k8s-master1 test]# kubectl apply -f httpd-svc.yaml
service "httpd-svc" created
deployment.apps "httpd-app" created
[root@k8s-master1 test]#
[root@k8s-master1 test]# kubectl get svc,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/httpd-svc NodePort 10.254.71.79 80:8763/TCP 45s
NAME READY STATUS RESTARTS AGE
pod/httpd-app-bbcbfb6cd-96v28 1/1 Running 0 44s
创建traefik ingress规则
[root@k8s-master1 test]# kubectl apply -f httpd-svc-ingress.yaml
ingress.extensions "httpd-svc-ingress" created
[root@k8s-master1 test]# cat httpd-svc-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: httpd-svc-ingress
namespace: default
spec:
rules:
- host: httpd-svc.ingress
http:
paths:
- path: /
backend:
serviceName: httpd-svc
servicePort: 80
[root@k8s-master1 test]#
traefik ui可以看到httpd-svc了.
5.
暴露traefik服务
用示意图分析下traefik的转发过程,见下:
简易分析:
k8s里有很多的service,我们通过traefik转发来访问service.
traefik我们已经部署好了,也能够发现后端service的了.
但是,我们的业务访问请求怎么到达traefik呢?
暴露traefik服务
对比ingress的暴露服务方法:
1.创建个service,然后给这个service指定extIP.
2.把pod配置hostNotwork: true模式,Pod中所有容器的端口号都将直接被映射到物理机上,访问物理机的端口就直接访问到了pod的容器的端口.
第1种方法暴露服务
请注意使用这种方法暴露服务,建议使用kind:deployment
在部署集群时,我们有配置keepalive+ha的api ip,指定extIP为这个ip
访问的时候,根据vip来访问node,从而访问traefik,实现转发.
[root@k8s-master1 traefik]# cat traefik-deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
replicas: 3
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
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
- 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
externalIPs:
- 192.168.32.127
[root@k8s-master1 traefik]#
作了两处修改
replicas: 3
externalIPs:
- 192.168.32.127
[root@k8s-master1 traefik]# kubectl get svc,pod -n kube-system -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kube-dns ClusterIP 10.254.0.2 53/UDP,53/TCP 16h k8s-app=kube-dns
service/traefik-ingress-service ClusterIP 10.254.97.199 192.168.32.127 80/TCP,8080/TCP 17m k8s-app=traefik-ingreb
service/traefik-web-ui ClusterIP 10.254.124.127 80/TCP 17h k8s-app=traefik-ingreb
NAME READY STATUS RESTARTS AGE IP NODE
pod/coredns-779ffd89bd-pz6s2 0/1 Unknown 1 16h k8s-node1
pod/coredns-779ffd89bd-wmzhf 1/1 Running 1 12m 172.30.55.2 k8s-master1
pod/traefik-ingress-controller-6545547764-646qg 1/1 Running 0 7m 172.30.60.3 k8s-master2
pod/traefik-ingress-controller-6545547764-hsjfg 1/1 Running 0 7m 172.30.55.3 k8s-master1
pod/traefik-ingress-controller-6545547764-ql4vp 1/1 Running 0 7m 172.30.41.2 k8s-master3
[root@k8s-master1 traefik]#
浏览器使用192.168.32.127:8080可以直接访问traefik web.
指定域名到192.168.32.127,traefik能够实现正常转发.
注意这个域名要是ing规则里的host名字
rules:
- host: httpd-svc.ingress
http:
paths:
- path: /
backend:
serviceName: httpd-svc
servicePort: 80
使用第2种方法暴露服务
[root@k8s-master1 traefik]# cat traefik-ds.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
hostNetwork: true
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8080
hostPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
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
[root@k8s-master1 traefik]#
注意:
hostNetwork: true
重新执行命令
[root@k8s-master1 traefik]# kubectl apply -f traefik-ds.yaml
serviceaccount "traefik-ingress-controller" unchanged
daemonset.extensions "traefik-ingress-controller" configured
service "traefik-ingress-service" unchanged
[root@k8s-master1 traefik]#
指定域名到任意一个node的ip,traefik能够实现正常转发.
注意这个域名要是ing规则里的host名字
rules:
- host: httpd-svc.ingress
http:
paths:
- path: /
backend:
serviceName: httpd-svc
servicePort: 80