如何使用 Rancher Desktop 访问 Traefik Proxy 仪表板

图片

Adrian Goins 最近举办了关于如何使用 K3s 和 Traefik 保护和控制边缘的 Kubernetes 大师班,演示了如何访问 K3s 的 Traefik Proxy 仪表板,可以通过以下途径注册观看回放:https://more.suse.com/MC_Secure_Edge_K3s_Traefik.html

Rancher Desktop 创建了一个单节点 K3s 集群,我非常好奇在使用 Rancher Desktop 时,是否可以访问 Traefik Proxy 仪表板。我在 Adrian 的课程上提出了这个问题,他说应该可以,于是我便开始着手操作。

注意:本文使用的环境为 Linux 操作系统,如 Mac 或 Windows 需视情况调整参数。

图片

本文参考了 Adrian 在 GitHub 上发布的一些课程: https://github.com/traefik-workshops/k3s-and-traefik-proxy

图片

首先,克隆 Adrian 的 repo:

> git clone https://github.com/traefik-workshops/k3s-and-traefik-proxy.git
> cd k3s-and-traefik-proxy/

第一课: 暴露 Traefik 仪表盘

注意:01-Expose-the-Dashboard 中的所有文件目前都没有在 Adrian 的课程中使用。

将集群 IP 设置为变量

Adrian 建议检查 kubeconfig 文件中的集群 IP 地址,Rancher Desktop 会在主机上创建一个 ~/.kube/config 文件:

> grep server ~/.kube/config
server: https://127.0.0.1:6443

> export CLUSTERIP=127.0.0.1

此时,Adrian 继续他的课程,但目前 Linux 上的 Rancher Desktop 存在一个问题:特权端口(低于 1024 的端口)无法访问。请参考 https://github.com/rancher-sandbox/rancher-desktop/issues/576

相反,Linux 上的 Rancher Desktop 用户必须了解 HTTP (80) 和 HTTPS (443) 端口已转发到哪些 Ingress 端口:

> kubectl get service -n kube-system traefik
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                      AGE
traefik   LoadBalancer   10.43.146.37   192.168.5.15   80:30876/TCP,443:30614/TCP   26

我们将 Ingress 端口保存到变量中,以便可以在整个课程中使用:

> export CLUSTERHTTP=`kubectl get service -n kube-system traefik -o json | jq '.spec.ports[0].nodePort'`
> export CLUSTERHTTPS=`kubectl get service -n kube-system traefik -o json | jq '.spec.ports[1].nodePort'`

切换当前 Namespace 为 kube-system

> kubectl config set-context --current --namespace kube-system
Context "rancher-desktop" modified.

创建 Service

> kubectl expose deploy/traefik -n kube-system --port=9000 --target-port=9000 --name=traefik-dashboard
service/traefik-dashboard exposed

创建 Ingress

> kubectl create ingress traefik-dashboard --rule="dashboard.traefik.$CLUSTERIP.sslip.io/*=traefik-dashboard:9000"
ingress.networking.k8s.io/traefik-dashboard created

访问仪表板

与 Adrian 步骤不同的是,我们需要在 URL 中包含 HTTP 的 Ingress 端口:

> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/dashboard/ | head -n 1
HTTP/1.1 200 OK
> echo http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/dashboard/
http://dashboard.traefik.127.0.0.1.sslip.io:30876/dashboard/
图片
图片
图片

添加 Annotations

> kubectl annotate ingress traefik-dashboard traefik.ingress.kubernetes.io/router.entrypoints=web
ingress.networking.k8s.io/traefik-dashboard annotated
图片

第 2 课:使用 Middleware 保护仪表板

> cd 02-Secure-the-Dashboard-With-Middleware

创建用户文件

注意 Adrian 已根据研讨会提供了用户文件设置:

> cat users
user@example.com:$apr1$nWlieTS.$pbESld2QB5uYuUTAfFICr.
admin@example.com:$apr1$XMtXkoUy$IwIKiM./ujfaYf6/MsCaf1

从用户文件中创建仪表板 dashboard-users Secret

> kubectl create secret generic dashboard-users --from-file=users
secret/dashboard-users created

从 middleware-auth.yaml 创建 Middleware

> cat middleware-auth.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: dashboard-auth
spec:
  basicAuth:
      secret: dashboard-users

> kubectl apply -f middleware-auth.yaml
middleware.traefik.containo.us/dashboard-auth created

将 Middleware 应用到 Ingress

