小黄人~~Kubernetes Service~~

栏目: 编程工具 · 发布时间: 6年前

内容简介:——3小时后——

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

——3小时后——

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

Service 是kubernetes中一个很重要的,也是很有用的概念,可以通过Service来将pod进行分组,并提供外网的访问endpoint。在这个过程中还有比如kube-proxy提供了对Service的访问。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

但pod是一个短暂存在的东西,很可能突然挂了然后重启,这时候ip地址就会改变,所以pod的ip地址并不是静态的。比如说:

小黄人~~Kubernetes Service~~

用户在这张图里面通过ip地址访问到了4个pod,突然其中有一个pod挂了,然后controller又起了一个pod:

小黄人~~Kubernetes Service~~

这时候用户就访问不到了,因为用户不知道新的ip地址是多少。

Kubernetes为了解决这个问题,提供了一个高层的抽象,叫做Service。Service从逻辑上把pod进行分组,并且设置访问的策略。一般我们是通过label和selector来达到分组的目的的。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

通过selector(app=frontend和app=db),我们就可以把这些pod分为两个逻辑组了。

小黄人~~Kubernetes Service~~

这个时候,我们再给这两个逻辑组加上一个名称,比如frontend-svc和db-svc,就是Service了(如下图):

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

kind: Service

apiVersion: v1

metadata:

name: frontend-svc

spec:

selector:

app: frontend

ports:

– protocol: TCP

port: 80

targetPort: 5000

在这个对象模型中,我们创建了一个叫做frontend-svc的Service,这个Service选择了所有的app=frontend的pod。在默认情况下,每个Service都会有一个cluster内部可以访问到的ip地址,也被称为ClusterIP:

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

当转发请求的时候,我们可以选择pod上的目标端口,比如在我们的例子里面,frontend-svc通过80端口来接受用户的请求,然后转发到pod的5000端口。如果目标端口没有被显式声明,那么会默认转发到Service接受请求的端口(和service端口一样)。

一个pod、ip地址和目标端口的元组代表了一个Service的endpoint,比如在这个例子里面,frontend-svc有3个endpoints,分别是10.0.1.3:5000, 10.0.1.4:5000和10.0.1.5:5000。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

所有的worker node都有一个后台任务,叫做kube-proxy。这个kube-proxy会检测API Server上对于Service和endpoint的新增或者移除。对于每个新的Service,在每个node上,kube-proxy都会设置相应的iptables的规则来记录应该转发的地址。当一个service被删除的时候,kube-proxy会在所有的pod上移除这些iptables的规则。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

我现在已经知道,Service是和kubernetes进行沟通的主要方式,那么我们就需要有一个办法来在运行的时候能够对已有的服务进行发现。请问Kubernetes是如何实现?

小黄人~~Kubernetes Service~~

方法一: 每个pod在worker node上启动的时候,kubelet都会通过环境变量把所有目前可用的Service的信息传进去。举个例子,我们有一个叫做redis-master的Service,这个service expose了6379的端口,并且ClusterIP是172.17.0.6,那么在一个新创建的pod上,我们可以看到以下环境变量:

REDIS_MASTER_SERVICE_HOST=172.17.0.6

REDIS_MASTER_SERVICE_PORT=6379

REDIS_MASTER_PORT=tcp://172.17.0.6:6379

REDIS_MASTER_PORT_6379_TCP=tcp://172.17.0.6:6379

REDIS_MASTER_PORT_6379_TCP_PROTO=tcp

REDIS_MASTER_PORT_6379_TCP_PORT=6379

REDIS_MASTER_PORT_6379_TCP_ADDR=172.17.0.6

如果使用这个解决方案,我们必须非常小心启动服务的顺序,因为pod不会获得自己启动之后的service的env。

方法二: Kubernetes有一些dns的addon,这些addon会自动为所有Service创建一个类似my-svc.my-namespace.svc.cluster.local的dns解析,并且在同一个Namespace里面的Service 可以直接用Service name进行访问。这是最为推荐的方法。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

是否只能在cluster内部访问

是否同时可以被cluster内部和外部访问

是否是映射到一个集群外的entity上

可访问的范围由Service 的类型决定,Service 的类型可以在创建Service 的时候声明。

ClusterIP 和 NodePort

ClusterIP是默认的Service type,一个Service 通过ClusterIP来获取自己的Virtual IP,这个IP是用来和别的service通信的,只能在集群内部被访问。

NodePort的Service type除了会创建一个ClusterIP之外,还会把所有worker node上的一个30000-32767之间的端口映射到这个Service ,比如假设32233端口映射到了frontend-svc,那么不管我们连接到哪个worker node,我们都会被转发到Service 分配的ClusterIP——172.17.0.4。

默认情况下,当expose到有一个nodeport的时候,kubernetes master会自动随机选择一个30000-32767之间的port,当然,我们自己也可以手动指定这个port。

小黄人~~Kubernetes Service~~

NodePort的这个Service type在我们想要让外网访问我们服务的时候非常有用,用户通过访问node上指定的port就可以访问到这个Service 。管理员可以在Kubernetes集群外再搭一个反向代理就可以更方便地进行访问了。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

NodePort和ClusterIP会被自动创建,外部的load balancer会自动路由上去

Service 会在一个静态的端口上被暴露

通过底层的cloud provider提供的load balancer来暴露到外网

小黄人~~Kubernetes Service~~

LoadBalancer这个Service type只有在底层的基础架构支持了自动创建load balancer的时候kubernetes才支持,比如Google Cloud Platform和aws。

ExternalName

ExternalName是一个特定的Service type,这种Service type没有任何的selector也没有任何声明的endpoint。当在集群中访问到这个Service 的时候,会返回一个外部服务的CNAME。

这个service一般是用来让一个外部的服务在集群内部可以访问到的,比如我们有一个外部服务叫做my-database.example.com,那么我们可以通过设置ExternalName类型的Service,让内部的其它Service 通过my-database之类的名字访问到这个服务。

ExternalIP

如果一个Service 可以路由到一个或者多个worker node上,那么它可以被映射到一个ExternalIP地址。通过这个ExternalIP进入到集群的流量会被路由到其中一个endpoint上。

小黄人~~Kubernetes Service~~

需要注意的是,ExternalIP并不是由k8s自动管理的,是由管理员手动设置路由到其中的一个node上的,ExternalIP可以和任意Service type来一起指定。

小黄人~~Kubernetes Service~~

小黄人~~Kubernetes Service~~

—-1小时后—-

小黄人~~Kubernetes Service~~


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Using Google App Engine

Using Google App Engine

Charles Severance / O'Reilly Media / 2009-5-23 / USD 29.99

With this book, you can build exciting, scalable web applications quickly and confidently, using Google App Engine - even if you have little or no experience in programming or web development. App Eng......一起来看看 《Using Google App Engine》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具