Service:让客户端发现pod并与之通信
5.1.Service介绍
5.1.1.Serice简介
5.1.1.1什么是Service
service是k8s中的一个重要概念,主要是提供负载均衡和服务自动发现。
Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。
5.1.1.2.Service的创建
创建Service的方法有两种:
1.通过kubectl expose创建
#kubectl expose deployment nginx --port=88 --type=NodePort --target-port=80 --name=nginx-service 这一步说是将服务暴露出去,实际上是在服务前面加一个负载均衡,因为pod可能分布在不同的结点上。
–port:暴露出去的端口
–type=NodePort:使用结点+端口方式访问服务
–target-port:容器的端口
–name:创建service指定的名称
2.通过yaml文件创建
创建一个名为hostnames-yaohong的服务,将在端口80接收请求并将链接路由到具有标签选择器是app=hostnames的pod的9376端口上。
使用kubectl creat来创建serivice
apiVersion: v1
kind: Service
metadata:
name: hostnames-yaohong
spec:
selector:
app: hostnames
ports:
- name: default
protocol: TCP
port: 80 //该服务的可用端口
targetPort: 9376 //具有app=hostnames标签的pod都属于该服务
5.1.1.3.检测服务
使用如下命令来检查服务:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.187.0.1 <none> 443/TCP 18d
5.1.1.4.在运行的容器中远程执行命令
使用kubectl exec 命令来远程执行容器中命令
$ kubectl -n kube-system exec coredns-7b8dbb87dd-pb9hk -- ls /
bin
coredns
dev
etc
home
lib
media
mnt
proc
root
run
sbin
srv
sys
tmp
usr
var 双横杠(--)代表kubectl命令项的结束,在双横杠后面的内容是指pod内部需要执行的命令。
5.2.连接集群外部的服务
5.2.1.介绍服务endpoint
服务并不是和pod直接相连的,介于他们之间的就是Endpoint资源。
Endpoint资源就是暴露一个服务的IP地址和端口列表。
通过service查看endpoint方法如下:
$ kubectl -n kube-system get svc kube-dns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterI
P 10.187.0.2 <none> 53/UDP,53/TCP 19d $ kubectl -n kube-system describe svc kube-dns
Name: kube-dns
Namespace: kube-system
Labels: addonmanager.kubernetes.io/mode=Reconcile
k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=CoreDNS
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"prometheus.io/scrape":"true"},"labels":{"addonmanager.kubernetes.io/mode":...
prometheus.io/scrape: true
Selector: k8s-app=kube-dns
Type: ClusterIP
IP: 10.187.0.2
Port: dns 53/UDP
TargetPort: 53/UDP
Endpoints: 10.186.0.2:53,10.186.0.3:53 //代表服务endpoint的pod的ip和端口列表
Port: dns-tcp 53/TCP
TargetPort: 53/TCP
Endpoints: 10.186.0.2:53,10.186.0.3:53
Session Affinity: None
Events: <none>
直接查看endpoint信息方法如下:
#kubectl -n kube-system get endpoints kube-dns
NAME ENDPOINTS AGE
kube-dns 10.186.0.2:53,10.186.0.3:53,10.186.0.2:53 + 1 more... 19d #kubectl -n kube-system describe endpoints kube-dns
Name: kube-dns
Namespace: kube-system
Labels: addonmanager.kubernetes.io/mode=Reconcile
k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=CoreDNS
Annotations: <none>
Subsets:
Addresses: 10.186.0.2,10.186.0.3
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
dns 53 UDP
dns-tcp 53 TCP Events: <none>
5.2.2.手动配置服务的endpoint
如果创建pod时不包含选择器,则k8s将不会创建endpoint资源。这样就需要创建endpoint来指的服务的对应的endpoint列表。
service中创建endpoint资源,其中一个作用就是用于service知道包含哪些pod。
5.2.3.为外部服务创建别名
除了手动配置来访问外部服务外,还可以使用完全限定域名(FQDN)访问外部服务。
apiVersion: v1
kind: Service
metadata:
name: Service-yaohong
spec:
type: ExternalName //代码的type被设置成了ExternalName
externalName: someapi.somecompany.com // 实际服务的完全限定域名(FQDN)
port: - port: 80
服务创建完成后,pod可以通过external-service.default.svc.cluster.local域名(甚至是external-service)连接外部服务。
5.3.将服务暴露给外部客户端
有3种方式在外部访问服务:
1.将服务的类型设置成NodePort;
2.将服务的类型设置成LoadBalance;
3.创建一个Ingress资源。
5.3.1.使用nodeport类型的服务
NodePort 服务是引导外部流量到你的服务的最原始方式。NodePort,正如这个名字所示,在所有节点(虚拟机)上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。
YAML 文件类似如下:
apiVersion: v1
kind: Service
metadata:
name: Service-yaohong
spec:
type: NodePort //为NodePort设置服务类型
ports:
- port: 80
targetPort: 8080
nodeport: 30123 //通过集群节点的30123端口可以访问服务
selector:
app: yh
这种方法有许多缺点:
1.每个端口只能是一种服务
2.端口范围只能是 30000-32767
如果节点/VM 的 IP 地址发生变化,你需要能处理这种情况
基于以上原因,我不建议在生产环境上用这种方式暴露服务。如果你运行的服务不要求一直可用,或者对成本比较敏感,你可以使用这种方法。这样的应用的最佳例子是 demo 应用,或者某些临时应用。
5.3.2.通过Loadbalance将服务暴露出来
LoadBalancer 服务是暴露服务到 internet 的标准方式。在 GKE 上,这种方式会启动一个 Network Load Balancer[2],它将给你一个单独的 IP 地址,转发所有流量到你的服务。
通过如下方法来定义服务使用负载均衡
apiVersion: v1
kind: Service
metadata:
name: loadBalancer-yaohong
spec:
type: LoadBalancer //该服务从k8s集群的基础架构获取负载均衡器
ports:
- port: 80
targetPort: 8080
selector:
app: yh
何时使用这种方式?
如果你想要直接暴露服务,这就是默认方式。所有通往你指定的端口的流量都会被转发到对应的服务。它没有过滤条件,没有路由等。这意味着你几乎可以发送任何种类的流量到该服务,像 HTTP,TCP,UDP,Websocket,gRPC 或其它任意种类。
这个方式的最大缺点是每一个用 LoadBalancer 暴露的服务都会有它自己的 IP 地址,每个用到的 LoadBalancer 都需要付费,这将是非常昂贵的。
5.4.通过Ingress暴露服务
为什么使用Ingress,一个重要的原因是LoadBalancer服务都需要创建自己的负载均衡器,以及独有的公有Ip地址,而Ingress只需要一个公网Ip就能为许多服务提供访问。
5.4.1.创建Ingress资源
Ingress 事实上不是一种服务类型。相反,它处于多个服务的前端,扮演着“智能路由”或者集群入口的角色。
你可以用 Ingress 来做许多不同的事情,各种不同类型的 Ingress 控制器也有不同的能力。
编写如下ingress.yml文件
kind: Ingress
metadata:
name: ingressyaohong
spec:
rules:
- host: kubia.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
servicePort: 80
通过如下命令进行查看ingress
# kubectl create -f ingress.yml
5.4.2.通过Ingress访问服务
通过kubectl get ing命令进行查看ingress
# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
ingressyaohong kubia.example.com 80 2m
了解Ingress的工作原理
何时使用这种方式?
Ingress 可能是暴露服务的最强大方式,但同时也是最复杂的。Ingress 控制器有各种类型,包括 Google Cloud Load Balancer, Nginx,Contour,Istio,等等。它还有各种插件,比如 cert-manager[5],它可以为你的服务自动提供 SSL 证书。
如果你想要使用同一个 IP 暴露多个服务,这些服务都是使用相同的七层协议(典型如 HTTP),那么Ingress 就是最有用的。如果你使用本地的 GCP 集成,你只需要为一个负载均衡器付费,且由于 Ingress是“智能”的,你还可以获取各种开箱即用的特性(比如 SSL、认证、路由等等)。
5.4.3.通过相同的Ingress暴露多少服务
1.将不同的服务映射到相同的主机不同的路径
apiVersion: v1
kind: Ingress
metadata:
name: Ingress-yaohong
spec:
rules:
- host: kubia.example.com
http:
paths:
- path: /yh //对kubia.example.com/yh请求转发至kubai服务
backend:
serviceName: kubia
servicePort:80
- path: /foo //对kubia.example.com/foo请求转发至bar服务
backend:
serviceName: bar
servicePort:80
2.将不同的服务映射到不同的主机上
apiVersion: v1
kind: Ingress
metadata:
name: Ingress-yaohong
spec:
rules:
- host: yh.example.com
http:
paths:
- path: / //对yh.example.com请求转发至kubai服务
backend:
serviceName: kubia
servicePort:80
- host: bar.example.com
http:
paths:
- path: / //对bar.example.com请求转发至bar服务
backend:
serviceName: bar
servicePort:80
5.4.4.配置Ingress处理TLS传输
客户端和控制器之间的通信是加密的,而控制器和后端pod之间的通信则不是。
apiVersion: v1
kind: Ingress
metadata:
name: Ingress-yaohong
spec:
tls: //在这个属性中包含所有的TLS配置
- hosts:
- yh.example.com //将接收来自yh.example.com的TLS连接
serviceName: tls-secret //从tls-secret中获得之前创立的私钥和证书
rules:
- host: yh.example.com
http:
paths:
- path: / //对yh.example.com请求转发至kubai服务
backend:
serviceName: kubia
servicePort:80
5.5.pod就绪后发出信号
5.5.1.介绍就绪探针
就绪探针有三种类型:
1.Exec探针,执行进程的地方。容器的状态由进程的退出状态代码确定。
2.HTTP GET探针,向容器发送HTTP GET请求,通过响应http状态码判断容器是否准备好。
3.TCP socket探针,它打开一个TCP连接到容器的指定端口,如果连接建立,则认为容器已经准备就绪。
启动容器时,k8s设置了一个等待时间,等待时间后才会执行一次准备就绪检查。之后就会周期性的进行调用探针,并根据就绪探针的结果采取行动。
如果某个pod未就绪成功,则会从该服务中删除该pod,如果pod再次就绪成功,则从新添加pod。
与存活探针区别:
就绪探针如果容器未准备就绪,则不会终止或者重启启动。
存活探针通过杀死异常容器,并用新的正常的容器来替代他保证pod正常工作。
就绪探针只有准备好处理请求pod才会接收他的请求。
重要性;
确保客户端只与正常的pod进行交互,并且永远不会知道系统存在问题。
5.5.2.向pod添加就绪探针
添加的yml文件如下
apiVersion: v1
kind: deployment
...
spec:
...
port:
containers:
- name: kubia-yh
imgress: luksa/kubia
readinessProbe:
failureThreshold: 2
httpGet:
path: /ping
port: 80
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3
相关参数解释如下:
- initialDelaySeconds:容器启动和探针启动之间的秒数。
- periodSeconds:检查的频率(以秒为单位)。默认为10秒。最小值为1。
- timeoutSeconds:检查超时的秒数。默认为1秒。最小值为1。
- successThreshold:失败后检查成功的最小连续成功次数。默认为1.活跃度必须为1。最小值为1。
- failureThreshold:当Pod成功启动且检查失败时,Kubernetes将在放弃之前尝试failureThreshold次。放弃生存检查意味着重新启动Pod。而放弃就绪检查,Pod将被标记为未就绪。默认为3.最小值为1。
HTTP探针在httpGet上的配置项:
- host:主机名,默认为pod的IP。
- scheme:用于连接主机的方案(HTTP或HTTPS)。默认为HTTP。
- path:探针的路径。
- httpHeaders:在HTTP请求中设置的自定义标头。 HTTP允许重复的请求头。
- port:端口的名称或编号。数字必须在1到65535的范围内
模拟就绪探针
# kubectl exec <pod_name> -- curl http://10.187.0.139:80/ping
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
5.6.使用headless服务发现独立的pod
5.6.1.创建headless服务
Headless Service
也是一种Service
,但不同的是会定义spec:clusterIP: None
,也就是不需要Cluster IP
的Service
。
顾名思义,Headless Service
就是没头的Service
。有什么使用场景呢?
第一种:自主选择权,有时候
client
想自己来决定使用哪个Real Server
,可以通过查询DNS
来获取Real Server
的信息。第二种:
Headless Services
还有一个用处(PS:也就是我们需要的那个特性)。Headless Service
的对应的每一个Endpoints
,即每一个Pod
,都会有对应的DNS
域名;这样Pod
之间就可以互相访问。
Service:让客户端发现pod并与之通信的更多相关文章
- Kubernetes 实战 —— 05. 服务:让客户端发现 pod 并与之通信(下)
将服务暴露给外部客户端 P136 有以下三种方式可以在外部访问服务: 将服务的类型设置成 NodePort 将服务的类型设置为 LoadBalance 创建一个 Ingress 资源 使用 NodeP ...
- 解压Taobao手机客户端发现的东西
今天解压了Taobao手机客户端发现了几个.so文件, 其中有两个挺感兴趣的,查了一下,以后去研究下. libBSPatch.so 是用于支持增量更新功能的库文件. libwebp.so 好像是We ...
- Warensoft Stock Service Api客户端接口说明
Warensoft Stock Service Api客户端接口说明 Warensoft Stock Service Api Client Reference 可使用环境(Available Envi ...
- Webservice报错客户端发现响应内容类型为“application/json;charset=UTF-8”,但应为“text/xml”。
控制台对接Webservice正常,同样的方法在Web项目上报错: 客户端发现响应内容类型为“application/json;charset=UTF-8”,但应为“text/xml”.请求失败,错误 ...
- SOAP: java+xfire(web service) + php客户端
作者: 吴俊杰 web service这项技术暂不说它有多落伍,但是项目中用到了,没法逃避! xml和json各有各的好处,但是JSON无疑是当今数据交互的主流了.客户soap服务器端用的是 j ...
- 基于Web Service的客户端框架搭建一:C#使用Http Post方式传递Json数据字符串调用Web Service
引言 前段时间一直在做一个ERP系统,随着系统功能的完善,客户端(CS模式)变得越来越臃肿.现在想将业务逻辑层以下部分和界面层分离,使用Web Service来做.由于C#中通过直接添加引用的方来调用 ...
- 基于Web Service的客户端框架搭建四:终结篇
前言 这是这个系列的终结篇,前面3个博客介绍了一下内容: 1.使用Http Post方式调用Web Service 2.客户端框架之数据转换层 3.客户端框架之代理层 框架结构 框架是基于C#的,在V ...
- 基于Web Service的客户端框架搭建二:数据转换层(FCL)
引言 要使用WebService来分离客户端与服务端,必定要使用约定好两者之间的数据契约.Json数据以其完全独立于语言的优势,成为开发者的首选.C# JavaScriptSerializer为Jso ...
- kubernetes学习之service、deployment、pod的关系
deployment根据Pod的标签关联到Pod,是为了管理pod的生命周期 service根据Pod的标签关联到pod,是为了让外部访问到pod,给pod做负载均衡 需要注意: deployment ...
随机推荐
- Java的自动装箱/拆箱
概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...
- 插入Oracle数据库后返回当前主键id
最近做一个spring版本3.0.4的老项目功能,应用场景要用到插入oracle表后返回主键ID拿来和其他表关联. 用oralce的可以一直用这种处理方式,高兼容低,搜索网上的资料都不能和这个Spri ...
- MySQL操作命令梳理(1)
一.索引 1.创建索引 索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER TABLE来给表增加索引.以下命令语句分别展示了如何创建主键索引(PRIM ...
- RE最全面的正则表达式----数字篇
一.校验数字的表达式 数字:^[0-9]*$n位的数字:^d{n}$至少n位的数字:^d{n,}$m-n位的数字:^d{m,n}$零和非零开头的数字:^(0|[1-9][0-9]*)$非零开头的最多带 ...
- 状压DP概念 及例题(洛谷 P1896 互不侵犯)
状压DP 就是状态压缩DP.所谓状态压缩,就是将一些复杂的状态压缩起来,一般来说是压缩为一个二进制数,用01来表示某一元素的状态. 比如一排灯泡(5个) 我们可以用一串二进制01串来表示他们的状态 1 ...
- spark源码阅读---Utils.getCallSite
1 作用 当该方法在spark内部代码中调用时,会返回当前调用spark代码的用户类的名称,以及其所调用的spark方法.所谓用户类,就是我们这些用户使用spark api的类. 2 内部实现 2.1 ...
- Docker 方式部署 Solo 博客系统总结
此篇为Docker部署方式,另有Tomcat部署方式,请参考文章<Tomcat 方式部署 Solo 博客系统总结> 最近搭建了一个博客系统,作为自己的主页,方便记录一些平时所见所闻 ...
- Python模块——HashLib(摘要算法)与base64
摘要算法(hashlib) Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度 ...
- StudyAndroid.1
目标: 手动创建第一个Activity 开发环境: Android Studio 3.3.1 Build #AI-182.5107.16.33.5264788, built on January 29 ...
- tracert和traceroute介绍
一.tracert和traceroute简介 相同点:都是用来跟踪路由,帮助排查问题,关注的是过程,而ping关注的是结果 不同点:tracert请求是icmp echo报文 traceroute请求 ...