> kubectl annotate ingress traefik-dashboard \
traefik.ingress.kubernetes.io/router.middlewares=kube-system-dashboard-auth@kubernetescrd
ingress.networking.k8s.io/traefik-dashboard annotated

请注意,如果你在浏览器中一直访问仪表板,那么现在应该提示你输入用户名和密码:

图片

测试 Middleware

> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/dashboard/ | head -n 1
HTTP/1.1 401 Unauthorized
> curl -si -u 'admin@example.com:admin1234' http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/dashboard/ | head -n 1
HTTP/1.1 200 OK

创建 Middleware 以添加 /dashboard 前缀

> cat middleware-rewrite.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: dashboard-rewrite
spec:
  addPrefix:
    prefix: /dashboard

> kubectl apply -f middleware-rewrite.yaml
middleware.traefik.containo.us/dashboard-rewrite created

将第二个 Middleware 应用到 Ingress

> kubectl annotate ingress traefik-dashboard \
  traefik.ingress.kubernetes.io/router.middlewares=kube-system-dashboard-rewrite@kubernetescrd,kube-system-dashboard-auth@kubernetescrd \
  --overwrite=true
ingress.networking.k8s.io/traefik-dashboard annotated

访问没有 /dashboard/ 的仪表板

> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/ | head -n 1
HTTP/1.1 401 Unauthorized
图片

修复仪表板

> kubectl create ingress traefik-dashboard-api --rule="dashboard.traefik.$CLUSTERIP.sslip.io/api/*=traefik-dashboard:9000"
ingress.networking.k8s.io/traefik-dashboard-api created
> kubectl annotate ingress traefik-dashboard-api \
  traefik.ingress.kubernetes.io/router.middlewares=kube-system-dashboard-auth@kubernetescrd
ingress.networking.k8s.io/traefik-dashboard-api annotated
图片

第 3 课:使用 IngressRoute 自定义资源

> cd ../03-Use-the-IngressRoute-Custom-Resource/

将 Ingress 更改为 IngressRoutes

移除之前创建的 Ingress:

> kubectl delete ingress/traefik-dashboard ingress/traefik-dashboard-api
ingress.networking.k8s.io "traefik-dashboard" deleted
ingress.networking.k8s.io "traefik-dashboard-api" deleted

创建新的 IngressRoute,我们需要更改 IP 地址:

> cat ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-secure
spec:
  entryPoints:
  - web
  routes:
  - kind: Rule
    match: Host("dashboard.traefik.10.68.0.70.sslip.io")
    services:
    - name: traefik-dashboard
      port: 9000
    middlewares:
    - name: dashboard-auth
    - name: dashboard-rewrite
  - kind: Rule
    match: Host("dashboard.traefik.10.68.0.70.sslip.io") && PathPrefix("/api")
    services:
    - name: traefik-dashboard
      port: 9000
    middlewares:
    - name: dashboard-auth

> sed -i "s/10\.68\.0\.70/${CLUSTERIP}/" ingressroute.yaml

> cat ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-secure
spec:
  entryPoints:
  - web
  routes:
  - kind: Rule
    match: Host("dashboard.traefik.127.0.0.1.sslip.io")
    services:
    - name: traefik-dashboard
      port: 9000
    middlewares:
    - name: dashboard-auth
    - name: dashboard-rewrite
  - kind: Rule
    match: Host("dashboard.traefik.127.0.0.1.sslip.io") && PathPrefix("/api")
    services:
    - name: traefik-dashboard
      port: 9000
    middlewares:
    - name: dashboard-auth

> kubectl apply -f ingressroute.yaml
ingressroute.traefik.containo.us/traefik-dashboard-secure created

查看 IngressRoute

> kubectl get ingressroute traefik-dashboard -o yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  annotations:
    helm.sh/hook: post-install,post-upgrade
  creationTimestamp: "2022-02-11T16:01:09Z"
  generation: 1
  labels:
    app.kubernetes.io/instance: traefik
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: traefik
    helm.sh/chart: traefik-10.9.100
  name: traefik-dashboard
  namespace: kube-system
  resourceVersion: "657"
  uid: 7993457e-7cde-478b-82c9-76acc5eebbd9
spec:
  entryPoints:
  - traefik
  routes:
  - kind: Rule
    match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
    services:
    - kind: TraefikService
      name: api@internal

什么是 TraefikService?

> kubectl patch ingressroute/traefik-dashboard-secure --type=json --patch-file patch-dashboard-service.yaml
ingressroute.traefik.containo.us/traefik-dashboard-secure patched
> kubectl delete service traefik-dashboard
service "traefik-dashboard" deleted
> curl -si -u 'admin@example.com:admin1234' http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/ | head -n 1
HTTP/1.1 200 OK

