Kubernetes中Service机制

Service

Pod的IP是在docker0网段动态分配的,当发生重启,扩容等操作时,IP地址会随之变化。当某个Pod(frontend)需要去访问其依赖的另外一组Pod(backend)时,如果backend的IP发生变化时,如何保证fronted到backend的正常通信变的非常重要。由此,引出了Service的概念。

这里docker0是一个网桥,docker daemon启动container时会根据docker0的网段来划粉container的IP地址Docker网络

在实际生产环境中,对Service的访问可能会有两种来源:Kubernetes集群内部的程序(Pod)和Kubernetes集群外部,为了满足上述的场景,Kubernetes service有以下三种类型:

  • ClusterIP:提供一个集群内部的虚拟IP以供Pod访问。
  • NodePort:在每个Node上打开一个端口以供外部访问。
  • LoadBalancer:通过外部的负载均衡器来访问。

ClusterIP && NodePort && LoadBalancer

1. ClusterIP

此模式会提供一个集群内部的虚拟IP(与Pod不在同一网段),以供集群内部的pod之间通信使用。
ClusterIP也是Kubernetes service的默认类型。

service-network.png

为了实现图上的功能主要需要以下几个组件的协同工作

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

下面我们实际发布一个Service,能够更清晰的了解到Service是如何工作的。

1.1 发布一个rc,并指定replices count为3.

yancey@ yancey-macbook kubernetes-1$kubectl create -f rc_nginx.yaml
yancey@ yancey-macbook kubernetes-1$kubectl get pods
NAME                     READY     STATUS    RESTARTS   AGE
k8s-master-core-v2-01    4/4       Running   0          8m
k8s-proxy-core-v2-01     1/1       Running   0          8m
nginx-controller-6bovu   1/1       Running   0          4m
nginx-controller-iowux   1/1       Running   0          4m
nginx-controller-o7m6u   1/1       Running   0          4m
yancey@ yancey-macbook kubernetes-1$kubectl describe pod nginx-controller-6bovu
Name:       nginx-controller-6bovu
Namespace:  default
Node:       core-v2-01/172.17.8.101
Start Time: Fri, 17 Jun 2016 15:22:20 +0800
Labels:     app=nginx
Status:     Running
IP:     10.1.13.3
Controllers:    ReplicationController/nginx-controller

1.2. 发布一个service,并指定步骤1中的label。

yancey@ yancey-macbook kubernetes-1$kubectl create -f service_nginx.yaml
yancey@ yancey-macbook kubernetes-1$kubectl get svc
NAME            CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes      10.0.0.1     <none>        443/TCP    9m
nginx-service   10.0.0.252   <none>        8000/TCP   4m

kubernetes为nginx-server这个service创建了一个10.0.0.252这个ClusterIP,也可以称为VirtualIP.

yancey@ yancey-macbook kubernetes-1$kubectl get ep
NAME            ENDPOINTS                                AGE
kubernetes      172.17.8.101:6443                        9m
nginx-service   10.1.13.2:80,10.1.13.3:80,10.1.13.4:80   4m

查看endpoint信息,发现nginx-service一共有三个endpoint地址,分别对应nginx的三个pod。

1.3. 查看iptables,观察其NAT表中的信息(只截取了部分和这个service有关的信息)

查看iptables中NAT表的命令:iptables -L -v -n -t nat

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   37  2766 KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
   33  2112 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

在PREROUTING链中会先匹配到KUBE-SERVICES这个Chain。

