Adrian Goins 最近举办了对于如何应用 K3s 和 Traefik 爱护和管制边缘的 Kubernetes 巨匠班,演示了如何拜访 K3s 的 Traefik Proxy 仪表板,能够通过以下路径注册观看回放:https://more.suse.com/MC_Secu... Desktop 创立了一个单节点 K3s 集群,我十分好奇在应用 Rancher Desktop 时,是否能够拜访 Traefik Proxy 仪表板。我在 Adrian 的课程上提出了这个问题,他说应该能够,于是我便开始着手操作。

留神:本文应用的环境为 Linux 操作系统,如 Mac 或 Windows 需视状况调整参数。

本文参考了 Adrian 在 GitHub 上公布的一些课程: https://github.com/traefik-wo...

首先,克隆 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/configserver: https://127.0.0.1:6443> export CLUSTERIP=127.0.0.1

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

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

> kubectl get service -n kube-system traefikNAME      TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                      AGEtraefik   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-systemContext "rancher-desktop" modified.

创立 Service

> kubectl expose deploy/traefik -n kube-system --port=9000 --target-port=9000 --name=traefik-dashboardservice/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 1HTTP/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=webingress.networking.k8s.io/traefik-dashboard annotated

第 2 课:应用 Middleware 爱护仪表板

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

创立用户文件

留神 Adrian 已依据研讨会提供了用户文件设置:

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

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

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

从 middleware-auth.yaml 创立 Middleware

> cat middleware-auth.yamlapiVersion: traefik.containo.us/v1alpha1kind: Middlewaremetadata:  name: dashboard-authspec:  basicAuth:      secret: dashboard-users> kubectl apply -f middleware-auth.yamlmiddleware.traefik.containo.us/dashboard-auth created

将 Middleware 利用到 Ingress

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

请留神,如果你在浏览器中始终拜访仪表板,那么当初应该提醒你输出用户名和明码:

测试 Middleware

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

创立 Middleware 以增加 /dashboard 前缀

> cat middleware-rewrite.yamlapiVersion: traefik.containo.us/v1alpha1kind: Middlewaremetadata:  name: dashboard-rewritespec:  addPrefix:    prefix: /dashboard> kubectl apply -f middleware-rewrite.yamlmiddleware.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=trueingress.networking.k8s.io/traefik-dashboard annotated

拜访没有 /dashboard/ 的仪表板

> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/ | head -n 1HTTP/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@kubernetescrdingress.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-apiingress.networking.k8s.io "traefik-dashboard" deletedingress.networking.k8s.io "traefik-dashboard-api" deleted

创立新的 IngressRoute,咱们须要更改 IP 地址:

> cat ingressroute.yamlapiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:  name: traefik-dashboard-securespec:  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.yamlapiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:  name: traefik-dashboard-securespec:  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.yamlingressroute.traefik.containo.us/traefik-dashboard-secure created

查看 IngressRoute

> kubectl get ingressroute traefik-dashboard -o yamlapiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:  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-76acc5eebbd9spec:  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.yamlingressroute.traefik.containo.us/traefik-dashboard-secure patched
> kubectl delete service traefik-dashboardservice "traefik-dashboard" deleted
> curl -si -u 'admin@example.com:admin1234' http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/ | head -n 1HTTP/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.yamlcustomresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io createdcustomresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created.........mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook createdvalidatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
> kubectl get pods -n cert-managerNAME                                     READY   STATUS    RESTARTS   AGEcert-manager-cainjector-d6cbc4d9-j8q8x   1/1     Running   0          70scert-manager-6d8d6b5dbb-ts2mq            1/1     Running   0          70scert-manager-webhook-85fb68c79b-ql658    1/1     Running   0          70s

创立 ClusterIssuer

> cat clusterissuer.yamlapiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:  name: selfsignedspec:  selfSigned: {}> kubectl apply -f clusterissuer.yamlclusterissuer.cert-manager.io/selfsigned created

为仪表板生成证书

咱们须要更改 IP 地址:

> cat certificate.yamlapiVersion: cert-manager.io/v1kind: Certificatemetadata:  name: dashboardspec:  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.yamlapiVersion: cert-manager.io/v1kind: Certificatemetadata:  name: dashboardspec:  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.yamlcertificate.cert-manager.io/dashboard created
> kubectl get secret | grep tlsk3s-serving                                          kubernetes.io/tls                     2      87mdashboard-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.yamlingressroute.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.yamlapiVersion: traefik.containo.us/v1alpha1kind: Middlewaremetadata:  name: redirect-permanentspec:  redirectScheme:    permanent: true    scheme: https

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

> echo "    port: \"${CLUSTERHTTPS}\"" >> middleware-scheme.yaml> cat middleware-scheme.yamlapiVersion: traefik.containo.us/v1alpha1kind: Middlewaremetadata:  name: redirect-permanentspec:  redirectScheme:    permanent: true    scheme: https    port: "30614"> kubectl apply -f middleware-scheme.yamlmiddleware.traefik.containo.us/redirect-permanent created> cat ingressroute.yamlapiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:  name: traefik-dashboard-httpspec:  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.yamlapiVersion: traefik.containo.us/v1alpha1kind: IngressRoutemetadata:  name: traefik-dashboard-httpspec:  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.yamlingressroute.traefik.containo.us/traefik-dashboard-http created
> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/ | head -n 1HTTP/1.1 301 Moved Permanently

如果咱们删除 head 命令,咱们能够看到它被挪动到了哪里:

> curl -si http://dashboard.traefik.$CLUSTERIP.sslip.io:$CLUSTERHTTP/HTTP/1.1 301 Moved PermanentlyLocation: https://dashboard.traefik.127.0.0.1.sslip.io:30614/Date: Fri, 11 Feb 2022 17:40:15 GMTContent-Length: 17Content-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 浏览器的缓存。