本文来自边缘计算k3s社区

作者简介

Cello Spring,瑞士人。从电子起步,拥有电子工程学位。尔后开始关注计算机领域,在软件开发领域拥有多年的工作经验。

Traefik是一个十分可靠的云原生动态反向代理。轻量级Kubernetes发行版K3s早在去年就已经内置Traefik,将其作为集群的默认反向代理和Ingress Controller。然而,在本文成文时K3s中的默认内置Traefik版本为v1.7.14。这一版本固然也能很好地运行,但还是少了一些有用的功能。我最想用的功能是为正在使用的Ingress Route自动生成Let’s Encrypt证书。而使用Traefik 2.x版本可以获得这一功能,甚至还有更多其他功能。那么,我们来看看如何使用K3s设置并使用新版本的Traefik。

本文的目标是设置一个新的K3s集群、安装Traefik 2.x版本并配置一些Ingress,这些Ingress将由自动生成的Let’s Encrypt证书保护。

以下是我们将要进行的步骤:

  • 在Civo上创建一个极小的K3s集群

  • 将我们的域(我会使用我的虚拟域celleri.ch)指向集群IP

  • 安装Klipper LB作为我们的LoadBalancer

  • 在集群上安装Traefik v2

  • 部署一个小型工作负载(whoami)到集群上

  • 创建一个Traefik ingress到服务(分为有TLS termination或没有)

  • 使用Traefik 中间件以通过基本身份验证访问Traefik Dashboard

创建Civo集群

为此,请到Civo(civo.com/)并创建一个只有2个节点的超小型集群。如果你还没有账户,可以注册并申请KUBE100 Beta项目以使用其提供的Kubernetes产品。

需要确保我们不使用基本设置安装Traefik(在“Architecture”选项卡上取消选择Traefik)

大约2分钟之后,我们将获得以下集群:

接下来,我们需要记下master节点的IP地址并下载kubeconfig文件。在本例中,它被命名为civo-k3s-with-traefik2-kubeconfig,因为我们将集群命名为k3s-with-traefik2。为了使用kubectl从命令行中访问该集群,我们需要将环境变量指向kubeconfig文件并将上下文更改至我们的新集群。

# set env variable with new cluster config
export KUBECONFIG=./civo-k3s-with-traefik2-kubeconfig
kubectl config use-context k3s-with-traefik2 #check the available nodes
kubectl get nodes NAME STATUS ROLES AGE VERSION
kube-master-de56 Ready master 9m15s v1.16.3-k3s.2
kube-node-40e7 Ready 7m21s v1.16.3-k3s.2

正如我们所见,带有1个master节点和1个worker节点的集群已经准备完毕!继续进行下一步。

将域名Celleri.ch指向新的集群IP地址

最近一段时间,我一直使用Cloudflare(cloudflare.com/dns/)的DNS服务来处理Kubernetes。它十分可靠,有友好的用户界面并且我使用的基本服务都是免费的。

在Cloudflare中我们应用以下设置:

本示例中,我们不想为可能用到的每个子域都创建一个CNAME条目,因此我们在此处创建一个通配符(*)条目作为CNAME。Traefik将确保稍后将流量路由到正确的位置。

安装Klipper LB作为我们的LoadBalancer

默认情况下,K3s内置的Traefik为v1.7.x版本。默认安装还部署了来自Rancher的内部LoadBalancer,Klipper LB。由于在设置集群时,我们没有安装Traefik,因此我们现在必须自己手动安装Klipper LB。

Klipper会将自己挂接到集群节点的主机端口上,并使用端口80、443和8080。

你可以在我的Github Repo里找到我所提到的所有文件:

https://github.com/cellerich/k3s-with-traefik2

# install KlipperLB
kubectl apply -f 00-klipper-lb/klipper.yaml # see if klipper hooked up to the host ports and is working
kc get pods --all-namespaces | grep svclb
kube-system svclb-traefik-gc8lg 3/3 Running 0 96s
kube-system svclb-traefik-pqbzb 3/3 Running 0 96s

这些Pod似乎可以与在其中运行的3个容器(每个主机端口一个容器)一起工作。接下来,我们开始安装Traefik v2。

