前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes系列之理解K8s Service的几种模式

Kubernetes系列之理解K8s Service的几种模式

作者头像
程序员同行者
发布2019-03-29 16:09:38
2.2K0
发布2019-03-29 16:09:38
举报
文章被收录于专栏:程序员同行者程序员同行者
image
image

今天给大家介绍下k8s的service的几种访问模式。

概述


我们知道pod的ip不是固定的,是根据所在宿主机的docker0网卡生成的,每次重启,更新,调度等情况IP都会变,那pod与pod之间需要互相调用,肯定不能用ip的,因为地址不是固定的, 如何能保障pod之前访问的可靠性,由此就衍生出Service的概念。

在实际生产环境中,一般有两种访问 对集群内部的访问, 集群外部的访问。service现在分为以下类型

ClusterIP

集群内部容器访问地址,会生成一个虚拟IP 与pod不在一个网段。

NodePort   

会在宿主机上映射一个端口,供外部应用访问模式。

Headless CluserIP   

无头模式,无serviceip,即把spec.clusterip设置为None 。

LoadBalancer

使用外部负载均衡。

Port类型


我们先理解Service Port的几种类型。

NodePort

指定暴露到宿主机的端口,不指定的话会随机分配个,分配的IP在apiserver的配置文件中指定了--service-node-port-range=30000-50000,表示只允许分配30000-50000之间的端口。

比如一个nginx应用需要能被外部访问,就需要配置类型为type=NodePort,并且需要配置下nodePort: 30002(指定固定端口),这样的话外部使用http://ip:30002就可以访问这个应用了。

也有一些内部服务是需要外部访问的,那就不需要到使用NodePort模式了。

代码语言:javascript
复制
apiVersion: v1

Port

集群内部服务之间访问的端口。

比如一个nginx容器暴露了80端口,但是其他容器需要通过nginx:80访问,就需要配置port:80 ,外部是没法访问这个端口的,因为没有对外开放端口。

代码语言:javascript
复制
apiVersion: v1

targetPort

容器本身暴露的端口,和dockerfile中的expose意思一样

例子说明


接下来我们通过几个例子来理解说明

创建NodePort类型Service

如果选择了“NodePort”,那么 Kubernetes master 会分配一个区域范围内,(默认是30000-32767),并且,每一个node,都会代理(proxy)这个端口到你的服务中,我们可以在spec.ports[*].nodePort 找到具体的值

如果我们指定一个端口,我们可以直接写在nodePort上,系统就会给你指派指定端口,但是这个值必须是指定范围内的。

Cluster service 的 IP 地址是虚拟的,因此,只能从node节点上使用该IP 地址访问应用。为了从集群外访问应用,K8S 提供了使用 node 节点的IP 地址访问应用的方式。

基本上,NodePort 服务与普通的 “ClusterIP” 服务 YAML 定义有两点区别。 首先,type 是 “NodePort”。还有一个称为 nodePort 的附加端口,指定在节点上打开哪个端口。 如果你不指定这个端口,它会选择一个随机端口。

 该端口号的范围是 kube-apiserver 的启动参数 –service-node-port-range指定的,在当前测试环境中其值是 30000-50000。表示只允许分配30000-50000之间的端口。

ps:一般使用NodePort 都会在外部搭建负载均衡来代理多个node节点。

创建一个Deployment

代码语言:javascript
复制
[root@master-01 ~]# cat nginx-deploy.yaml 

创建service 

代码语言:javascript
复制
[root@master-01 ~]# cat ng-svc.yaml 

查看详情

代码语言:javascript
复制
[root@master-01 ~]# kubectl  describe  svc  nginx

查看状态

代码语言:javascript
复制
[root@master-01 ~]# kubectl  get po,ep,svc

访问测试

代码语言:javascript
复制
# 通过endpoint 访问

在pod中也可以通过service的名称访问(一般都这样使用)

创建ClusterIP类型Service

会生成一个集群内部的虚拟IP(网段和pod不同)只是给集群内部和pod之间访问的,外部无法访问,网段通过配置文件指定。

ClusterIP也是Kubernetes service的默认类型。

原理

用户通过kubectl命令向apiserver发送创建service的命令,apiserver接收到请求以后将数据存储到etcd中。

每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables中。

iptables 使用NAT等技术将virtualIP的流量转至endpoint中。

创建pod

代码语言:javascript
复制
[root@master-01 ~]# cat nginx-deployment.yaml 

创建Service

代码语言:javascript
复制
[root@master-01 ~]# cat ng-svc-clusterip.yaml 

创建HeadlessClusterIP类型Service

有时候我们可能不需要一个固定的IP和分发,这个时候我们只需要将spec.clusterIP的值设置为none就可以了,通过设置标签绑定到pod的方式完成,对于这样的服务来说,集群IP没有分配,这个时候当你查询服务的名称的时候,DNS会返回多个A记录,这些记录都是指向后端Pod的。Kube-proxy代理不会处理这个服务,在服务的前端也没有负载均衡器。但是endpoints controller还是会创建Endpoints,在访问服务的时候返回后端的全部的Pod IP地址。

创建pod

代码语言:javascript
复制
[root@master-01 ~]# cat busybox-deploy.yaml 

创建service

代码语言:javascript
复制
[root@master-01 ~]# cat busybox-svc-headless.yaml 

查看状态

可以看到CLUSTER-IP  为None了,

代码语言:javascript
复制
[root@master-01 ~]# kubectl  get svc,ep,po

以上可以看出后端的pod列表已经加到该svc。

我们进容器中通过service名字是否能够解析访问到pod

查看dns域

代码语言:javascript
复制
root@busybox-deploy-b47575595-khxsp:/# cat /etc/resolv.conf 

可以看到以上的A记录,解析出的是pod的ip地址

1.普通 Service:解析成 ClusterIP

2.Headless Service:解析为指定 Pod的IP列表,Serivce域名也起到了通过dns做负载的能力。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档