kubernetes之service

每创建一个pod,kubernetes都会为pod创建一个虚拟的ip地址,基于这样一个虚拟的IP地址,kebernetes下的每一个pod就可以相互访问了,而不用管该pod是否在同一个node上。如下图所示,node-worker1下的pod-1可以访问node-worker2下的pod-web提供的nginx服务。


pod.png
# 一个master节点和一个work节点
apiVersion: v1
kind: Pod
metadata:
  name: svc-pod1
spec:
  containers:
  - name: nginx
    image: nginx 
# 由于只有一个work节点,所以该pod将会被调度到work节点上
# 此时可以在master节点查看该pod的ip地址,在master节点上使用curl命令查看是否能否访问
# kubectl get pods -o wide
NAME                                READY   STATUS               RESTARTS   AGE     IP
svc-pod1                            1/1     Running              0          32m     10.44.0.30
# curl http://10.44.0.30
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
# 说明从master节点上可以访问来自于work节点上的pod所提供的服务

由kubernetes为pod创建的虚拟IP只能够在kubernetes集群范围内有效,集群外的客户端无法通过pod的ip地址加容器端口访问到其所提供的服务,因此kubernetes为Pod提供了一个端口映射的字段-hostPort。其作用是能够通过主机ip加端口的方式访问pod中容器提供的服务。基本原理是将hostport端口映射到pod中某一容器的端口上,从而实现访问。客户根据node的ip + hostport端口请求服务,node接到请求后,根据iptables,会将请求转发到pod_web上的nginx端口上去从而实现访问

apiVersion: v1
kind: Pod
metadata:
  name: svc-pod1
spec:
  containers:
  - name: nginx
    image: nginx 
    ports:
    - containerPort: 80
      hostPort: 10000
# 在有多个节点的情况下,首先需要查询该pod被调度在哪个node上,然后基于该node的ip地址加端口进行访问
# kubectl describe pod svc-pod1    # 查询node的ip地址
# curl http://node_ip:10000
# 需要注意的是,hostPort端口在node节点上必须是唯一的。若出现相同的hostPort则会应该port冲突导致pod创建失败。比如,在上一个pod的基础上,在同一个节点添加这样一个pod,则会创建失败
apiVersion: v1
kind: Pod
metadata:
  name: svc-pod2
spec:
  containers:
  - name: tomcat
    image: tomcat
    ports:
    - containerPort: 8080
      hostPort: 10000
# 报错如下
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  35s   default-scheduler  0/2 nodes are available: 1 node(s) didn't have free ports for the requested pod ports, 1 node(s) had taints that the pod didn't tolerate.

由于kubernete所提供强大的编排能力,根据上图所示,如果pod_web从worker2调度到worker1上,此时访问pod_web所提供nginx服务,就需要重新查询woker1的ip地址。也就是说通过hostport暴露pod服务是和node的ip地址所绑定的。

那么,有没有一种方式,不管pod被调度在哪里,也就是上图中的pod_web,我不管你在node_worker1上还是在node_worker2上,我都有一个固定的访问地址,能够访问pod所提供的服务呢?

service对象就是专门来做这样事情的,service是为多个功能相同的pod提供一个固定的访问入口,不管背后的pod是如何变化,是增加一个还是减少一个,还是从一个node调度到另外一个node。使用这个固定的访问入口就可以访问到背后的pod。。如下图所示,首先service对象(web-service)通过选择器选择相应的pod(web1和web2),然后通过配置映射相应的端口,最后kubernetes会为service生成一个cluster ip地址。就可以通过cluster ip加端口访问其选择的pod了。

pod2.png
# 分别在两个节点上创建一个pod
# cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: svc-pod1
 labels:
   app: web
spec:
 nodeName: compute1
 containers:
 - name: nginx
   image: nginx
 - name: tomcat
   image: tomcat
# cat pod2.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: svc-pod2
 labels:
   app: web
spec:
 nodeName: worker1
 containers:
 - name: nginx
   image: nginx
 - name: tomcat
   image: tomcat
# 创建一个service对象
# cat svc1.yaml 
apiVersion: v1
kind: Service
metadata:
 name: svc-web1
spec:
 selector:
   app: web
 ports:
  - port: 80
    targetPort: 80
    name: nginx
  - port: 8080
    targetPort: 8080
    name: tomcat
# 查看service的cluster ip
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)
svc-web1       ClusterIP   10.102.136.177   <none>        80/TCP,8080/TCP
# 通过同一个cluster ip,即可以访问worker1上的pod,也可以访问worker2上的p,访问规则可以根据cpu等资源使用来确定,默认是轮询
# curl http://10.102.136.177:8080   # 在任何一个节点(master或worker)上都能够得到正常的响应

# 设置type为NodePort使得外部可以进行访问
# cat svc-web2
apiVersion: v1
kind: Service
metadata:
 name: svc-web2
spec:
 type: NodePort
 selector:
   app: web
 ports:
  - port: 80
    targetPort: 80
    name: nginx
    # nodePort: 30000  nodeport不手动指定,kubernetes会自动指定
  - port: 8080
    targetPort: 8080
    name: tomcat
#  kubectl get service -o wide
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S) 
svc-web2       NodePort    10.100.104.20    <none>        80:31245/TCP,8080:31723/TCP
# curl http://node_ip:31245  # 集群中的任何一个节点的ip地址都可以

外网访问流程(以上为例子)

  1. 创建一个service对象后,每个node上的kube-proxy会对iptables进行编写转发规则
  2. 发起一个请求 curl http://node_ip:31723
  3. iptables中的规则会将该流转发对某一个worker_ip
  4. iptables中的规则会将2中的流转发到servie_ip:
  5. iptables中的规则会将3中的流转发到pod_ip上去
  6. 最后请求到达了pod中的容器中去了

小结: 不管iptables怎么进行转换,最终的目的是将请求发送到某个pod里的某容器中去

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