Linkerd的设计目的是使service-to-service的内部通信在应用程序中安全、快速和可靠。然而,这些目标同样适用于edge。在这篇文章中,我们将展示Linkerd的一个新特性,允许它充当Kubernetes入口控制器,并展示它如何在使用和不使用TLS的情况下处理通信流。
这是关于Linkerd,Kubernetes和服务网格的一系列文章中的其中一篇文章。本系列的其他部分还包括:
在本系列的前一篇文章中,我们探讨了如何通过将Linkerd部署为Kubernetes DaemonSet并通过相应的Service VIP路由流量来接收外部请求。在这篇文章中,我们将通过使用Linkerd作为Kubernetes入口控制器来简化这个设置,利用 Linkerd 0.9.1中引入的功能 。
这种方法具有简单性和Kubernetes API紧密集成的好处。然而,对于更复杂的需求,如按需TLS证书生成,SNI或基于cookie值的路由(例如本系列第五部分讨论的员工dogfooding方法 ),将Linkerd与专用边缘层(如NGINX)结合仍然是必要的。
什么是Kubernetes入口控制器?入口控制器是一个边缘路由器,它接受来自外界的流量并将其转发到Kubernetes群集中的服务。入口控制器使用在Kubernetes的入口资源中定义的HTTP主机和路径路由规则 。
使用 Kubernetes配置 从 linkerd-例子 回购协议,我们可以把Linkerd作为专用入口控制器。配置遵循与我们之前在k8s daemonsets上的文章相同的模式 :它部署 l5d-config
ConfigMap, l5d
DaemonSet和 l5d
Service。
首先,我们来部署Linkerd。当然,您可以将其部署到默认名称空间中,但是在这里我们已经将Linkerd放在了自己的名称空间中,以便更好地分离关注点:
$ kubectl create ns l5d-system
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/linkerd-ingress-controller.yml -n l5d-system
您可以通过运行来验证Linkerd窗格是否已启动:
$ Kubectl get po -n 15d-system
NAME READY STATUS RESTARTS AGE
l5d-0w0f4 2/2 Running 0 5s
l5d-3cmfp 2/2 Running 0 5s
l5d-dj1sm 2/2 Running 0 5s
并查看管理控制台(该命令假定您的集群支持LoadBalancer服务,并记住入口LB可能需要几分钟才能变为可用)。
$ L5D_SVC_IP = $(kubectl get svc l5d -n l5d-system -o jsonpath =“{。status.loadBalancer.ingress [0]。*}”)
在OS X上打开 http:// $ L5D_SVC_IP:9990 #
让我们仔细看看我们刚刚部署的ConfigMap。Linkerd在启动时加载的文件它存储为config.yaml
.
。
$ Kubectl get cm 15d-config -n 15d-system -o yaml
apiVersion:v1
data:
config.yaml:|-
namers:
- kind: io.15d.k8s
routers:
- protocol: http
identifier:
kind: io.15d.ingress
servers:
-port:80
ip:0.0.0.0
clearContext: true
dtab: /svc =>/#/io.15d.k8s
usage:
orgId:linkerd-examples-ingress
您可以看到,此配置在端口80上定义了一个使用入口资源(通过io.l5d.ingress
标识符)标识传入到请求的HTTP路由器 ,然后将得到的命名空间,端口和服务名称。最后,传递给 Kubernetes编号器 进行解析。我们还设置 clearContext
到 true
为了从不可信的源中删除任何传入Linkerd上下文的标头。
现在是时候部署我们的应用程序,以便我们的入口控制器可以将流量路由给我们。我们将部署一个由hello和world服务组成的简单应用程序。
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world.yml
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/world-v2.yml
您可以再次验证pods已启动并正在运行:
$ kubectl get po
NAME READY STATUS RESTARTS AGE
hello-0v0vx 1/1 Running 0 5s
hello-84wfp 1/1 Running 0 5s
hello-mrcfr 1/1 Running 0 5s
world-v1-105tl 1/1 Running 0 5s
world-v1-1t6jc 1/1 Running 0 5s
world-v1-htwsw 1/1 Running 0 5s
world-v2-5tl10 1/1 Running 0 5s
world-v2-6jc1t 1/1 Running 0 5s
world-v2-wswht 1/1 Running 0 5s
此时,如果您尝试发送入口请求,则会看到如下所示的内容:
$ curl $ L5D_SVC_IP
Unknown destination:Request(“GET /”,从/184.23.234.210:58081)/no ingress rule matches
为了使我们的Linkerd入口控制器正常工作,我们需要创建一个使用它的入口资源。
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/hello-world-ingress.yml
验证资源:
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
hello-world world.v2 80 7s
这种“hello,world”的入口资源引用了我们的后端(所以我们用了 world-v1
和 world-v2
这个演示):
apiVersion : extensions / v1beta1
kind: Ingress
metadata:
name:hello-world
annotations:
kubernetes.io/ingress.class :“linkerd”
spec:
backend:
serviceName : world-v1
servicePort : http
rules:
- host: world.v2
http:
paths:
- backend:
serviceName : world-v2
servicePort : http
资源
wordl-v1
作为默认的后端。rule
,其中包含主机头的所有请求world.v2
都将被路由到world-v2
服务。kubernetes.io/ingress.class
注释设置 为“linkerd”。请注意,只有在群集中运行多个入口控制器时,才需要此注释。GCE默认运行一个; 您可以按照这些说明选择禁用它 。就是以下这样!您可以通过将分配给l5d服务负载平衡器的IP来行使这些规则。
$ curl $ L5D_SVC_IP
world(10.0.4.7)!
$ curl -H “Host:world.v2” $ L5D_SVC_IP
world(10.0.1.5)!
虽然这个例子是以全新的实例开始的,但是将入口标识符路由器添加到预先存在的链接设置也很容易的。此外,尽管我们在此使用了一个DaemonSet(为了与Kubernetes系列的其余服务网格保持一致),但使用Kubernetes对Linkerd入口控制器部署也同样适用。使用部署是留给读者一个练习。
Linkerd已经支持群集内客户端和服务器的TLS。本系列的第三部分详细介绍了如何设置TLS 。在该入口控制器配置,Linkerd希望在一个Kubernetes隐私中定义命名为ingress-certs
,并遵循 入口用户指南中描述的格式。请注意,不需要将TLS部分作为入口资源的一部分:Linkerd不会实现资源的该部分。所有的TLS配置都是作为l5d-config
配置映射的一部分 。
Linkerd配置保持不变,保存更新服务器端口443,
并添加TLS文件路径:
...
servers:
- port:443
ip:0.0.0.0
clearContext:true
tls:
certPath : /io.buoyant/linkerd/certs/tls.crt
keyPath : /io.buoyant/linkerd/certs/tls.key
...
l5d DaemonSet现在可以以预期的名字安装一个隐私卷: ingress-certs
spec:
volumes:
- name: certificates
secret:
secretName: ingress-certs
...
containers:
- name: 15d
...
ports:
- name:tls
containerPort:443
hostPort:443
...
volumeMounts:
- name:"certificates"
mountPath:"/io.buoyant/linkerd/certs"
readOnly :true
...
并更新的服务配置公开端口 443
。
提醒一下,我们这里使用的证书仅用于测试目的!创建这个私密,删除DaemonSet和ConfigMap,并重新应用入口控制器配置:
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/ingress-certificates.yml -n l5d-system
$ kubectl delete ds / l5d configmap / l5d-config -n l5d-system
$ kubectl apply -f https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/k8s/linkerd-tls-ingress-controller.yml -n l5d-system
你现在应该可以做一个加密的请求:
# Example requires this development cert:https://raw.githubusercontent.com/linkerd/linkerd-examples/master/k8s-daemonset/certificates/cert.pem
# The cert expects “hello.world” host,so we add an / etc / hosts entry,eg:
# 104.198。196.230 hello.world
# where “104.198.196.230” is the ip stored in $ L5D_SVC_IP
$ curl - cacert cert.pem -H"Host:world.v2" HTTPS://hello.world
$ earth(10.0.1.5)!
结论
Linkerd作为边缘路由器提供了许多好处。除了本文中介绍的动态路由和TLS终结外,它还提供了 集中了连接, 动态负载均衡, 断开电路和支持 分布式跟踪。使用本文中引用的Linkerd入口控制器和 Kubernetes配置 ,您可以很容易使用Kubernetes-native方法访问所有这些功能。最重要的是,这种方法可与服务网格的其它部分无缝协作,从而在几乎任何云架构中实现操作、可见性和高可用性。
该ingress identifier是新的功能,所以我们很想得到你从入口控制器想要什么功能,你的看法。你可以在Linkerd community Slack 或在 Linkerd discourse 找到我们。