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的端口.