第五课:部署Ingress服务
14 部署Ingress (master01)
服务反向代理
部署Traefik 2.0版本
14.1 创建traefik-crd.yaml文件
全局生效,不局限于ns,定义kind类型,用于ingress-route.yaml里的kind使用。
mkdir /root/traefik && cd /root/traefik
cat >traefik-crd.yaml<<EOF
## IngressRoute
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
---
## IngressRouteTCP
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
---
## Middleware
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
scope: Namespaced
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
EOF
14.1.1 创建treafik crd资源
[root@master01 traefik]# kubectl create -f traefik-crd.yaml
customresourcedefinition.apiextensions.k8s.io/ingressroutes.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/ingressroutetcps.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/middlewares.traefik.containo.us created
customresourcedefinition.apiextensions.k8s.io/tlsoptions.traefik.containo.us created
[root@master01 traefik]# kubectl get CustomResourceDefinition
NAME CREATED AT
ingressroutes.traefik.containo.us 2020-08-11T07:41:42Z
ingressroutetcps.traefik.containo.us 2020-08-11T07:41:42Z
middlewares.traefik.containo.us 2020-08-11T07:41:42Z
tlsoptions.traefik.containo.us 2020-08-11T07:41:43Z
14.2 创建traefik RABC文件
traefik-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: kube-system
name: traefik-ingress-controller
---
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"]
- apiGroups: ["traefik.containo.us"]
resources: ["middlewares"]
verbs: ["get","list","watch"]
- apiGroups: ["traefik.containo.us"]
resources: ["ingressroutes"]
verbs: ["get","list","watch"]
- apiGroups: ["traefik.containo.us"]
resources: ["ingressroutetcps"]
verbs: ["get","list","watch"]
- apiGroups: ["traefik.containo.us"]
resources: ["tlsoptions"]
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
14.2.1 创建权限文件
[root@master01 traefik]# kubectl create -f traefik-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
14.3 创建traefik configmap文件
traefik-config.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
data:
traefik.yaml: |-
serversTransport:
insecureSkipVerify: true
api:
insecure: true
dashboard: true
debug: true
metrics:
prometheus: ""
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
redistcp:
address: ":6379"
providers:
kubernetesCRD: ""
log:
filePath: ""
level: error
format: json
accessLog:
filePath: ""
format: json
bufferingSize: 0
filters:
retryAttempts: true
minDuration: 20
fields:
defaultMode: keep
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Authorization: drop
Content-Type: keep
14.3.1 创建traefik configmap资源配置
[root@master01 traefik]# kubectl create -f traefik-config.yaml -n kube-system
configmap/traefik-config created
14.4 设置节点标签
设置节点label 作用是对应traefik-deploy.yaml文件中的nodeSelector:IngressProxy: "true"
的节点才会作为traefik服务的节点,不做标签的节点不会提供traefik服务。
[root@master01 traefik]# kubectl label nodes 192.168.68.149 IngressProxy=true
node/192.168.68.149 labeled
[root@master01 traefik]# kubectl label nodes 192.168.68.151 IngressProxy=true
node/192.168.68.151 labeled
14.4.1 查看节点标签
检查是否成功
[root@master01 traefik]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
192.168.68.149 Ready <none> 21h v1.15.1 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.68.149,kubernetes.io/os=linux
192.168.68.151 Ready <none> 24h v1.15.1 IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.68.151,kubernetes.io/os=linux
14.5 创建traefik部署文件
注意每个node节点的80与443端口不能被占用,每个节点都检查一下
其中ports字段我们可以自定义,可以添加你需要的端口,常用为80和443。
生产环境可以适当调整资源cpu和内存的大小。
traefik-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
labels:
app: traefik-metrics
spec:
ports:
- name: web
port: 80
- name: websecure
port: 443
- name: admin
port: 8080
selector:
app: traefik
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: traefik-ingress-controller
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
template:
metadata:
name: traefik
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 1
containers:
#- image: traefik:latest
- image: traefik:2.0.5
name: traefik-ingress-lb
ports:
- name: web
containerPort: 80
hostPort: 80
- name: websecure
containerPort: 443
hostPort: 443
- name: admin
containerPort: 8080
- name: redistcp
containerPort: 6379
hostPort: 6379
resources:
limits:
cpu: 200m
memory: 300Mi
requests:
cpu: 100m
memory: 256Mi
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --configfile=/config/traefik.yaml
volumeMounts:
- mountPath: "/config"
name: "config"
volumes:
- name: config
configMap:
name: traefik-config
tolerations: #设置容忍所有污点,防止节点被设置污点
- operator: "Exists"
nodeSelector: #设置node筛选器,在特定label的节点上启动
IngressProxy: "true"
14.5.1 部署traefik资源
[root@master01 traefik]# kubectl apply -f traefik-deploy.yaml -n kube-system
service/traefik created
daemonset.apps/traefik-ingress-controller created
[root@master01 traefik]# kubectl get DaemonSet -A
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system traefik-ingress-controller 2 2 2 2 2 IngressProxy=true 11m
14.6 traefik路由配置
14.6.1 配置traefik dashboard
traefik-dashboard-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`ingress.abcd.com`)
kind: Rule
services:
- name: traefik
port: 8080
14.6.2 部署dashboard
[root@master01 traefik]# kubectl apply -f traefik-dashboard-route.yaml
ingressroute.traefik.containo.us/traefik-dashboard-route created
14.6.3 访问dashboard
修改本地hosts文件
192.168.68.149 ingress.abcd.com
访问dashboard
14.7 部署访问服务
创建nginx服务
kubectl run nginx-ingress-demo --image=nginx --replicas=1 -n kube-system
kubectl expose deployment nginx-ingress-demo --port=1099 --target-port=80 -n kube-system
[root@master01 traefik]# kubectl run nginx-ingress-demo --image=nginx --replicas=1 -n kube-system
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx-ingress-demo created
[root@master01 traefik]# kubectl expose deployment nginx-ingress-demo --port=1099 --target-port=80 -n kube-system
service/nginx-ingress-demo exposed
创建路由
cat >nginx-ingress-demo-route.yaml<<EOF
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-nginx-demo-route
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(\`nginx.abcd.com\`)
kind: Rule
services:
- name: nginx-ingress-demo
port: 1099
EOF
创建nginx代理路由服务
[root@master01 traefik]# kubectl create -f nginx-ingress-demo-route.yaml
ingressroute.traefik.containo.us/traefik-nginx-demo-route created
[root@master01 traefik]# kubectl get IngressRoute -A
NAMESPACE NAME AGE
kube-system traefik-dashboard-route 16h
kube-system traefik-nginx-demo-route 57s
绑定域名以后可以通过nginx.abcd.com访问上面创建的nginx服务。
14.8 创建https服务
代理dashboard https服务
创建自签名证书
cd /root/traefik
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=cloud.abcd.com"
将证书存储到kubernetes secret中
kubectl create secret tls dashboard-tls --key=tls.key --cert=tls.crt -n kube-system
查看系统secret
[root@master01 traefik]# kubectl get secret -n kube-system
NAME TYPE DATA AGE
coredns-token-mv2gz kubernetes.io/service-account-token 3 41h
dashboard-tls kubernetes.io/tls 2 13s
default-token-q5bxc kubernetes.io/service-account-token 3 2d
traefik-ingress-controller-token-ldcr8 kubernetes.io/service-account-token 3 18h
创建代理路由
cat >kubernetes-dashboard-route.yaml<<EOF
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: kubernetes-dashboard-route
namespace: kubernetes-dashboard
spec:
entryPoints:
- websecure
tls:
secretName: dashboard-tls
routes:
- match: Host(\`cloud.abcd.com\`)
kind: Rule
services:
- name: kubernetes-dashboard
port: 443
EOF
创建kubernetes-dashboard代理路由服务
[root@master01 traefik]# kubectl create -f kubernetes-dashboard-route.yaml
ingressroute.traefik.containo.us/kubernetes-dashboard-route created
[root@master01 traefik]# kubectl get IngressRoute -A
NAMESPACE NAME AGE
kube-system traefik-dashboard-route 18h
kube-system traefik-nginx-demo-route 48m
kubernetes-dashboard kubernetes-dashboard-route 19s
绑定cloud.abcd.com域名并通过https访问。
Ingress的意义是什么?
我们在做svc关联的时候,使用nodeport模式从外部访问的流程是,k8s根据yaml文件中的port配置生成服务(svc)的端口和容器内的端口的映射关系,然后会自动生成一个节点node的随机端口(高于32768的端口号)映射到服务(svc)的端口。那么如果有很多服务同时使用nodeport模式会出现几个问题,1.我们需要去查找某个服务对应的某个端口,会比较复杂,2.node上的端口提供给某个服务以后就不能提供给其他服务使用,这个是服务和端口一对一对应的,数量有限。如何解决这些问题呢,就引入了ingress模式,traefik是一个开源实现ingress的工具,实现方式是前端使用域名去关联service和端口,后端的service和pod的对应不需要用户关心,由traefik-route自动完成。我们访问某个服务的时候只需要访问域名,可以由域名解析到pod的地址,不需要再去查找服务pod所在node的IP地址和对应的端口访问。简化了服务访问的流程。
用户访问->域名->ingess服务->svc服务->pod
ingress-route yaml文件说明:
apiVersion: traefik.containo.us/v1alpha1 -----ingress-route api类型
kind: IngressRoute ---------------------------资源类型,不是kubernetes的资源类别,而是在traefik-crd.yaml中定义的。
metadata:
name: kubernetes-dashboard-route -----------ingress-route name,可以通过kubectl get IngressRouter查看
namespace: kubernetes-dashboard -----------所属namespace
spec:
entryPoints:
- websecure -----------------------------客户访问入口,可以在traefik-config.yaml里配置
tls:
secretName: dashboard-tls ---------------tls secret文件名
routes:
- match: Host(\`cloud.abcd.com\`) -------对外客户访问域名
kind: Rule
services:
- name: kubernetes-dashboard -------后端svc名,可以从kubectl get svc查看
port: 443 ------------------------svc端口号
14.9 Ingress-TCP服务访问
修改配置文件traefik-config.yaml
和traefik-deploy.yaml
文件中的port字段块:
traefik-config.yaml
entryPoints:
redistcp:
address: ":6379"
traefik-deploy.yaml
ports:
- name: redistcp
containerPort: 6379
hostPort: 6379
14.9.1 TCP ingress案例
启用redis服务
kubectl apply -f redis-tcp-deploy.yaml
[root@master01 traefik]# kubectl apply -f redis-tcp-deploy.yaml
deployment.extensions/redis-tcp created
service/redis-tcp-svc created
启用traefik-route代理tcp端口
[root@master01 traefik]# more traefik-redis-tcp-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: redis-tcp-ingress
spec:
entryPoints:
- redistcp
routes:
- match: HostSNI(`*`)
services:
- name: redis-tcp-svc
port: 6379
weight: 10
terminationDelay: 400
kubectl apply -f traefik-redis-tcp-route.yaml
[root@master01 traefik]# kubectl apply -f traefik-redis-tcp-route.yaml
ingressroutetcp.traefik.containo.us/redis-tcp-ingress created
[root@master01 traefik]# kubectl get IngressRouteTCP -A
NAMESPACE NAME AGE
default redis-tcp-ingress 42s
14.9.2 测试redis tcp服务
我们在master02上安装redis服务
yum -y epel-release
yum -y install redis
修改hosts文件,我们在redis-route文件中使用的host为*,所以我们可以随意绑定一个域名,假设访问域名为redis.cc.com
,或者我们直接访问node的IP和端口。
cat >> /etc/hosts<<EOF
192.168.68.149 redis.cc.com
EOF
从master02访问我们安装的redis服务
redis-cli -h redis.cc.com -p 6379
redis.cc.com:6379> set a 1123
OK
redis.cc.com:6379> get a
"1123"
redis.cc.com:6379>info #获取redis服务端信息,此处内容较多,就不全部显示了
192.168.68.149:6379> info
# Server
redis_version:6.0.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:19d4277f1e8a2fed
redis_mode:standalone
os:Linux 3.10.0-1127.el7.x86_64 x86_64
...
14.10 监控traefik服务
以下内容在“第六课:部署集群监控系统”监控系统部署完毕后进行
启用traefik监控服务
kubectl apply -f traefik-serviceMonitor.yaml
[root@master01 traefik]# kubectl apply -f traefik-serviceMonitor.yaml
servicemonitor.monitoring.coreos.com/traefik created
添加页面到grafana
导入模板文件 Traefik 2-1587191399741.json
安装grafana插件
prometheus-operator-6685db5c6-hszsn 1/1 Running 1 28h
[root@master01 prometheus]# kubectl exec -it -n monitoring grafana-5dc77ff8cb-9lcgc /bin/bash
bash-5.0$ grafana-cli plugins install grafana-piechart-panel
installing grafana-piechart-panel @ 1.6.0
from: https://grafana.com/api/plugins/grafana-piechart-panel/versions/1.6.0/download
into: /var/lib/grafana/plugins
✔ Installed grafana-piechart-panel successfully
Restart grafana after installing plugins . <service grafana-server restart>
删除pod
kubectl delete pods grafana-5dc77ff8cb-9lcgc -n monitoring
k8s会自动重建一个grafana的pod并刷新dashboard加载我们刚才安装的插件。
再次登录grafana监控页面可以看到相应的监控展示
模拟访问
模拟错误页面访问可以查看监控上404访问数量
for i in `seq 1 100001`;do sleep 0.5;curl http://nginx.cc.com/213131;done