1. 背景
Kubernetes Service 服务默认只能内网访问,而使用 nodePort 方式的服务暴露会在每台服务器上开放目标端口,
存在大量端口占用现象,难以应用于生产环境,本文介绍通过 traefik ingress 方式实现内部服务的外部可访问化。
2. 基本步骤
2.1 导入 traefik 镜像到 kubernetes 集群(如果是内网环境,就上传镜像 tar 包,用 docker load 载入即可)
# docker pull traefik:alpine
2.2 部署 traefik 服务
权限授予
# vim ingress-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress
namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: ingress
subjects:
- kind: ServiceAccount
name: ingress
namespace: kube-system
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
# kubectl create -f ingress-rbac.yaml
服务创建
# vim traefik.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: traefik-ingress-lb
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
terminationGracePeriodSeconds: 60
hostNetwork: true
restartPolicy: Always
serviceAccountName: ingress
containers:
- image: traefik:alpine
name: traefik-ingress-lb
resources:
limits:
cpu: 200m
memory: 30Mi
requests:
cpu: 100m
memory: 20Mi
ports:
- name: http
containerPort: 80
hostPort: 80
- name: admin
containerPort: 8580
hostPort: 8580
args:
- --web
- --web.address=:8580
- --kubernetes
# kubectl create -f traefik.yaml
UI 创建(host 字段可以替换成自己想要的域名,这里以 ui.traefik.kubernetes.local 为例说明)
# vim 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: 8580
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
rules:
- host: ui.traefik.kubernetes.local
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
# kubectl create -f ui.yaml
2.3 验证 traefik 工作是否正常
浏览器访问 traefik-ingress-lb 容器运行所在物理机的 8580 端口,查看 traefik 状态 ,类似下图则正常
2.4 应用实例(可选,到 2.3 步,其实已经完成 traefik 的部署了)
开放服务的前提是已经有服务在正常运行,这里我的实验集群中已经运行好了 ELK 日志收集系统,就以 kibana 服务为例,讲解服务暴露的步骤。
a)创建 ingress
其中,namespace 为 kibana 服务所在的命名空间,host 为 kibana 服务的访问域名(用户可以任意设置)
serviceName 和 servicePort 为 kibana 服务的内网访问服务名和端口(这是在创建服务时可指定的)
# vim kibana-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-kibana
namespace: development
spec:
rules:
- host: kibana.traefik.kubernetes.local
http:
paths:
- path: /
backend:
serviceName: kibana-headless-svc
servicePort: 5601
# kubectl create -f kibana-ingress.yaml
b) 配置客户端 hosts
选择任意一台与 traefik-ingress-lb 容器运行所在物理机互联的机器作为客户端,
编辑客户端本地 hosts 文件,将 kibana 服务的外部访问域名与 traefik 容器所在物理机 IP 地址建立起映射关系,如
然后,客户端就可以直接通过该域名访问 kibana 服务了,traefik 将通过域名将流量自动转发给后端的真实Pod。
当然,配置 hosts 文件只是一种暴力方式实现映射,更好的方法是配置一个 DNS 服务,具体方法不再赘述!
可参考http://blog.csdn.net/shida_csdn/article/details/78931436
最后附一张 traefik 代理原理图,来自官网