本文的试验环境为CentOS 7.3,Kubernetes集群为1.11.2,安装步骤参见kubeadm安装kubernetes V1.11.1 集群

Service 介绍

我们通过Pod、Deployment等可以将应用发布到Kubernetes平台中,但是如果我们如何才能访问我们部署的应用呢?有一个办法就是通过节点的IP加上节点的端口来访问这个节点上的容器应用,但是如果我们有多个跨节点的相通应用时该怎么办呢?特别是应用发生扩容、缩容时应该如何处理,这时我们就需要利用Service来实现。

在Kubernetes中,Service是一种资源,提供了我们访问单个或多个容器应用的能力。每个服务在其生命周期内,都拥有一个固定的IP地址和端口。每个服务对应了后台的一个或多个Pod,通过这种方式,客户端就不需要关心Pod所在的位置,方便后端进行方便的Pod扩容、缩容等操作。

可以通过下面的示意图来理解Service的作用。

由此可知,服务可以被外部的客户访问,也可以被内部的客户访问。Service通过创建时指定的标签选择器来决定用户的请求转发到后台的哪些Pods中。看一下Service创建的具体例子。

apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
sessionAffinity: ClientIP # 该参数可以设置相同IP的请求总是定位到同一个Pod
ports:
- port: 8080
targetPort: 8080
selector:
app: tomcat

这个例子定义了一个Service名为tomcat-svc,端口为8080,该服务会将用户的请求转发到后台带有app=tomcat标签的Pods上。

kubectl get svc

我们在测试服务是否正常的时候,不能使用ping命令。因为Kubernetes中实现服务时,并不支持ping。因此不能使用ping的方式检查服务是否正常,应当使用telnet或者nc等命令进行测试。

Pod中的应用访问Service有两种方式,一种是通过向Pod中注入环境变量的方式,这种方式缺点很明显,必须首先创建Service,Pod内的应用才能通过环境变量访问;另一种方式是通过DNS的方式,这种方式非常灵活。

Service 与 endpints

Endpoints 是组成Service的一组IP地址和端口资源。

kubectl get endpoints kubia

默认情况下创建Service的时候,会创建一个同名的Endpoints资源,通过kubectl descirbe svc svc-name可以看到这个服务对应的Endpoints。

如果创建Service的时候,不指定Pod的选择器,则不会创建Endpoints资源。也可以手工创建Endpoints类型。创建时需要注意名称要与Service的名称一致。

apiVersion: v1
kind: Endpoints
metadata:
name: external-service
subsets:
- addresses:
- ip: 11.11.11.11
- ip: 22.22.22.22
ports:
- port: 80

Service 的类型

  • NodePort
  • Loadbalance
  • Ingress

实例解析

1. 创建内部服务

创建用于内部访问的服务很简单,创建后服务将在生命周期内拥有固定的IP和端口。

apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
sessionAffinity: ClientIP # 该参数可以设置相同IP的请求总是定位到同一个Pod
ports:
- port: 8080
targetPort: 8080
selector:
app: tomcat

客户每次链接Service时,都会对应到后端的一个Pod上,如果客户需要链接所有的后端Pod呢,可以使用headless service。通过这种方式,Kubernetes内部的DNS服务会将Service对应的所有IP返回。

apiVersion: v1
kind: Service
metadata:
name: tomcat-headless
spec:
clusterIP: None
ports:
- port: 8080
targetPort: 8080
selector:
app: tomcat

或者可以在客户端通过程序调用Kubernetes API的方式获取地址列表。

2. 为外部服务创建一个内部别名

容器内部的应用要访问外部应用时,可以直接在容器内访问外部服务地址,也可以通过创建一个外部服务的别名进行转发,这样相当于将内外部调用关系解耦了,每次外部发生变化的时候,可以不用修改应用的代码。

apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: api.baidu.com
ports:
- port: 80

3. 向外部暴露内部服务

向外部暴露内部服务有三种方式:

  • NodePort
  • LoadBalancer
  • Ingress,7层负载均衡
3.1 NodePort 方式

创建这种方式的Service,内部可以通过ClusterIP进行访问,外部用户可以通过NodeIP:NodePort的方式单独访问每个Node上的实例。这种方式有很多问题,直接访问节点的地址和端口需要在客户端记录很多信息,Pod发生迁移后这些信息没办法动态更新,节点的防火墙及节点所在网络区域的防火墙策略配置会比较麻烦。

apiVersion: v1
kind: Service
metadata:
name: nodeport
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30123
selector:
app: httpd

端口如果忽略,Kubernetes会自动生成。

$ kubectl get svc nodeport

获取一些信息

kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type="InternalIP")].address}'

3.2 load balancer 方式

这种方式一般需要云供应商的支持,或者一些本地资源如F5的支持。这里不做过多介绍了。

3.3 Ingress 方式

LoadBalancer要求的IP资源较多,每个负载均衡服务都需要一个IP,Ingress可以只用一个IP,通过URL来判断需要访问的服务。Ingress工作在HTTP层,配置与使用更加灵活。目前为止还是一个beta特性。

