Service概念

Kubernetes Service定义了一个Pod的逻辑分组,一种可以访问它们的策略。这组Pod能被Service访问到,通常是通过label Selector。



Service能够提供负载均衡的能力,它只提供4层负载均衡的能力,而没有7层功能,有时我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。

Service的类型

Service在K8S中有四种类型

  • ClusterIp:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP。
  • NodePort:ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过NodePort来访问服务。
  • LoadBalancer:NodePort的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到NodePort
  • ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,只有Kubernetes1.7或更高版本的kube-dns才支持。

VIP和Service代理

​ 在Kubernetes集群中,每个Node运行一个kube-proxy进程。kube-proxy负责为Service实现了一种VIP(虚拟IP)的形式,而不是ExternalName的形式。在Kubernetes v1.0版本,代理v完全在userspace。在Kubernetes v1.1版本,新增了iptables代理,但并不是默认的运行模式。从Kubernetes v1.2起,默认就是iptables代理。在Kubernetes v1.8.0-beta.0中,添加了ipvs代理,在Kubernetes 1.14版本开始默认使用ipvs代理。在Kubernetes v1.0版本,Service是“4层”(TCP/UDP over IP)的概念。在Kubernetes v1.1版本,新增了Ingress API(beta版),用来表示“7层”(HTTP)服务。

代理模式的分类

  • userspace代理模式

  • iptables代理模式

  • ipvs代理模式

    kube-proxy会监视Kubernetes Service对象和Endpoints对象,调用netlink接口以相应地创建ipvs规则并定期与Kubernetes Service对象和Endpoints对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将被重定向到其中一个后端Pod。与iptables类似,ipvsnetfilterhook功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着ipvs可以更快地重定向流量,并在同步代理规则时具有更好地性能。此外,ipvs为负载均衡算法提供了更多选项,例如:

    • rr轮询调度
    • lc最小连接数
    • dh目标哈希
    • sh源哈希
    • sed最短期望延迟
    • nq不排队调度

    注意:ipvs模式假定在运行kube-proxy之前在节点上都已经安装了ipvs内核模块。当kube-proxy以ipvs代理模式启动时,kube-proxy将验证节点上是否安装了ipvs模块,如果未安装,则kube-proxy将回退到iptables代理模式。

Service的 spec.type

ClusterIP

ClusterIP主要在每个node节点使用iptables,将发向clusterIP对应端口的数据,转发到kube-proxy中。然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod地址和端口。

  • 用户通过kubectl命令向apiserver发送创建service的命令,apiserver收到请求后将数据存储到etcd中。
  • kubernetes的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知servicepod的变化,并将变化的信息写入本地的iptables规则中。
  • iptables使用NAT等技术将virtualIP的流量转至endpoint中。

创建myapp-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
labels:
app: myapp-deploy
spec:
replicas: 3
template:
metadata:
name: myapp-deploy
labels:
app: myapp-deploy
release: stabel
env: test
spec:
containers:
- name: myapp-deploy
image: chinda.com/library/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
restartPolicy: Always
selector:
matchLabels:
app: myapp-deploy
release: stabel

创建myapp-service.yaml

apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp-service
release: stabel
ports:
- port: 80
targetPort: 80
name: http
type: ClusterIP

测试

