Step by Step!教你如何在k3s集群上使用Traefik 2.x
本文来自边缘计算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中间件文档:
Step by Step!教你如何在k3s集群上使用Traefik 2.x的更多相关文章
- 实操教程丨如何在K8S集群中部署Traefik Ingress Controller
注:本文使用的Traefik为1.x的版本 在生产环境中,我们常常需要控制来自互联网的外部进入集群中,而这恰巧是Ingress的职责. Ingress的主要目的是将HTTP和HTTPS从集群外部暴露给 ...
- 仅需5步,轻松升级K3s集群!
Rancher 2.4是Rancher目前最新的版本,在这一版本中你可以通过Rancher UI对K3s集群进行升级管理. K3s是一个轻量级Kubernetes发行版,借助它你可以几分钟之内设置你的 ...
- 仅需60秒,使用k3sup快速部署高可用K3s集群
作者简介 Dmitriy Akulov,连续创业者,16岁时搭建了开源CDN公共服务jsDelivr的v1版本.目前是边缘托管平台appfleet创始人. 原文链接: https://ma.ttias ...
- 如何安装一个高可用K3s集群?
作者介绍 Janakiram MSV是Janakiram & Associates的首席分析师,也是国际信息技术学院的兼职教师.他也是Google Qualified Developer.亚马 ...
- 1款开源工具,实现自动化升级K3S集群!
即便你的集群能够平稳运行,Kubernetes升级依旧是一项艰难的任务.由于每3个月Kubernetes会发布一个新版本,所以升级是十分必要的.如果一年内你不升级你的Kubernetes集群,你就会落 ...
- 多云搭建 K3S 集群
作者:SRE运维博客 博客地址: https://www.cnsre.cn/ 文章地址:https://www.cnsre.cn/posts/211119132529/ 相关话题:https://ww ...
- 如何在 Kubernetes 集群中玩转 Fluid + JuiceFS
作者简介: 吕冬冬,云知声超算平台架构师, 负责大规模分布式机器学习平台架构设计与功能研发,负责深度学习算法应用的优化与 AI 模型加速.研究领域包括高性能计算.分布式文件存储.分布式缓存等. 朱唯唯 ...
- 不同云服务器下,ubuntu下开k3s集群
首先先感谢老哥的文章:h构建多云环境下的K3S集群,但是我尝试在centos 8.2上面前面一直执行报错 并且安装glibc 2.17时还会报错make版本太低,所以直接放弃centos,投入ubun ...
- 跨云厂商部署 k3s 集群
原文链接:https://fuckcloudnative.io/posts/deploy-k3s-cross-public-cloud/ 最近一两年各大云服务商都出了各种福利活动,很多小伙伴薅了一波又 ...
随机推荐
- 第八章、小节二vuex
a.用vuex首先先安装vuex npm install vuex --save b.在src目录下创建store文件夹,在store中创建index.js存放各个状态 c.在一个模块化的打包系统中, ...
- 谈谈集合.Map
本文来谈谈我们平时使用最多的HashMap. 1. 简介 HashMap是我们在开发过程中用的最多的一个集合结构,没有之一.HashMap实现了Map接口,内部存放Key-Value键值对,支持泛型. ...
- 编写程序实现输入x,y,判断属于第几象限。
x = float(input("请输入横坐标:")) y = float(input("请输入纵坐标:")) if x > 0 and y > 0 ...
- Oracle根据实体类比对2个数据库结构差异(demo)
源起 在公司做项目时 经常出现 实体结构和线上的数据结构以及公司开发库数据结构不匹配的问题 但是又不能直接把开发库导入到生产库因为生产库已经有实际数据了 所以弄了一个小工具 此处只做记录用 demo级 ...
- C++类的多态
目录 一.静态多态 二.动态多态 三.虚函数 四.纯虚函数 五.C++ 接口(抽象类) 六.应用经验 七.版权声明 多态按字面的意思就是多种形态.当类之间存在层次结构,并且类之间是通过继承关联时,就可 ...
- HTML5&CCS3(2) 处理网页文件
2.1 规划网站 为什么要创建这个站点,需要展示的内容是什么? 应该如何调整内容使之吸引期望的访问者? 需要多少个页面?网站的结构是怎样? 为页面.图像和其他外部文件设计一个简单且一致的命名规则. 2 ...
- python如何用format进行进制转换与如何删除进制前缀
10进行十进制,十六进制,八进制,二进制的转换:(#:保留进制前缀)对于带着进制前缀的,如"0x"“0o”“0b”,可以直接在后面加上’x’‘o’'b’进行删除:其他的一些小技巧: ...
- vue组件通信(props,$emit,$attrs,$listeners)
朝颜陌 vue基础----组件通信(props,$emit,$attrs,$listeners) 一.父传子,子传孙 1. props 1>在父组件中通过子组件自定义的标签属性来传递数据. ...
- js小数计算引起的精度误差问题
我记得刚开始学js的时候学到浮点有举例0.1+0.2 它的计算结果是: 0.1+0.20.30000000000000004 很神奇的一个计算,js是弱语言,在精度上没做处理: 我就自己定义了加减乘除 ...
- HTML每日学习笔记(2)
7.16.2019 1.html表单:用于得到用户不同类型的输入 <form>元素定义表单: <form> First name:<br> <input ty ...