目前有很多Ingress的支持:

使用过程中的最佳实践:

  • 总是添加 Readiness 探测
  • 不要在探测中使用关闭的逻辑

参考资料

  1. Kubernetes in action
  2. JSONPath Support

Kubernetes基础:Service的更多相关文章

  1. kubernetes进阶(04)kubernetes的service

    一.service概念 Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口.借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级.Service ...

  2. Kubernetes基础:查看状态、管理服务

    目标 了解Kubernetes Pod 了解Kubernetes Node 学习如何调试部署问题 了解如何通过Service暴露应用 Kubernetes Pods 在Kubernetes中创建一个D ...

  3. Kubernetes基础

    Kubernetes是什么 Kubernetes是当今最流行的开源容器管理平台,它就是大名鼎鼎的Google Borg的开源版本.Google在2014年推出了Kubernetes,本文发布时最新的版 ...

  4. 【Kubernetes】Kubernetes的Service外部访问方式:NodePort和LoadBalancer

    Kubernetes的Pod的寿命是有限的,它们不会复活,因此尽管每个Pod都有自己的IP地址,但是这些IP地址是不可靠的,会随着Pod的消亡而消失. 这就带来一个问题,如果一些Pod的集合(称之为b ...

  5. 1-2、kubernetes架构概述和kubernetes基础概念

    kubernetes https://draveness.me/understanding-kubernetes http://kubernetes.kansea.com/docs/ master/n ...

  6. linux运维、架构之路-Kubernetes基础(一)

    一.Kubernetes介绍 Kubernetes最初源于谷歌内部的Borg,提供了面向应用的容器集群部署和管理系统.Kubernetes的目标旨在消除编排物理/虚拟计算,网络和存储基础设施的负担,并 ...

  7. [Kubernetes]说说 Service 与 Ingress

    在 Kubernetes 中, Service 有三种对外暴露的方法,但是由于每个 Service 都要有一个负载均衡的服务,所以采用 Service 的话,会造成既浪费成本又高的现象.对于用户来说, ...

  8. kubernetes 基础一

    从集群外部访问pod或service pod 在Kubernetes中,创建.调度和管理的最小单位是pod而不是容器.pod代表着一个运行着的工作单元.一般情况下,每个pod中只有一个容器(原因是为了 ...

  9. Kubernetes的Service运行原理

    一.为什么Servcie能定位到Pod 因为Pod的IP是不固定的,所以Kubernetes需要Service,除此之外它还可以在多个Pod间负载均衡 Service的访问入口,其实是宿主机的kube ...

  10. Kubernetes中Service的使用

    目录 简介 1. Service资源定义 1.1 Service Type ClusterIP 无头service NodePort sessionAffinity实现源地址session绑定 简介 ...

随机推荐

  1. tasksetCPU亲和力&docke容器资源限制

    [taskset详解] taskset设置cpu亲和力,taskset能够将一个或者多个进程绑定到一个或者多个处理器上运行 参数: 选项: -a, --all-tasks 在给定 pid 的所有任务( ...

  2. User模型扩展和自定义

    参考如下: django文档参考 django signal使用总结 django 信号注册 django信号问题1 django oneTooneFiled     1. django 自定义用户u ...

  3. Codeforces 982E Billiard 扩展欧几里德

    原文链接http://www.cnblogs.com/zhouzhendong/p/9055728.html 题目传送门 - Codeforces 928E 题意 一束与坐标轴平行或者成$45^\ci ...

  4. BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并

    原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...

  5. 不同路径II(一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?网格中的障碍物和空位置分别用 1 和 0 来表示。)

    示例 1: 输入: [   [0,0,0],   [0,1,0],   [0,0,0] ] 输出: 2 解释: 3x3 网格的正中间有一个障碍物. 从左上角到右下角一共有 2 条不同的路径: 1. 向 ...

  6. day 42 mycql 查询操作,重点中的重点

    数据库的查询操作是重点中的重点,最核心的内容就是它! 在查询时关键字的定义顺序: select distinct(select-list) from (left-table) (type-join) ...

  7. 动态规划-poj1949

    题目链接:http://poj.org/problem?id=1949 题目描述: 思路:用一个数组dp来存完成第i个任务时所需的最短的时间,dp[i] = max(dp[j]) +time, j是需 ...

  8. Service插件化解决方案

    --摘自<android插件化开发指南> 1.ActivityThread最终是通过Instrumentation启动一个Activity的.而ActivityThread启动Servic ...

  9. 2018 icpc 青岛网络赛 J.Press the Button

    Press the Button Time Limit: 1 Second      Memory Limit: 131072 KB BaoBao and DreamGrid are playing ...

  10. 使用vue iview遇到的一些问题

    使用阿里巴巴图标库 下载代码 这五个文件 iconfount.css 如果导入多个文件记得把@font-face复制到里面 改成./路径 //main.js import './assets/font ...