Chain KUBE-SERVICES (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SVC-GKN7Y2BSGW4NJTYL  tcp  --  *      *       0.0.0.0/0            10.0.0.252           /* default/nginx-service: cluster IP */ tcp dpt:8000
   18  1080 KUBE-NODEPORTS  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL

所有destinationIP为10.0.0.252的包都转到KUBE-SVC-GKN7Y2BSGW4NJTYL这个Chain

Chain KUBE-SVC-GKN7Y2BSGW4NJTYL (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SEP-7ROBBXFV7SD4AIRW  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ statistic mode random probability 0.33332999982
    0     0 KUBE-SEP-XY3F6VJIZ7ELIF4Z  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-JIDZHFC4A3T535AK  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */

这里能看到请求会平均执行KUBE-SEP-7ROBBXFV7SD4AIRW,KUBE-SEP-XY3F6VJIZ7ELIF4Z,KUBE-SEP-XY3F6VJIZ7ELIF4Z这三个Chain.最后我们看下KUBE-SEP-7ROBBXFV7SD4AIRW这个Chain做了什么

Chain KUBE-SEP-7ROBBXFV7SD4AIRW (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.1.13.2            0.0.0.0/0            /* default/nginx-service: */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ tcp to:10.1.13.2:80

这个Chain使用了DNAT规则将流量转发到10.1.13.2:80这个地址。至此从Pod发出来的流量通过本地的iptables将流量转至了service背后的pod上。

2. NodePort

Kubernetes将会在每个Node上打开一个端口并且每个Node的端口都是一样的,通过<NodeIP>:NodePort的方式Kubernetes集群外部的程序可以访问Service。

修改kubernetes/service_nginx.yaml,将Service的type改为NodePort类型。

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
  - port: 8000
    targetPort: 80
    protocol: TCP
  # just like the selector in the replication controller,
  # but this time it identifies the set of pods to load balance
  # traffic to.
  selector:
    app: nginx

发布这个service,可以看到已经随机分配了一个NodePort端口。

yancey@ yancey-macbook kubernetes-1$kubectl get svc nginx-service -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2016-06-18T03:29:42Z
  name: nginx-service
  namespace: default
  resourceVersion: "1405"
  selfLink: /api/v1/namespaces/default/services/nginx-service
  uid: e50ba23a-3504-11e6-a94f-080027a75e9e
spec:
  clusterIP: 10.0.0.229
  ports:
  - nodePort: 30802
    port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

观察Iptables中的变化,KUBE-NODEPORTS这个Chain中增加了如下内容

Chain KUBE-NODEPORTS (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ tcp dpt:30802
    0     0 KUBE-SVC-GKN7Y2BSGW4NJTYL  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/nginx-service: */ tcp dpt:30802

可以看到流量会转至KUBE-SVC-GKN7Y2BSGW4NJTYL这个Chain中处理一次,也就是ClusterIP中提到的通过负载均衡将流量平均分配到3个endpoint上。

3. LoadBalancer

待补充。

服务发现

当发布一个服务之后,我们要使用这个服务,第一个问题就是要拿到这些服务的IP和PORT,kubernetes提供两种方式以便在程序中去动态的获取这些信息。

  1. ENV环境变量
    在Pod其中之后,kubernetes会将现有服务的IP,PORT以环境变量的方式写入pod中,程序只要读取这些环境变量即可。
  2. DNS,程序中可以使用server的名称对服务进行访问,在程序启时候,不必预先读取环境变量中的内容。

这是两种方式的详细说明:http://kubernetes.io/docs/user-guide/services/#discovering-services

附录

  1. iptables文档
  2. Debuging Service
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • •Kubernetes介绍1.背景介绍云计算飞速发展- IaaS- PaaS- SaaSDocker技术突飞猛进-...
    Zero___阅读 14,726评论 0 21
  • kubernetes 简介 一个迅速过一遍kubernetes 非常不错的资源:基于Kubernetes构建Doc...
    bradyjoestar阅读 15,277评论 2 7
  • 1.1 Kubernetes是什么 首先,它是一个全新的基于容器技术的分布式架构领先方案; 其次,Kubernet...
    c84f3109853b阅读 80,564评论 1 117
  • 如何不去思念一个人 大概没人知道 谈恋爱的人哪怕对方在眼前也依然想念
    熬出欢喜阅读 135评论 0 1
  • 我听了那么多网上课程,结果一个多月的寒假最大的成就是没有跟我妈吵架(大概是我妈也懒得嫌弃我了),而最糟心是总有人问...
    安月白阅读 335评论 4 7