原文链接:https://blog.scorpii.net/2019/11/08/traefik/
先熟悉k8s
这一节我们先熟悉一下 k8s
,并且利用这个过程了解为什么需要 traefik
。如果你已经做过调研,可以安全的跳过这一节。
这一节的任务是部署一个 nginx
。我们需要编写配置文件,应用到 k8s
中。之后 k8s
会根据配置文件中的设置自动下载 nignx
的镜像并且运行。
首先第一个文件是 nginx-deployment.yml
,内容如下:
apiVersion: apps/v1 # 1.9.0 之前使用 apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 1 # 告诉k8s只运行一个实例
template: # 这下面是pod
metadata:
labels:
app: nginx # 记住这里
spec:
containers:
- name: nginx
image: nginx:1.7.9 # nginx镜像
ports:
- containerPort: 80
这个配置文件部署了两个东西, pod
和 deployment
。它们的关系如下图所示。
[图片上传失败...(image-2561bb-1573183728438)]
pod
是 k8s
中调度的最小单位, deployment
是一个 controller
我们下面都称作控制器,它的目的就是按照配置文件所描述的那样控制 pod
的状态。如果 pod
挂了, deployment
负责重启 pod
。而如果 replicas
设置为2,就会变成下面这样:
[图片上传失败...(image-70b936-1573183728438)]
编写好以后,我们直接应用
然后我们来看看 pod
的状态。
看到已经 running
了,并且 ready
也是 1/1
了。
但是这个时候,我们只能在 k8s
内部访问这个 pod
,而不能从外部访问。
要想从外部访问,我们需要再写一个配置文件 nginx-service.yml
。看代码:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: nginx # 这里对应上面的 *记住这里*
ports:
- protocol: TCP
port: 80 # k8s中服务的访问端口,用于k8s内部访问
nodePort: 30000 # 映射到物理服务器上的端口,用于k8s外部访问,记住这个端口号
targetPort: 80 # pod的端口
service
也是一个 controller
,它的作用是暴露 pod
的服务。暴露哪个 pod
的服务呢?其实就是 selector
选中的 pod
。我们也来应用一下:
接着我们用命令看看这个 service
:
kubernetes
这个服务本来就有,我们先不管它。我们看到我们的 my-service
已经存在了。接着我们来访问访问。
你猜的没错,我换 ip
了,不要在意这些细节。我们能看到的是,我们部署了一个 nginx
,而三台服务器相同的端口下面都能访问到。一般情况下,在线上只需要暴露一个服务器到公网即可。
配置文件可以合并,如果你愿意,可以把上面的两个配置文件的内容复制到一个文件中,用---(三个短横线)分割。
如果你深入研究 k8s
你会发现你找不到一个方法来做域名路由,实际上 k8s
也没有提供这样一个方法。也就是说,当你需要部署两个网站的时候,你只能通过端口号来区分它们。要想解决这个问题,我们就需要 traefik
了(终于绕回来了~)。
treafik
与 traefik
有一样作用的还有 nginx-ingress
,我们这里只研究 traefik
。
不过首先,我们需要修改一下
k8s
的配置。上面nginx
的端口我设置的30000
,其实我是想设置8080
的,但是失败了。
上面说有效的端口是30000-32767
,这可不是我们想要了。所以,我们需要修改api-server
这个pod
的配置文件来让k8s
接管几乎所有的端口。
api-server
这个pod
是k8s
自身的组件,它的配置文件是/etc/kubernetes/manifests/kube-apiserver.yaml
。我们在启动参数中加入一项。
由于这个系统组件的配置文件是常驻的,所有我们只需要保存,被修改的pod
就会自动重启。
在api-server
组件重启期间你是无法使用k8s
命令的,这也说明其实真正执行我们命令的就是api-server
组件。
就在前段时间 traefik
发布了2.0版本,我们也直接来尝尝鲜。文档里其实已经讲的很详细了,上面说我们需要写四个配置文件。我们照着这个上面来,先应用第一个配置。就是文档里面的 IngressRoute Definition
节的第一个代码块。
第二个, traefik
的 service
配置(文档里面 service
节的第一个代码块),不过这里,我们需要改一改。
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: NodePort
ports:
- protocol: TCP
name: web
port: 80
nodePort: 80
- protocol: TCP
name: admin
port: 8080
nodePort: 8080
- protocol: TCP
name: websecure
port: 443
nodePort: 443
selector:
app: traefik
我们应用它:
最后是 deployment
(文档里面 deployments
节的第一个代码块),也要改一改:
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.0
args:
- --api.insecure
- --accesslog
- --entrypoints.web.Address=:80 # http访问80
- --entrypoints.websecure.Address=:443 # https访问443
- --providers.kubernetescrd # 这个定式,固定写就好
- --certificatesresolvers.default.acme.tlschallenge # 这个是let's Encrypt配置,跟下面两个固定写,可以自动帮你申请证书,你没有看错,是自动的。
- [email protected] # 这地方填你自己邮箱地址,这样你能收到let's Encrypt对你这个域名的通知。
- --certificatesresolvers.default.acme.storage=acme.json # 定式
ports:
- name: web # 端口可以命名,这样service就可以直接使用端口名代替端口,往上看service的配置文件。
containerPort: 8000
- name: websecure
containerPort: 4443
- name: admin
containerPort: 8080
好,我们应用它:
接着我们查看一下 pod
:
可以看到 traefik
的 pod
已经 running
了,怎么确定它已经部署成功了呢?我们试试访问 80
和 8080
( 443
我就不访问,因为是在本地虚拟机上面,公网到不到,所以 let's Encrypt
无法自动设置 https
)。
上面 404
是因为我们还没有部署任何服务, traefik
找不到要代理的东西,无奈的打出了 404
。
接下来我们看看怎么使用它。老规矩,上 nginx
。
apiVersion: apps/v1 # 1.9.0 之前使用 apps/v1beta2
kind: Deployment
metadata:
name: new-nginx-deployment
spec:
selector:
matchLabels:
app: new-nginx
replicas: 1 # 告诉k8s只运行一个实例
template: # 这下面是pod
metadata:
labels:
app: new-nginx # 记住这里
spec:
containers:
- name: nginx
image: nginx:1.7.9 # nginx镜像
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: new-my-service
spec:
# type: NodePort traefik会自己将服务暴露出来,所以不用我们自己暴露了
selector:
app: new-nginx # 这里对应上面的 *记住这里*
ports:
- protocol: TCP
port: 80 # k8s中服务的访问端口,用于k8s内部访问
# nodePort: 30000 # traefik会自己将服务暴露出来,所以不用我们自己暴露了
targetPort: 80 # pod的端口
这个配置文件跟上面的没有太大区别,就是没有暴露服务,和改了名字。并且将 service
和 deployment
合到了一起。应用它:
关键的来了,为了让 traefik
暴露我们的服务,我们还需要一个配置:
# 这个是http
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: simpleingressroute
namespace: default
spec:
entryPoints:
- web # 也就是traefik的80端口
routes:
- match: Host(`your.domain.com`) # 里面填你的域名,match还有其他函数(我们姑且就叫函数吧),可以参考文档
kind: Rule
services:
- name: new-my-service # 填服务的名字
port: 80
---
# 这个是https
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
namespace: default
spec:
entryPoints:
- websecure # 也就是traefik的443端口
routes:
- match: Host(`your.domain.com`) # 里面填你的域名
kind: Rule
services:
- name: new-my-service # 填服务的名字
port: 80
tls:
certResolver: default
盘它~:
我们再来访问(访问之前记得添加 host
):
还是看一看 https
会是什么效果:
最后我们再来看看 traefik
管理端的情况:
对了, traefik 2.0
加入的新特性之一就是支持 tcp
连接了,因为我了解到有一些变态大佬已经开始用二进制(比如 protobuf
)来做前后端数据交互了。
上一篇:devops(1)- k8s安装记录
下一篇:devops(3)- helm的安装记录