之前初试k3s
,发现其自带traefik
实现ingress
。与使用nginx
实现ingress
不同,traefik
无需额外部署ingress-controller
,自己就可以做到服务发现。
traefik
自带一个web-ui
,但是k3s
中的默认没开启,本博客关注如何开启traefik
自带的web-ui
,并配置一个ingress
指向此web-ui
。
k3s
相关的内容可见笔者另一篇博客《k3s初探》
我用的k3s版本为v1.17.0+k3s.1
,其自带traefik版本为1.7.19
ingress简介
ingress
有点像apache
或nginx
中的VirtualHost
,可以做到一个ip
处理指向多个域名的请求,借助http
头中的Host
实现七层负载均衡
traefik简介
traefik
自己的一句话自我介绍为:
The Cloud Native Edge Router
其官网截图如下:
之前的官网风格更卡通一些,有个拿着交通指挥棒的
golang
吉祥物,可见老站的文档部分,截图如下:k3s中启用traefik自带的dashboard
默认情况下k3s
安装traefik
没有启用其dashboard
先看配置在哪里,kubectl describe
观察可得如下信息,略去不关注的:
$ kubectl describe deploy traefik -n kube-system
# 略
Pod Template:
# 略
Containers:
traefik:
Image: traefik:1.7.14
Ports: 80/TCP, 8880/TCP, 443/TCP, 8080/TCP
Host Ports: 0/TCP, 0/TCP, 0/TCP, 0/TCP
Args:
--configfile=/config/traefik.toml
# 略
Mounts:
/config from config (rw)
/ssl from ssl (rw)
Volumes:
config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: traefik
Optional: false
ssl:
Type: Secret (a volume populated by a Secret)
SecretName: traefik-default-cert
Optional: false
可知使用了配置文件/config/traefik.toml
,其挂载为一个ConfigMap
,describe
得到如下:
$ kubectl describe configmap traefik -n kube-system
Name: traefik
Namespace: kube-system
Labels: app=traefik
chart=traefik-1.77.1
heritage=Tiller
release=traefik
Annotations: <none>
Data
====
traefik.toml:
----
# traefik.toml
logLevel = "info"
defaultEntryPoints = ["http","https"]
[entryPoints]
[entryPoints.http]
address = ":80"
compress = true
[entryPoints.https]
address = ":443"
compress = true
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
CertFile = "/ssl/tls.crt"
KeyFile = "/ssl/tls.key"
[ping]
entryPoint = "http"
[kubernetes]
[kubernetes.ingressEndpoint]
publishedService = "kube-system/traefik"
[traefikLog]
format = "json"
[metrics]
[metrics.prometheus]
entryPoint = "traefik"
Events: <none>
修改前,traefik
启动日志如下:
$ kubectl logs traefik-65bccdc4bd-q624r -n kube-system
{"level":"info","msg":"Using TOML configuration file /config/traefik.toml","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"No tls.defaultCertificate given for https: using the first item in tls.certificates as a fallback.","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Traefik version v1.7.14 built on 2019-08-14_09:46:58AM","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://docs.traefik.io/basics/#collected-data\n","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Preparing server http \u0026{Address::80 TLS:\u003cnil\u003e Redirect:\u003cnil\u003e Auth:\u003cnil\u003e WhitelistSourceRange:[] WhiteList:\u003cnil\u003e Compress:true ProxyProtocol:\u003cnil\u003e ForwardedHeaders:0xc0006e5c20} with readTimeout=0s writeTimeout=0s idleTimeout=3m0s","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Preparing server https \u0026{Address::443 TLS:0xc0001270e0 Redirect:\u003cnil\u003e Auth:\u003cnil\u003e WhitelistSourceRange:[] WhiteList:\u003cnil\u003e Compress:true ProxyProtocol:\u003cnil\u003e ForwardedHeaders:0xc0006e5c40} with readTimeout=0s writeTimeout=0s idleTimeout=3m0s","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Starting server on :80","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Preparing server traefik \u0026{Address::8080 TLS:\u003cnil\u003e Redirect:\u003cnil\u003e Auth:\u003cnil\u003e WhitelistSourceRange:[] WhiteList:\u003cnil\u003e Compress:false ProxyProtocol:\u003cnil\u003e ForwardedHeaders:0xc0006e5ca0} with readTimeout=0s writeTimeout=0s idleTimeout=3m0s","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Starting provider configuration.ProviderAggregator {}","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Starting server on :8080","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Starting server on :443","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Starting provider *kubernetes.Provider {\"Watch\":true,\"Filename\":\"\",\"Constraints\":[],\"Trace\":false,\"TemplateVersion\":0,\"DebugLogGeneratedTemplate\":false,\"Endpoint\":\"\",\"Token\":\"\",\"CertAuthFilePath\":\"\",\"DisablePassHostHeaders\":false,\"EnablePassTLSCert\":false,\"Namespaces\":null,\"LabelSelector\":\"\",\"IngressClass\":\"\",\"IngressEndpoint\":{\"IP\":\"\",\"Hostname\":\"\",\"PublishedService\":\"kube-system/traefik\"}}","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"ingress label selector is: \"\"","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Creating in-cluster Provider client","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Server configuration reloaded on :443","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Server configuration reloaded on :8080","time":"2019-11-15T00:42:19Z"}
{"level":"info","msg":"Server configuration reloaded on :80","time":"2019-11-15T00:42:19Z"}
先修改一下,在前述文件最后追加如下内容:
[web]
address = ":8080"
这种情况下,依然无法访问。见官网关于web的配置文档被标记为deprecated
,也可见其启动日志,其中略去重复部分
$ kubectl logs -f traefik-65bccdc4bd-5k68p -n kube-system
...
{"level":"warning","msg":"web provider configuration is deprecated, you should use these options : api, rest provider, ping and metrics","time":"2019-11-15T03:08:06Z"}
{"level":"warning","msg":"web option is ignored if you use it with one of these options : api, rest provider, ping or metrics","time":"2019-11-15T03:08:06Z"}
...
{"level":"warning","msg":"Endpoints not available for kube-system/traefik","time":"2019-11-15T03:08:06Z"}
...
{"level":"warning","msg":"Endpoints not available for kube-system/traefik","time":"2019-11-15T03:08:06Z"}
{"level":"warning","msg":"Endpoints not available for kube-system/traefik","time":"2019-11-15T03:08:06Z"}
见官网关于api的配置文档,改用api
,前述文件最后追加内容改为:
[api]
address = ":8080"
entryPoint = "traefik"
另一种方法,可见github上traefik的示例:
kind: Deployment
# 略
spec:
# 略
template:
# 略
spec:
# 略
containers:
- image: traefik:v1.7
# 略
args:
- --api
# 略
即,增加traefik
启动参数--api
两种方法均可成功访问,未见日志中有新内容。
配置ingress
至此即可着手配置一个ingress
,Deployment
部分信息如下:
kind: Deployment
metadata:
name: traefik
namespace: kube-system
spec:
replicas: 1
template:
spec:
containers:
- name: traefik
ports:
- containerPort: 8080
name: dash
protocol: TCP
于是在service
中也增加一个指向pod
的dash
的端口,起名暂定dash
:
- name: dash
port: 18080
targetPort: dash
最后即可写出Ingress
的配置:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: traefik.dracula.io
http:
paths:
- backend:
serviceName: traefik
servicePort: dash # 使用service中的名字
历史版本不同之处
如果使用k3s v1.0.0
,其自带traefik v1.7.14
。Service
中名为metrics
的端口指向Pod
中的dash
$ kubectl describe svc traefik -n kube-system
Name: traefik
Namespace: kube-system
Labels: app=traefik
chart=traefik-1.77.1
heritage=Tiller
release=traefik
Annotations: <none>
Selector: app=traefik,release=traefik
Type: LoadBalancer
IP: 10.43.138.65
LoadBalancer Ingress: 115.171.210.215
Port: http 80/TCP
TargetPort: http/TCP
NodePort: http 30536/TCP
Endpoints: 10.42.0.66:80
Port: https 443/TCP
TargetPort: https/TCP
NodePort: https 30312/TCP
Endpoints: 10.42.0.66:443
Port: metrics 8080/TCP
TargetPort: dash/TCP
NodePort: metrics 32554/TCP
Endpoints: 10.42.0.66:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
$ kubectl get svc -n kube-system traefik -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2019-11-20T14:35:13Z"
labels:
app: traefik
chart: traefik-1.77.1
heritage: Tiller
release: traefik
name: traefik
namespace: kube-system
resourceVersion: "24172"
selfLink: /api/v1/namespaces/kube-system/services/traefik
uid: e36ac022-9e3b-43d4-94d1-e639c02cb99e
spec:
clusterIP: 10.43.60.112
externalTrafficPolicy: Cluster
ports:
- name: http
nodePort: 32125
port: 80
protocol: TCP
targetPort: http
- name: https
nodePort: 30918
port: 443
protocol: TCP
targetPort: https
- name: metrics
nodePort: 31742
port: 8080
protocol: TCP
targetPort: dash
selector:
app: traefik
release: traefik
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.168.3.24
可知service
中端口metrics
对应到pod
中端口dash
,据此,ingress
的yaml
中servicePort
字段不同:
apiVersion: extensions/v1beta1
kind: Ingress
(略)
spec:
rules:
- host: traefik.dracula.io
http:
paths:
- backend:
serviceName: traefik
servicePort: metrics # 不同之处