第 4 课:使用 TLS 保护仪表板

> cd ../04-Secure-the-Dashboard-With-TLS/

设置 cert-manager

我使用了最新版本的 cert-manager,目前是 1.7.1:

> kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
...
...
...
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
> kubectl get pods -n cert-manager
NAME                                     READY   STATUS    RESTARTS   AGE
cert-manager-cainjector-d6cbc4d9-j8q8x   1/1     Running   0          70s
cert-manager-6d8d6b5dbb-ts2mq            1/1     Running   0          70s
cert-manager-webhook-85fb68c79b-ql658    1/1     Running   0          70s

创建 ClusterIssuer

> cat clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned
spec:
  selfSigned: {}

> kubectl apply -f clusterissuer.yaml
clusterissuer.cert-manager.io/selfsigned created

为仪表板生成证书

我们需要更改 IP 地址:

> cat certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: dashboard
spec:
  subject:
    organizations:
    - Traefik Academy
  commonName: dashboard.traefik.10.68.0.70.sslip.io
  issuerRef:
    kind: ClusterIssuer
    name: selfsigned
  secretName: dashboard-crt

> sed -i "s/10\.68\.0\.70/${CLUSTERIP}/" certificate.yaml

> cat certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: dashboard
spec:
  subject:
    organizations:
    - Traefik Academy
  commonName: dashboard.traefik.127.0.0.1.sslip.io
  issuerRef:
    kind: ClusterIssuer
    name: selfsigned
  secretName: dashboard-crt

> kubectl apply -f certificate.yaml
certificate.cert-manager.io/dashboard created
> kubectl get secret | grep tls
k3s-serving                                          kubernetes.io/tls                     2      87m
dashboard-crt

将证书添加到 IngressRoute

> cat patch-dashboard-tls.yaml
- op: replace
  path: /spec/entryPoints
  value:
    - websecure
- op: add
  path: /spec/tls
  value:
    secretName: dashboard-crt

> kubectl patch ingressroute/traefik-dashboard-secure \
  --type=json \
  --patch-file patch-dashboard-tls.yaml
ingressroute.traefik.containo.us/traefik-dashboard-secure patched
> echo https://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTPS/
https://dashboard.traefik.127.0.0.1.sslip.io:30614/
图片
图片

添加 HTTP 重定向

> cat middleware-scheme.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-permanent
spec:
  redirectScheme:
    permanent: true
    scheme: https

需要在 middleware-scheme.yaml 添加 HTTPS 端口,并在 ingressroute.yaml 中更改 IP 地址:

> echo "    port: \"${CLUSTERHTTPS}\"" >> middleware-scheme.yaml

> cat middleware-scheme.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-permanent
spec:
  redirectScheme:
    permanent: true
    scheme: https
    port: "30614"

> kubectl apply -f middleware-scheme.yaml
middleware.traefik.containo.us/redirect-permanent created

> cat ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-http
spec:
  entryPoints:
  - web
  routes:
  - kind: Rule
    match: Host("dashboard.traefik.10.68.0.70.sslip.io")
    services:
    - name: api@internal
      kind: TraefikService
    middlewares:
    - name: redirect-permanent

> sed -i "s/10\.68\.0\.70/${CLUSTERIP}/" ingressroute.yaml

> cat ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-http
spec:
  entryPoints:
  - web
  routes:
  - kind: Rule
    match: Host("dashboard.traefik.127.0.0.1.sslip.io")
    services:
    - name: api@internal
      kind: TraefikService
    middlewares:
    - name: redirect-permanent

> kubectl apply -f ingressroute.yaml
ingressroute.traefik.containo.us/traefik-dashboard-http created
> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/ | head -n 1
HTTP/1.1 301 Moved Permanently

如果我们删除 head 命令,我们可以看到它被移动到了哪里:

> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/
HTTP/1.1 301 Moved Permanently
Location: https://dashboard.traefik.127.0.0.1.sslip.io:30614/
Date: Fri, 11 Feb 2022 17:40:15 GMT
Content-Length: 17
Content-Type: text/plain; charset=utf-8

该位置应包括 HTTPS 的 Ingress 端口:

> echo http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/
http://dashboard.traefik.127.0.0.1.sslip.io:30876/

如果我们在 Web 浏览器中打开 URL,它应该重定向到 HTTPS 站点。如果没有,你可能需要清除 Web 浏览器的缓存。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容