在集群中安装Traefik v2

Traefik v2附带了许多CRD,这似乎是扩展Kubernetes对象的一种新方法。我还没有完全把精力放在这些CRD上面,但是无论如何我们都要使用它们。你可以在Traefik文档(https://docs.traefik.io/v2.0/user-guides/crd-acme/)中找到正确的yaml文件,或者你可以使用我在Github repo上提供的01-traefik-crd/traefik-crd.yaml文件。

# apply traefik crd's
kubectl apply -f 01-traefik-crd/traefik-crd.yaml

这个命令应该会创建5个CRD。

为了让Traefik可以做它所需要做的事情,我们需要一个clusterrole和一个clusterrolebinding。我们可以使用以下命令:

# apply clusterrole and clusterrolebinding
kubectl apply -f 01-traefik-crd/traefik-clusterrole.yaml

请注意:我们将在命名空间kube-system中为ServiceAccount进行clusterrolebinding,因为稍后我们会将流量安装到该命名空间中。


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: kube-system

最后,我们把Traefik Service、ServiceAccount以及Deployment部署到集群中:

kubectl apply -f 02-traefik-service/traefik.yaml

这应该为我们提供一个LoadBalancer类型的服务,该服务具有集群的master节点的外部地址:

# get traefik service
kubectl get svc -n kube-system | grep traefik traefik LoadBalancer 192.168.211.177 185.136.232.122 80:32286/TCP,443:30108/TCP,8080:30582/TCP 3m43s

部署一个小型工作负载(whoami)到集群

现在是时候在我们的集群中创建一个服务并尝试通过我们的Traefik代理从外部调用它。本示例中我使用的是whoami服务,它也用于Traefik文档中的所有示例。让我们部署它:


# deploy `whoami` in namespace `default`
kubectl apply -f 03-workload/whoami-service.yaml #check the deployment
kubectl get pods | grep whoami whoami-bd6b677dc-lfxbx 1/1 Running 0 5m37s
whoami-bd6b677dc-92jzj 1/1 Running 0 5m37s

好像已经可以运行了。现在要到激动人心的部分了,Traefik Ingress。

为服务创建两个Traefik Ingress(有/没有TLS Termination)

我们想要从外部访问whoami服务,以让我们最终可以定义IngressRoute对象。没错,那些对象是在我们之前安装的CRD中定义的。现在它们派上用场了。我们按照以下方式部署IngressRoutes:

kubectl apply -f 03-workload/whoami-ingress-route.yaml

正如你在定义中所看到的,我们使用tls.certResolver=default指定了一个路由(附带PathPrefix '/tls')。该certResolver在我们的02-traefik-service / traefik.yaml文件中定义。


apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute-notls
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`celleri.ch`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80 ---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute-tls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`celleri.ch`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: default

现在启动浏览器并访问地址http://celleri.ch/notls,查看即将发生的事情——pod正在响应:

那么https://celleri.ch/tls发生了什么呢?它也在正常运行,但是告诉我们第一个连接不安全。如果我们查看证书,我们就能找到原因:

为了防止因我们的安装程序无法正常工作而使生产服务器受到许多请求的困扰,我们一开始没有使用Let’s Encrypt,而在Traefik Service中使用staging服务器。因此,我们接下来要更改这一设置并使用生产服务器获得一个真实的证书。

更改certresolver以使用Let’s Encrypt生产服务器

在我们定义的Traefik Deployment中,我们有以下参数:


... cropped for readability ... spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.0
args:
- --api.insecure
- --accesslog
- --entrypoints.web.Address=:80
- --entrypoints.websecure.Address=:443
- --providers.kubernetescrd
- --certificatesresolvers.default.acme.tlschallenge
- --certificatesresolvers.default.acme.email=me@myself.com
- --certificatesresolvers.default.acme.storage=acme.json
# Please note that this is the staging Let's Encrypt server.
- --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory ... cropped for readability ...

我们告诉Traefik使用tlschallenge的方法来使用名为default的certificateresolvers。此外,我们还需要提供我们的邮件和证书的存储。我们在前文中还提到我们要使用staging caserver。

重点:在我们的部署中,我们没有存储提供程序或者volume。这意味着,部署重新加载后我们的证书就会消失。证书仅存在于我们的pod内存中。在生产环境中,我们必须解决这一问题并提供一个volume。

好的,让我们注释掉caserver行,然后重新部署Traefik deployment,看看我们是否获得了真实的证书:


... cropped for readability ... spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.0
args:
- --api.insecure
- --accesslog
- --entrypoints.web.Address=:80
- --entrypoints.websecure.Address=:443
- --providers.kubernetescrd
- --certificatesresolvers.default.acme.tlschallenge
- --certificatesresolvers.default.acme.email=me@myself.com
- --certificatesresolvers.default.acme.storage=acme.json
# Please note that this is the staging Let's Encrypt server.
# - --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory ... cropped for readability ...
# deploy the changed file
kubectl apply -f 02-traefik-service/traefik.yaml

一会儿之后,我们将获得一个有效证书:

在这之后,我们可以稍稍放轻松了。但是我们想更近一步,Traefik v2还有一个不错的dashboard,可以查看正在运行的所有Ingress内容。但是我们并不希望每个人都能访问我们的dashboard。有一些基本的身份验证可以更好地保护我们的dashboard。

使用Traefik 中间件以通过基本身份验证访问Traefik Dashboard

在Traefik 2.x中引入了一个新机制——中间件,该机制在处理传入请求时可以帮助我们完成许多任务。我们将使用basicAuth中间件来保护Traefik dashboard并将其暴露给外部。

首先,我们需要使用我们的用户名和哈希密码创建一个Secret,以便basicAuth 中间件在以后使用:

# create user:password file 'user'
htpasswd -c ./user cellerich # enter password twice... # create secret from password file
kubectl create secret generic traefik-admin --from-file user -n kube-system

确保在命名空间kube-system内创建该Secret,因为Traefik Service及其Dashboard也位于此命名空间中。

然后我们部署该中间件以及IngressRoute到我们的集群:

kubectl apply -f 04-traefik-dashboard/traefik-admin-withauth.yaml

现在,我们访问https://traefik.celleri.ch,出现登陆提示:

使用正确的凭据,我们将访问Traefik v2的dashboard:

并且我们会获得许多关于我们Ingress Route的信息:

结 语

这就是教程的全部。在研究过程中,我没有发现太多关于如何在k3s中设置Traefik v2的示例,特别是Klipper LB的部分从未被提及。这就是为什么我想向大家分享我的经验,希望它能够帮助到你,退一万步来说,至少它对我的将来会有所帮助。

参考链接:

Github :

https://github.com/cellerich/k3s-with-traefik2

关于Rancher的Klipper LB:

https://github.com/rancher/klipper-lb

Traefik中间件文档:

https://docs.traefik.io/v2.0/middlewares/overview/

Step by Step!教你如何在k3s集群上使用Traefik 2.x的更多相关文章

  1. 实操教程丨如何在K8S集群中部署Traefik Ingress Controller

    注:本文使用的Traefik为1.x的版本 在生产环境中,我们常常需要控制来自互联网的外部进入集群中,而这恰巧是Ingress的职责. Ingress的主要目的是将HTTP和HTTPS从集群外部暴露给 ...

  2. 仅需5步,轻松升级K3s集群!

    Rancher 2.4是Rancher目前最新的版本,在这一版本中你可以通过Rancher UI对K3s集群进行升级管理. K3s是一个轻量级Kubernetes发行版,借助它你可以几分钟之内设置你的 ...

  3. 仅需60秒,使用k3sup快速部署高可用K3s集群

    作者简介 Dmitriy Akulov,连续创业者,16岁时搭建了开源CDN公共服务jsDelivr的v1版本.目前是边缘托管平台appfleet创始人. 原文链接: https://ma.ttias ...

  4. 如何安装一个高可用K3s集群?

    作者介绍 Janakiram MSV是Janakiram & Associates的首席分析师,也是国际信息技术学院的兼职教师.他也是Google Qualified Developer.亚马 ...

  5. 1款开源工具,实现自动化升级K3S集群!

    即便你的集群能够平稳运行,Kubernetes升级依旧是一项艰难的任务.由于每3个月Kubernetes会发布一个新版本,所以升级是十分必要的.如果一年内你不升级你的Kubernetes集群,你就会落 ...

  6. 多云搭建 K3S 集群

    作者:SRE运维博客 博客地址: https://www.cnsre.cn/ 文章地址:https://www.cnsre.cn/posts/211119132529/ 相关话题:https://ww ...

  7. 如何在 Kubernetes 集群中玩转 Fluid + JuiceFS

    作者简介: 吕冬冬,云知声超算平台架构师, 负责大规模分布式机器学习平台架构设计与功能研发,负责深度学习算法应用的优化与 AI 模型加速.研究领域包括高性能计算.分布式文件存储.分布式缓存等. 朱唯唯 ...

  8. 不同云服务器下,ubuntu下开k3s集群

    首先先感谢老哥的文章:h构建多云环境下的K3S集群,但是我尝试在centos 8.2上面前面一直执行报错 并且安装glibc 2.17时还会报错make版本太低,所以直接放弃centos,投入ubun ...

  9. 跨云厂商部署 k3s 集群

    原文链接:https://fuckcloudnative.io/posts/deploy-k3s-cross-public-cloud/ 最近一两年各大云服务商都出了各种福利活动,很多小伙伴薅了一波又 ...

随机推荐

  1. 移动webApp必备技能一、WebApp 里Meta标签大全,webappmeta标签大全

    1.先说说mate标签里的viewport: viewport即可视区域,对于桌面浏览器而言,viewport指的就是除去所有工具栏.状态栏.滚动条等等之后用于看网页的区域.对于传统WEB页面来说,9 ...

  2. 最新版jdk 13环境变量配置

    1.配置环境变量 右击“我的电脑”-->"属性"-->"高级系统设置"-->"高级"-->"环境变量&qu ...

  3. rest framework serializer

    串行器 扩大串行的用处是什么,我们想地址.然而,这不是一个简单的问题,它会采取一些严重的设计工作. -罗素基思-马吉,Django的用户组 串行器允许诸如查询集和模型实例复杂的数据转换为原生的Pyth ...

  4. Gorm 预加载及输出处理(一)- 预加载应用

    单条关联查询 先创建两个关联模型: // 用户模型 type User struct { gorm.Model Username string `gorm:"type:varchar(20) ...

  5. 如何搭建自己的SpringBoot源码调试环境?--SpringBoot源码(一)

    1 前言 这是SpringBoot2.1源码分析专题的第一篇文章,主要讲如何来搭建我们的源码阅读调试环境.如果有经验的小伙伴们可以略过此篇文章. 2 环境安装要求 IntelliJ IDEA JDK1 ...

  6. 简单的猜数字小游戏--Python

    猜数字小游戏: #coding=utf-8 import random   answer =random.randint(1,100) #生成随机数 n=int (input("Please ...

  7. C++ 【静态成员】static修饰的成员

    首先,我们先通过字面意思来理解... 成员:成员变量.成员函数. static  修饰成员变量,还有修饰成员函数. static  声明为静态的,称为静态成员.不管这个类创建了多少个对象,静态成员只有 ...

  8. vscode 的tab空格设置设置为4的方法

    1.点击“文件>首选项>设置” 进入设置页面,设置如下几个选项 2.在“文件>首选项>设置” 的“用户设置”里添加 "editor.detectIndentation ...

  9. linux无文件执行— fexecve 揭秘

    前言 良好的习惯是人生产生复利的有力助手. 继续2020年的flag,至少每周更一篇文章. 无文件执行 之前的文章中,我们讲到了无文件执行的方法以及混淆进程参数的方法,今天我们继续讲解一种linux上 ...

  10. SpringBoot 拦截器 && 拦截之后返回前台自定义格式

    1.加入 阿里的 json jar包 <!--json jar相关jar包--> <dependency> <groupId>com.fasterxml.jacks ...