CentOS上安装Kubernetes集群(四)使用Traefi暴露Kubernetes服务

k8s的集群大多数情况需要对外服务,而服务暴露的方式有很多,这里选取traefik来讲解,其它就暂时不详细介绍,包括Istio,代后续更新后再补充上来。一句话,来不及解释,赶紧上车。

Traefkik简介

Traefik是开源边缘路由器,类似 nginx、apache 那样的反向代理服务器、网关,代表系统接收请求,并找出负责处理这些请求的组件。Traefik自动发现适合您服务的配置,同时热更新支持多种负载均衡算法断路器,重试提供监控、管理 UI 界面用 go 语言开发,天然的拥抱 k8s

Traefik 2.0 几个值得关注的功能

  • 使用 CRD 来完成之前 Ingress + 注解的功能
  • 支持多协议的 TCP 端口路由
  • 引入了 MiddleWare,使用中间件完全自定义路由
  • 金丝雀发布

部署Traefik

部署规划

本人的k8s环境是一台华为TaiShan2280v2的ARM服务器+多台x86_64服务器,TaiShan2280v2服务器作为master节点,同时运行traefik组为边界路由和负载均衡器(本人的应用需求没有那么高,想充分利用这台新近的ARM服务器,高可用方面暂时没有考虑,后续会逐渐跟上),而其它服务器则只作为node节点。Traefik作为边界路由、负载均衡,采用了hostport+特定节点的方式进行部署。

部署CRD资源

比较固定,使用官方文档即可

创建traefik-crd.yaml文件

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingre***outes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Ingre***oute
plural: ingre***outes
singular: ingre***oute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingre***outetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Ingre***outeTCP
plural: ingre***outetcps
singular: ingre***outetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced

创建CRD(CustomResourceDefinition)资源

$ kubectl apply -f traefik-crd.yaml

创建 RBAC 权限

Kubernetes 在 1.6 版本中引入了基于角色的访问控制(RBAC)策略,方便对 Kubernetes 资源和 API 进行细粒度控制。Traefik 需要一定的权限,所以这里提前创建好 Traefik ServiceAccount 并分配一定的权限。

创建 traefik-rbac.yaml 文件

apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
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:
- ingre***outes
verbs:
- get
- list
- watch
- apiGroups:
- traefik.containo.us
resources:
- ingre***outetcps
verbs:
- get
- list
- watch
- apiGroups:
- traefik.containo.us
resources:
- tlsoptions
verbs:
- get
- list
- watch
- apiGroups:
- traefik.containo.us
resources:
- traefikservices
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: default

创建RBAC资源

$ kubectl apply -f traefik-rbac.yaml

节点设置(可选)

标签

因为我的集群里面有ARM服务器,想让traefik运行在特定的节点上,该节点也作为负载均衡和路由节点,因此需要设置标签,当然我这里的环境也可以不用设置,因为ARM服务器只有一台),直接利用系统的标签也可以。

设置标签

$ kubectl label node taishan2280v2 IngressProxy=true

查看标签

$ kubectl get nodes --show-lables

通过查看标签命令可以看见默认设置的标签,可以自己加以利用。

设置污点taints和容忍tolerations

查看污点 taint

污点是设置在 Node 节点上,所以我们可以通过查看节点信息来查找该节点是否设置污点以及对污点的信息。查看节点名称如下:

  • 语法:kubectl describe nodes [节点名]
$ kubectl describe node 

显示节点信息如下:

Name: taishan2280v2
Labels: beta.kubernetes.io/arch=arm64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=master.k8s
Annotations:  volumes.kubernetes.io/controller-managed-attach-detach=tr
Taints: node-role.kubernetes.io/master:NoSchedule     #污点信息

设置容忍 tolerations

如果计划调度的节点有污点设置,则部署的时候需要相应的设置,详见下面的部署文件。

参考

关于污点taints和容忍tolerations,详见参考文档(待写:))

部署Traefik

部署Traefik采用Daemonset+hostport方式(兼顾后期hostport+特定节点)

创建traefik-deploy.yaml

