traefik基础部署(外部访问kuberntes业务应用)
在k8s集群部署了业务应用,外面怎么访问业务应用呢?首先想到的肯定是端口映射,前面篇章的svc就是使用的端口映射.
但是端口映射存在很多,一个服务映射一个端口,在防火墙出入口,安全性和管理都是问题.主流并不是使用端口映射,而是使用ingress和traefik,实现外部访问集群内部业务应用.
喜欢用traefik,部署简单.这篇是traefik部署的简单记录.
1.获取traefik配置文件
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-node1 traefik]# ls
traefik-deployment.yaml traefik-ds.yaml traefik-rbac.yaml ui.yaml
2.配置文件简要说明
rbac权限配置文件
创建clusterrole traefik-ingress-controller,并且把clusterrole traefik-ingress-controller绑定给serviceaccount traefik-ingress-controller.
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
deployment部署文件
部署svc,名字为traefik-ingress-service,svc映射两个端口80和8080,其中80为web端口,8080为admin端口.
创建sa, traefik-ingress-controller,对应rbac文件.
部署deployment,使用镜像traefik:v1.7,只生成一个pod.
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:v1.7
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
daemonset部署文件
和deployment部署差不多,只是daemonset控制器部署,会在每个节点生成一个pod.
cat traefik-ds.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
selector:
matchLabels:
k8s-app: traefik-ingress-lb
name: 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:v1.7
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
测试文件
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
3.部署
部署,这里使用的是traefik-ds.yaml文件部署
kubectl apply -f traefik-ds.yaml
serviceaccount/traefik-ingress-controller created
daemonset.apps/traefik-ingress-controller created
service/traefik-ingress-service created
kubectl apply -f traefik-rbac.yaml
clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created
服务起来
kubectl get svc,pod -n kube-system -o wide |grep traefik
service/traefik-ingress-service NodePort 10.254.32.20 <none> 80:8817/TCP,8080:8924/TCP 7m53s k8s-app=traefik-ingress-lb
pod/traefik-ingress-controller-5mmc5 1/1 Running 0 7m53s 172.30.49.3 k8s-node2 <none> <none>
pod/traefik-ingress-controller-jfkjs 1/1 Running 0 7m53s 172.30.75.4 k8s-node3 <none> <none>
pod/traefik-ingress-controller-jvt46 1/1 Running 0 7m53s 172.30.77.2 k8s-node1 <none> <none>
可以看到,svc有两个端口80和8080,其中80端口是traefik的服务端口,8080是traefik的ui端口,通过任何一个节点ip:8080端口可以正常访问traefik ui了.
默认页面空白,见下
使用测试ui看看
kubectl apply -f ui.yaml
service/traefik-web-ui created
ingress.extensions/traefik-web-ui created
4.创建使用一个ingress
前面在集群部署了httpd和wordpress的svc,创建个ingress试试.
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd-svc NodePort 10.254.125.1 <none> 80:8400/TCP 7d23h
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 22d
mysql-t ClusterIP 10.254.177.63 <none> 3306/TCP 4d19h
mysql-test ClusterIP 10.254.177.188 <none> 3306/TCP 41h
wordpress NodePort 10.254.208.45 <none> 8080:8800/TCP 6d19h
需要配置Ingress文件,格式见下
kubectl apply -f wordpress-ingress.yaml
ingress.extensions/wordpress-ingress created
cat wordpress-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: wordpress-ingress
namespace: default
spec:
rules:
- host: wordpress.ingress
http:
paths:
- path: /
backend:
serviceName: wordpress
servicePort: 8080
traefik ui可以看到新加的wordpress
把wordpres.ingress这个域名地址解析到任意node节点IP地址,然后使用域名wordpress.ingress即可访问应用wordpress.
我这是虚机环境,使用win10,修改下Host文件,然后即可正常访问,见下:
5.traefik实现访问的分析
简易分析:
k8s里有很多的service,我们通过traefik转发来访问service.
traefik我们已经部署好了,也能够发现后端service的了.
但是,我们的业务访问请求怎么到达traefik呢?
最简单的方法,把pod配置hostNotwork: true模式,Pod中所有容器的端口号都将直接被映射到物理机上,访问物理机的端口就直接访问到了pod的容器的端口.
traefik-ds部署方式是怎么实现的呢?见下
cat traefik-ds.yaml |grep -A 10 containers
containers:
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8080
hostPort: 8080
注意HostPort这个参数.
hostPort配置在pod里,就是映射pod的端口到节点,访问节点的端口就是访问pod的端口.