[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
myapp-service ClusterIP 10.107.157.192 <none> 80/TCP 9s
[root@k8s-master01 ~]# curl 10.107.157.192
curl: (7) Failed connect to 10.107.157.192:80; Connection refused
[root@k8s-master01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.0.1:443 rr
-> 192.168.0.150:6443 Masq 1 3 0
TCP 10.96.0.10:53 rr
-> 10.244.0.43:53 Masq 1 0 0
-> 10.244.0.44:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.244.0.43:9153 Masq 1 0 0
-> 10.244.0.44:9153 Masq 1 0 0
TCP 10.107.157.192:80 rr
UDP 10.96.0.10:53 rr
-> 10.244.0.43:53 Masq 1 0 0
-> 10.244.0.44:53 Masq 1 0 0
[root@k8s-master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-6f87986465-2pcgp 1/1 Running 0 14m 10.244.1.123 k8s-node01 <none> <none>
myapp-deploy-6f87986465-7rhrq 1/1 Running 0 14m 10.244.1.124 k8s-node01 <none> <none>
myapp-deploy-6f87986465-scz2v 1/1 Running 0 14m 10.244.2.110 k8s-node02 <none> <none>

拒绝连接,ipvs检测service下没有挂载任何的pod,原因是deployment和service的spec.selector命名不相同。

修改后

修改后myapp-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
labels:
app: myapp-deploy
spec:
replicas: 3
template:
metadata:
name: myapp
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp-deploy
image: chinda.com/library/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
restartPolicy: Always
selector:
matchLabels:
app: myapp
release: stabel

修改后myapp-service.yaml

apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
release: stabel
ports:
- port: 80
targetPort: 80
name: http
type: ClusterIP

检测

[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
myapp-service ClusterIP 10.104.50.207 <none> 80/TCP 10s
[root@k8s-master01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.0.1:443 rr
-> 192.168.0.150:6443 Masq 1 3 0
TCP 10.96.0.10:53 rr
-> 10.244.0.43:53 Masq 1 0 0
-> 10.244.0.44:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.244.0.43:9153 Masq 1 0 0
-> 10.244.0.44:9153 Masq 1 0 0
TCP 10.104.50.207:80 rr
-> 10.244.1.125:80 Masq 1 0 0
-> 10.244.1.126:80 Masq 1 0 0
-> 10.244.2.111:80 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.244.0.43:53 Masq 1 0 0
-> 10.244.0.44:53 Masq 1 0 0
[root@k8s-master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-677ccc888c-m42jt 1/1 Running 0 119s 10.244.1.125 k8s-node01 <none> <none>
myapp-deploy-677ccc888c-rgsn4 1/1 Running 0 119s 10.244.2.111 k8s-node02 <none> <none>
myapp-deploy-677ccc888c-w6hzg 1/1 Running 0 119s 10.244.1.126 k8s-node01 <none> <none>
[root@k8s-master01 ~]# curl 10.104.50.207
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

Headless Service

有时不需要或不想要负载均衡,以及单独的Service IP。遇到这种情况,可以通过指定Cluster IP(spec.clusterIP)的值为“None”来创建Headless Service。这类Service并不会分配Cluster IP,kube-proxy不会处理他们,而且平台也不会为它们进行负载均衡和路由。

创建myapp-headless-svc.yaml

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

解析coredns

# svc 创建成功会写入到coredns中
[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
myapp-headless ClusterIP None <none> 80/TCP 6s
myapp-service ClusterIP 10.104.50.207 <none> 80/TCP 16m
[root@k8s-master01 ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-5c98db65d4-dhrw6 1/1 Running 21 13d 10.244.0.44 k8s-master01 <none> <none>
coredns-5c98db65d4-jhvv2 1/1 Running 21 13d 10.244.0.43 k8s-master01 <none> <none>
etcd-k8s-master01 1/1 Running 22 13d 192.168.0.150 k8s-master01 <none> <none>
kube-apiserver-k8s-master01 1/1 Running 22 13d 192.168.0.150 k8s-master01 <none> <none>
kube-controller-manager-k8s-master01 1/1 Running 22 13d 192.168.0.150 k8s-master01 <none> <none>
kube-flannel-ds-amd64-bm5px 1/1 Running 28 13d 192.168.0.150 k8s-master01 <none> <none>
kube-flannel-ds-amd64-cfhhg 1/1 Running 23 13d 192.168.0.152 k8s-node02 <none> <none>
kube-flannel-ds-amd64-mlqgl 1/1 Running 20 13d 192.168.0.151 k8s-node01 <none> <none>
kube-proxy-4f8dk 1/1 Running 19 13d 192.168.0.152 k8s-node02 <none> <none>
kube-proxy-lg875 1/1 Running 19 13d 192.168.0.151 k8s-node01 <none> <none>
kube-proxy-zwpmh 1/1 Running 22 13d 192.168.0.150 k8s-master01 <none> <none>
kube-scheduler-k8s-master01 1/1 Running 22 13d 192.168.0.150 k8s-master01 <none> <none>
# 安装dig命令
[root@k8s-master01 ~]# yum -y install bind-utils
# 访问svc {service-name}.{namespace}.svc.cluster.local
[root@k8s-master01 ~]# dig -t A myapp-headless.default.svc.cluster.local. @10.244.0.44 ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.2 <<>> -t A myapp-headless.default.svc.cluster.local. @10.244.0.44
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6438
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp-headless.default.svc.cluster.local. IN A ;; ANSWER SECTION:
myapp-headless.default.svc.cluster.local. 30 IN A 10.244.1.125
myapp-headless.default.svc.cluster.local. 30 IN A 10.244.1.126
myapp-headless.default.svc.cluster.local. 30 IN A 10.244.2.111 ;; Query time: 0 msec
;; SERVER: 10.244.0.44#53(10.244.0.44)
;; WHEN: Fri May 01 09:57:24 CST 2020
;; MSG SIZE rcvd: 237
[root@k8s-master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-677ccc888c-m42jt 1/1 Running 0 48m 10.244.1.125 k8s-node01 <none> <none>
myapp-deploy-677ccc888c-rgsn4 1/1 Running 0 48m 10.244.2.111 k8s-node02 <none> <none>
myapp-deploy-677ccc888c-w6hzg 1/1 Running 0 48m 10.244.1.126 k8s-node01 <none> <none>

NodePort

NodePort的原理在于在Node上开了一个端口,将向该端口的流量导入kube-proxy,然后由kube-proxy进一步给对应的Pod。

创建nodeport.yaml

apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
spec:
selector:
app: myapp
release: stabel
ports:
- port: 80
targetPort: 80
type: NodePort

测试

[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
myapp-headless ClusterIP None <none> 80/TCP 36m
myapp-nodeport NodePort 10.105.209.63 <none> 80:31509/TCP 5s
myapp-service ClusterIP 10.104.50.207 <none> 80/TCP 52m
# 每个节点都会开放此端口
[root@k8s-master01 ~]# netstat -anp | grep 31509
tcp6 0 0 :::31509 :::* LISTEN 3338/kube-proxy

LoadBalancer

云供应商提供的服务,其实和NodePort是同一种方式。

ExternalName

这种类型的Service通过返回CNAME和它的值,可以将服务映射到externalName字段的内容(例如:www.123.com)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群之外的服务,它通过返回该外部服务的别名这种方式来提供服务。

创建ex.yaml

apiVersion: v1
kind: Service
metadata:
name: myapp-ex
spec:
type: ExternalName
externalName: www.123.com

检测

[root@k8s-master01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
myapp-ex ExternalName <none> www.123.com <none> 6s
myapp-headless ClusterIP None <none> 80/TCP 99m
myapp-nodeport NodePort 10.105.209.63 <none> 80:31509/TCP 62m
myapp-service ClusterIP 10.104.50.207 <none> 80/TCP 115m
[root@k8s-master01 ~]# dig -t A myapp-ex.default.svc.cluster.local. @10.244.0.44 ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.2 <<>> -t A myapp-ex.default.svc.cluster.local. @10.244.0.44
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41068
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp-ex.default.svc.cluster.local. IN A ;; ANSWER SECTION:
myapp-ex.default.svc.cluster.local. 30 IN CNAME www.123.com.
www.123.com. 30 IN A 61.132.13.130 ;; Query time: 68 msec
;; SERVER: 10.244.0.44#53(10.244.0.44)
;; WHEN: Fri May 01 11:08:54 CST 2020
;; MSG SIZE rcvd: 149

当查询主机 myapp-ex.default.svc.cluster.local时,集群的DNS服务将返回一个值www.123.comd的CNAME记录。访问这个服务的工作方式和其他的相同,唯一不同的时重定向发生在DNS层,而且不会进行代理或转发。

Kubernetes【K8S】(五):Service的更多相关文章

  1. Kubernetes K8S之Service服务详解与示例

    K8S之Service概述与代理说明,并详解所有的service服务类型与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master Cent ...

  2. Kubernetes K8S在IPVS代理模式下Service服务的ClusterIP类型访问失败处理

    Kubernetes K8S使用IPVS代理模式,当Service的类型为ClusterIP时,如何处理访问service却不能访问后端pod的情况. 背景现象 Kubernetes K8S使用IPV ...

  3. kubernetes 实践五:Service详解

    Service 是 k8s 的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上. Service 的定义 Servic ...

  4. 《两地书》--Kubernetes(K8s)基础知识(docker容器技术)

    大家都知道历史上有段佳话叫“司马相如和卓文君”.“皑如山上雪,皎若云间月”.卓文君这么美,却也抵不过多情女儿薄情郎. 司马相如因一首<子虚赋>得汉武帝赏识,飞黄腾达之后便要与卓文君“故来相 ...

  5. Kubernetes(k8s)集群安装

    一:简介 二:基础环境安装 1.系统环境 os Role ip Memory Centos 7 master01 192.168.25.30 4G Centos 7 node01 192.168.25 ...

  6. Kubernetes(K8s)基础知识(docker容器技术)

    今天谈谈K8s基础知识关键词: 一个目标:容器操作:两地三中心:四层服务发现:五种Pod共享资源:六个CNI常用插件:七层负载均衡:八种隔离维度:九个网络模型原则:十类IP地址:百级产品线:千级物理机 ...

  7. 使用kubectl管理Kubernetes(k8s)集群:常用命令,查看负载,命名空间namespace管理

    目录 一.系统环境 二.前言 三.kubectl 3.1 kubectl语法 3.2 kubectl格式化输出 四.kubectl常用命令 五.查看kubernetes集群node节点和pod负载 5 ...

  8. Istio(二):在Kubernetes(k8s)集群上安装部署istio1.14

    目录 一.模块概览 二.系统环境 三.安装istio 3.1 使用 Istioctl 安装 3.2 使用 Istio Operator 安装 3.3 生产部署情况如何? 3.4 平台安装指南 四.Ge ...

  9. kubernetes系列08—service资源详解

    本文收录在容器技术学习系列文章总目录 1.认识service 1.1 为什么要使用service Kubernetes Pod 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结 ...

  10. Docker Kubernetes(K8s)简介

    入职了新公司,使用了Docker和K8s,需要有一个基础的了解,对网络上相关信息进行了简单总结. 一Docker 1简介: Docker 将应用程序与该程序的依赖,打包在一个文件里面.运行这个文件,就 ...

随机推荐

  1. [web安全原理分析]-文件上传漏洞基础

    简介 前端JS过滤绕过 待更新... 文件名过滤绕过 待更新 Content-type过滤绕过 Content-Type用于定义网络文件的类型和网页编码,用来告诉文件接收方以什么形式.什么编码读取这个 ...

  2. 云计算之路-出海记:建一个免费仓库 Amazon RDS for SQL Server

    上周由于园子后院起火,不得不调兵回去救火,出海记暂时停更,这周继续更新,"出海记"记录的是我们在 AWS 上建设博客园海外站的历程. 在这一记中记录的是我们基于 AWS 免费套餐( ...

  3. 思维导图软件iMindMap怎么用模板制作思维导图

    随着思维导图的不断发展,市场上相关的软件也越来越多.像XMind.MindManager等.每一款软件都有它独特的亮点.作为众多思维导图软件中的一款,iMindMap算是比较亮眼的了.现在很多人都在用 ...

  4. css3系列之详解border-radius

    border-radius border-radius 几种写法: 1.border-radius: 50%; 以正方形为例子, 这样写就是设置 4个角 为50%. 2.border-radius: ...

  5. web自动化测试,弹出窗的操作

    弹出窗有两种: 1.alert弹窗 2.页面弹出窗 什么是alert弹窗呢,点击某一个事件后,会弹出一个弹窗,如下图所示,相信大家在测试中有遇到过,怎么操作它呢 1.1弹窗出现后,使用switch_t ...

  6. leetcode137. 只出现一次的数字 II

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素.说明:你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗?示例 1:输入: [2,2 ...

  7. 关于UILabel标签控件的使用小节

    前段时间一直想停下来,总结一下近期在开发中遇到的一些问题顺便分享一下解决问题的思路和方法,无奈人生就像蒲公英,看似自由却身不由己.太多的时间和精力被占用在新项目的开发和之前项目的维护中,总之一句话外包 ...

  8. linux命令 ——netstat

    作用: 能查到与客户端链接状态和数量 netstat各选项参数说明: -a : 列出所有连接,服务监听,Socket信息 -c : 持续列出网络状态 #每隔一秒输出网络信息 -t : 显示TCP端口  ...

  9. 【Updating】汇编语言学习记录02

    换码指令.字符的输出 前置知识: XLAT 指令:将BX指定的缓冲区中.AL指定的位移处的一个字节数据取出赋给AL,实际相当于(AL) = (DS:(BX+AL)).注意,不是单纯地赋予AL+BX,而 ...

  10. redis面试问题(一)

    五大常用数据类型 redis与其他缓存的比较 rdb和aof 主从复制,读写分离,哨兵机制 -------------------------------- 1.为什么使用redis (一)性能 我们 ...