来源 : http://blog.itpub.net/28916011/viewspace-2214745/

service是要通过coreDNS来管理pod的。

kube-proxy始终监视着apiserver,获取与service资源的变动状态。一旦发现有service资源发生变动,kube-proxy都要把它转变为当前节点之上的,能够实现service资源调度,包括将客户端资源调度到pod的规则(iptables或者ipvs)。

service工作模式有三种:userspace(k8s 1.1版本之前),iptables(k8s 1.10版本之前)和ipvs(k8s 1.11版本之后)

userspace模型:用户空间模型。k8s 1.11版本用ipvs了,这个比iptables效率高。

[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
redis ClusterIP 10.106.138.181 <none> 6379/TCP 23h

  

[root@master ~]# kubectl delete svc redis
service "redis" deleted

  

注意kubernetes这个service千万别删,因为K8s都是通过10.96.0.1这个地址联系的。

[root@master ~]# kubectl explain svc

  

service类型:

a)、ExternalName:表示把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部的服务进行通信;

b)、ClusterIP:只能在集群内部通讯;

c)、NodePort:可以和集群外部通讯;

d)、LoadBalancer:这个表示我们把k8s部署在虚拟机上,自动在外部创建负载均衡器。比如在阿里云上,底层是LBAAS。

ClusterIP

以前我们使用kubectl expose创建service,下面我们使用清单来创建service。

[root@master manifests]# cat redis-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: redis
role: logstor
clusterIP: 10.97.97.97 #这个ip可以不指定,让它自动分配
type: ClusterIP
ports:
- port: 6379 #service ip中的端口
targetPort: 6379 #容器ip中的端口

  

[root@master manifests]# kubectl apply -f redis-svc.yaml
service/redis created

  

[root@master manifests]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
redis ClusterIP 10.97.97.97 <none> 6379/TCP 1m

  

[root@master manifests]# kubectl describe svc redis
Name: redis
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","ports":[{"por...
Selector: app=redis,role=logstor
Type: ClusterIP
IP: 10.97.97.97
Port: <unset> 6379/TCP
TargetPort: 6379/TCP
Endpoints: 10.244.2.65:6379 ##这是pod的ip
Session Affinity: None
Events: <none>

  

资源记录:SVC_NAME.NAMESPACE_NAME.DOMAIN.LTD

集群默认后缀是svc.cluster.local

比如我们创建的redis默认名称就是redis.defalut.svc.cluster.local

NodePort

访问路径:client---->NodeIP:NodePoint----->ClusterIP:ServerPort---->PodIP:containerPort

[root@master manifests]# cat myapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
clusterIP: 10.99.99.99 #这个ip可以不指定,让他自动分配
type: NodePort
ports:
- port: 80 #service ip的端口
targetPort: 80 #容器ip的端口
nodePort: 30080 #node节点上端口,这个端口也可以不指定,会自动分配端口

  

[root@master manifests]# kubectl apply -f myapp-svc.yaml
service/myapp created

  

[root@master manifests]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
myapp NodePort 10.99.99.99 <none> 80:30080/TCP 44s
redis ClusterIP 10.97.97.97 <none> 6379/TCP 15m

  

[root@master manifests]# curl http://172.16.1.101:30080/hostname.html
myapp-deploy-69b47bc96d-79fqh
[root@master manifests]# curl http://172.16.1.101:30080/hostname.html
myapp-deploy-69b47bc96d-tc54k

  

注意:172.16.1.101是Node节点的Ip,并且可以看到访问是做了负载均衡的

下面我们再把来自同一个客户端会话请求用sessionAffinity粘滞到一个固定的pod上,这样就不会出现负载均衡现象了,相当于nginx的 ip_hash功能,如下:

[root@master manifests]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClientIP"}}'
service/myapp patched

  

上面打的补丁也可以直接用edit方法编辑。

[root@master manifests]# kubectl describe svc myapp
Session Affinity: ClientIP

  

再改回负载均衡模式:
[root@master manifests]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"None"}}'
service/myapp patched

  

无头service

我们前面介绍的service是service name解析为cluster ip,然后cluster ip对应到后面的pod ip。

而无头service是指service name 直接解析为后面的pod ip。

无头就是没有cluster ip牵头了。