# 创建和RBAC相关的ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: traefik-ingress-controller
---
# 创建traefik服务
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
ports:
- protocol: TCP
name: web
port: 8000
- protocol: TCP
name: admin
port: 8080
- protocol: TCP
name: websecure
port: 4443
selector:
app: traefik
---
# 创建traefik的daemonset
kind: DaemonSet
apiVersion: apps/v1
metadata:
namespace: default
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.0.7
args:
- --api.insecure
- --accesslog
- --entrypoints.web.Address=:8000
- --entrypoints.websecure.Address=:4443
- --providers.kubernetescrd
- --certificatesresolvers.default.acme.tlschallenge
- --certificatesresolvers.default.acme.email=foo@you.com
- --certificatesresolvers.default.acme.storage=acme.json
# Please note that this is the staging Let's Encrypt server.
# Once you get things working, you should remove that whole line altogether.
- --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
ports:
- name: web
containerPort: 8000
hostPort: 8000
- name: websecure
containerPort: 4443
hostPort: 4443
- name: admin
containerPort: 8080
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 1000m
memory: 1024Mi
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
tolerations: #设置容忍所有污点,防止节点被设置污点
- operator: "Exists"
nodeSelector: #设置node筛选器,在特定label的节点上启动
IngressProxy: "true"

注意:此处的镜像用的是traefik:v2.0.7,写这篇文章的时候2.1.1也出来了,我自己也调试过,换个版本有问题!

部署traefik

kubectl apply -f traefik-deploy.yaml

配置Traefik路由规则

配置 HTTP 路由规则 (Traefik Dashboard 为例)

Traefik 应用已经部署完成,但是想让外部访问 Kubernetes 内部服务,还需要配置路由规则,这里开启了 Traefik Dashboard 配置,所以首先配置 Traefik Dashboard 看板的路由规则,使外部能够访问 Traefik Dashboard。

创建 Traefik Dashboard 路由规则文件 traefik-dashboard-route.yaml

apiVersion: traefik.containo.us/v1alpha1
kind: Ingre***oute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
routes:
- match: Host(`traefik`)
kind: Rule
services:
- name: traefik
port: 8080

创建 Traefik Dashboard 路由规则对象

$ kubectl apply -f traefik-dashboard-route.yaml

接下来配置 Hosts,客户端想通过域名访问服务,必须要进行 DNS 解析,由于这里没有 DNS 服务器进行域名解析,所以修改 hosts 文件将 Traefik 指定节点的 IP 和自定义 host 绑定。我自己的如下:

172.17.1.254  traefik 

配置完成后,打开浏览器输入地址:http://traefik 打开 Traefik Dashboard。

配置 HTTPS 路由规则(Kubernetes Dashboard 为例)

Kubernetes 的 Dashboard 看板,它是 Https 协议方式,由于它是需要使用 Https 请求,所以我们配置基于 Https 的路由规则并指定证书。

  • 下载部署kubernetes dashboard
$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

离线部署注意准备好镜像,同时,我的kubernetes dashboard部署在ARM服务器上,还需要更改yaml文件中的nodeSelect,同时注意污点和容忍。

$ kubectl appply -f recommended.yaml
  • 创建自签名证书
$ openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=kubernetes-dashboard-admin"
  • 将证书存储到 Kubernetes Secret 中
$ kubectl create secret generic kubernetes-dashboard-admin--from-file=tls.crt --from-file=tls.key -n kubernetes-dashboard
  • 创建kubernetes-dashboard的账户和相关绑定。

1.创建文件kubernetes-dashboard-admin.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: dashboard-admin
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: dashboard-admin-bind-cluster-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kubernetes-dashboard

2.创建账户和绑定

$ kubectl apply -f kubernetes-dashboard-admin.yaml -n kubernetes-dashboard
  • 创建 Traefik Dashboard 路由规则文件 kubernetes-dashboard-route.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Ingre***oute
metadata:
name: kubernetes-dashboard-route
spec:
entryPoints:
- websecure
tls:
secretName: kubernetes-dashboard-admin
routes:
- match: Host(`kubernetes-dashboard`)
kind: Rule
services:
- name: kubernetes-dashboard
port: 443
  • 创建 Kubernetes Dashboard 路由规则对象
$ kubectl apply -f kubernetes-dashboard-route.yaml -n kubernetes-dashboard
  • 查卡记录token
kubectl describe secret/$(kubectl get secret -n kube-system |grep admin|awk '{print $1}') -n kubernete-dashboard
  • 配置 Hosts 文件,使用token进行访问
172.17.1.254  kubernetes-dashboard

配置完成后,打开浏览器输入地址:https://kubernetes-dashboard.

有关Kubernetes DashBoard的详细部署见(待写)