[root@master manifests]# cat myapp-svc-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
namespace: default
spec:
selector:
app: myapp #挑选的pod还是myapp。一个pod可以有多个service
release: canary
clusterIP: None #None表示是无头service
ports:
- port: 80 #service ip中的端口
targetPort: 80 #容器ip中的端口

  

[root@master manifests]# kubectl apply -f myapp-svc-headless.yaml
service/myapp-svc created

  

[root@master manifests]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
myapp NodePort 10.99.99.99 <none> 80:30080/TCP 1h
myapp-svc ClusterIP None <none> 80/TCP 28s
redis ClusterIP 10.97.97.97 <none> 6379/TCP 1h

  

看到上面myapp-svc的cluster-ip是空,这就是无头service。

[root@master manifests]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 16d

  

可以看到coreDNS的地址是10.96.0.10

[root@master manifests]# dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10702
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;myapp-svc.default.svc.cluster.local. INA
;; ANSWER SECTION:
myapp-svc.default.svc.cluster.local. 5 IN A10.244.1.63
myapp-svc.default.svc.cluster.local. 5 IN A10.244.2.51
;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Mon Sep 24 00:22:07 EDT 2018
;; MSG SIZE rcvd: 166

  

[root@master manifests]# kubectl get pods -o wide -l app=myapp
NAME READY STATUS RESTARTS AGE IP NODE
myapp-deploy-69b47bc96d-79fqh 1/1 Running 0 1d 10.244.1.63 node1
myapp-deploy-69b47bc96d-tc54k 1/1 Running 0 1d 10.244.2.51 node2

  

上面看到无头service name直接被解析到另个pod上的ip了。

ExternalName

我们可以用ExternalName对Service名称和集群外部服务地址做一个映射,使之访问Service名称就是访问外部服务。例如下面的例子是将 svc1 和 xxx.xxx.xxx.xxx 做了对等关系。

kind: Service
apiVersion: v1
metadata:
name: svc1
namespace: default
spec:
type: ExternalName
externalName: somedomain.org

  

不过,ExternalName 类型的服务适用于外部服务使用域名的方式,缺点是不能指定端口。

另外,要实现集群内访问集群外服务的这个需求,也是非常简单的。因为集群内的Pod会继承Node上的DNS解析规则。因此只要Node可以访问的服务,Pod中也可以访问到

=========================================阿里云上某个服务的svc文件例子和解释===========================

apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet
service.beta.kubernetes.io/alicloud-loadbalancer-force-override-listeners: 'false'
service.beta.kubernetes.io/alicloud-loadbalancer-id: xxxxxxx
labels:
app: xxxx
name: xxxx-inner
namespace: xxxx-dev
spec:
clusterIP: 10.129.16.253
externalTrafficPolicy: Local
healthCheckNodePort:
ports:
- name: azvs-https
nodePort:
port:
protocol: TCP
targetPort:
- name: xxxx
nodePort:
port:
protocol: TCP
targetPort:
selector:
app: xxxx
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 10.250.7.77
externalTrafficPolicy: Local  表示此服务是否希望将外部流量路由到节点本地或集群范围的端点。
有两个可用选项:”Cluster”(默认)和 “Local”。
”Cluster” 隐藏了客户端源 IP,可能导致第二跳到另一个节点,但具有良好的整体负载分布。
“Local” 保留客户端源 IP 并避免 LoadBalancer 和 NodePort 类型服务的第二跳,但存在潜在的不均衡流量传播风险
大白话就是:“Local 会在某个节点上把流量引过来,SLB上只能看到该端口通的那个节点,而Cluster把流量分到后面的所有work节点,阿里的SLB上能看到所有的work节点”
service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet  表示内部,把intranet 改成internet就是外部
service.beta.kubernetes.io/alicloud-loadbalancer-force-override-listeners: 'false'  是否强制覆盖的意思
service.beta.kubernetes.io/alicloud-loadbalancer-id: xxxxxxx  这个就是你的SLB的id
 
 

k8s系列---service的更多相关文章

  1. k8s系列---Service之ExternalName用法

    需求:需要两个不同的namespace之间的不同pod可以通过name的形式访问 实现方式: A:在其他pod内ping [svcname].[namespace] ping出来到结果就是svc的ip ...

  2. Docker & k8s 系列二:本机k8s环境搭建

    本篇将会讲解k8s是什么?本机k8s环境搭建,部署一个pod并演示几个kubectl命令,k8s dashboard安装. k8s是什么 k8s是kubernetes的简写,它是一个全新的基于容器技术 ...

  3. Docker & k8s 系列三:在k8s中部署单个服务实例

    本章将会讲解: pod的概念,以及如何向k8s中部署一个单体应用实例. 在上面的篇幅中,我们了解了docker,并制作.运行了docker镜像,然后将镜像发布至中央仓库了.然后又搭建了本机的k8s环境 ...

  4. Docker & k8s 系列一:快速上手docker

    Docker & k8s 系列一:快速上手docker 本篇文章将会讲解:docker是什么?docker的安装,创建一个docker镜像,运行我们创建的docker镜像,发布自己的docke ...

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

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

  6. 容器编排系统k8s之Service资源

    前文我们了解了k8s上的DemonSet.Job和CronJob控制器的相关话题,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14157306.html:今 ...

  7. k8s 无头service 方式向内发布

    k8s 无头service 是指 clusterIP 为 None 的service 案例,假定有一个 deployment,containerPort 端口80,同时还被打上 python=mywe ...

  8. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)

    更多精彩内容请关注微信公众号:新猿技术生态圈 更多精彩内容请关注微信公众号:新猿技术生态圈 更多精彩内容请关注微信公众号:新猿技术生态圈 Endpoints 命名空间级资源,如果endpoints和s ...

  9. k8s系列文章第五篇(docker-compose)

    更多精彩内容,猛搓这里 目录 一.Docker Compose 1.前言 2.官方介绍 1.Compose 中有两个重要的概念 2.三步骤 3.Compose是Docker官方的开源项目,需要安装! ...

随机推荐

  1. C++Primer第五版 6.1节练习

    练习6.1:实参和形参的区别是什么? 通俗解释: 实参是形参的初始值.编译器能以任意可行的顺序对实参求值.实参的类型必须与对应的形参类型匹配. 详解1) 形参变量只有在函数被调用时才会分配内存,调用结 ...

  2. 【一头扎进Spring】 01 | 从 HelloWorld 开始看Spring

    Spring 是一个开源框架. Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能. Spring 是一个 IOC(DI ...

  3. 【Flink】Flink作业调度流程分析

    1. 概述 当向Flink集群提交用户作业时,从用户角度看,只需要作业处理逻辑正确,输出正确的结果即可:而不用关心作业何时被调度的,作业申请的资源又是如何被分配的以及作业何时会结束:但是了解作业在运行 ...

  4. 20191211 HNOI2017模拟赛 C题

    题目: 分析: 开始觉得是神仙题... 然后发现n最多有2个质因子 这说明sm呢... 学过物理的小朋友们知道,当一个物体受多个不同方向相同的力时,只有相邻力的夹角相等,受力就会平衡 于是拆扇叶相当于 ...

  5. ASP.NET MVC4 使用UEditor富文本

    原帖:http://user.qzone.qq.com/369175376/infocenter?ptlang=2052     第一步:先到http://ueditor.baidu.com/webs ...

  6. Solution: 题解 CF1196E Connected Component on a Chessboard

    感觉这题还可以 因为总空间比输入数量 不知高到哪里去了 ,所以完全不需要考虑放不下的问题 从贪心的角度考虑,如果要使相差数量巨大的\(b\)和\(w\)能够成功放下来,应该使这些方块尽量分散(似乎有点 ...

  7. MySql配置环境变量

    完成后安装好MySQL,为MySQL配置环境变量. 0)在我的电脑上点击右键选择属性-->高级系统设置-->环境变量1)新建MYSQL_HOME变量,并配置:D:\Develop\mysq ...

  8. Nginx-负载均衡实现解读

    负载均衡在服务端开发中算是一个比较重要的特性.因为Nginx除了作为常规的Web服务器外,还会被大规模的用于反向代理前端,因为Nginx的异步框架可以处理很大的并发请求,把这些并发请求hold住之后就 ...

  9. equals()和hashCode()使用总结

    equals()和hashCode()使用总结 equals() Object类中的equals方法和"=="是一样的,没有区别,即俩个对象的比较是比较他们的栈内存中存储的内存地址 ...

  10. 深入理解Java虚拟机内存模型

    前言 本文中部分内容引用至<深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)>第12章,如果有兴趣可自行深入阅读,文末放有书籍PDF版本连接. 一.物理机中的并发 物理机遇到的并 ...